Skip to content

Commit 50a9ceb

Browse files
authored
Merge pull request #1 from e111077/cm6-extensions
feat(editor): enable adding codemirror extensions
2 parents 0d51a88 + e2e388f commit 50a9ceb

13 files changed

+1451
-210
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
/playground-*.js
1717
/playground-*.d.ts
1818
/playground-*.d.ts.map
19+
/codemirror-extension*.js
20+
/codemirror-extension*.d.ts
21+
/codemirror-extension*.d.ts.map
1922
/cm-lang-lit.js
2023
/cm-lang-lit.d.ts
2124
/cm-lang-lit.d.ts.map

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616

1717
### Added
1818

19+
- Added `extensions` property to `<playground-ide>`,
20+
`<playground-file-editor>`, and `<playground-code-editor>` for applying
21+
programmatic CodeMirror extensions.
22+
- Added an `extensions` slot to `<playground-ide>`,
23+
`<playground-file-editor>`, and `<playground-code-editor>` for applying
24+
declarative CodeMirror extensions.
25+
- Exported `codemirrorExtensionMixin` for creating declarative CodeMirror
26+
extensions.
1927
- Upgraded CodeMirror to v6
2028

2129
### Fixed

README.md

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
• <a href="#typescript">TypeScript</a>
2222
• <a href="#hiding--folding">Hiding & Folding</a>
2323
• <a href="#custom-layouts">Custom layouts</a>
24+
• <a href="#extending-the-editor">Extending the editor</a>
2425
• <a href="#bundling">Bundling</a>
2526
• <a href="#sandbox-security">Sandbox security</a>
2627
• <a href="#components">Components</a>
@@ -517,6 +518,60 @@ Finally, add a little style:
517518
</style>
518519
```
519520

521+
## Extending the editor
522+
523+
Playground's code editor is built on [CodeMirror 6](https://codemirror.net/), and can be extended with any CodeMirror extension. This allows for deep customization of the editor's behavior, such as adding new themes, keymaps, autocompletion sources, and more.
524+
525+
There are two ways to apply extensions: programmatically and declaratively.
526+
527+
### Programmatic extensions
528+
529+
The `<playground-ide>`, `<playground-file-editor>`, and `<playground-code-editor>` components all have an `extensions` property which accepts a CodeMirror `Extension` object (or an array of them).
530+
531+
```js
532+
import {EditorView} from '@codemirror/view';
533+
534+
const ide = document.querySelector('playground-ide');
535+
const myTheme = EditorView.theme({
536+
'&': {
537+
backgroundColor: 'lightpink',
538+
},
539+
});
540+
ide.extensions = myTheme;
541+
```
542+
543+
### Declarative extensions
544+
545+
For simpler use-cases, or for when you want to package an extension as a reusable HTML element, you can use declarative extensions.
546+
547+
A declarative extension is a custom element that provides one or more CodeMirror extensions. Playground elements will automatically find any declarative extension elements placed in their `extensions` slot and apply them.
548+
549+
Here's an example of a custom theme packaged as a declarative extension:
550+
551+
```html
552+
<playground-ide>
553+
<my-theme-extension slot="extensions"></my-theme-extension>
554+
</playground-ide>
555+
556+
<script type="module">
557+
import {codemirrorExtensionMixin} from 'playground-elements';
558+
import {EditorView} from '@codemirror/view';
559+
560+
class MyTheme extends codemirrorExtensionMixin(HTMLElement) {
561+
getExtensions() {
562+
return EditorView.theme({
563+
'&': {
564+
backgroundColor: 'lightpink',
565+
},
566+
});
567+
}
568+
}
569+
customElements.define('my-theme-extension', MyTheme);
570+
</script>
571+
```
572+
573+
The `codemirrorExtensionMixin` handles the communication with the playground editor. Your class just needs to implement the `getExtensions()` method.
574+
520575
## Bundling
521576

522577
Playground uses a [Web
@@ -692,12 +747,14 @@ All-in-one project, editor, file switcher, and preview with a horizontal side-by
692747
| `modified` | `boolean` | `false` | Whether the user has modified, added, or removed any project files. Resets whenever a new project is loaded. |
693748
| `htmlFile` | `string` | `"index.html"` | The HTML file used in the preview. |
694749
| `noCompletions` | `boolean` | `false` | If interactive code completions should be shown. This setting only applies to TypeScript files. |
750+
| `extensions` | `Extension \| Extension[]` | `undefined` | A CodeMirror extension to apply to the editor ([details](#extending-the-editor)). |
695751

696752
### Slots
697753

698-
| Name | Description |
699-
| --------- | ----------------------------------------- |
700-
| `default` | Inline files ([details](#inline-scripts)) |
754+
| Name | Description |
755+
| ------------ | --------------------------------------------------------------------- |
756+
| `default` | Inline files ([details](#inline-scripts)). |
757+
| `extensions` | Declarative CodeMirror extensions ([details](#extending-the-editor)). |
701758

702759
---
703760

@@ -769,6 +826,13 @@ project element.
769826
| `pragmas` | `"on" \| "off" \| "off-visible"` | `"on"` | How to handle `playground-hide` and `playground-fold` comments ([details](#hiding--folding)). |
770827
| `readonly` | `boolean` | `false` | Do not allow edits |
771828
| `noCompletions` | `boolean` | `false` | If interactive code completions should be shown. This setting only applies to TypeScript files. |
829+
| `extensions` | `Extension \| Extension[]` | `undefined` | A CodeMirror extension to apply to the editor ([details](#extending-the-editor)). |
830+
831+
### Slots
832+
833+
| Name | Description |
834+
| ------------ | --------------------------------------------------------------------- |
835+
| `extensions` | Declarative CodeMirror extensions ([details](#extending-the-editor)). |
772836

773837
---
774838

@@ -787,6 +851,13 @@ A pure text editor based on CodeMirror with syntax highlighting for HTML, CSS, J
787851
| `pragmas` | `"on" \| "off" \| "off-visible"` | `"on"` | How to handle `playground-hide` and `playground-fold` comments ([details](#hiding--folding)). |
788852
| `documentKey` | `object` | `undefined` | Editor history for undo/redo is isolated per `documentKey`. Default behavior is a single instance. |
789853
| `noCompletions` | `boolean` | `false` | If interactive code completions should be shown. This setting only applies to TypeScript files. |
854+
| `extensions` | `Extension \| Extension[]` | `undefined` | A CodeMirror extension to apply to the editor ([details](#extending-the-editor)). |
855+
856+
### Slots
857+
858+
| Name | Description |
859+
| ------------ | --------------------------------------------------------------------- |
860+
| `extensions` | Declarative CodeMirror extensions ([details](#extending-the-editor)). |
790861

791862
### Events
792863

0 commit comments

Comments
 (0)