Skip to content
This repository has been archived by the owner on Nov 6, 2024. It is now read-only.

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
gdotdesign committed Jul 18, 2018
0 parents commit ec73b8d
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.mint
dist
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# mint-codemirror
This package provides a component for the [CodeMirror](https://codemirror.net) code editor to be used in Mint projects.

## Installation
To use the component just add this to the `dependencies` field of the projects
`mint.json` file.

```
"mint-codemirror": {
"repository": "https://github.com/mint-lang/mint-codemirror",
"constraint": "1.0.0 <= v < 2.0.0"
}
```

## Usage
To get the basic component without any modes and the default theme, just add the component to your render function:

```
component Main {
fun onChange (value : String) : Void {
do {
Debug.log(value)
}
}
fun render : Html {
<CodeMirror onChange={onChange}/>
}
}
```

## Properties
The following properties are available:
* `javaScripts : Array(String)` - URLs for the JavaScript files that are needed for CodeMirror to work. This can come from a CDN or from local files. This should contian the base JavaScript and any other addons or modes that is required.
* `styles : Array(String)` - URLs for the CSS files that are that are needed for CodeMirror to work. This can come from a CDN or from local files. This should contain the base CSS and any other files for themes.
* `loadingContent : Html` - This is shown until the all the files have loaded and editor is ready.
* `onChange : Function(String, Void)` - This is called when the content changes.
* `value : String` - When provided this value will be in the editor.

## Advanced Usage
This is an example for using the all of the properties:
```
```
12 changes: 12 additions & 0 deletions mint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "mint-codemirror",
"source-directories": [
"source"
],
"dependencies": {
"mint-core": {
"repository": "https://github.com/mint-lang/mint-core",
"constraint": "0.0.0 <= v < 1.0.0"
}
}
}
35 changes: 35 additions & 0 deletions source/AssetLoader.mint
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* Functions for loading assets (JavaScripts, CSS) asyncronously. */
module AssetLoader {
/* Loads the stylesheet from the given URL. */
fun loadStyle (url : String) : Promise(Never, Void) {
`
new Promise((resolve, reject) => {
let link = document.createElement('link')
link.rel = "stylesheet"
document.head.appendChild(link)
link.onload = resolve
link.href = url
})
`
}

/* Loads the script from the given URL. */
fun loadScript (url : String) : Promise(Never, Void) {
`
new Promise((resolve, reject) => {
let script = document.createElement('script')
document.body.appendChild(script)
script.onload = () => {
document.body.removeChild(script)
resolve()
}
script.src = url
})
`
}

/* Waits for all promises to load. */
fun loadAll (promises : Array(Promise(a, b))) : Promise(a, b) {
`Promise.all(promises)`
}
}
136 changes: 136 additions & 0 deletions source/CodeMirror.mint
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/* A component that integrates the CodeMirror editor. */
component CodeMirror {
/* The JavaScript files of Codemirror to load, either locally or from a CDN. */
property javaScripts : Array(String) = [
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.39.0" \
"/codemirror.min.js"
]

/* The CSS files of Codemirror to load, either locally or from a CDN. */
property styles : Array(String) = [
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.39.0" \
"/codemirror.min.css"
]

/* The content to display until the editor is loaded. */
property loadingContent : Html = Html.empty()

/* Handler for the change event. */
property onChange : Function(String, Void) = (\value : String => void)

/* The value of the editor. */
property value : String = ""

/* The theme of the editor. */
property theme : String = ""

/* The mode of the editor. */
property mode : String = ""

/* Whether or not show line numbers. */
property lineNumbers : Bool = true

/* Initializes the editor for the given dom element. */
fun initializeEditor (element : Dom.Element) : Void {
do {
javaScripts
|> Array.map(AssetLoader.loadScript)
|> AssetLoader.loadAll()

styles
|> Array.map(AssetLoader.loadStyle)
|> AssetLoader.loadAll()

`
(() => {
if (this.editor) { return }

this.editor = CodeMirror.fromTextArea(element, {
lineNumbers: this.lineNumbers,
theme: this.theme,
mode: this.mode,
})

this.editor.on('change', (value) => {
this.onChange(this.editor.getValue())
})

this.forceUpdate()
})()
`
}
}

/* After an update, update the underlying editor instance. */
fun componentDidUpdate : Void {
`
(() => {
if (this.editor) {
if (this.props.value != null) {
if (this.editor.getValue() !== this.props.value) {
this.editor.setValue(this.props.value);
}
}
}
})()
`
}

style editor {
display: {display};
}

/*
Returns the content for the `display` property,
to hide the textarea until it's ready.
*/
get display : String {
if (`this.editor`) {
""
} else {
"none"
}
}

/* Renders the component. */
fun render : Array(Html) {
[
<textarea::editor ref={initializeEditor}/>,
if (`this.editor`) {
Html.empty()
} else {
loadingContent
}
]
}
}

record Main.State {
value : String
}
component Main {
state : Main.State {
value = "function(){ \n <div>{ this.text }</div>\n}"
}

fun onChange (value : String) : Void {
next { state | value = value }
}

fun render : Html {
<CodeMirror
javaScripts=[
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.39.0/codemirror.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.39.0/mode/jsx/jsx.min.js"
]
styles=[
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.39.0/codemirror.min.css",
"https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.39.0/theme/dracula.min.css",
]
onChange={onChange}
value={state.value}
theme="dracula"
mode="jsx"
/>
}
}

0 comments on commit ec73b8d

Please sign in to comment.