@dxos/react-ui-editor 0.4.2-next.262aee9 → 0.4.3-main.c3bfede

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 (41) hide show
  1. package/dist/lib/browser/index.mjs +233 -185
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +20 -0
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +20 -0
  7. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  8. package/dist/types/src/components/TextEditor/automerge.stories.d.ts +22 -2
  9. package/dist/types/src/components/TextEditor/automerge.stories.d.ts.map +1 -1
  10. package/dist/types/src/components/TextEditor/hooks.stories.d.ts +20 -0
  11. package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -1
  12. package/dist/types/src/components/Toolbar/Toolbar.d.ts +7 -10
  13. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  14. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +23 -6
  15. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  16. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  17. package/dist/types/src/extensions/automerge/{semaphore.d.ts → sync.d.ts} +6 -5
  18. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -0
  19. package/dist/types/src/index.d.ts +1 -1
  20. package/dist/types/src/index.d.ts.map +1 -1
  21. package/dist/types/src/styles/index.d.ts +1 -0
  22. package/dist/types/src/styles/index.d.ts.map +1 -1
  23. package/dist/types/src/styles/layout.d.ts +2 -0
  24. package/dist/types/src/styles/layout.d.ts.map +1 -0
  25. package/dist/types/src/translations.d.ts +20 -0
  26. package/dist/types/src/translations.d.ts.map +1 -0
  27. package/package.json +24 -24
  28. package/src/components/TextEditor/MarkdownEditor.stories.tsx +13 -16
  29. package/src/components/TextEditor/TextEditor.stories.tsx +11 -14
  30. package/src/components/TextEditor/TextEditor.tsx +3 -3
  31. package/src/components/TextEditor/automerge.stories.tsx +38 -44
  32. package/src/components/TextEditor/hooks.stories.tsx +15 -16
  33. package/src/components/Toolbar/Toolbar.stories.tsx +16 -12
  34. package/src/components/Toolbar/Toolbar.tsx +156 -129
  35. package/src/extensions/automerge/automerge.ts +5 -21
  36. package/src/extensions/automerge/{semaphore.ts → sync.ts} +32 -34
  37. package/src/index.ts +1 -1
  38. package/src/styles/index.ts +1 -0
  39. package/src/styles/layout.ts +6 -0
  40. package/src/translations.ts +25 -0
  41. package/dist/types/src/extensions/automerge/semaphore.d.ts.map +0 -1
@@ -14,7 +14,7 @@ import defaultsDeep2 from "lodash.defaultsdeep";
14
14
  import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
15
15
  import { log as log2 } from "@dxos/log";
16
16
  import { useThemeContext } from "@dxos/react-ui";
17
- import { focusRing, mx as mx3 } from "@dxos/react-ui-theme";
17
+ import { focusRing } from "@dxos/react-ui-theme";
18
18
  import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
19
19
 
20
20
  // packages/ui/react-ui-editor/src/extensions/annotations.ts
@@ -154,7 +154,6 @@ var autocomplete = ({ onSearch }) => {
154
154
  };
155
155
 
156
156
  // packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
157
- import { invertedEffects } from "@codemirror/commands";
158
157
  import { StateField as StateField2 } from "@codemirror/state";
159
158
  import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
160
159
  import { next as A4 } from "@dxos/automerge/automerge";
@@ -208,7 +207,7 @@ var isReconcile = (tr) => {
208
207
  return !!tr.annotation(reconcileAnnotation);
209
208
  };
210
209
 
211
- // packages/ui/react-ui-editor/src/extensions/automerge/semaphore.ts
210
+ // packages/ui/react-ui-editor/src/extensions/automerge/sync.ts
212
211
  import { next as A3 } from "@dxos/automerge/automerge";
213
212
 
214
213
  // packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
@@ -349,40 +348,42 @@ var charPath = (textPath, candidatePath) => {
349
348
  return null;
350
349
  };
351
350
 
352
- // packages/ui/react-ui-editor/src/extensions/automerge/semaphore.ts
353
- var PatchSemaphore = class {
351
+ // packages/ui/react-ui-editor/src/extensions/automerge/sync.ts
352
+ var Syncer = class {
354
353
  // prettier-ignore
355
354
  constructor(_handle, _state) {
356
355
  this._handle = _handle;
357
356
  this._state = _state;
358
- this._inReconcile = false;
357
+ this._pending = false;
359
358
  }
360
- reconcile(view) {
361
- if (!this._inReconcile) {
362
- this._inReconcile = true;
363
- this.doReconcile(view);
364
- this._inReconcile = false;
359
+ reconcile(view, editor) {
360
+ if (this._pending) {
361
+ return;
365
362
  }
363
+ this._pending = true;
364
+ if (editor) {
365
+ this.onEditorChange(view);
366
+ } else {
367
+ this.onAutomergeChange(view);
368
+ }
369
+ this._pending = false;
366
370
  }
367
- doReconcile(view) {
368
- const path = getPath(view.state, this._state);
369
- const oldHeads = getLastHeads(view.state, this._state);
370
- let selection = view.state.selection;
371
+ onEditorChange(view) {
371
372
  const transactions = view.state.field(this._state).unreconciledTransactions.filter((tx) => !isReconcile(tx));
372
- const toInvert = transactions.slice().reverse();
373
- for (const tr of toInvert) {
374
- const inverted = tr.changes.invert(tr.startState.doc);
375
- selection = selection.map(inverted);
373
+ const newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
374
+ if (newHeads) {
376
375
  view.dispatch({
377
- changes: inverted,
378
- annotations: reconcileAnnotation.of(true)
376
+ effects: updateHeads(newHeads),
377
+ annotations: reconcileAnnotation.of(false)
379
378
  });
380
379
  }
381
- let newHeads = updateAutomerge(this._state, this._handle, transactions, view.state);
382
- if (newHeads === null || newHeads === void 0) {
383
- newHeads = A3.getHeads(this._handle.docSync());
384
- }
380
+ }
381
+ onAutomergeChange(view) {
382
+ const oldHeads = getLastHeads(view.state, this._state);
383
+ const newHeads = A3.getHeads(this._handle.docSync());
385
384
  const diff = A3.equals(oldHeads, newHeads) ? [] : A3.diff(this._handle.docSync(), oldHeads, newHeads);
385
+ const selection = view.state.selection;
386
+ const path = getPath(view.state, this._state);
386
387
  updateCodeMirror(view, selection, path, diff);
387
388
  view.dispatch({
388
389
  effects: updateHeads(newHeads),
@@ -422,7 +423,7 @@ var automerge = ({ handle, path }) => {
422
423
  return result;
423
424
  }
424
425
  });
425
- const semaphore = new PatchSemaphore(handle, syncState);
426
+ const syncer = new Syncer(handle, syncState);
426
427
  return [
427
428
  Cursor.converter.of(cursorConverter(handle, path)),
428
429
  syncState,
@@ -436,25 +437,14 @@ var automerge = ({ handle, path }) => {
436
437
  handle.removeListener("change", this._handleChange.bind(this));
437
438
  }
438
439
  _handleChange() {
439
- semaphore.reconcile(this._view);
440
+ syncer.reconcile(this._view, false);
440
441
  }
441
442
  }),
442
443
  // Reconcile local updates.
443
444
  EditorView2.updateListener.of(({ view, changes }) => {
444
445
  if (!changes.empty) {
445
- semaphore.reconcile(view);
446
+ syncer.reconcile(view, true);
446
447
  }
447
- }),
448
- // TODO(burdon): Record undo transactions.
449
- // See https://github.com/yjs/y-codemirror.next/tree/main
450
- // https://codemirror.net/examples/inverted-effect
451
- invertedEffects.of((tr) => {
452
- const effects = [];
453
- if (!tr.changes.empty) {
454
- tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => {
455
- });
456
- }
457
- return effects;
458
448
  })
459
449
  ];
460
450
  };
@@ -1025,7 +1015,7 @@ var random = (min, max) => {
1025
1015
  };
1026
1016
 
1027
1017
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1028
- import { invertedEffects as invertedEffects2 } from "@codemirror/commands";
1018
+ import { invertedEffects } from "@codemirror/commands";
1029
1019
  import { Facet as Facet3, StateEffect as StateEffect2, StateField as StateField3 } from "@codemirror/state";
1030
1020
  import { hoverTooltip, keymap as keymap3, Decoration as Decoration3, EditorView as EditorView6 } from "@codemirror/view";
1031
1021
  import sortBy from "lodash.sortby";
@@ -1100,6 +1090,9 @@ import { tailwindConfig } from "@dxos/react-ui-theme";
1100
1090
  var tokens = tailwindConfig({}).theme;
1101
1091
  var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
1102
1092
 
1093
+ // packages/ui/react-ui-editor/src/styles/layout.ts
1094
+ var editorWithToolbarLayout = "fixed inset-0 grid grid-cols-1 grid-rows-[min-content_1fr] justify-center content-start overflow-hidden";
1095
+
1103
1096
  // packages/ui/react-ui-editor/src/util.ts
1104
1097
  import { log } from "@dxos/log";
1105
1098
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
@@ -1269,7 +1262,7 @@ var trackPastedComments = (onUpdate) => {
1269
1262
  copy: handleTrack
1270
1263
  }),
1271
1264
  // Track deleted comments.
1272
- invertedEffects2.of((tr) => {
1265
+ invertedEffects.of((tr) => {
1273
1266
  const { comments: comments2 } = tr.startState.field(commentsState);
1274
1267
  const effects = [];
1275
1268
  tr.changes.iterChangedRanges((fromA, toA) => {
@@ -3988,10 +3981,10 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
3988
3981
  });
3989
3982
  var defaultSlots = {
3990
3983
  root: {
3991
- className: mx3("grow", focusRing)
3984
+ className: focusRing
3992
3985
  },
3993
3986
  editor: {
3994
- className: "bs-full"
3987
+ className: "min-bs-full"
3995
3988
  }
3996
3989
  };
3997
3990
  var defaultTextSlots = {
@@ -4002,11 +3995,35 @@ var defaultMarkdownSlots = {
4002
3995
  };
4003
3996
 
4004
3997
  // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
4005
- import { CaretRight, ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic } from "@phosphor-icons/react";
3998
+ import { ChatText, Code, CodeBlock, Link, ListBullets, ListChecks, ListNumbers, Paragraph, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, Quotes, CaretDown } from "@phosphor-icons/react";
4006
3999
  import { createContext } from "@radix-ui/react-context";
4007
4000
  import React2 from "react";
4008
- import { Button, DensityProvider, Select } from "@dxos/react-ui";
4009
- import { getSize, mx as mx4 } from "@dxos/react-ui-theme";
4001
+ import { DensityProvider, ElevationProvider, Select, Toolbar as NaturalToolbar, useTranslation } from "@dxos/react-ui";
4002
+ import { getSize } from "@dxos/react-ui-theme";
4003
+
4004
+ // packages/ui/react-ui-editor/src/translations.ts
4005
+ var translationKey = "react-ui-editor";
4006
+ var translations_default = [
4007
+ {
4008
+ "en-US": {
4009
+ [translationKey]: {
4010
+ "strong label": "Strong",
4011
+ "emphasis label": "Emphasis",
4012
+ "strikethrough label": "Strike-through",
4013
+ "code label": "Code",
4014
+ "bullet label": "Bullet list",
4015
+ "ordered label": "Numbered list",
4016
+ "task label": "Task list",
4017
+ "blockquote label": "Block quote",
4018
+ "codeblock label": "Code block",
4019
+ "comment label": "Create comment",
4020
+ "heading label": "Heading level"
4021
+ }
4022
+ }
4023
+ }
4024
+ ];
4025
+
4026
+ // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
4010
4027
  var HeadingIcons = {
4011
4028
  "0": Paragraph,
4012
4029
  "1": TextHOne,
@@ -4017,42 +4034,40 @@ var HeadingIcons = {
4017
4034
  "6": TextHSix
4018
4035
  };
4019
4036
  var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
4020
- var ToolbarRoot = ({ children, onAction, state }) => {
4037
+ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
4021
4038
  return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
4022
4039
  onAction,
4023
4040
  state
4024
4041
  }, /* @__PURE__ */ React2.createElement(DensityProvider, {
4025
4042
  density: "fine"
4026
- }, /* @__PURE__ */ React2.createElement("div", {
4027
- role: "toolbar",
4028
- className: "flex w-full shrink-0 p-1 gap-4 items-center whitespace-nowrap overflow-hidden"
4029
- }, children)));
4043
+ }, /* @__PURE__ */ React2.createElement(ElevationProvider, {
4044
+ elevation: "chrome"
4045
+ }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Root, {
4046
+ classNames: [
4047
+ "is-full shrink-0 overflow-x-auto p-1",
4048
+ classNames
4049
+ ]
4050
+ }, children))));
4030
4051
  };
4031
- var ToolbarButton = ({ Icon, onClick, title, getState, disable }) => {
4032
- const { onAction, state } = useToolbarContext("ToolbarButton");
4033
- const active = getState && state ? getState(state) : false;
4034
- const disabled = disable && state ? disable(state) : false;
4035
- const handleClick = (event) => {
4036
- const action = onClick(state);
4037
- if (action) {
4038
- onAction?.(action);
4039
- event.preventDefault();
4040
- }
4041
- };
4042
- return /* @__PURE__ */ React2.createElement(Button, {
4052
+ var buttonStyles = "min-bs-0 p-2";
4053
+ var iconStyles = getSize(4);
4054
+ var ToolbarButton = ({ Icon, children, ...props }) => {
4055
+ return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
4043
4056
  variant: "ghost",
4044
- classNames: mx4("p-2", active && "ring-[1px]"),
4045
- onMouseDown: handleClick,
4046
- title,
4047
- disabled
4057
+ ...props,
4058
+ classNames: buttonStyles
4048
4059
  }, /* @__PURE__ */ React2.createElement(Icon, {
4049
- className: getSize(5)
4050
- }));
4060
+ className: iconStyles
4061
+ }), /* @__PURE__ */ React2.createElement("span", {
4062
+ className: "sr-only"
4063
+ }, children));
4051
4064
  };
4052
4065
  var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
4066
+ role: "separator",
4053
4067
  className: "grow"
4054
4068
  });
4055
4069
  var MarkdownHeading = () => {
4070
+ const { t } = useTranslation(translationKey);
4056
4071
  const { onAction, state } = useToolbarContext("MarkdownFormatting");
4057
4072
  const blockType = state ? state.blockType : "paragraph";
4058
4073
  const header = blockType && /heading(\d)/.exec(blockType);
@@ -4065,9 +4080,19 @@ var MarkdownHeading = () => {
4065
4080
  type: "heading",
4066
4081
  data: parseInt(value2)
4067
4082
  })
4068
- }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, null, /* @__PURE__ */ React2.createElement(HeadingIcon, {
4069
- className: getSize(5)
4070
- })), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
4083
+ }, /* @__PURE__ */ React2.createElement(Select.Trigger, {
4084
+ asChild: true
4085
+ }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4086
+ variant: "ghost",
4087
+ classNames: buttonStyles
4088
+ }, /* @__PURE__ */ React2.createElement("span", {
4089
+ className: "sr-only"
4090
+ }, t("heading label")), /* @__PURE__ */ React2.createElement(HeadingIcon, {
4091
+ className: iconStyles
4092
+ }), /* @__PURE__ */ React2.createElement(CaretDown, {
4093
+ className: getSize(2),
4094
+ weight: "bold"
4095
+ }))), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
4071
4096
  value: "0"
4072
4097
  }, "Paragraph"), [
4073
4098
  1,
@@ -4079,120 +4104,142 @@ var MarkdownHeading = () => {
4079
4104
  ].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
4080
4105
  key: level,
4081
4106
  value: String(level)
4082
- }, "Heading ", level))))));
4107
+ }, "Heading ", level))), /* @__PURE__ */ React2.createElement(Select.ScrollDownButton, null), /* @__PURE__ */ React2.createElement(Select.Arrow, null))));
4108
+ };
4109
+ var markdownStyles = [
4110
+ {
4111
+ key: "strong",
4112
+ Icon: TextB
4113
+ },
4114
+ {
4115
+ key: "emphasis",
4116
+ Icon: TextItalic
4117
+ },
4118
+ {
4119
+ key: "strikethrough",
4120
+ Icon: TextStrikethrough
4121
+ },
4122
+ {
4123
+ key: "code",
4124
+ Icon: Code
4125
+ },
4126
+ {
4127
+ key: "link",
4128
+ Icon: Link
4129
+ }
4130
+ ];
4131
+ var MarkdownStyles = () => {
4132
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
4133
+ const { t } = useTranslation(translationKey);
4134
+ return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4135
+ type: "multiple",
4136
+ value: markdownStyles.filter(({ key }) => !!state?.[key]).map(({ key }) => key)
4137
+ }, markdownStyles.map(({ key, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4138
+ key,
4139
+ value: key,
4140
+ Icon,
4141
+ disabled: state?.blockType === "codeblock",
4142
+ onClick: () => onAction?.({
4143
+ type: key,
4144
+ data: state ? !state[key] : null
4145
+ })
4146
+ }, t(`${key} label`))));
4147
+ };
4148
+ var markdownLists = [
4149
+ {
4150
+ key: "bullet",
4151
+ Icon: ListBullets,
4152
+ actionType: "list-bullet"
4153
+ },
4154
+ {
4155
+ key: "ordered",
4156
+ Icon: ListNumbers,
4157
+ actionType: "list-ordered"
4158
+ },
4159
+ {
4160
+ key: "task",
4161
+ Icon: ListChecks,
4162
+ actionType: "list-tasks"
4163
+ }
4164
+ ];
4165
+ var MarkdownLists = () => {
4166
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
4167
+ const { t } = useTranslation(translationKey);
4168
+ return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4169
+ type: "single",
4170
+ value: state?.listStyle ?? void 0
4171
+ }, markdownLists.map(({ key, Icon, actionType }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4172
+ key,
4173
+ value: key,
4174
+ Icon,
4175
+ onClick: () => onAction?.({
4176
+ type: actionType,
4177
+ data: state ? state.listStyle !== key : null
4178
+ })
4179
+ }, t(`${key} label`))));
4180
+ };
4181
+ var markdownBlocks = [
4182
+ {
4183
+ key: "blockquote",
4184
+ Icon: Quotes,
4185
+ pressed: (state) => state?.blockQuote,
4186
+ action: (state) => ({
4187
+ type: "blockquote",
4188
+ data: state ? !state.blockQuote : null
4189
+ }),
4190
+ disabled: (state) => false
4191
+ },
4192
+ {
4193
+ key: "codeblock",
4194
+ Icon: CodeBlock,
4195
+ pressed: (state) => state?.blockType === "codeblock",
4196
+ action: (state) => ({
4197
+ type: "blockquote",
4198
+ data: state ? !state.blockQuote : null
4199
+ }),
4200
+ disabled: (state) => !state?.blankLine
4201
+ }
4202
+ ];
4203
+ var MarkdownBlocks = () => {
4204
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
4205
+ const { t } = useTranslation(translationKey);
4206
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4207
+ type: "multiple",
4208
+ value: markdownBlocks.filter(({ pressed }) => pressed(state)).map(({ key }) => key)
4209
+ }, markdownBlocks.map(({ key, Icon, action }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4210
+ key,
4211
+ value: key,
4212
+ Icon,
4213
+ onClick: () => onAction?.(action(state))
4214
+ }, t(`${key} label`)))), /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4215
+ variant: "ghost",
4216
+ disabled: !state?.blankLine,
4217
+ onClick: () => onAction?.({
4218
+ type: "table"
4219
+ }),
4220
+ classNames: buttonStyles
4221
+ }, /* @__PURE__ */ React2.createElement(Table2, {
4222
+ className: iconStyles
4223
+ }), /* @__PURE__ */ React2.createElement("span", {
4224
+ className: "sr-only"
4225
+ }, t("table label"))));
4226
+ };
4227
+ 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));
4228
+ var MarkdownExtended = () => {
4229
+ const { onAction } = useToolbarContext("MarkdownStyles");
4230
+ const { t } = useTranslation(translationKey);
4231
+ return /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4232
+ variant: "ghost",
4233
+ onClick: () => onAction?.({
4234
+ type: "comment"
4235
+ }),
4236
+ classNames: buttonStyles
4237
+ }, /* @__PURE__ */ React2.createElement(ChatText, {
4238
+ className: iconStyles
4239
+ }), /* @__PURE__ */ React2.createElement("span", {
4240
+ className: "sr-only"
4241
+ }, t("comment label")));
4083
4242
  };
4084
- var MarkdownStyles = () => /* @__PURE__ */ React2.createElement("div", {
4085
- role: "none"
4086
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4087
- Icon: TextB,
4088
- title: "String",
4089
- disable: (s) => s.blockType === "codeblock",
4090
- getState: (s) => s.strong,
4091
- onClick: (s) => ({
4092
- type: "strong",
4093
- data: s ? !s.strong : null
4094
- })
4095
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4096
- Icon: TextItalic,
4097
- title: "Emphasis",
4098
- disable: (s) => s.blockType === "codeblock",
4099
- getState: (s) => s.emphasis,
4100
- onClick: (s) => ({
4101
- type: "emphasis",
4102
- data: s ? !s.emphasis : null
4103
- })
4104
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4105
- Icon: TextStrikethrough,
4106
- title: "Strike-through",
4107
- disable: (s) => s.blockType === "codeblock",
4108
- getState: (s) => s.strikethrough,
4109
- onClick: (s) => ({
4110
- type: "strikethrough",
4111
- data: s ? !s.strikethrough : null
4112
- })
4113
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4114
- Icon: Code,
4115
- title: "Inline code",
4116
- disable: (s) => s.blockType === "codeblock",
4117
- getState: (s) => s.code,
4118
- onClick: (s) => ({
4119
- type: "code",
4120
- data: s ? !s.code : null
4121
- })
4122
- }));
4123
- var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
4124
- role: "none"
4125
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4126
- Icon: ListBullets,
4127
- title: "Bullet list",
4128
- getState: (s) => s.listStyle === "bullet",
4129
- onClick: (s) => ({
4130
- type: "list-bullet",
4131
- data: s ? s.listStyle !== "bullet" : null
4132
- })
4133
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4134
- Icon: ListNumbers,
4135
- title: "Numbered list",
4136
- getState: (s) => s.listStyle === "ordered",
4137
- onClick: (s) => ({
4138
- type: "list-ordered",
4139
- data: s ? s.listStyle !== "ordered" : null
4140
- })
4141
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4142
- Icon: ListChecks,
4143
- title: "Task list",
4144
- getState: (s) => s.listStyle === "task",
4145
- onClick: (s) => ({
4146
- type: "list-tasks",
4147
- data: s ? s.listStyle !== "task" : null
4148
- })
4149
- }));
4150
- var MarkdownBlocks = () => /* @__PURE__ */ React2.createElement("div", {
4151
- role: "none"
4152
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4153
- Icon: CaretRight,
4154
- title: "Block quote",
4155
- getState: (s) => s.blockQuote,
4156
- onClick: (s) => ({
4157
- type: "blockquote",
4158
- data: s ? !s.blockQuote : null
4159
- })
4160
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4161
- Icon: CodeBlock,
4162
- title: "Code block",
4163
- disable: (s) => !s.blankLine,
4164
- getState: (s) => s.blockType === "codeblock",
4165
- onClick: (s) => ({
4166
- type: "codeblock",
4167
- data: s ? s.blockType !== "codeblock" : null
4168
- })
4169
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4170
- Icon: Table2,
4171
- title: "Table",
4172
- disable: (s) => !s.blankLine,
4173
- onClick: () => ({
4174
- type: "table"
4175
- })
4176
- }));
4177
- var MarkdownLinks = () => /* @__PURE__ */ React2.createElement("div", {
4178
- role: "none"
4179
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4180
- Icon: Link,
4181
- title: "Link",
4182
- getState: (s) => s.link,
4183
- onClick: (s) => ({
4184
- type: "link",
4185
- data: s ? !s.link : null
4186
- })
4187
- }));
4188
- 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), /* @__PURE__ */ React2.createElement(MarkdownLinks, null));
4189
- var MarkdownExtended = () => /* @__PURE__ */ React2.createElement(Toolbar.Button, {
4190
- Icon: ChatText,
4191
- title: "Create comment",
4192
- onClick: () => ({
4193
- type: "comment"
4194
- })
4195
- });
4196
4243
  var Toolbar = {
4197
4244
  Root: ToolbarRoot,
4198
4245
  Button: ToolbarButton,
@@ -4596,6 +4643,7 @@ export {
4596
4643
  defaultSlots,
4597
4644
  defaultTextSlots,
4598
4645
  defaultTheme,
4646
+ editorWithToolbarLayout,
4599
4647
  focusComment,
4600
4648
  formatting,
4601
4649
  getFormatting,