@dxos/react-ui-editor 0.6.8-main.046e6cf → 0.6.8-staging.63bcb81

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 (53) hide show
  1. package/dist/lib/browser/index.mjs +535 -521
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/TextEditor.stories.d.ts +5 -2
  5. package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/defaults.d.ts +2 -2
  7. package/dist/types/src/defaults.d.ts.map +1 -1
  8. package/dist/types/src/extensions/doc.d.ts +3 -0
  9. package/dist/types/src/extensions/doc.d.ts.map +1 -1
  10. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  11. package/dist/types/src/extensions/folding.d.ts.map +1 -1
  12. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  13. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  14. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
  15. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  16. package/dist/types/src/extensions/markdown/highlight.d.ts +2 -1
  17. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  18. package/dist/types/src/extensions/markdown/link-paste.d.ts +3 -0
  19. package/dist/types/src/extensions/markdown/link-paste.d.ts.map +1 -1
  20. package/dist/types/src/extensions/markdown/link.d.ts +3 -1
  21. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  22. package/dist/types/src/extensions/state.d.ts +14 -14
  23. package/dist/types/src/extensions/state.d.ts.map +1 -1
  24. package/dist/types/src/extensions/util/react.d.ts +1 -1
  25. package/dist/types/src/extensions/util/react.d.ts.map +1 -1
  26. package/dist/types/src/hooks/useTextEditor.d.ts +5 -3
  27. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  28. package/dist/types/src/index.d.ts +1 -0
  29. package/dist/types/src/index.d.ts.map +1 -1
  30. package/dist/types/src/styles/markdown.d.ts +7 -17
  31. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  32. package/dist/types/src/styles/theme.d.ts +3 -1
  33. package/dist/types/src/styles/theme.d.ts.map +1 -1
  34. package/dist/types/src/styles/tokens.d.ts +5 -7
  35. package/dist/types/src/styles/tokens.d.ts.map +1 -1
  36. package/package.json +24 -24
  37. package/src/TextEditor.stories.tsx +40 -27
  38. package/src/defaults.ts +9 -2
  39. package/src/extensions/doc.ts +3 -0
  40. package/src/extensions/factories.ts +3 -2
  41. package/src/extensions/folding.tsx +5 -7
  42. package/src/extensions/markdown/bundle.ts +1 -3
  43. package/src/extensions/markdown/decorate.ts +31 -24
  44. package/src/extensions/markdown/formatting.ts +3 -1
  45. package/src/extensions/markdown/highlight.ts +33 -19
  46. package/src/extensions/markdown/link-paste.ts +3 -0
  47. package/src/extensions/state.ts +41 -35
  48. package/src/extensions/util/react.tsx +3 -4
  49. package/src/hooks/useTextEditor.ts +24 -29
  50. package/src/index.ts +2 -0
  51. package/src/styles/markdown.ts +17 -40
  52. package/src/styles/theme.ts +91 -86
  53. package/src/styles/tokens.ts +9 -7
@@ -1 +1 @@
1
- {"version":3,"file":"useTextEditor.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useTextEditor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAIf,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAK5D,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,eAAe,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,GAAG;QACtD,QAAQ,EAAE,CAAC,CAAC;QACZ,OAAO,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;KAC/C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,WAAW,GAAG,YAAY,CAAC,GAAG;IACrF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,aAAa,WACjB,aAAa,CAAC,kBAAkB,CAAC,SAClC,cAAc,KACnB,aA6HF,CAAC"}
1
+ {"version":3,"file":"useTextEditor.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useTextEditor.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAGf,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,EAA6D,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhH,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,eAAe,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,GAAG;QACtD,QAAQ,EAAE,CAAC,CAAC;QACZ,OAAO,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAC;KAC/C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,GAAG;IACvE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,aAAa,WACjB,aAAa,CAAC,kBAAkB,CAAC,SAClC,cAAc,KACnB,aAwHF,CAAC"}
@@ -3,6 +3,7 @@ export { type Extension, type EditorState } from '@codemirror/state';
3
3
  export { type EditorView, keymap } from '@codemirror/view';
4
4
  export { tags } from '@lezer/highlight';
5
5
  export { TextKind } from '@dxos/protocols/proto/dxos/echo/model/text';
6
+ export { getToken } from './styles';
6
7
  export * from './components';
7
8
  export * from './defaults';
8
9
  export * from './extensions';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAE,QAAQ,EAAE,MAAM,4CAA4C,CAAC;AAEtE,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAE,QAAQ,EAAE,MAAM,4CAA4C,CAAC;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -1,19 +1,9 @@
1
1
  export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
2
- export declare const heading: (level: HeadingLevel) => string;
3
- export declare const text = "text-neutral-800 dark:text-neutral-200";
4
- export declare const light = "text-neutral-200 dark:text-neutral-800";
5
- export declare const mark: string;
6
- export declare const paragraph = "mlb-1";
7
- export declare const bold = "font-bold";
8
- export declare const italic = "italic";
9
- export declare const strikethrough = "line-through";
10
- export declare const code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
11
- export declare const codeMark = "font-mono text-primary-500";
12
- export declare const codeBlock = "mlb-2 font-mono bg-neutral-500/10 p-3 rounded";
13
- export declare const inlineUrl: string;
14
- export declare const blockquote: string;
15
- export declare const horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-200 dark:border-neutral-800";
16
- export declare const unorderedList = "mlb-2 grid grid-cols-[min-content_1fr] [&>li:before]:content-[attr(marker)] [&>li:before]:mlb-1 [&>li:before]:mie-2";
17
- export declare const orderedList = "mlb-2 grid grid-cols-[min-content_1fr] [&>li:before]:content-[counters(section,_\".\")_\"._\"] [counter-reset:section] [&>li:before]:mlb-1";
18
- export declare const listItem = "contents before:[counter-increment:section]";
2
+ export declare const theme: {
3
+ mark: string;
4
+ code: string;
5
+ codeMark: string;
6
+ blockquote: string;
7
+ heading: (level: HeadingLevel) => string;
8
+ };
19
9
  //# sourceMappingURL=markdown.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../../src/styles/markdown.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAcjD,eAAO,MAAM,OAAO,UAAW,YAAY,WAE1C,CAAC;AAEF,eAAO,MAAM,IAAI,2CAA2C,CAAC;AAC7D,eAAO,MAAM,KAAK,2CAA2C,CAAC;AAE9D,eAAO,MAAM,IAAI,QAAmE,CAAC;AAErF,eAAO,MAAM,SAAS,UAAU,CAAC;AAEjC,eAAO,MAAM,IAAI,cAAc,CAAC;AAChC,eAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,eAAO,MAAM,aAAa,iBAAiB,CAAC;AAE5C,eAAO,MAAM,IAAI,mEAAmE,CAAC;AACrF,eAAO,MAAM,QAAQ,+BAA+B,CAAC;AACrD,eAAO,MAAM,SAAS,kDAAkD,CAAC;AAEzE,eAAO,MAAM,SAAS,QAAmB,CAAC;AAE1C,eAAO,MAAM,UAAU,QAAwF,CAAC;AAEhH,eAAO,MAAM,cAAc,0GAC8E,CAAC;AAG1G,eAAO,MAAM,aAAa,wHAC6F,CAAC;AACxH,eAAO,MAAM,WAAW,+IACkH,CAAC;AAE3I,eAAO,MAAM,QAAQ,gDAAgD,CAAC"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../../src/styles/markdown.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAcjD,eAAO,MAAM,KAAK;;;;;qBAMC,YAAY;CAG9B,CAAC"}
@@ -1,4 +1,5 @@
1
- import { type ThemeStyles } from './tokens';
1
+ import { type StyleSpec } from 'style-mod';
2
+ export type ThemeStyles = Record<string, StyleSpec>;
2
3
  /**
3
4
  * Minimal styles.
4
5
  * https://codemirror.net/examples/styling
@@ -9,6 +10,7 @@ import { type ThemeStyles } from './tokens';
9
10
  *
10
11
  * Main layout:
11
12
  * https://codemirror.net/examples/styling
13
+ * https://codemirror.net/docs/guide (DOM Structure).
12
14
  *
13
15
  * <div class="cm-editor [cm-focused] [generated classes]">
14
16
  * <div class="cm-scroller">
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../../src/styles/theme.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,WAAW,EAAU,MAAM,UAAU,CAAC;AAKpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,YAAY,EAAE,WAkQ1B,CAAC"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../../src/styles/theme.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAI3C,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAMpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,YAAY,EAAE,WAmQ1B,CAAC"}
@@ -1,8 +1,6 @@
1
- import type { StyleSpec } from 'style-mod';
2
- import { type TailwindConfig } from '@dxos/react-ui-theme';
3
- export type ThemeStyles = {
4
- [selector: string]: StyleSpec;
5
- };
6
- export declare const tokens: TailwindConfig['theme'];
7
- export declare const getToken: (path: string, defaultValue?: any) => any;
1
+ /**
2
+ * @deprecated
3
+ * Replace with CSS vars.
4
+ */
5
+ export declare const getToken: (path: string, defaultValue?: string | string[]) => string;
8
6
  //# sourceMappingURL=tokens.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../../src/styles/tokens.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3E,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,OAAO,CAA4B,CAAC;AAExE,eAAO,MAAM,QAAQ,SAAU,MAAM,iBAAgB,GAAG,QAAgD,CAAC"}
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../../src/styles/tokens.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,eAAO,MAAM,QAAQ,SAAU,MAAM,iBAAiB,MAAM,GAAG,MAAM,EAAE,KAAG,MAGzE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/react-ui-editor",
3
- "version": "0.6.8-main.046e6cf",
3
+ "version": "0.6.8-staging.63bcb81",
4
4
  "description": "Document editing experience within a DXOS shell.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -46,19 +46,19 @@
46
46
  "lodash.sortby": "^4.7.0",
47
47
  "react-dropzone": "^14.2.3",
48
48
  "style-mod": "^4.1.0",
49
- "@dxos/async": "0.6.8-main.046e6cf",
50
- "@dxos/debug": "0.6.8-main.046e6cf",
51
- "@dxos/automerge": "0.6.8-main.046e6cf",
52
- "@dxos/display-name": "0.6.8-main.046e6cf",
53
- "@dxos/echo-schema": "0.6.8-main.046e6cf",
54
- "@dxos/invariant": "0.6.8-main.046e6cf",
55
- "@dxos/context": "0.6.8-main.046e6cf",
56
- "@dxos/log": "0.6.8-main.046e6cf",
57
- "@dxos/protocols": "0.6.8-main.046e6cf",
58
- "@dxos/react-async": "0.6.8-main.046e6cf",
59
- "@dxos/react-ui": "0.6.8-main.046e6cf",
60
- "@dxos/react-ui-theme": "0.6.8-main.046e6cf",
61
- "@dxos/util": "0.6.8-main.046e6cf"
49
+ "@dxos/async": "0.6.8-staging.63bcb81",
50
+ "@dxos/automerge": "0.6.8-staging.63bcb81",
51
+ "@dxos/context": "0.6.8-staging.63bcb81",
52
+ "@dxos/debug": "0.6.8-staging.63bcb81",
53
+ "@dxos/display-name": "0.6.8-staging.63bcb81",
54
+ "@dxos/echo-schema": "0.6.8-staging.63bcb81",
55
+ "@dxos/invariant": "0.6.8-staging.63bcb81",
56
+ "@dxos/log": "0.6.8-staging.63bcb81",
57
+ "@dxos/protocols": "0.6.8-staging.63bcb81",
58
+ "@dxos/react-async": "0.6.8-staging.63bcb81",
59
+ "@dxos/react-ui": "0.6.8-staging.63bcb81",
60
+ "@dxos/react-ui-theme": "0.6.8-staging.63bcb81",
61
+ "@dxos/util": "0.6.8-staging.63bcb81"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@phosphor-icons/react": "^2.1.5",
@@ -83,21 +83,21 @@
83
83
  "vite-plugin-top-level-await": "^1.4.1",
84
84
  "vite-plugin-wasm": "^3.3.0",
85
85
  "vitest": "^1.5.0",
86
- "@dxos/automerge": "0.6.8-main.046e6cf",
87
- "@dxos/config": "0.6.8-main.046e6cf",
88
- "@dxos/echo-typegen": "0.6.8-main.046e6cf",
89
- "@dxos/echo-signals": "0.6.8-main.046e6cf",
90
- "@dxos/keyboard": "0.6.8-main.046e6cf",
91
- "@dxos/random": "0.6.8-main.046e6cf",
92
- "@dxos/react-client": "0.6.8-main.046e6cf",
93
- "@dxos/react-ui": "0.6.8-main.046e6cf",
94
- "@dxos/storybook-utils": "0.6.8-main.046e6cf"
86
+ "@dxos/automerge": "0.6.8-staging.63bcb81",
87
+ "@dxos/config": "0.6.8-staging.63bcb81",
88
+ "@dxos/echo-signals": "0.6.8-staging.63bcb81",
89
+ "@dxos/echo-typegen": "0.6.8-staging.63bcb81",
90
+ "@dxos/keyboard": "0.6.8-staging.63bcb81",
91
+ "@dxos/random": "0.6.8-staging.63bcb81",
92
+ "@dxos/react-client": "0.6.8-staging.63bcb81",
93
+ "@dxos/react-ui": "0.6.8-staging.63bcb81",
94
+ "@dxos/storybook-utils": "0.6.8-staging.63bcb81"
95
95
  },
96
96
  "peerDependencies": {
97
97
  "@phosphor-icons/react": "^2.1.5",
98
98
  "react": "^18.0.0",
99
99
  "react-dom": "^18.0.0",
100
- "@dxos/react-client": "0.6.8-main.046e6cf"
100
+ "@dxos/react-client": "0.6.8-staging.63bcb81"
101
101
  },
102
102
  "publishConfig": {
103
103
  "access": "public"
@@ -17,11 +17,11 @@ import { PublicKey } from '@dxos/keys';
17
17
  import { log } from '@dxos/log';
18
18
  import { faker } from '@dxos/random';
19
19
  import { createDocAccessor, createEchoObject } from '@dxos/react-client/echo';
20
- import { Button, DensityProvider, Input, ThemeProvider, useThemeContext } from '@dxos/react-ui';
21
- import { baseSurface, defaultTx, mx, getSize } from '@dxos/react-ui-theme';
20
+ import { Button, DensityProvider, Input, useThemeContext } from '@dxos/react-ui';
21
+ import { baseSurface, mx, getSize } from '@dxos/react-ui-theme';
22
22
  import { withFullscreen, withTheme } from '@dxos/storybook-utils';
23
23
 
24
- import { editorContent } from './defaults';
24
+ import { editorContent, editorGutter } from './defaults';
25
25
  import {
26
26
  InputModeExtensions,
27
27
  annotations,
@@ -47,11 +47,11 @@ import {
47
47
  table,
48
48
  typewriter,
49
49
  type CommandAction,
50
- type CommandOptions,
51
50
  type Comment,
52
51
  type CommentsOptions,
53
- type SelectionState,
52
+ type EditorSelectionState,
54
53
  } from './extensions';
54
+ import { renderRoot } from './extensions/util';
55
55
  import { useTextEditor, type UseTextEditorProps } from './hooks';
56
56
  import translations from './translations';
57
57
 
@@ -153,17 +153,19 @@ const content = {
153
153
  ...[1, 2, 3, 4, 5, 6].map((level) => ['#'.repeat(level) + ` Heading ${level}`, faker.lorem.sentences(), '']).flat(),
154
154
  ),
155
155
 
156
- formatting: str('### Formatting', 'This this is **bold**, ~~strikethrough~~, _italic_, and `f(INLINE)`.'),
156
+ formatting: str('### Formatting', '', 'This this is **bold**, ~~strikethrough~~, _italic_, and `f(INLINE)`.', ''),
157
157
 
158
158
  blockquotes: str(
159
159
  '### Blockquotes',
160
+ '',
160
161
  '> This is a block quote.',
161
162
  '',
162
163
  '> This is a long wrapping block quote. Neque reiciendis ullam quae error labore sit, at, et, nulla, aut at nostrum omnis quas nostrum, at consectetur vitae eos asperiores non omnis ullam in beatae at vitae deserunt asperiores sapiente.',
163
164
  '',
164
- '> This is',
165
- '> a multi-line',
165
+ '> This is ...',
166
+ '> ... a multi-line ...',
166
167
  '> block quote.',
168
+ '',
167
169
  ),
168
170
 
169
171
  paragraphs: str(...faker.helpers.multiple(() => [faker.lorem.paragraph(), ''], { count: 3 }).flat()),
@@ -264,7 +266,7 @@ type StoryProps = {
264
266
  text?: string;
265
267
  readonly?: boolean;
266
268
  placeholder?: string;
267
- } & Pick<UseTextEditorProps, 'selection' | 'extensions'>;
269
+ } & Pick<UseTextEditorProps, 'scrollTo' | 'selection' | 'extensions'>;
268
270
 
269
271
  const Story = ({
270
272
  id = 'editor-' + PublicKey.random().toHex().slice(0, 8),
@@ -272,6 +274,7 @@ const Story = ({
272
274
  extensions,
273
275
  readonly,
274
276
  placeholder = 'New document.',
277
+ scrollTo,
275
278
  selection,
276
279
  }: StoryProps) => {
277
280
  const [object] = useState(createEchoObject(create(Expando, { content: text ?? '' })));
@@ -294,6 +297,7 @@ const Story = ({
294
297
  }),
295
298
  extensions || [],
296
299
  ],
300
+ scrollTo,
297
301
  selection,
298
302
  }),
299
303
  [object, extensions, themeMode],
@@ -313,13 +317,25 @@ const defaults = [
313
317
  autocomplete({
314
318
  onSearch: (text) => links.filter(({ label }) => label.toLowerCase().includes(text.toLowerCase())),
315
319
  }),
316
- decorateMarkdown({ renderLinkButton, selectionChangeDelay: 100, numberedHeadings: { from: 1, to: 4 } }),
320
+ decorateMarkdown({ renderLinkButton, selectionChangeDelay: 100 }),
317
321
  formattingKeymap(),
318
322
  linkTooltip(renderLinkTooltip),
319
323
  ];
320
324
 
321
325
  export const Default = {
322
- render: () => <Story text={text} extensions={defaults} />,
326
+ render: () => <Story text={text} extensions={defaults} selection={{ anchor: 99, head: 110 }} />,
327
+ };
328
+
329
+ export const ScrollTo = {
330
+ render: () => {
331
+ // NOTE: Selection won't appear if text is reformatted.
332
+ const word = 'Scroll to here...';
333
+ const text = str('# Scroll To', longText, '', word, '', longText);
334
+ const idx = text.indexOf(word);
335
+ return (
336
+ <Story text={text} extensions={defaults} scrollTo={idx} selection={{ anchor: idx, head: idx + word.length }} />
337
+ );
338
+ },
323
339
  };
324
340
 
325
341
  export const Readonly = {
@@ -335,10 +351,10 @@ export const NoExtensions = {
335
351
  };
336
352
 
337
353
  export const Folding = {
338
- render: () => <Story text={text} extensions={[folding()]} />,
354
+ render: () => <Story text={text} extensions={[editorGutter, folding()]} />,
339
355
  };
340
356
 
341
- const large = faker.helpers.multiple(() => faker.lorem.paragraph({ min: 8, max: 16 }), { count: 20 }).join('\n\n');
357
+ const longText = faker.helpers.multiple(() => faker.lorem.paragraph({ min: 8, max: 16 }), { count: 20 }).join('\n\n');
342
358
 
343
359
  const largeWithImages = faker.helpers
344
360
  .multiple(() => [faker.lorem.paragraph({ min: 12, max: 16 }), img], { count: 20 })
@@ -355,12 +371,12 @@ export const Headings = {
355
371
  render: () => <Story text={headings} extensions={decorateMarkdown({ numberedHeadings: { from: 2, to: 4 } })} />,
356
372
  };
357
373
 
358
- const global = new Map<string, SelectionState>();
374
+ const global = new Map<string, EditorSelectionState>();
359
375
 
360
376
  export const Scrolling = {
361
377
  render: () => (
362
378
  <Story
363
- text={str('# Large Document', '', large)}
379
+ text={str('# Large Document', '', longText)}
364
380
  extensions={state({
365
381
  setState: (id, state) => global.set(id, state),
366
382
  getState: (id) => global.get(id),
@@ -489,21 +505,18 @@ const CommandDialog: FC<{ onClose: (action?: CommandAction) => void }> = ({ onCl
489
505
  );
490
506
  };
491
507
 
492
- const renderCommandDialog: CommandOptions['onRender'] = (el, onClose) => {
493
- createRoot(el).render(
494
- <StrictMode>
495
- <ThemeProvider tx={defaultTx}>
496
- <CommandDialog onClose={onClose} />
497
- </ThemeProvider>
498
- </StrictMode>,
499
- );
500
- };
501
-
502
508
  export const Command = {
503
509
  render: () => (
504
510
  <Story
505
511
  text={str('# Command', '')}
506
- extensions={[command({ onRender: renderCommandDialog, onHint: () => 'Press / for commands.' })]}
512
+ extensions={[
513
+ command({
514
+ onRender: (el, onClose) => {
515
+ renderRoot(el, <CommandDialog onClose={onClose} />);
516
+ },
517
+ onHint: () => 'Press / for commands.',
518
+ }),
519
+ ]}
507
520
  />
508
521
  ),
509
522
  };
@@ -558,7 +571,7 @@ export const Vim = {
558
571
  };
559
572
 
560
573
  export const Annotations = {
561
- render: () => <Story text={str('# Annotations', '', large)} extensions={[annotations({ match: /volup/gi })]} />,
574
+ render: () => <Story text={str('# Annotations', '', longText)} extensions={[annotations({ match: /volup/gi })]} />,
562
575
  };
563
576
 
564
577
  export const DND = {
package/src/defaults.ts CHANGED
@@ -4,14 +4,14 @@
4
4
 
5
5
  import { EditorView } from '@codemirror/view';
6
6
 
7
- export { getToken } from './styles';
7
+ import { getToken } from './styles';
8
8
 
9
9
  /**
10
10
  * CodeMirror content width.
11
11
  * 40rem = 640px. Corresponds to initial plank width (Google docs, Stashpad, etc.)
12
12
  * 50rem = 800px. Maximum content width for solo mode.
13
13
  */
14
- export const editorContent = '!mt-[16px] !mli-auto w-full max-w-[min(50rem,100%-4rem)]';
14
+ export const editorContent = '!mt-[16px] !mb-[32px] !mli-auto w-full max-w-[min(50rem,100%-8rem)]';
15
15
 
16
16
  export const editorWithToolbarLayout =
17
17
  'grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden';
@@ -20,9 +20,16 @@ export const editorGutter = EditorView.baseTheme({
20
20
  '.cm-gutters': {
21
21
  // Match margin from content.
22
22
  marginTop: '16px',
23
+ marginBottom: '16px',
23
24
  // Inside within content margin.
24
25
  marginRight: '-32px',
25
26
  width: '32px',
26
27
  backgroundColor: 'transparent !important',
27
28
  },
28
29
  });
30
+
31
+ export const editorMonospace = EditorView.baseTheme({
32
+ '.cm-content': {
33
+ fontFamily: `${getToken('fontFamily.mono')} !important`,
34
+ },
35
+ });
@@ -6,6 +6,9 @@ import { Facet } from '@codemirror/state';
6
6
 
7
7
  import { invariant } from '@dxos/invariant';
8
8
 
9
+ /**
10
+ * Currently edited document id as FQ string.
11
+ */
9
12
  export const documentId = Facet.define<string, string>({
10
13
  combine: (providers) => {
11
14
  invariant(providers.length <= 1);
@@ -3,7 +3,7 @@
3
3
  //
4
4
 
5
5
  import { closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete';
6
- import { defaultKeymap, history, historyKeymap, indentWithTab, standardKeymap } from '@codemirror/commands';
6
+ import { defaultKeymap, history, historyKeymap, standardKeymap } from '@codemirror/commands';
7
7
  import { bracketMatching } from '@codemirror/language';
8
8
  import { searchKeymap } from '@codemirror/search';
9
9
  import { EditorState, type Extension } from '@codemirror/state';
@@ -109,8 +109,9 @@ export const createBasicExtensions = (_props?: BasicExtensionsOptions): Extensio
109
109
  keymap.of(
110
110
  [
111
111
  ...((props.keymap && keymaps[props.keymap]) ?? []),
112
+ // NOTE: Tab configured by markdown extension.
112
113
  // https://codemirror.net/docs/ref/#commands.indentWithTab
113
- ...(props.indentWithTab ? [indentWithTab] : []),
114
+ // ...(props.indentWithTab ? [indentWithTab] : []),
114
115
  // https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
115
116
  ...(props.closeBrackets ? closeBracketsKeymap : []),
116
117
  // https://codemirror.net/docs/ref/#commands.historyKeymap
@@ -6,8 +6,7 @@ import { codeFolding, foldGutter } from '@codemirror/language';
6
6
  import { type Extension } from '@codemirror/state';
7
7
  import React from 'react';
8
8
 
9
- import { ThemeProvider } from '@dxos/react-ui';
10
- import { defaultTx, getSize, mx } from '@dxos/react-ui-theme';
9
+ import { getSize, mx } from '@dxos/react-ui-theme';
11
10
 
12
11
  import { renderRoot } from './util';
13
12
 
@@ -23,11 +22,10 @@ export const folding = (_props: FoldingOptions = {}): Extension => [
23
22
  foldGutter({
24
23
  markerDOM: (open) => {
25
24
  return renderRoot(
26
- <ThemeProvider tx={defaultTx}>
27
- <svg className={mx(getSize(3), 'm-3 cursor-pointer', open && 'rotate-90')}>
28
- <use href={'/icons.svg#ph--caret-right--regular'} />
29
- </svg>
30
- </ThemeProvider>,
25
+ document.createElement('div'),
26
+ <svg className={mx(getSize(3), 'm-3 cursor-pointer', open && 'rotate-90')}>
27
+ <use href={'/icons.svg#ph--caret-right--regular'} />
28
+ </svg>,
31
29
  );
32
30
  },
33
31
  }),
@@ -15,7 +15,6 @@ import { keymap } from '@codemirror/view';
15
15
  import { type ThemeMode } from '@dxos/react-ui';
16
16
 
17
17
  import { markdownHighlightStyle, markdownTagsExtensions } from './highlight';
18
- import { linkPastePlugin } from './link-paste';
19
18
 
20
19
  export type MarkdownBundleOptions = {
21
20
  themeMode?: ThemeMode;
@@ -58,9 +57,8 @@ export const createMarkdownExtensions = ({ themeMode }: MarkdownBundleOptions =
58
57
  // Custom styles.
59
58
  syntaxHighlighting(markdownHighlightStyle()),
60
59
 
61
- linkPastePlugin,
62
-
63
60
  keymap.of([
61
+ // TODO(burdon): Indent by 4 if in task list.
64
62
  // https://codemirror.net/docs/ref/#commands.indentWithTab
65
63
  indentWithTab,
66
64
 
@@ -11,8 +11,9 @@ import { invariant } from '@dxos/invariant';
11
11
  import { mx } from '@dxos/react-ui-theme';
12
12
 
13
13
  import { image } from './image';
14
+ import { linkPastePlugin } from './link-paste';
14
15
  import { table } from './table';
15
- import { getToken, heading, type HeadingLevel } from '../../styles';
16
+ import { getToken, theme, type HeadingLevel } from '../../styles';
16
17
  import { wrapWithCatch } from '../util';
17
18
 
18
19
  //
@@ -57,8 +58,9 @@ class CheckboxWidget extends WidgetType {
57
58
 
58
59
  override toDOM(view: EditorView) {
59
60
  const input = document.createElement('input');
60
- input.className = 'cm-task-checkbox ch-checkbox ch-focus-ring';
61
+ input.className = 'cm-task-checkbox ch-checkbox';
61
62
  input.type = 'checkbox';
63
+ input.tabIndex = -1;
62
64
  input.checked = this._checked;
63
65
  if (view.state.readOnly) {
64
66
  input.setAttribute('disabled', 'true');
@@ -201,28 +203,34 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
201
203
  }
202
204
 
203
205
  const editing = editingRange(state, node, focus);
204
- if (!editing) {
205
- const mark = node.node.firstChild!;
206
- if (mark?.name === 'HeaderMark') {
207
- let text = view.state.sliceDoc(mark.to, node.to).trim();
208
- const { from, to } = options.numberedHeadings ?? {};
209
- if (from && (!to || level <= to)) {
210
- const num = headers
206
+ if (editing) {
207
+ break;
208
+ }
209
+
210
+ const mark = node.node.firstChild!;
211
+ if (mark?.name === 'HeaderMark') {
212
+ const { from, to = 6 } = options.numberedHeadings ?? {};
213
+ const text = view.state.sliceDoc(node.from, node.to);
214
+ const len = text.match(/[#\s]+/)![0].length;
215
+ if (!from || level < from || level > to) {
216
+ atomicDeco.add(mark.from, mark.from + len, hide);
217
+ } else {
218
+ // TODO(burdon): Number format/style.
219
+ const num =
220
+ headers
211
221
  .slice(from - 1)
212
222
  .map((level) => level?.number ?? 0)
213
- .join('.');
214
- if (num.length) {
215
- text = `${num} ${text}`;
216
- }
223
+ .join('.') + ' ';
224
+
225
+ if (num.length) {
226
+ atomicDeco.add(
227
+ mark.from,
228
+ mark.from + len,
229
+ Decoration.replace({
230
+ widget: new TextWidget(num, theme.heading(level)),
231
+ }),
232
+ );
217
233
  }
218
-
219
- deco.add(
220
- node.from,
221
- node.to,
222
- Decoration.replace({
223
- widget: new TextWidget(text, heading(level)),
224
- }),
225
- );
226
234
  }
227
235
  }
228
236
 
@@ -271,7 +279,6 @@ const buildDecorations = (view: EditorView, options: DecorateOptions, focus: boo
271
279
  // const mark = node.node.firstChild!;
272
280
  // console.log(mark?.name);
273
281
  // if (mark?.name === 'ListMark') {}
274
-
275
282
  break;
276
283
  }
277
284
 
@@ -515,6 +522,7 @@ export const decorateMarkdown = (options: DecorateOptions = {}) => {
515
522
  },
516
523
  ),
517
524
  formattingStyles,
525
+ linkPastePlugin,
518
526
  image(),
519
527
  table(),
520
528
  ];
@@ -522,7 +530,7 @@ export const decorateMarkdown = (options: DecorateOptions = {}) => {
522
530
 
523
531
  const formattingStyles = EditorView.baseTheme({
524
532
  '& .cm-code': {
525
- fontFamily: getToken('fontFamily.mono', []).join(','),
533
+ fontFamily: getToken('fontFamily.mono'),
526
534
  },
527
535
 
528
536
  '& .cm-codeblock-line': {
@@ -579,7 +587,6 @@ const formattingStyles = EditorView.baseTheme({
579
587
  '& .cm-list-mark': {
580
588
  display: 'inline-block',
581
589
  textAlign: 'right',
582
- color: getToken('extend.colors.neutral.500'),
583
590
  fontVariant: 'tabular-nums',
584
591
  },
585
592
  '& .cm-list-mark-bullet': {
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  import { snippet } from '@codemirror/autocomplete';
6
+ import { indentWithTab } from '@codemirror/commands';
6
7
  import { syntaxTree } from '@codemirror/language';
7
8
  import {
8
9
  type Extension,
@@ -1015,8 +1016,9 @@ export const toggleCodeblock: StateCommand = (target) => {
1015
1016
  //
1016
1017
 
1017
1018
  export type FormattingOptions = {};
1019
+ indentWithTab;
1018
1020
 
1019
- export const formattingKeymap = (options: FormattingOptions = {}): Extension => {
1021
+ export const formattingKeymap = (_options: FormattingOptions = {}): Extension => {
1020
1022
  return [
1021
1023
  keymap.of([
1022
1024
  {