@dxos/react-ui-editor 0.4.8-main.3a03fb7 → 0.4.8-main.46f461d

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 (47) hide show
  1. package/dist/lib/browser/index.mjs +215 -86
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +1 -0
  5. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/Toolbar/Toolbar.d.ts +11 -5
  7. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  8. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +4 -2
  9. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  10. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +1 -0
  11. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  12. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  13. package/dist/types/src/extensions/factories.d.ts +3 -0
  14. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  15. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  16. package/dist/types/src/extensions/markdown/formatting.d.ts +7 -4
  17. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  18. package/dist/types/src/extensions/markdown/image.d.ts +6 -0
  19. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  20. package/dist/types/src/extensions/modes.d.ts +1 -1
  21. package/dist/types/src/extensions/modes.d.ts.map +1 -1
  22. package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
  23. package/dist/types/src/hooks/useDocAccessor.d.ts +4 -2
  24. package/dist/types/src/hooks/useDocAccessor.d.ts.map +1 -1
  25. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  26. package/dist/types/src/hooks/useTextEditor.stories.d.ts +1 -0
  27. package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +1 -1
  28. package/dist/types/src/themes/default.d.ts.map +1 -1
  29. package/dist/types/src/translations.d.ts +1 -0
  30. package/dist/types/src/translations.d.ts.map +1 -1
  31. package/package.json +26 -24
  32. package/src/components/TextEditor/TextEditor.tsx +2 -2
  33. package/src/components/Toolbar/Toolbar.stories.tsx +23 -24
  34. package/src/components/Toolbar/Toolbar.tsx +101 -35
  35. package/src/extensions/automerge/automerge.ts +4 -4
  36. package/src/extensions/comments.ts +2 -2
  37. package/src/extensions/factories.ts +30 -7
  38. package/src/extensions/markdown/bundle.ts +8 -11
  39. package/src/extensions/markdown/formatting.test.ts +13 -13
  40. package/src/extensions/markdown/formatting.ts +95 -87
  41. package/src/extensions/markdown/image.ts +6 -0
  42. package/src/extensions/modes.ts +8 -1
  43. package/src/hooks/useActionHandler.ts +5 -1
  44. package/src/hooks/useDocAccessor.ts +8 -2
  45. package/src/hooks/useTextEditor.ts +3 -0
  46. package/src/themes/default.ts +24 -8
  47. package/src/translations.ts +1 -0
@@ -15,6 +15,7 @@ var translations_default = [
15
15
  "blockquote label": "Block quote",
16
16
  "codeblock label": "Code block",
17
17
  "comment label": "Create comment",
18
+ "image label": "Insert image",
18
19
  "heading label": "Heading level",
19
20
  "table label": "Create table"
20
21
  }
@@ -23,7 +24,7 @@ var translations_default = [
23
24
  ];
24
25
 
25
26
  // packages/ui/react-ui-editor/src/index.ts
26
- import { keymap as keymap10 } from "@codemirror/view";
27
+ import { keymap as keymap11 } from "@codemirror/view";
27
28
  import { tags as tags2 } from "@lezer/highlight";
28
29
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
29
30
  import { Doc, YText, YXmlFragment } from "@dxos/text-model";
@@ -474,13 +475,13 @@ var automerge = (accessor) => {
474
475
  ViewPlugin.fromClass(class {
475
476
  constructor(_view) {
476
477
  this._view = _view;
477
- accessor.handle.addListener("change", this._handleChange.bind(this));
478
+ this._handleChange = () => {
479
+ syncer.reconcile(this._view, false);
480
+ };
481
+ accessor.handle.addListener("change", this._handleChange);
478
482
  }
479
483
  destroy() {
480
- accessor.handle.removeListener("change", this._handleChange.bind(this));
481
- }
482
- _handleChange() {
483
- syncer.reconcile(this._view, false);
484
+ accessor.handle.removeListener("change", this._handleChange);
484
485
  }
485
486
  }),
486
487
  // Reconcile local updates.
@@ -1831,14 +1832,14 @@ var focusComment = (view, id, center = true) => {
1831
1832
  });
1832
1833
  }
1833
1834
  };
1834
- var useComments = (view, id, comments2 = []) => {
1835
+ var useComments = (view, id, comments2) => {
1835
1836
  useEffect(() => {
1836
1837
  if (view) {
1837
1838
  if (id === view.state.facet(documentId)) {
1838
1839
  view.dispatch({
1839
1840
  effects: setComments.of({
1840
1841
  id,
1841
- comments: comments2
1842
+ comments: comments2 ?? []
1842
1843
  })
1843
1844
  });
1844
1845
  }
@@ -1951,11 +1952,12 @@ var dnd = () => {
1951
1952
  };
1952
1953
 
1953
1954
  // packages/ui/react-ui-editor/src/extensions/factories.ts
1954
- import { closeBrackets } from "@codemirror/autocomplete";
1955
- import { history } from "@codemirror/commands";
1955
+ import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
1956
+ import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
1956
1957
  import { bracketMatching } from "@codemirror/language";
1958
+ import { searchKeymap } from "@codemirror/search";
1957
1959
  import { EditorState } from "@codemirror/state";
1958
- import { EditorView as EditorView10, crosshairCursor, drawSelection, dropCursor, highlightActiveLine, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
1960
+ import { EditorView as EditorView10, crosshairCursor, drawSelection, dropCursor, highlightActiveLine, highlightSpecialChars, keymap as keymap5, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
1959
1961
  import defaultsDeep2 from "lodash.defaultsdeep";
1960
1962
  import { generateName } from "@dxos/display-name";
1961
1963
  import { log as log7 } from "@dxos/log";
@@ -2163,41 +2165,59 @@ var defaultTheme = {
2163
2165
  * </div>
2164
2166
  * </div
2165
2167
  */
2166
- ".cm-panels": {
2167
- border: `1px solid ${get3(tokens, "extend.colors.neutral.200")}`
2168
- },
2168
+ ".cm-panels": {},
2169
2169
  ".cm-panel": {
2170
- background: get3(tokens, "extend.colors.neutral.50"),
2171
2170
  fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2172
2171
  },
2172
+ ".cm-panel input[type=checkbox]": {
2173
+ marginRight: "0.4rem !important"
2174
+ },
2175
+ "&light .cm-panel": {
2176
+ background: get3(tokens, "extend.colors.neutral.50")
2177
+ },
2178
+ "&dark .cm-panel": {
2179
+ background: get3(tokens, "extend.colors.neutral.850")
2180
+ },
2173
2181
  ".cm-button": {
2174
2182
  margin: "4px",
2175
2183
  fontFamily: get3(tokens, "fontFamily.body", []).join(","),
2176
- background: get3(tokens, "extend.colors.neutral.100"),
2177
2184
  backgroundImage: "none",
2178
2185
  border: "none",
2186
+ "&:active": {
2187
+ backgroundImage: "none"
2188
+ }
2189
+ },
2190
+ "&light .cm-button": {
2191
+ background: get3(tokens, "extend.colors.neutral.100"),
2179
2192
  "&:hover": {
2180
2193
  background: get3(tokens, "extend.colors.neutral.200")
2181
2194
  },
2182
2195
  "&:active": {
2183
- background: get3(tokens, "extend.colors.neutral.300"),
2184
- backgroundImage: "none"
2196
+ background: get3(tokens, "extend.colors.neutral.300")
2185
2197
  }
2186
2198
  },
2187
- ".cm-panel input[type=checkbox]": {
2188
- marginRight: "0.4rem !important"
2199
+ "&dark .cm-button": {
2200
+ background: get3(tokens, "extend.colors.neutral.800"),
2201
+ "&:hover": {
2202
+ background: get3(tokens, "extend.colors.neutral.700")
2203
+ },
2204
+ "&:active": {
2205
+ background: get3(tokens, "extend.colors.neutral.600")
2206
+ }
2189
2207
  }
2190
2208
  };
2191
2209
 
2192
2210
  // packages/ui/react-ui-editor/src/extensions/factories.ts
2193
2211
  var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/factories.ts";
2194
2212
  var defaults = {
2213
+ allowMultipleSelections: true,
2195
2214
  bracketMatching: true,
2196
2215
  closeBrackets: true,
2197
2216
  drawSelection: true,
2198
2217
  editable: true,
2199
2218
  history: true,
2200
- lineWrapping: true
2219
+ lineWrapping: true,
2220
+ search: true
2201
2221
  };
2202
2222
  var createBasicExtensions = (_props) => {
2203
2223
  const props = defaultsDeep2({}, _props, defaults);
@@ -2206,7 +2226,7 @@ var createBasicExtensions = (_props) => {
2206
2226
  EditorView10.exceptionSink.of((err) => {
2207
2227
  log7.catch(err, void 0, {
2208
2228
  F: __dxlog_file9,
2209
- L: 78,
2229
+ L: 83,
2210
2230
  S: void 0,
2211
2231
  C: (f, a) => f(...a)
2212
2232
  });
@@ -2218,6 +2238,7 @@ var createBasicExtensions = (_props) => {
2218
2238
  props.dropCursor && dropCursor(),
2219
2239
  props.drawSelection && drawSelection(),
2220
2240
  props.highlightActiveLine && highlightActiveLine(),
2241
+ highlightSpecialChars(),
2221
2242
  props.history && history(),
2222
2243
  props.lineNumbers && lineNumbers(),
2223
2244
  props.lineWrapping && EditorView10.lineWrapping,
@@ -2227,7 +2248,20 @@ var createBasicExtensions = (_props) => {
2227
2248
  EditorView10.editable.of(false)
2228
2249
  ],
2229
2250
  props.scrollPastEnd && scrollPastEnd(),
2230
- props.tabSize && EditorState.tabSize.of(props.tabSize)
2251
+ props.tabSize && EditorState.tabSize.of(props.tabSize),
2252
+ // https://codemirror.net/docs/ref/#view.KeyBinding
2253
+ keymap5.of([
2254
+ // https://codemirror.net/docs/ref/#commands.standardKeymap
2255
+ ...standardKeymap,
2256
+ // https://codemirror.net/docs/ref/#commands.indentWithTab
2257
+ props.indentWithTab && indentWithTab,
2258
+ // https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
2259
+ ...props.closeBrackets ? closeBracketsKeymap : [],
2260
+ // https://codemirror.net/docs/ref/#commands.historyKeymap
2261
+ ...props.history ? historyKeymap : [],
2262
+ // https://codemirror.net/docs/ref/#search.searchKeymap
2263
+ ...props.search ? searchKeymap : []
2264
+ ].filter(isNotFalsy2))
2231
2265
  ].filter(isNotFalsy2);
2232
2266
  };
2233
2267
  var defaultSlots = {
@@ -2286,14 +2320,14 @@ var listener = ({ onFocus, onChange }) => {
2286
2320
  };
2287
2321
 
2288
2322
  // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
2289
- import { closeBracketsKeymap } from "@codemirror/autocomplete";
2290
- import { historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
2323
+ import { completionKeymap as completionKeymap2 } from "@codemirror/autocomplete";
2324
+ import { defaultKeymap, indentWithTab as indentWithTab2 } from "@codemirror/commands";
2291
2325
  import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
2292
2326
  import { defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
2293
2327
  import { languages } from "@codemirror/language-data";
2294
- import { searchKeymap } from "@codemirror/search";
2328
+ import { lintKeymap } from "@codemirror/lint";
2295
2329
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
2296
- import { keymap as keymap5 } from "@codemirror/view";
2330
+ import { keymap as keymap6 } from "@codemirror/view";
2297
2331
 
2298
2332
  // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
2299
2333
  import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
@@ -2508,17 +2542,13 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
2508
2542
  themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
2509
2543
  // Custom styles.
2510
2544
  syntaxHighlighting(markdownHighlightStyle()),
2511
- keymap5.of([
2545
+ keymap6.of([
2512
2546
  // https://codemirror.net/docs/ref/#commands.indentWithTab
2513
- indentWithTab,
2514
- // https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
2515
- ...closeBracketsKeymap,
2516
- // https://codemirror.net/docs/ref/#commands.historyKeymap
2517
- ...historyKeymap,
2518
- // https://codemirror.net/docs/ref/#search.searchKeymap
2519
- ...searchKeymap,
2520
- // https://codemirror.net/docs/ref/#commands.standardKeymap
2521
- ...standardKeymap
2547
+ indentWithTab2,
2548
+ // https://codemirror.net/docs/ref/#commands.defaultKeymap
2549
+ ...defaultKeymap,
2550
+ ...completionKeymap2,
2551
+ ...lintKeymap
2522
2552
  ])
2523
2553
  ];
2524
2554
  };
@@ -2795,9 +2825,9 @@ var formattingStyles = EditorView12.baseTheme({
2795
2825
  import { snippet } from "@codemirror/autocomplete";
2796
2826
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2797
2827
  import { EditorSelection } from "@codemirror/state";
2798
- import { EditorView as EditorView13, keymap as keymap6 } from "@codemirror/view";
2799
- import { useState, useMemo } from "react";
2800
- var compareFormatting = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
2828
+ import { EditorView as EditorView13, keymap as keymap7 } from "@codemirror/view";
2829
+ import { useMemo, useState } from "react";
2830
+ var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
2801
2831
  var Inline;
2802
2832
  (function(Inline2) {
2803
2833
  Inline2[Inline2["Strong"] = 0] = "Strong";
@@ -3163,7 +3193,7 @@ var removeLink = ({ state: state2, dispatch }) => {
3163
3193
  }));
3164
3194
  return true;
3165
3195
  };
3166
- var addLink = ({ state: state2, dispatch }) => {
3196
+ var addLink = ({ url, image: image2 } = {}) => ({ state: state2, dispatch }) => {
3167
3197
  const changes = state2.changeByRange((range) => {
3168
3198
  let { from, to } = range;
3169
3199
  const cutStyles = [];
@@ -3234,15 +3264,15 @@ var addLink = ({ state: state2, dispatch }) => {
3234
3264
  }
3235
3265
  changes2.push({
3236
3266
  from,
3237
- insert: "["
3267
+ insert: image2 ? "![" : "["
3238
3268
  }, {
3239
3269
  from: to,
3240
- insert: "]()"
3270
+ insert: `](${url ?? ""})`
3241
3271
  });
3242
3272
  const changeSet = state2.changes(changes2.concat(changesAfter));
3243
3273
  return {
3244
3274
  changes: changeSet,
3245
- range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset)
3275
+ range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
3246
3276
  };
3247
3277
  });
3248
3278
  if (changes.changes.empty) {
@@ -3667,7 +3697,7 @@ var toggleCodeblock = (target) => {
3667
3697
  };
3668
3698
  var formattingKeymap = (options = {}) => {
3669
3699
  return [
3670
- keymap6.of([
3700
+ keymap7.of([
3671
3701
  {
3672
3702
  key: "meta-b",
3673
3703
  run: toggleStrong
@@ -3864,15 +3894,20 @@ var getFormatting = (state2) => {
3864
3894
  };
3865
3895
  };
3866
3896
  var useFormattingState = () => {
3867
- const [state2, setState] = useState(null);
3897
+ const [state2, setState] = useState();
3868
3898
  const observer = useMemo(() => EditorView13.updateListener.of((update2) => {
3869
3899
  if (update2.docChanged || update2.selectionSet) {
3870
- const newState = getFormatting(update2.state);
3871
- if (!state2 || !compareFormatting(state2, newState)) {
3872
- setState(newState);
3873
- }
3900
+ setState((prevState) => {
3901
+ const newState = getFormatting(update2.state);
3902
+ if (!prevState || !formattingEquals(prevState, newState)) {
3903
+ return newState;
3904
+ }
3905
+ return prevState;
3906
+ });
3874
3907
  }
3875
- }), []);
3908
+ }), [
3909
+ setState
3910
+ ]);
3876
3911
  return [
3877
3912
  state2,
3878
3913
  observer
@@ -3959,6 +3994,8 @@ var ImageWidget = class extends WidgetType4 {
3959
3994
  return img;
3960
3995
  }
3961
3996
  };
3997
+ var imageUpload = (options = {}) => {
3998
+ };
3962
3999
 
3963
4000
  // packages/ui/react-ui-editor/src/extensions/markdown/link.ts
3964
4001
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
@@ -4134,21 +4171,30 @@ var mention = ({ onSearch }) => {
4134
4171
 
4135
4172
  // packages/ui/react-ui-editor/src/extensions/modes.ts
4136
4173
  import { Facet as Facet6 } from "@codemirror/state";
4137
- import { keymap as keymap7 } from "@codemirror/view";
4174
+ import { keymap as keymap8 } from "@codemirror/view";
4138
4175
  import { vim } from "@replit/codemirror-vim";
4176
+ import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
4139
4177
  var focusEvent = "focus.container";
4140
4178
  var editorMode = Facet6.define({
4141
4179
  combine: (modes) => modes[0] ?? {}
4142
4180
  });
4143
4181
  var EditorModes = {
4144
4182
  default: [],
4183
+ vscode: [
4184
+ // https://github.com/replit/codemirror-vscode-keymap
4185
+ editorMode.of({
4186
+ type: "vscode"
4187
+ }),
4188
+ keymap8.of(vscodeKeymap)
4189
+ ],
4145
4190
  vim: [
4191
+ // https://github.com/replit/codemirror-vim
4146
4192
  vim(),
4147
4193
  editorMode.of({
4148
4194
  type: "vim",
4149
4195
  noTabster: true
4150
4196
  }),
4151
- keymap7.of([
4197
+ keymap8.of([
4152
4198
  {
4153
4199
  key: "Alt-Escape",
4154
4200
  run: (view) => {
@@ -4164,7 +4210,7 @@ var EditorModes = {
4164
4210
 
4165
4211
  // packages/ui/react-ui-editor/src/extensions/state.ts
4166
4212
  import { Transaction as Transaction2 } from "@codemirror/state";
4167
- import { EditorView as EditorView16, keymap as keymap8 } from "@codemirror/view";
4213
+ import { EditorView as EditorView16, keymap as keymap9 } from "@codemirror/view";
4168
4214
  import { debounce as debounce2 } from "@dxos/async";
4169
4215
  import { invariant as invariant4 } from "@dxos/invariant";
4170
4216
  import { isNotFalsy as isNotFalsy3 } from "@dxos/util";
@@ -4228,7 +4274,7 @@ var state = ({ getState, setState } = {}) => {
4228
4274
  }
4229
4275
  }
4230
4276
  }),
4231
- getState && keymap8.of([
4277
+ getState && keymap9.of([
4232
4278
  {
4233
4279
  key: "ctrl-r",
4234
4280
  run: (view) => {
@@ -4250,7 +4296,7 @@ var state = ({ getState, setState } = {}) => {
4250
4296
  };
4251
4297
 
4252
4298
  // packages/ui/react-ui-editor/src/extensions/typewriter.ts
4253
- import { keymap as keymap9 } from "@codemirror/view";
4299
+ import { keymap as keymap10 } from "@codemirror/view";
4254
4300
  var defaultItems = [
4255
4301
  "hello world!",
4256
4302
  "this is a test.",
@@ -4260,7 +4306,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4260
4306
  let t;
4261
4307
  let idx = 0;
4262
4308
  return [
4263
- keymap9.of([
4309
+ keymap10.of([
4264
4310
  {
4265
4311
  // Reset.
4266
4312
  key: "alt-meta-'",
@@ -4330,7 +4376,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
4330
4376
  autoFocus
4331
4377
  ]);
4332
4378
  useEffect2(() => {
4333
- log9("updating", {
4379
+ log9("create", {
4334
4380
  id,
4335
4381
  instanceId
4336
4382
  }, {
@@ -4390,8 +4436,16 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
4390
4436
  }
4391
4437
  setView(view2);
4392
4438
  return () => {
4439
+ log9("destroy", {
4440
+ id,
4441
+ instanceId
4442
+ }, {
4443
+ F: __dxlog_file12,
4444
+ L: 150,
4445
+ S: void 0,
4446
+ C: (f, a) => f(...a)
4447
+ });
4393
4448
  view2?.destroy();
4394
- setView(null);
4395
4449
  };
4396
4450
  }, [
4397
4451
  doc,
@@ -4421,9 +4475,10 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
4421
4475
  });
4422
4476
 
4423
4477
  // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
4424
- import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes } from "@phosphor-icons/react";
4478
+ import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic } from "@phosphor-icons/react";
4425
4479
  import { createContext } from "@radix-ui/react-context";
4426
- import React2, { useRef as useRef2, useState as useState3 } from "react";
4480
+ import React2, { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
4481
+ import { useDropzone } from "react-dropzone";
4427
4482
  import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
4428
4483
  import { getSize } from "@dxos/react-ui-theme";
4429
4484
  var tooltipProps = {
@@ -4457,7 +4512,7 @@ var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
4457
4512
  };
4458
4513
  var buttonStyles = "min-bs-0 p-2";
4459
4514
  var iconStyles = getSize(5);
4460
- var ToolbarButton = ({ Icon, children, ...props }) => {
4515
+ var ToolbarToggleButton = ({ Icon, children, ...props }) => {
4461
4516
  return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4462
4517
  asChild: true
4463
4518
  }, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
@@ -4470,6 +4525,19 @@ var ToolbarButton = ({ Icon, children, ...props }) => {
4470
4525
  className: "sr-only"
4471
4526
  }, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4472
4527
  };
4528
+ var ToolbarButton = ({ Icon, children, ...props }) => {
4529
+ return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4530
+ asChild: true
4531
+ }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4532
+ variant: "ghost",
4533
+ ...props,
4534
+ classNames: buttonStyles
4535
+ }, /* @__PURE__ */ React2.createElement(Icon, {
4536
+ className: iconStyles
4537
+ }), /* @__PURE__ */ React2.createElement("span", {
4538
+ className: "sr-only"
4539
+ }, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4540
+ };
4473
4541
  var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
4474
4542
  role: "separator",
4475
4543
  className: "grow"
@@ -4580,7 +4648,7 @@ var MarkdownStyles = () => {
4580
4648
  return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4581
4649
  type: "multiple",
4582
4650
  value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
4583
- }, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4651
+ }, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
4584
4652
  key: type,
4585
4653
  value: type,
4586
4654
  Icon,
@@ -4614,7 +4682,7 @@ var MarkdownLists = () => {
4614
4682
  return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4615
4683
  type: "single",
4616
4684
  value: state2?.listStyle ? `list-${state2.listStyle}` : ""
4617
- }, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4685
+ }, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
4618
4686
  key: type,
4619
4687
  value: type,
4620
4688
  Icon,
@@ -4649,7 +4717,7 @@ var MarkdownBlocks = () => {
4649
4717
  return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4650
4718
  type: "single",
4651
4719
  value: value?.type ?? ""
4652
- }, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4720
+ }, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
4653
4721
  key: type,
4654
4722
  value: type,
4655
4723
  Icon,
@@ -4661,30 +4729,68 @@ var MarkdownBlocks = () => {
4661
4729
  }, t(`${type} label`))));
4662
4730
  };
4663
4731
  var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(MarkdownHeading, null), /* @__PURE__ */ React2.createElement(MarkdownStyles, null), /* @__PURE__ */ React2.createElement(MarkdownLists, null), /* @__PURE__ */ React2.createElement(MarkdownBlocks, null));
4664
- var MarkdownExtended = () => {
4732
+ var MarkdownCustom = ({ onUpload } = {}) => {
4665
4733
  const { onAction } = useToolbarContext("MarkdownStyles");
4666
4734
  const { t } = useTranslation(translationKey);
4667
- return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4668
- asChild: true
4669
- }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4670
- variant: "ghost",
4735
+ const { acceptedFiles, getInputProps, open } = useDropzone({
4736
+ multiple: false,
4737
+ noDrag: true,
4738
+ accept: {
4739
+ "image/*": [
4740
+ ".jpg",
4741
+ ".jpeg",
4742
+ ".png",
4743
+ ".gif"
4744
+ ]
4745
+ }
4746
+ });
4747
+ useEffect3(() => {
4748
+ if (onUpload && acceptedFiles.length) {
4749
+ setTimeout(async () => {
4750
+ const f = acceptedFiles[0];
4751
+ const file = new File([
4752
+ f
4753
+ ], f.name, {
4754
+ type: f.type,
4755
+ lastModified: f.lastModified
4756
+ });
4757
+ const { url } = await onUpload(file);
4758
+ if (url) {
4759
+ onAction?.({
4760
+ type: "image",
4761
+ data: url
4762
+ });
4763
+ }
4764
+ });
4765
+ }
4766
+ }, [
4767
+ acceptedFiles
4768
+ ]);
4769
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("input", getInputProps()), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4770
+ value: "image",
4771
+ Icon: Image,
4772
+ onClick: () => open()
4773
+ }, t("image label")));
4774
+ };
4775
+ var MarkdownActions = () => {
4776
+ const { onAction } = useToolbarContext("MarkdownStyles");
4777
+ const { t } = useTranslation(translationKey);
4778
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4779
+ value: "comment",
4780
+ Icon: ChatText,
4671
4781
  "data-testid": "editor.toolbar.comment",
4672
4782
  onClick: () => onAction?.({
4673
4783
  type: "comment"
4674
- }),
4675
- classNames: buttonStyles
4676
- }, /* @__PURE__ */ React2.createElement(ChatText, {
4677
- className: iconStyles
4678
- }), /* @__PURE__ */ React2.createElement("span", {
4679
- className: "sr-only"
4680
- }, t("comment label")))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("comment label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4784
+ })
4785
+ }, t("comment label")));
4681
4786
  };
4682
4787
  var Toolbar = {
4683
4788
  Root: ToolbarRoot,
4684
- Button: ToolbarButton,
4789
+ Button: ToolbarToggleButton,
4685
4790
  Separator: ToolbarSeparator,
4686
4791
  Markdown: MarkdownStandard,
4687
- Extended: MarkdownExtended
4792
+ Custom: MarkdownCustom,
4793
+ Actions: MarkdownActions
4688
4794
  };
4689
4795
 
4690
4796
  // packages/ui/react-ui-editor/src/hooks/useActionHandler.ts
@@ -4721,7 +4827,13 @@ var useActionHandler = (view) => {
4721
4827
  insertTable(view);
4722
4828
  break;
4723
4829
  case "link":
4724
- (action.data === false ? removeLink : addLink)(view);
4830
+ (action.data === false ? removeLink : addLink())(view);
4831
+ break;
4832
+ case "image":
4833
+ addLink({
4834
+ url: action.data,
4835
+ image: true
4836
+ })(view);
4725
4837
  break;
4726
4838
  case "comment":
4727
4839
  createComment(view);
@@ -4751,7 +4863,7 @@ var useDocAccessor = (text) => {
4751
4863
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
4752
4864
  import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
4753
4865
  import { EditorView as EditorView18 } from "@codemirror/view";
4754
- import { useEffect as useEffect3, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
4866
+ import { useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
4755
4867
  import { log as log10 } from "@dxos/log";
4756
4868
  import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
4757
4869
  var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
@@ -4760,9 +4872,17 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
4760
4872
  const onUpdate = useRef3();
4761
4873
  const [view, setView] = useState4();
4762
4874
  const parentRef = useRef3(null);
4763
- useEffect3(() => {
4875
+ useEffect4(() => {
4764
4876
  let view2;
4765
4877
  if (parentRef.current) {
4878
+ log10("create", {
4879
+ id
4880
+ }, {
4881
+ F: __dxlog_file13,
4882
+ L: 36,
4883
+ S: void 0,
4884
+ C: (f, a) => f(...a)
4885
+ });
4766
4886
  const state2 = EditorState3.create({
4767
4887
  doc,
4768
4888
  selection,
@@ -4772,7 +4892,7 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
4772
4892
  EditorView18.exceptionSink.of((err) => {
4773
4893
  log10.catch(err, void 0, {
4774
4894
  F: __dxlog_file13,
4775
- L: 44,
4895
+ L: 46,
4776
4896
  S: void 0,
4777
4897
  C: (f, a) => f(...a)
4778
4898
  });
@@ -4799,10 +4919,18 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
4799
4919
  setView(view2);
4800
4920
  }
4801
4921
  return () => {
4922
+ log10("destroy", {
4923
+ id
4924
+ }, {
4925
+ F: __dxlog_file13,
4926
+ L: 74,
4927
+ S: void 0,
4928
+ C: (f, a) => f(...a)
4929
+ });
4802
4930
  view2?.destroy();
4803
4931
  };
4804
4932
  }, deps);
4805
- useEffect3(() => {
4933
+ useEffect4(() => {
4806
4934
  if (view) {
4807
4935
  if (!selection && !view.state.selection.main.anchor) {
4808
4936
  selection = EditorSelection2.single(view.state.doc.line(1).to);
@@ -4861,7 +4989,6 @@ export {
4861
4989
  callbackWrapper,
4862
4990
  command,
4863
4991
  comments,
4864
- compareFormatting,
4865
4992
  createBasicExtensions,
4866
4993
  createComment,
4867
4994
  createDataExtensions,
@@ -4879,12 +5006,14 @@ export {
4879
5006
  editorWithToolbarLayout,
4880
5007
  focusComment,
4881
5008
  focusEvent,
5009
+ formattingEquals,
4882
5010
  formattingKeymap,
4883
5011
  getFormatting,
4884
5012
  getToken,
4885
5013
  image,
5014
+ imageUpload,
4886
5015
  insertTable,
4887
- keymap10 as keymap,
5016
+ keymap11 as keymap,
4888
5017
  linkTooltip,
4889
5018
  listener,
4890
5019
  localStorageStateStoreAdapter,