@dxos/react-ui-editor 0.7.5-main.9d26e3a → 0.7.5-main.b19bfc8

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 (87) hide show
  1. package/dist/lib/browser/index.mjs +1125 -1137
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +1145 -1171
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +1125 -1137
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/InputMode.stories.d.ts +3 -4
  11. package/dist/types/src/InputMode.stories.d.ts.map +1 -1
  12. package/dist/types/src/TextEditor.stories.d.ts +34 -35
  13. package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
  14. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts +3 -0
  15. package/dist/types/src/components/EditorToolbar/EditorToolbar.d.ts.map +1 -0
  16. package/dist/types/src/components/EditorToolbar/blocks.d.ts +18 -0
  17. package/dist/types/src/components/EditorToolbar/blocks.d.ts.map +1 -0
  18. package/dist/types/src/components/EditorToolbar/comment.d.ts +17 -0
  19. package/dist/types/src/components/EditorToolbar/comment.d.ts.map +1 -0
  20. package/dist/types/src/components/EditorToolbar/formatting.d.ts +18 -0
  21. package/dist/types/src/components/EditorToolbar/formatting.d.ts.map +1 -0
  22. package/dist/types/src/components/EditorToolbar/headings.d.ts +18 -0
  23. package/dist/types/src/components/EditorToolbar/headings.d.ts.map +1 -0
  24. package/dist/types/src/components/EditorToolbar/index.d.ts +3 -0
  25. package/dist/types/src/components/EditorToolbar/index.d.ts.map +1 -0
  26. package/dist/types/src/components/EditorToolbar/lists.d.ts +18 -0
  27. package/dist/types/src/components/EditorToolbar/lists.d.ts.map +1 -0
  28. package/dist/types/src/components/EditorToolbar/util.d.ts +58 -0
  29. package/dist/types/src/components/EditorToolbar/util.d.ts.map +1 -0
  30. package/dist/types/src/components/EditorToolbar/viewMode.d.ts +18 -0
  31. package/dist/types/src/components/EditorToolbar/viewMode.d.ts.map +1 -0
  32. package/dist/types/src/components/index.d.ts +1 -1
  33. package/dist/types/src/components/index.d.ts.map +1 -1
  34. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +5 -6
  35. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  36. package/dist/types/src/extensions/comments.d.ts +3 -4
  37. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  38. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  39. package/dist/types/src/extensions/markdown/editorAction.d.ts +12 -0
  40. package/dist/types/src/extensions/markdown/editorAction.d.ts.map +1 -0
  41. package/dist/types/src/extensions/markdown/formatting.d.ts +14 -12
  42. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  43. package/dist/types/src/extensions/markdown/index.d.ts +1 -1
  44. package/dist/types/src/extensions/markdown/index.d.ts.map +1 -1
  45. package/dist/types/src/extensions/markdown/styles.d.ts.map +1 -1
  46. package/dist/types/src/hooks/useActionHandler.d.ts +2 -2
  47. package/dist/types/src/hooks/useActionHandler.d.ts.map +1 -1
  48. package/dist/types/src/index.d.ts +1 -0
  49. package/dist/types/src/index.d.ts.map +1 -1
  50. package/dist/types/src/styles/stack-item-content-class-names.d.ts +3 -0
  51. package/dist/types/src/styles/stack-item-content-class-names.d.ts.map +1 -0
  52. package/dist/types/src/styles/theme.d.ts.map +1 -1
  53. package/dist/types/tsconfig.tsbuildinfo +1 -1
  54. package/package.json +31 -29
  55. package/src/InputMode.stories.tsx +7 -10
  56. package/src/components/EditorToolbar/EditorToolbar.tsx +106 -0
  57. package/src/components/EditorToolbar/blocks.ts +41 -0
  58. package/src/components/EditorToolbar/comment.ts +23 -0
  59. package/src/components/EditorToolbar/formatting.ts +41 -0
  60. package/src/components/EditorToolbar/headings.ts +59 -0
  61. package/src/components/EditorToolbar/index.ts +6 -0
  62. package/src/components/EditorToolbar/lists.ts +40 -0
  63. package/src/components/EditorToolbar/util.ts +65 -0
  64. package/src/components/EditorToolbar/viewMode.ts +48 -0
  65. package/src/components/index.ts +1 -1
  66. package/src/extensions/automerge/automerge.stories.tsx +2 -2
  67. package/src/extensions/comments.ts +12 -19
  68. package/src/extensions/factories.ts +11 -5
  69. package/src/extensions/markdown/decorate.ts +1 -1
  70. package/src/extensions/markdown/{action.ts → editorAction.ts} +22 -20
  71. package/src/extensions/markdown/formatting.test.ts +7 -6
  72. package/src/extensions/markdown/formatting.ts +20 -24
  73. package/src/extensions/markdown/index.ts +1 -1
  74. package/src/extensions/markdown/styles.ts +21 -0
  75. package/src/hooks/useActionHandler.ts +4 -4
  76. package/src/index.ts +4 -0
  77. package/src/styles/markdown.ts +1 -1
  78. package/src/styles/stack-item-content-class-names.ts +17 -0
  79. package/src/styles/theme.ts +2 -3
  80. package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -34
  81. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
  82. package/dist/types/src/components/Toolbar/index.d.ts +0 -2
  83. package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
  84. package/dist/types/src/extensions/markdown/action.d.ts +0 -9
  85. package/dist/types/src/extensions/markdown/action.d.ts.map +0 -1
  86. package/src/components/Toolbar/Toolbar.tsx +0 -522
  87. package/src/components/Toolbar/index.ts +0 -5
@@ -1,522 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import {
6
- type Icon,
7
- ChatText,
8
- Code,
9
- CodeBlock,
10
- Image,
11
- Link,
12
- ListBullets,
13
- ListChecks,
14
- ListNumbers,
15
- MagnifyingGlass,
16
- Paragraph,
17
- Quotes,
18
- TextStrikethrough,
19
- Table,
20
- TextB,
21
- TextHOne,
22
- TextHTwo,
23
- TextHThree,
24
- TextHFour,
25
- TextHFive,
26
- TextHSix,
27
- TextItalic,
28
- CaretDown,
29
- Check,
30
- PencilSimpleSlash,
31
- MarkdownLogo,
32
- PencilSimple,
33
- } from '@phosphor-icons/react';
34
- import { createContext } from '@radix-ui/react-context';
35
- import React, { type PropsWithChildren, useEffect, useRef, useState } from 'react';
36
- import { useDropzone } from 'react-dropzone';
37
-
38
- import {
39
- Button,
40
- DropdownMenu,
41
- ElevationProvider,
42
- Toolbar as NaturalToolbar,
43
- Tooltip,
44
- type ThemedClassName,
45
- type ToolbarToggleGroupItemProps as NaturalToolbarToggleGroupItemProps,
46
- type ToolbarButtonProps as NaturalToolbarButtonProps,
47
- useTranslation,
48
- } from '@dxos/react-ui';
49
- import { getSize } from '@dxos/react-ui-theme';
50
-
51
- import { type EditorViewMode, type Action, type ActionType, type Formatting, EditorViewModes } from '../../extensions';
52
- import { translationKey } from '../../translations';
53
-
54
- const iconStyles = getSize(5);
55
- const buttonStyles = 'min-bs-0 p-1';
56
- const tooltipProps = { side: 'top' as const, classNames: 'z-10' };
57
-
58
- const ToolbarSeparator = () => <div role='separator' className='grow' />;
59
-
60
- //
61
- // Root
62
- //
63
-
64
- const [ToolbarContextProvider, useToolbarContext] = createContext<ToolbarProps>('Toolbar');
65
-
66
- export type ToolbarProps = ThemedClassName<
67
- PropsWithChildren<{
68
- state: (Formatting & { comment?: boolean; mode?: EditorViewMode; selection?: boolean }) | undefined;
69
- onAction?: (action: Action) => void;
70
- }>
71
- >;
72
-
73
- const ToolbarRoot = ({ children, onAction, classNames, state }: ToolbarProps) => {
74
- return (
75
- <ToolbarContextProvider onAction={onAction} state={state}>
76
- <ElevationProvider elevation='positioned'>
77
- <NaturalToolbar.Root
78
- classNames={['p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden', classNames]}
79
- style={{ contain: 'layout' }}
80
- >
81
- {children}
82
- </NaturalToolbar.Root>
83
- </ElevationProvider>
84
- </ToolbarContextProvider>
85
- );
86
- };
87
-
88
- //
89
- // Button
90
- //
91
-
92
- type ButtonProps = {
93
- type: ActionType;
94
- Icon: Icon;
95
- getState: (state: Formatting) => boolean;
96
- disabled?: (state: Formatting) => boolean;
97
- };
98
-
99
- type ToolbarToggleButtonProps = NaturalToolbarToggleGroupItemProps & { Icon: Icon };
100
-
101
- const ToolbarToggleButton = ({ Icon, children, ...props }: ToolbarToggleButtonProps) => {
102
- return (
103
- <Tooltip.Root>
104
- <Tooltip.Trigger asChild>
105
- <NaturalToolbar.ToggleGroupItem variant='ghost' {...props} classNames={buttonStyles}>
106
- <Icon className={iconStyles} />
107
- <span className='sr-only'>{children}</span>
108
- </NaturalToolbar.ToggleGroupItem>
109
- </Tooltip.Trigger>
110
- <Tooltip.Portal>
111
- <Tooltip.Content {...tooltipProps}>
112
- {children}
113
- <Tooltip.Arrow />
114
- </Tooltip.Content>
115
- </Tooltip.Portal>
116
- </Tooltip.Root>
117
- );
118
- };
119
-
120
- type ToolbarButtonProps = NaturalToolbarButtonProps & { Icon: Icon };
121
-
122
- const ToolbarButton = ({ Icon, children, ...props }: ToolbarButtonProps) => {
123
- return (
124
- <Tooltip.Root>
125
- <Tooltip.Trigger asChild>
126
- <NaturalToolbar.Button variant='ghost' {...props} classNames={buttonStyles}>
127
- <Icon className={iconStyles} />
128
- <span className='sr-only'>{children}</span>
129
- </NaturalToolbar.Button>
130
- </Tooltip.Trigger>
131
- <Tooltip.Portal>
132
- <Tooltip.Content {...tooltipProps}>
133
- {children}
134
- <Tooltip.Arrow />
135
- </Tooltip.Content>
136
- </Tooltip.Portal>
137
- </Tooltip.Root>
138
- );
139
- };
140
-
141
- //
142
- // Heading
143
- //
144
-
145
- const HeadingIcons: { [key: string]: Icon } = {
146
- '0': Paragraph,
147
- '1': TextHOne,
148
- '2': TextHTwo,
149
- '3': TextHThree,
150
- '4': TextHFour,
151
- '5': TextHFive,
152
- '6': TextHSix,
153
- };
154
-
155
- const MarkdownHeading = () => {
156
- const { t } = useTranslation(translationKey);
157
- const { onAction, state } = useToolbarContext('MarkdownFormatting');
158
- const blockType = state ? state.blockType : 'paragraph';
159
- const header = blockType && /heading(\d)/.exec(blockType);
160
- const value = header ? header[1] : blockType === 'paragraph' || !blockType ? '0' : undefined;
161
- const HeadingIcon = HeadingIcons[value ?? '0'];
162
- const suppressNextTooltip = useRef<boolean>(false);
163
- const [tooltipOpen, setTooltipOpen] = useState<boolean>(false);
164
- const [selectOpen, setSelectOpen] = useState<boolean>(false);
165
- return (
166
- <Tooltip.Root
167
- open={tooltipOpen}
168
- onOpenChange={(nextOpen) => {
169
- if (nextOpen && suppressNextTooltip.current) {
170
- suppressNextTooltip.current = false;
171
- return setTooltipOpen(false);
172
- } else {
173
- return setTooltipOpen(nextOpen);
174
- }
175
- }}
176
- >
177
- {/* TODO(thure): `Select` encounters a ref error if used here (repro: select a heading, then select another
178
- heading). Determine the root cause and fix or report to Radix. */}
179
- <DropdownMenu.Root
180
- open={selectOpen}
181
- onOpenChange={(nextOpen: boolean) => {
182
- if (!nextOpen) {
183
- suppressNextTooltip.current = true;
184
- }
185
- return setSelectOpen(nextOpen);
186
- }}
187
- >
188
- <Tooltip.Trigger asChild>
189
- <NaturalToolbar.Button asChild>
190
- <DropdownMenu.Trigger asChild>
191
- <Button variant='ghost' classNames={buttonStyles} disabled={value === null}>
192
- <span className='sr-only'>{t('heading label')}</span>
193
- <HeadingIcon className={iconStyles} />
194
- <CaretDown />
195
- </Button>
196
- </DropdownMenu.Trigger>
197
- </NaturalToolbar.Button>
198
- </Tooltip.Trigger>
199
- <DropdownMenu.Portal>
200
- <DropdownMenu.Content classNames='is-min md:is-min' onCloseAutoFocus={(e) => e.preventDefault()}>
201
- <DropdownMenu.Viewport>
202
- {Object.keys(HeadingIcons).map((level) => {
203
- const Icon = HeadingIcons[level];
204
- return (
205
- <DropdownMenu.CheckboxItem
206
- key={level}
207
- checked={value === level}
208
- onClick={() => onAction?.({ type: 'heading', data: level })}
209
- >
210
- <span className='sr-only'>{t('heading level label', { count: parseInt(level) })}</span>
211
- <Icon className={iconStyles} />
212
- <DropdownMenu.ItemIndicator>
213
- <Check />
214
- </DropdownMenu.ItemIndicator>
215
- </DropdownMenu.CheckboxItem>
216
- );
217
- })}
218
- </DropdownMenu.Viewport>
219
- <DropdownMenu.Arrow />
220
- </DropdownMenu.Content>
221
- </DropdownMenu.Portal>
222
- </DropdownMenu.Root>
223
- <Tooltip.Portal>
224
- <Tooltip.Content {...tooltipProps}>
225
- {t('heading label')}
226
- <Tooltip.Arrow />
227
- </Tooltip.Content>
228
- </Tooltip.Portal>
229
- </Tooltip.Root>
230
- );
231
- };
232
-
233
- //
234
- // Markdown
235
- //
236
-
237
- const markdownStyles: ButtonProps[] = [
238
- { type: 'strong', Icon: TextB, getState: (state) => !!state?.strong },
239
- { type: 'emphasis', Icon: TextItalic, getState: (state) => !!state?.emphasis },
240
- { type: 'strikethrough', Icon: TextStrikethrough, getState: (state) => !!state?.strikethrough },
241
- { type: 'code', Icon: Code, getState: (state) => !!state?.code },
242
- { type: 'link', Icon: Link, getState: (state) => !!state?.link },
243
- ];
244
-
245
- const MarkdownStyles = () => {
246
- const { onAction, state } = useToolbarContext('MarkdownStyles');
247
- const { t } = useTranslation(translationKey);
248
-
249
- return (
250
- <NaturalToolbar.ToggleGroup
251
- type='multiple'
252
- value={markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)}
253
- >
254
- {markdownStyles.map(({ type, getState, Icon }) => (
255
- <ToolbarToggleButton
256
- key={type}
257
- value={type}
258
- Icon={Icon}
259
- disabled={state?.blockType === 'codeblock'}
260
- onClick={state ? () => onAction?.({ type, data: !getState(state) }) : undefined}
261
- >
262
- {t(`${type} label`)}
263
- </ToolbarToggleButton>
264
- ))}
265
- </NaturalToolbar.ToggleGroup>
266
- );
267
- };
268
-
269
- const markdownLists: ButtonProps[] = [
270
- { type: 'list-bullet', Icon: ListBullets, getState: (state) => state.listStyle === 'bullet' },
271
- { type: 'list-ordered', Icon: ListNumbers, getState: (state) => state.listStyle === 'ordered' },
272
- { type: 'list-task', Icon: ListChecks, getState: (state) => state.listStyle === 'task' },
273
- ];
274
-
275
- const MarkdownLists = () => {
276
- const { onAction, state } = useToolbarContext('MarkdownStyles');
277
- const { t } = useTranslation(translationKey);
278
- return (
279
- <NaturalToolbar.ToggleGroup type='single' value={state?.listStyle ? `list-${state.listStyle}` : ''}>
280
- {markdownLists.map(({ type, getState, Icon }) => (
281
- <ToolbarToggleButton
282
- key={type}
283
- value={type}
284
- Icon={Icon}
285
- onClick={state ? () => onAction?.({ type, data: !getState(state) }) : undefined}
286
- >
287
- {t(`${type} label`)}
288
- </ToolbarToggleButton>
289
- ))}
290
- </NaturalToolbar.ToggleGroup>
291
- );
292
- };
293
-
294
- const markdownBlocks: ButtonProps[] = [
295
- {
296
- type: 'blockquote',
297
- Icon: Quotes,
298
- getState: (state) => !!state?.blockQuote,
299
- },
300
- {
301
- type: 'codeblock',
302
- Icon: CodeBlock,
303
- getState: (state) => state.blockType === 'codeblock',
304
- },
305
- {
306
- type: 'table',
307
- Icon: Table,
308
- getState: (state) => state.blockType === 'tablecell',
309
- disabled: (state) => !state.blankLine,
310
- },
311
- ];
312
-
313
- const MarkdownBlocks = () => {
314
- const { onAction, state } = useToolbarContext('MarkdownStyles');
315
- const { t } = useTranslation(translationKey);
316
- const value = markdownBlocks.find(({ getState }) => state && getState(state));
317
- return (
318
- <NaturalToolbar.ToggleGroup type='single' value={value?.type ?? ''}>
319
- {markdownBlocks.map(({ type, disabled, getState, Icon }) => (
320
- <ToolbarToggleButton
321
- key={type}
322
- value={type}
323
- Icon={Icon}
324
- disabled={!state || disabled?.(state)}
325
- onClick={state ? () => onAction?.({ type, data: !getState(state) }) : undefined}
326
- >
327
- {t(`${type} label`)}
328
- </ToolbarToggleButton>
329
- ))}
330
- </NaturalToolbar.ToggleGroup>
331
- );
332
- };
333
-
334
- const MarkdownStandard = () => (
335
- <>
336
- <MarkdownHeading />
337
- <MarkdownStyles />
338
- <MarkdownLists />
339
- <MarkdownBlocks />
340
- </>
341
- );
342
-
343
- //
344
- // Custom
345
- //
346
-
347
- // TODO(burdon): Make extensible.
348
- export type MarkdownCustomOptions = {
349
- onUpload?: (file: File) => Promise<{ url?: string } | undefined>;
350
- };
351
-
352
- const MarkdownCustom = ({ onUpload }: MarkdownCustomOptions = {}) => {
353
- const { onAction } = useToolbarContext('MarkdownStyles');
354
- const { t } = useTranslation(translationKey);
355
- // https://react-dropzone.js.org/#src
356
- const { acceptedFiles, getInputProps, open } = useDropzone({
357
- multiple: false,
358
- noDrag: true,
359
- accept: {
360
- 'image/*': ['.jpg', '.jpeg', '.png', '.gif'],
361
- },
362
- });
363
-
364
- useEffect(() => {
365
- if (onUpload && acceptedFiles.length) {
366
- requestAnimationFrame(async () => {
367
- // NOTE: Clone file since react-dropzone patches in a non-standard `path` property, which confuses IPFS.
368
- const f = acceptedFiles[0];
369
- const file = new File([f], f.name, {
370
- type: f.type,
371
- lastModified: f.lastModified,
372
- });
373
-
374
- const info = await onUpload(file);
375
- if (info) {
376
- onAction?.({ type: 'image', data: info.url });
377
- }
378
- });
379
- }
380
- }, [acceptedFiles]);
381
-
382
- return (
383
- <>
384
- <input {...getInputProps()} />
385
- <ToolbarButton value='image' Icon={Image} onClick={() => open()}>
386
- {t('image label')}
387
- </ToolbarButton>
388
- </>
389
- );
390
- };
391
-
392
- //
393
- // View Mode
394
- //
395
-
396
- const ViewModeIcons: Record<EditorViewMode, Icon> = {
397
- preview: PencilSimple,
398
- readonly: PencilSimpleSlash,
399
- source: MarkdownLogo,
400
- };
401
-
402
- const MarkdownView = ({ mode }: { mode: EditorViewMode }) => {
403
- const { t } = useTranslation(translationKey);
404
- const { onAction } = useToolbarContext('ViewMode');
405
- const ModeIcon = ViewModeIcons[mode ?? 'preview'];
406
- const suppressNextTooltip = useRef<boolean>(false);
407
- const [tooltipOpen, setTooltipOpen] = useState<boolean>(false);
408
- const [selectOpen, setSelectOpen] = useState<boolean>(false);
409
- return (
410
- <Tooltip.Root
411
- open={tooltipOpen}
412
- onOpenChange={(nextOpen) => {
413
- if (nextOpen && suppressNextTooltip.current) {
414
- suppressNextTooltip.current = false;
415
- return setTooltipOpen(false);
416
- } else {
417
- return setTooltipOpen(nextOpen);
418
- }
419
- }}
420
- >
421
- {/* TODO(thure): `Select` encounters a ref error if used here (repro: select a heading, then select another
422
- heading). Determine the root cause and fix or report to Radix. */}
423
- <DropdownMenu.Root
424
- open={selectOpen}
425
- onOpenChange={(nextOpen: boolean) => {
426
- if (!nextOpen) {
427
- suppressNextTooltip.current = true;
428
- }
429
- return setSelectOpen(nextOpen);
430
- }}
431
- >
432
- <Tooltip.Trigger asChild>
433
- <NaturalToolbar.Button asChild>
434
- <DropdownMenu.Trigger asChild>
435
- <Button variant='ghost' classNames={buttonStyles}>
436
- <span className='sr-only'>{t('mode label')}</span>
437
- <ModeIcon className={iconStyles} />
438
- <CaretDown />
439
- </Button>
440
- </DropdownMenu.Trigger>
441
- </NaturalToolbar.Button>
442
- </Tooltip.Trigger>
443
- <DropdownMenu.Portal>
444
- <DropdownMenu.Content classNames='is-min md:is-min' onCloseAutoFocus={(e) => e.preventDefault()}>
445
- <DropdownMenu.Viewport>
446
- {EditorViewModes.map((value) => {
447
- const Icon = ViewModeIcons[value];
448
- return (
449
- <DropdownMenu.CheckboxItem
450
- key={value}
451
- checked={value === mode}
452
- onClick={() => onAction?.({ type: 'view-mode', data: value })}
453
- >
454
- <Icon className={iconStyles} />
455
- <span className='whitespace-nowrap grow'>{t(`${value} mode label`)}</span>
456
- <Check className={value === mode ? 'visible' : 'invisible'} />
457
- </DropdownMenu.CheckboxItem>
458
- );
459
- })}
460
- </DropdownMenu.Viewport>
461
- <DropdownMenu.Arrow />
462
- </DropdownMenu.Content>
463
- </DropdownMenu.Portal>
464
- </DropdownMenu.Root>
465
- <Tooltip.Portal>
466
- <Tooltip.Content {...tooltipProps}>
467
- {t('view mode label')}
468
- <Tooltip.Arrow />
469
- </Tooltip.Content>
470
- </Tooltip.Portal>
471
- </Tooltip.Root>
472
- );
473
- };
474
-
475
- //
476
- // Actions
477
- //
478
-
479
- const MarkdownActions = () => {
480
- const { onAction, state } = useToolbarContext('MarkdownActions');
481
- const { t } = useTranslation(translationKey);
482
-
483
- let commentToolTipKey = 'comment label';
484
- if (state?.comment) {
485
- commentToolTipKey = 'selection overlaps existing comment label';
486
- } else if (state?.selection === false) {
487
- commentToolTipKey = 'select text to comment label';
488
- }
489
-
490
- return (
491
- <>
492
- <ToolbarButton value='search' Icon={MagnifyingGlass} onClick={() => onAction?.({ type: 'search' })}>
493
- {t('search label')}
494
- </ToolbarButton>
495
- <ToolbarButton
496
- value='comment'
497
- Icon={ChatText}
498
- data-testid='editor.toolbar.comment'
499
- onClick={() => onAction?.({ type: 'comment' })}
500
- disabled={!state || state.comment || !state.selection}
501
- >
502
- {t(commentToolTipKey)}
503
- </ToolbarButton>
504
- </>
505
- );
506
- };
507
-
508
- //
509
- // Toolbar
510
- //
511
-
512
- export const Toolbar = {
513
- Root: ToolbarRoot,
514
- Button: ToolbarToggleButton,
515
- Separator: ToolbarSeparator,
516
- View: MarkdownView,
517
- Markdown: MarkdownStandard,
518
- Custom: MarkdownCustom,
519
- Actions: MarkdownActions,
520
- };
521
-
522
- export { useToolbarContext };
@@ -1,5 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- export * from './Toolbar';