@fusion.dev/helix-sandbox 0.0.0-dev

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -0
  3. package/api.json +1 -0
  4. package/custom-elements.json +1182 -0
  5. package/dist/code-block/code-block-highlight.d.ts +16 -0
  6. package/dist/code-block/code-block-highlight.d.ts.map +1 -0
  7. package/dist/code-block/code-block-highlight.js +10 -0
  8. package/dist/code-block/code-block-highlight.js.map +1 -0
  9. package/dist/code-block/index.d.ts +2 -0
  10. package/dist/code-block/index.d.ts.map +1 -0
  11. package/dist/code-block/index.js +5 -0
  12. package/dist/code-block/index.js.map +1 -0
  13. package/dist/editor/index.d.ts +2 -0
  14. package/dist/editor/index.d.ts.map +1 -0
  15. package/dist/editor/index.js +2 -0
  16. package/dist/editor/index.js.map +1 -0
  17. package/dist/editor/root/editor-root.css.d.ts +2 -0
  18. package/dist/editor/root/editor-root.css.d.ts.map +1 -0
  19. package/dist/editor/root/editor-root.css.js +3 -0
  20. package/dist/editor/root/editor-root.css.js.map +1 -0
  21. package/dist/editor/root/editor-root.d.ts +146 -0
  22. package/dist/editor/root/editor-root.d.ts.map +1 -0
  23. package/dist/editor/root/editor-root.js +199 -0
  24. package/dist/editor/root/editor-root.js.map +1 -0
  25. package/dist/highlight/highlight.d.ts +25 -0
  26. package/dist/highlight/highlight.d.ts.map +1 -0
  27. package/dist/highlight/highlight.js +97 -0
  28. package/dist/highlight/highlight.js.map +1 -0
  29. package/dist/highlight/index.d.ts +4 -0
  30. package/dist/highlight/index.d.ts.map +1 -0
  31. package/dist/highlight/index.js +4 -0
  32. package/dist/highlight/index.js.map +1 -0
  33. package/dist/highlight/language.d.ts +26 -0
  34. package/dist/highlight/language.d.ts.map +1 -0
  35. package/dist/highlight/language.js +21 -0
  36. package/dist/highlight/language.js.map +1 -0
  37. package/dist/highlight/shell.d.ts +10 -0
  38. package/dist/highlight/shell.d.ts.map +1 -0
  39. package/dist/highlight/shell.js +31 -0
  40. package/dist/highlight/shell.js.map +1 -0
  41. package/dist/highlight/stream.d.ts +10 -0
  42. package/dist/highlight/stream.d.ts.map +1 -0
  43. package/dist/highlight/stream.js +178 -0
  44. package/dist/highlight/stream.js.map +1 -0
  45. package/dist/highlight/syntax.d.ts +10 -0
  46. package/dist/highlight/syntax.d.ts.map +1 -0
  47. package/dist/highlight/syntax.js +100 -0
  48. package/dist/highlight/syntax.js.map +1 -0
  49. package/dist/index.d.ts +20 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +2 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/sandbox/editor/sandbox-editor.css.d.ts +2 -0
  54. package/dist/sandbox/editor/sandbox-editor.css.d.ts.map +1 -0
  55. package/dist/sandbox/editor/sandbox-editor.css.js +3 -0
  56. package/dist/sandbox/editor/sandbox-editor.css.js.map +1 -0
  57. package/dist/sandbox/editor/sandbox-editor.d.ts +147 -0
  58. package/dist/sandbox/editor/sandbox-editor.d.ts.map +1 -0
  59. package/dist/sandbox/editor/sandbox-editor.js +199 -0
  60. package/dist/sandbox/editor/sandbox-editor.js.map +1 -0
  61. package/examples.json +1 -0
  62. package/lint.json +1 -0
  63. package/package.json +116 -0
  64. package/types/jsx.d.ts +638 -0
  65. package/types/svelte.d.ts +36 -0
  66. package/types/vue.d.ts +134 -0
  67. package/types/words.d.ts +22 -0
@@ -0,0 +1,16 @@
1
+ import { type CSSResult } from 'lit';
2
+ /**
3
+ * Highlights a block's code by its `language`, in any case and by any name
4
+ * `languageOf` reads, such as `ts`, `TypeScript` or `bash`, or returns
5
+ * `undefined` for a language no grammar here reads, which the block then
6
+ * draws plain.
7
+ *
8
+ * **In the editor's own style**, so a snippet in a block and the same snippet
9
+ * open in the sandbox are colored by one source: the classes are the ones
10
+ * `syntaxHighlighter` gives each token, and `codeBlockSheet` holds the rules
11
+ * for them, in the `--helix-color-syntax-*` tokens.
12
+ */
13
+ export declare const codeBlockHighlighter: (code: string, language: string) => string | undefined;
14
+ /** The rules that color `codeBlockHighlighter`'s classes, for a block to adopt. */
15
+ export declare const codeBlockSheet: CSSResult;
16
+ //# sourceMappingURL=code-block-highlight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block-highlight.d.ts","sourceRoot":"","sources":["../../src/code-block/code-block-highlight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,KAAK,CAAA;AAK/C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,SAAU,MAAM,YAAY,MAAM,KAAG,MAAM,GAAG,SAG9E,CAAA;AAED,mFAAmF;AACnF,eAAO,MAAM,cAAc,EAAE,SAAkC,CAAA"}
@@ -0,0 +1,10 @@
1
+ import { unsafeCSS } from 'lit';
2
+ import { highlight } from '../highlight/highlight.js';
3
+ import { languageOf } from '../highlight/language.js';
4
+ import { syntaxHighlighter, syntaxRules } from '../highlight/syntax.js';
5
+ export const codeBlockHighlighter = (code, language) => {
6
+ const grammar = languageOf(language);
7
+ return grammar ? highlight(code, grammar, syntaxHighlighter) : undefined;
8
+ };
9
+ export const codeBlockSheet = unsafeCSS(syntaxRules);
10
+ //# sourceMappingURL=code-block-highlight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-block-highlight.js","sourceRoot":"","sources":["../../src/code-block/code-block-highlight.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,MAAM,KAAK,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAavE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAsB,EAAE;IACzF,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;IACpC,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAC1E,CAAC,CAAA;AAGD,MAAM,CAAC,MAAM,cAAc,GAAc,SAAS,CAAC,WAAW,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { codeBlockHighlighter, codeBlockSheet } from './code-block-highlight.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/code-block/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { registerHighlighter } from '@fusion.dev/helix-headless/code-block';
2
+ import { codeBlockHighlighter, codeBlockSheet } from './code-block-highlight.js';
3
+ registerHighlighter(codeBlockHighlighter, codeBlockSheet);
4
+ export { codeBlockHighlighter, codeBlockSheet } from './code-block-highlight.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/code-block/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAA;AAC3E,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAEhF,mBAAmB,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAA;AAEzD,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from '../sandbox/editor/sandbox-editor.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/editor/index.ts"],"names":[],"mappings":"AASA,cAAc,qCAAqC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from '../sandbox/editor/sandbox-editor.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/editor/index.ts"],"names":[],"mappings":"AASA,cAAc,qCAAqC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const styles: import("lit").CSSResult;
2
+ //# sourceMappingURL=editor-root.css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-root.css.d.ts","sourceRoot":"","sources":["../../../src/editor/root/editor-root.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,yBAAihC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { createSheet } from '@fusion.dev/helix-core';
2
+ export const styles = createSheet(`:host {display: block;min-block-size: 0;overflow: hidden}[part="editor"] {block-size: 100%;font-family: var(--helix-font-mono);font-size: var(--helix-text-sm)}[part="editor"] .cm-editor {block-size: 100%}[part="editor"] .cm-scroller {font-family: inherit;line-height: var(--helix-leading-normal)}[part="editor"] .cm-gutters {background-color: transparent;border: none;color: var(--helix-color-foreground-muted)}[part="editor"] .cm-activeLineGutter, [part="editor"] .cm-activeLine {background-color: var(--helix-color-surface-sunken)}[part="editor"] .cm-content {caret-color: var(--helix-color-primary)}[part="editor"] .cm-cursor {border-left-color: var(--helix-color-primary)}[part="editor"] .cm-selectionBackground, [part="editor"] .cm-editor.cm-focused .cm-selectionBackground {background-color: var(--helix-color-primary-subtle)}[part="editor"] .cm-editor.cm-focused {outline: none}:host([readonly]) [part="editor"] .cm-cursor {border-left-color: var(--helix-color-foreground-subtle)}@media print {:host {display: none}}`);
3
+ //# sourceMappingURL=editor-root.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-root.css.js","sourceRoot":"","sources":["../../../src/editor/root/editor-root.css.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAEpD,MAAM,CAAC,MAAM,MAAM,GAAG,WAAW,CAAC,igCAAigC,CAAC,CAAA"}
@@ -0,0 +1,146 @@
1
+ import { type CaretDetail, HelixElement } from '@fusion.dev/helix-core';
2
+ import type { CSSResultGroup, PropertyValues, TemplateResult } from 'lit';
3
+ /**
4
+ * A language the editor knows, by the name a file or a sandbox pane carries.
5
+ *
6
+ * **Written out, where `keyof typeof` would hide the values.** The manifest
7
+ * records a property's type as the text somebody wrote, so a type derived from
8
+ * a record's keys reached it as a name with nothing in it and the reference
9
+ * page listed no values. A union on one line resolves for every reader of these
10
+ * sources without a type system, the `axes` rule included.
11
+ *
12
+ * The names are the panes': `js`, `jsx`, `mjs`, `ts` and `tsx` beside `css`,
13
+ * `html` and `sh`, and `javascript`. The editor reads every name `languageOf`
14
+ * from `@fusion.dev/helix-sandbox/highlight` reads, such as `TypeScript` or
15
+ * `bash`, and `jsx` as `tsx`.
16
+ */
17
+ export type EditorLanguage = 'css' | 'html' | 'javascript' | 'js' | 'jsx' | 'mjs' | 'sh' | 'ts' | 'tsx';
18
+ /**
19
+ * @summary An editable pane of source, with highlighting and line numbers.
20
+ *
21
+ * @description
22
+ * CodeMirror, not a `<textarea>`. A textarea cannot highlight what it holds,
23
+ * number its lines, or say where the cursor is, and a status bar reading line
24
+ * and column has to ask something.
25
+ *
26
+ * **On its own path.** This is `@fusion.dev/helix-sandbox/editor`, and the
27
+ * package's root exports its class as a type only, because CodeMirror is most
28
+ * of what the package weighs over the wire. A sandbox with no editable pane
29
+ * pays for none, and neither does a site that registers its elements once.
30
+ *
31
+ * `language` names the grammar by the name a file or a sandbox pane carries:
32
+ * `css`, `html`, `js`, `jsx`, `mjs`, `sh`, `ts` or `tsx`. A name the editor
33
+ * does not read draws the source plain, and the console says so once.
34
+ *
35
+ * Each edit a reader makes is `helix-before-edit` first, which you can cancel
36
+ * to refuse the edit, and `helix-edit` once the source holds it, as
37
+ * `helix-sandbox-source` sends them. A `value` set from outside is the source the editor is given, and
38
+ * sends neither. **The editor is `:state(modified)` while its source differs
39
+ * from the source it was given**, the first `value` or the last one set from
40
+ * outside, and `reset()` puts that source back as an edit.
41
+ *
42
+ * The view is built once and reconfigured, not rebuilt. Replacing it on every
43
+ * change would throw away the undo history, the scroll position, and the
44
+ * selection, which is most of what an editor is.
45
+ *
46
+ * @since 0.1.0
47
+ * @status experimental
48
+ * @category tooling
49
+ * @aliases Code editor, Source pane
50
+ * @documentation https://fusion.dev/helix/docs/sandbox
51
+ *
52
+ * @event {HelixBeforeEditEvent} helix-before-edit - Fired before the source is edited. Cancelable: refusing it takes the decision and nothing moves.
53
+ * @event {HelixCaretEvent} helix-caret - Fired when the cursor moves, with its line and column.
54
+ * @event {HelixEditEvent} helix-edit - Fired after the source was edited, with the new source.
55
+ *
56
+ * @csspart editor - The element CodeMirror is mounted into.
57
+ *
58
+ * @cssstate modified - While the source differs from the source the editor was given, until `reset()` or a new `value`.
59
+ */
60
+ export declare class HelixSandboxEditor extends HelixElement {
61
+ /**
62
+ * The key the editor's words are registered under, its tag:
63
+ * `registerWords('de', { 'helix-sandbox-editor': { fieldLabel: 'Quelltext' } })`.
64
+ */
65
+ static words: string;
66
+ /**
67
+ * Accessible name for the editable region.
68
+ */
69
+ fieldLabel: string;
70
+ /**
71
+ * The language of the source, which decides how it is highlighted. A name
72
+ * the editor does not read draws the source plain.
73
+ */
74
+ language: EditorLanguage;
75
+ /**
76
+ * Which source this pane holds, echoed in every change.
77
+ */
78
+ name: string;
79
+ /**
80
+ * Whether the text can be changed.
81
+ *
82
+ * `EditorState.readOnly` rather than removing the editor's focus or its
83
+ * keymap: a reader still needs to select the text, scroll it, and put a
84
+ * cursor in it to read a long line. What it stops is the typing.
85
+ */
86
+ readOnly: boolean;
87
+ /**
88
+ * The source being edited.
89
+ */
90
+ value: string;
91
+ private readonly readOnly$;
92
+ private view;
93
+ private readonly language$;
94
+ /** The editable region's name, which follows `field-label` and the words registered for it. */
95
+ private readonly name$;
96
+ /** The source the editor was given: its first `value`, or the last one set from outside. */
97
+ private baseline;
98
+ /** The source the last edit left, while `value` still holds it. */
99
+ private edited;
100
+ /** The `language` last reported as one the editor does not read. */
101
+ private unread;
102
+ /**
103
+ * Whether the source differs from the source the editor was given: its
104
+ * first `value`, or the last one set from outside.
105
+ */
106
+ get modified(): boolean;
107
+ /**
108
+ * Puts back the source the editor was given, as an edit: `helix-before-edit`
109
+ * is sent first and can refuse it, and a sandbox passes it to its preview.
110
+ */
111
+ reset(): void;
112
+ /**
113
+ * What `language` turns on: its grammar, or nothing for a name the editor
114
+ * does not read, which it reports once for each name.
115
+ */
116
+ private grammar;
117
+ /** Where the cursor is, counted from one, as an editor reports it. */
118
+ get caret(): CaretDetail;
119
+ private get mount();
120
+ /**
121
+ * Builds the view once the mount exists.
122
+ *
123
+ * `root` is the shadow root rather than the document, or CodeMirror puts its
124
+ * stylesheet where this element cannot see it and the editor renders unstyled.
125
+ */
126
+ private create;
127
+ /**
128
+ * Moves focus into the text, not onto the host.
129
+ *
130
+ * The host is not focusable: what a reader types into is CodeMirror's
131
+ * contenteditable, several nodes down inside this shadow root. Without this,
132
+ * `editor.focus()` from outside silently does nothing.
133
+ */
134
+ focus(): void;
135
+ disconnectedCallback(): void;
136
+ protected willUpdate(changed: PropertyValues): void;
137
+ protected updated(changed: PropertyValues): void;
138
+ protected render(): TemplateResult;
139
+ static styles: CSSResultGroup;
140
+ }
141
+ declare global {
142
+ interface HTMLElementTagNameMap {
143
+ 'helix-sandbox-editor': HelixSandboxEditor;
144
+ }
145
+ }
146
+ //# sourceMappingURL=editor-root.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-root.d.ts","sourceRoot":"","sources":["../../../src/editor/root/editor-root.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,WAAW,EAKhB,YAAY,EAGb,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AAQzE;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,GACtB,KAAK,GACL,MAAM,GACN,YAAY,GACZ,IAAI,GACJ,KAAK,GACL,KAAK,GACL,IAAI,GACJ,IAAI,GACJ,KAAK,CAAA;AA0BT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,qBACa,kBAAmB,SAAQ,YAAY;IAClD;;;OAGG;IACH,MAAM,CAAC,KAAK,SAAyB;IAErC;;OAEG;IAGH,UAAU,SAAmB;IAE7B;;;OAGG;IAEH,QAAQ,EAAE,cAAc,CAAS;IAEjC;;OAEG;IAEH,IAAI,SAAS;IAEb;;;;;;OAMG;IAEH,QAAQ,UAAQ;IAEhB;;OAEG;IAEH,KAAK,SAAK;IAEV,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAE9C,OAAO,CAAC,IAAI,CAAwB;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAE9C,+FAA+F;IAC/F,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAE1C,4FAA4F;IAC5F,OAAO,CAAC,QAAQ,CAAK;IAErB,mEAAmE;IACnE,OAAO,CAAC,MAAM,CAAoB;IAElC,oEAAoE;IACpE,OAAO,CAAC,MAAM,CAAoB;IAElC;;;OAGG;IACH,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;OAGG;IACH,KAAK,IAAI,IAAI,CAKZ;IAED;;;OAGG;IACH,OAAO,CAAC,OAAO;IAkBf,sEAAsE;IACtE,IAAI,KAAK,IAAI,WAAW,CAQvB;IAED,OAAO,KAAK,KAAK,GAEhB;IAED;;;;;OAKG;IACH,OAAO,CAAC,MAAM;IAiFd;;;;;;OAMG;IACM,KAAK,IAAI,IAAI,CAErB;IAEQ,oBAAoB,IAAI,IAAI,CAIpC;IAED,UAAmB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAQ3D;IAED,UAAmB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAwCxD;IAED,UAAmB,MAAM,IAAI,cAAc,CAE1C;IAED,OAAgB,MAAM,EAAE,cAAc,CAAmC;CAC1E;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,kBAAkB,CAAA;KAC3C;CACF"}
@@ -0,0 +1,199 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands';
8
+ import { css } from '@codemirror/lang-css';
9
+ import { html as htmlLanguage } from '@codemirror/lang-html';
10
+ import { javascript } from '@codemirror/lang-javascript';
11
+ import { indentUnit, StreamLanguage, syntaxHighlighting } from '@codemirror/language';
12
+ import { Annotation, Compartment, EditorState } from '@codemirror/state';
13
+ import { EditorView, keymap, lineNumbers } from '@codemirror/view';
14
+ import { customElement, HelixBeforeEditEvent, HelixCaretEvent, HelixEditEvent, HelixElement, reportRuntime, words, } from '@fusion.dev/helix-core';
15
+ import { html, unsafeCSS } from 'lit';
16
+ import { property } from 'lit/decorators.js';
17
+ import { languageOf } from '../../highlight/language.js';
18
+ import { shellMode, shellTokens } from '../../highlight/shell.js';
19
+ import { syntaxHighlighter, syntaxRules } from '../../highlight/syntax.js';
20
+ import { styles } from './editor-root.css.js';
21
+ const shellLanguage = StreamLanguage.define({ ...shellMode, tokenTable: shellTokens });
22
+ const LANGUAGES = {
23
+ css: () => css(),
24
+ html: () => htmlLanguage(),
25
+ js: () => javascript(),
26
+ sh: () => shellLanguage,
27
+ ts: () => javascript({ typescript: true }),
28
+ tsx: () => javascript({ jsx: true, typescript: true }),
29
+ };
30
+ const given = Annotation.define();
31
+ let HelixSandboxEditor = class HelixSandboxEditor extends HelixElement {
32
+ constructor() {
33
+ super(...arguments);
34
+ this.fieldLabel = 'Example source';
35
+ this.language = 'html';
36
+ this.name = 'html';
37
+ this.readOnly = false;
38
+ this.value = '';
39
+ this.readOnly$ = new Compartment();
40
+ this.language$ = new Compartment();
41
+ this.name$ = new Compartment();
42
+ this.baseline = '';
43
+ }
44
+ static { this.words = 'helix-sandbox-editor'; }
45
+ get modified() {
46
+ return this.value === this.edited && this.value !== this.baseline;
47
+ }
48
+ reset() {
49
+ const view = this.view;
50
+ if (view && this.modified) {
51
+ view.dispatch({ changes: { from: 0, insert: this.baseline, to: view.state.doc.length } });
52
+ }
53
+ }
54
+ grammar() {
55
+ const read = languageOf(typeof this.language === 'string' ? this.language : '');
56
+ if (read !== undefined) {
57
+ return LANGUAGES[read]();
58
+ }
59
+ if (this.unread !== this.language) {
60
+ this.unread = this.language;
61
+ reportRuntime({
62
+ kind: 'unknown-language',
63
+ message: `<${this.localName} language="${this.language}"> names no language the editor reads, ` +
64
+ 'so its source is drawn plain. Use css, html, js, jsx, mjs, sh, ts or tsx.',
65
+ tag: this.localName,
66
+ });
67
+ }
68
+ return [];
69
+ }
70
+ get caret() {
71
+ const state = this.view?.state;
72
+ if (!state) {
73
+ return { column: 1, line: 1 };
74
+ }
75
+ const head = state.selection.main.head;
76
+ const line = state.doc.lineAt(head);
77
+ return { column: head - line.from + 1, line: line.number };
78
+ }
79
+ get mount() {
80
+ return this.renderRoot.querySelector('[part="editor"]');
81
+ }
82
+ create() {
83
+ const parent = this.mount;
84
+ if (!parent || this.view) {
85
+ return;
86
+ }
87
+ this.view = new EditorView({
88
+ parent,
89
+ root: this.shadowRoot ?? document,
90
+ state: EditorState.create({
91
+ doc: this.value,
92
+ extensions: [
93
+ lineNumbers(),
94
+ history(),
95
+ indentUnit.of(' '),
96
+ EditorState.tabSize.of(2),
97
+ keymap.of([...defaultKeymap, ...historyKeymap, indentWithTab]),
98
+ syntaxHighlighting(syntaxHighlighter, { fallback: true }),
99
+ this.language$.of(this.grammar()),
100
+ this.readOnly$.of(EditorState.readOnly.of(this.readOnly)),
101
+ EditorView.lineWrapping,
102
+ EditorState.transactionFilter.of((transaction) => {
103
+ if (!transaction.docChanged || transaction.annotation(given)) {
104
+ return transaction;
105
+ }
106
+ const next = transaction.newDoc.toString();
107
+ const request = new HelixBeforeEditEvent({ value: next });
108
+ return this.dispatchEvent(request) ? transaction : [];
109
+ }),
110
+ EditorView.updateListener.of((update) => {
111
+ const edit = update.docChanged &&
112
+ !update.transactions.some((transaction) => transaction.annotation(given));
113
+ if (edit) {
114
+ const next = update.state.doc.toString();
115
+ this.edited = next;
116
+ this.value = next;
117
+ this.dispatchEvent(new HelixEditEvent({ value: next }));
118
+ }
119
+ if (update.selectionSet || update.docChanged || update.focusChanged) {
120
+ this.dispatchEvent(new HelixCaretEvent(this.caret));
121
+ }
122
+ }),
123
+ this.name$.of(EditorView.contentAttributes.of({ 'aria-label': this.fieldLabel })),
124
+ ],
125
+ }),
126
+ });
127
+ this.dispatchEvent(new HelixCaretEvent(this.caret));
128
+ }
129
+ focus() {
130
+ this.view?.focus();
131
+ }
132
+ disconnectedCallback() {
133
+ super.disconnectedCallback();
134
+ this.view?.destroy();
135
+ this.view = undefined;
136
+ }
137
+ willUpdate(changed) {
138
+ super.willUpdate(changed);
139
+ if (this.value !== this.edited) {
140
+ this.baseline = this.value;
141
+ this.edited = undefined;
142
+ }
143
+ this.toggleState('modified', this.modified);
144
+ }
145
+ updated(changed) {
146
+ super.updated(changed);
147
+ this.create();
148
+ const view = this.view;
149
+ if (!view) {
150
+ return;
151
+ }
152
+ if (changed.has('language')) {
153
+ view.dispatch({ effects: this.language$.reconfigure(this.grammar()) });
154
+ }
155
+ if (changed.has('fieldLabel')) {
156
+ view.dispatch({
157
+ effects: this.name$.reconfigure(EditorView.contentAttributes.of({ 'aria-label': this.fieldLabel })),
158
+ });
159
+ }
160
+ if (changed.has('readOnly')) {
161
+ view.dispatch({
162
+ effects: this.readOnly$.reconfigure(EditorState.readOnly.of(this.readOnly)),
163
+ });
164
+ }
165
+ if (changed.has('value') && this.value !== view.state.doc.toString()) {
166
+ const head = view.state.selection.main.head;
167
+ view.dispatch({
168
+ annotations: given.of(true),
169
+ changes: { from: 0, insert: this.value, to: view.state.doc.length },
170
+ selection: { anchor: Math.min(head, this.value.length) },
171
+ });
172
+ }
173
+ }
174
+ render() {
175
+ return html `<div part="editor"></div>`;
176
+ }
177
+ static { this.styles = [styles, unsafeCSS(syntaxRules)]; }
178
+ };
179
+ __decorate([
180
+ words,
181
+ property({ attribute: 'field-label' })
182
+ ], HelixSandboxEditor.prototype, "fieldLabel", void 0);
183
+ __decorate([
184
+ property()
185
+ ], HelixSandboxEditor.prototype, "language", void 0);
186
+ __decorate([
187
+ property()
188
+ ], HelixSandboxEditor.prototype, "name", void 0);
189
+ __decorate([
190
+ property({ attribute: 'readonly', reflect: true, type: Boolean })
191
+ ], HelixSandboxEditor.prototype, "readOnly", void 0);
192
+ __decorate([
193
+ property()
194
+ ], HelixSandboxEditor.prototype, "value", void 0);
195
+ HelixSandboxEditor = __decorate([
196
+ customElement('helix-sandbox-editor')
197
+ ], HelixSandboxEditor);
198
+ export { HelixSandboxEditor };
199
+ //# sourceMappingURL=editor-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-root.js","sourceRoot":"","sources":["../../../src/editor/root/editor-root.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type Highlighter } from '@lezer/highlight';
2
+ import type { HighlightLanguage } from './language.js';
3
+ /**
4
+ * Highlights a snippet, returning HTML with one span per token.
5
+ *
6
+ * **A parser, and no editor.** Lezer's grammars are parsers, and parsing is a
7
+ * pure function of the text: `highlightCode` walks a tree and hands back
8
+ * tokens. Nothing is mounted, no document is created, and this runs on a server
9
+ * with no DOM at all, which is what lets a static page ship highlighted code
10
+ * with no client JavaScript spent on it.
11
+ *
12
+ * **`CodeBlock` holds no parser.** A `dependencies` entry is paid by every
13
+ * consumer whether or not they import it, so the grammars are in this package,
14
+ * beside the editor that reads them too. `CodeBlock` renders a `<slot>`, so the
15
+ * output of this drops straight into one. A snippet on a reference page and the
16
+ * same snippet open in the sandbox are then colored by one source.
17
+ *
18
+ * `classHighlighter` emits Lezer's own `tok-` class names. Mapping those to
19
+ * colors is yours, because the classes are stable and a palette is not: the
20
+ * Fusion site paints them from `--helix-color-syntax-*`. Pass another
21
+ * `highlighter` for other classes, such as `syntaxHighlighter`, the editor's
22
+ * own, whose rules are `syntaxRules`.
23
+ */
24
+ export declare const highlight: (code: string, language: HighlightLanguage, highlighter?: Highlighter) => string;
25
+ //# sourceMappingURL=highlight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlight.d.ts","sourceRoot":"","sources":["../../src/highlight/highlight.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,WAAW,EAAiB,MAAM,kBAAkB,CAAA;AAGpF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AA2GtD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,SAAS,SACd,MAAM,YACF,iBAAiB,gBACd,WAAW,KACvB,MAcF,CAAA"}
@@ -0,0 +1,97 @@
1
+ import { parser as cssParser } from '@lezer/css';
2
+ import { classHighlighter, highlightCode } from '@lezer/highlight';
3
+ import { configureNesting, parser as htmlParser } from '@lezer/html';
4
+ import { parser as jsParser } from '@lezer/javascript';
5
+ import { shellMode, shellTokens } from './shell.js';
6
+ import { highlightStream } from './stream.js';
7
+ const EVENT_ATTRIBUTES = [
8
+ 'beforeunload',
9
+ 'blur',
10
+ 'change',
11
+ 'click',
12
+ 'copy',
13
+ 'cut',
14
+ 'drag',
15
+ 'dragend',
16
+ 'dragenter',
17
+ 'dragleave',
18
+ 'dragover',
19
+ 'dragstart',
20
+ 'focus',
21
+ 'keydown',
22
+ 'keyup',
23
+ 'load',
24
+ 'mousedown',
25
+ 'mouseenter',
26
+ 'mouseleave',
27
+ 'mouseup',
28
+ 'paste',
29
+ 'resize',
30
+ 'scroll',
31
+ 'unload',
32
+ ].map((name) => `on${name}`);
33
+ const typescript = jsParser.configure({ dialect: 'ts' });
34
+ const tsx = jsParser.configure({ dialect: 'jsx ts' });
35
+ const PARSERS = {
36
+ css: cssParser,
37
+ html: htmlParser.configure({
38
+ wrap: configureNesting([
39
+ {
40
+ attrs: (attrs) => attrs.type === 'text/typescript' || attrs.lang === 'ts',
41
+ parser: typescript,
42
+ tag: 'script',
43
+ },
44
+ {
45
+ attrs: (attrs) => attrs.type === 'text/babel' || attrs.type === 'text/jsx',
46
+ parser: jsParser.configure({ dialect: 'jsx' }),
47
+ tag: 'script',
48
+ },
49
+ {
50
+ attrs: (attrs) => attrs.type === 'text/typescript-jsx',
51
+ parser: tsx,
52
+ tag: 'script',
53
+ },
54
+ {
55
+ attrs: (attrs) => /^(importmap|speculationrules|application\/(.+\+)?json)$/i.test(attrs.type ?? ''),
56
+ parser: jsParser.configure({ top: 'SingleExpression' }),
57
+ tag: 'script',
58
+ },
59
+ {
60
+ attrs: (attrs) => !attrs.type ||
61
+ /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i.test(attrs.type),
62
+ parser: jsParser,
63
+ tag: 'script',
64
+ },
65
+ {
66
+ attrs: (attrs) => (!attrs.lang || attrs.lang === 'css') &&
67
+ (!attrs.type || /^(text\/)?(x-)?(stylesheet|css)$/i.test(attrs.type)),
68
+ parser: cssParser,
69
+ tag: 'style',
70
+ },
71
+ ], [
72
+ { name: 'style', parser: cssParser.configure({ top: 'Styles' }) },
73
+ ...EVENT_ATTRIBUTES.map((name) => ({ name, parser: jsParser })),
74
+ ]),
75
+ }),
76
+ js: jsParser,
77
+ ts: typescript,
78
+ tsx,
79
+ };
80
+ const escapeHtml = (text) => text.replace(/[&<>"']/g, (char) => ({ "'": '&#39;', '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' })[char] ?? char);
81
+ export const highlight = (code, language, highlighter = classHighlighter) => {
82
+ let out = '';
83
+ const put = (text, classes) => {
84
+ out += classes ? `<span class="${classes}">${escapeHtml(text)}</span>` : escapeHtml(text);
85
+ };
86
+ const putBreak = () => {
87
+ out += '\n';
88
+ };
89
+ if (language === 'sh') {
90
+ highlightStream(code, shellMode, shellTokens, highlighter, put, putBreak);
91
+ }
92
+ else {
93
+ highlightCode(code, PARSERS[language].parse(code), highlighter, put, putBreak);
94
+ }
95
+ return out;
96
+ };
97
+ //# sourceMappingURL=highlight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlight.js","sourceRoot":"","sources":["../../src/highlight/highlight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { highlight } from './highlight.js';
2
+ export { type HighlightLanguage, languageOf } from './language.js';
3
+ export { syntaxHighlighter, syntaxRules } from './syntax.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/highlight/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { highlight } from './highlight.js';
2
+ export { languageOf } from './language.js';
3
+ export { syntaxHighlighter, syntaxRules } from './syntax.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/highlight/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAA0B,UAAU,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The languages a snippet can be written in.
3
+ *
4
+ * **`ts` and `tsx` are here because the documentation is mostly written in
5
+ * them**, and the base JavaScript grammar reads both wrongly, where a partial
6
+ * reading would be harmless. Measured on a `tsx` fence highlighted as `js`:
7
+ * `<helix-input` came out as the variable `helix`, the operator `-` and the
8
+ * variable `input`, which is the parser doing arithmetic on a tag name and
9
+ * coloring the result confidently. A grammar that does not know the dialect
10
+ * does not degrade, it lies.
11
+ *
12
+ * `tsx` covers JSX as well, since the dialect is a superset: there is no `jsx`
13
+ * member because a JSX file that is not TypeScript still parses under it, and
14
+ * a fourth entry would be a distinction with no consequence. `languageOf`
15
+ * reads `jsx` as `tsx`.
16
+ *
17
+ * `sh` is the one grammar here that is not shipped as it comes: see `shell.ts`
18
+ * for why a mode that knows sh perfectly colors nothing in `bun add`.
19
+ */
20
+ export type HighlightLanguage = 'css' | 'html' | 'js' | 'sh' | 'ts' | 'tsx';
21
+ /**
22
+ * The language a name stands for, in any case: `TypeScript`, `bash` or `mjs`.
23
+ * `undefined` for a name no grammar here reads.
24
+ */
25
+ export declare const languageOf: (name: string) => HighlightLanguage | undefined;
26
+ //# sourceMappingURL=language.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/highlight/language.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,CAAA;AA2B3E;;;GAGG;AACH,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,iBAAiB,GAAG,SAC5B,CAAA"}