@dxos/react-ui-editor 0.4.2-main.0e5b9e5 → 0.4.2-main.21916d1

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 (35) hide show
  1. package/dist/lib/browser/index.mjs +203 -145
  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 +20 -0
  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/index.d.ts +1 -1
  17. package/dist/types/src/index.d.ts.map +1 -1
  18. package/dist/types/src/styles/index.d.ts +1 -0
  19. package/dist/types/src/styles/index.d.ts.map +1 -1
  20. package/dist/types/src/styles/layout.d.ts +2 -0
  21. package/dist/types/src/styles/layout.d.ts.map +1 -0
  22. package/dist/types/src/translations.d.ts +20 -0
  23. package/dist/types/src/translations.d.ts.map +1 -0
  24. package/package.json +24 -24
  25. package/src/components/TextEditor/MarkdownEditor.stories.tsx +13 -16
  26. package/src/components/TextEditor/TextEditor.stories.tsx +11 -14
  27. package/src/components/TextEditor/TextEditor.tsx +3 -3
  28. package/src/components/TextEditor/automerge.stories.tsx +6 -8
  29. package/src/components/TextEditor/hooks.stories.tsx +15 -16
  30. package/src/components/Toolbar/Toolbar.stories.tsx +16 -12
  31. package/src/components/Toolbar/Toolbar.tsx +156 -129
  32. package/src/index.ts +1 -1
  33. package/src/styles/index.ts +1 -0
  34. package/src/styles/layout.ts +6 -0
  35. package/src/translations.ts +25 -0
@@ -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
@@ -1090,6 +1090,9 @@ import { tailwindConfig } from "@dxos/react-ui-theme";
1090
1090
  var tokens = tailwindConfig({}).theme;
1091
1091
  var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
1092
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
+
1093
1096
  // packages/ui/react-ui-editor/src/util.ts
1094
1097
  import { log } from "@dxos/log";
1095
1098
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
@@ -3978,10 +3981,10 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeh
3978
3981
  });
3979
3982
  var defaultSlots = {
3980
3983
  root: {
3981
- className: mx3("grow", focusRing)
3984
+ className: focusRing
3982
3985
  },
3983
3986
  editor: {
3984
- className: "bs-full"
3987
+ className: "min-bs-full"
3985
3988
  }
3986
3989
  };
3987
3990
  var defaultTextSlots = {
@@ -3992,11 +3995,35 @@ var defaultMarkdownSlots = {
3992
3995
  };
3993
3996
 
3994
3997
  // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
3995
- 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";
3996
3999
  import { createContext } from "@radix-ui/react-context";
3997
4000
  import React2 from "react";
3998
- import { Button, DensityProvider, Select } from "@dxos/react-ui";
3999
- 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
4000
4027
  var HeadingIcons = {
4001
4028
  "0": Paragraph,
4002
4029
  "1": TextHOne,
@@ -4007,42 +4034,40 @@ var HeadingIcons = {
4007
4034
  "6": TextHSix
4008
4035
  };
4009
4036
  var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
4010
- var ToolbarRoot = ({ children, onAction, state }) => {
4037
+ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
4011
4038
  return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
4012
4039
  onAction,
4013
4040
  state
4014
4041
  }, /* @__PURE__ */ React2.createElement(DensityProvider, {
4015
4042
  density: "fine"
4016
- }, /* @__PURE__ */ React2.createElement("div", {
4017
- role: "toolbar",
4018
- className: "flex w-full shrink-0 p-1 gap-4 items-center whitespace-nowrap overflow-hidden"
4019
- }, 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))));
4020
4051
  };
4021
- var ToolbarButton = ({ Icon, onClick, title, getState, disable }) => {
4022
- const { onAction, state } = useToolbarContext("ToolbarButton");
4023
- const active = getState && state ? getState(state) : false;
4024
- const disabled = disable && state ? disable(state) : false;
4025
- const handleClick = (event) => {
4026
- const action = onClick(state);
4027
- if (action) {
4028
- onAction?.(action);
4029
- event.preventDefault();
4030
- }
4031
- };
4032
- 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, {
4033
4056
  variant: "ghost",
4034
- classNames: mx4("p-2", active && "ring-[1px]"),
4035
- onMouseDown: handleClick,
4036
- title,
4037
- disabled
4057
+ ...props,
4058
+ classNames: buttonStyles
4038
4059
  }, /* @__PURE__ */ React2.createElement(Icon, {
4039
- className: getSize(5)
4040
- }));
4060
+ className: iconStyles
4061
+ }), /* @__PURE__ */ React2.createElement("span", {
4062
+ className: "sr-only"
4063
+ }, children));
4041
4064
  };
4042
4065
  var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
4066
+ role: "separator",
4043
4067
  className: "grow"
4044
4068
  });
4045
4069
  var MarkdownHeading = () => {
4070
+ const { t } = useTranslation(translationKey);
4046
4071
  const { onAction, state } = useToolbarContext("MarkdownFormatting");
4047
4072
  const blockType = state ? state.blockType : "paragraph";
4048
4073
  const header = blockType && /heading(\d)/.exec(blockType);
@@ -4055,9 +4080,19 @@ var MarkdownHeading = () => {
4055
4080
  type: "heading",
4056
4081
  data: parseInt(value2)
4057
4082
  })
4058
- }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, null, /* @__PURE__ */ React2.createElement(HeadingIcon, {
4059
- className: getSize(5)
4060
- })), /* @__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, {
4061
4096
  value: "0"
4062
4097
  }, "Paragraph"), [
4063
4098
  1,
@@ -4069,120 +4104,142 @@ var MarkdownHeading = () => {
4069
4104
  ].map((level) => /* @__PURE__ */ React2.createElement(Select.Option, {
4070
4105
  key: level,
4071
4106
  value: String(level)
4072
- }, "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")));
4073
4242
  };
4074
- var MarkdownStyles = () => /* @__PURE__ */ React2.createElement("div", {
4075
- role: "none"
4076
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4077
- Icon: TextB,
4078
- title: "String",
4079
- disable: (s) => s.blockType === "codeblock",
4080
- getState: (s) => s.strong,
4081
- onClick: (s) => ({
4082
- type: "strong",
4083
- data: s ? !s.strong : null
4084
- })
4085
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4086
- Icon: TextItalic,
4087
- title: "Emphasis",
4088
- disable: (s) => s.blockType === "codeblock",
4089
- getState: (s) => s.emphasis,
4090
- onClick: (s) => ({
4091
- type: "emphasis",
4092
- data: s ? !s.emphasis : null
4093
- })
4094
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4095
- Icon: TextStrikethrough,
4096
- title: "Strike-through",
4097
- disable: (s) => s.blockType === "codeblock",
4098
- getState: (s) => s.strikethrough,
4099
- onClick: (s) => ({
4100
- type: "strikethrough",
4101
- data: s ? !s.strikethrough : null
4102
- })
4103
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4104
- Icon: Code,
4105
- title: "Inline code",
4106
- disable: (s) => s.blockType === "codeblock",
4107
- getState: (s) => s.code,
4108
- onClick: (s) => ({
4109
- type: "code",
4110
- data: s ? !s.code : null
4111
- })
4112
- }));
4113
- var MarkdownLists = () => /* @__PURE__ */ React2.createElement("div", {
4114
- role: "none"
4115
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4116
- Icon: ListBullets,
4117
- title: "Bullet list",
4118
- getState: (s) => s.listStyle === "bullet",
4119
- onClick: (s) => ({
4120
- type: "list-bullet",
4121
- data: s ? s.listStyle !== "bullet" : null
4122
- })
4123
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4124
- Icon: ListNumbers,
4125
- title: "Numbered list",
4126
- getState: (s) => s.listStyle === "ordered",
4127
- onClick: (s) => ({
4128
- type: "list-ordered",
4129
- data: s ? s.listStyle !== "ordered" : null
4130
- })
4131
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4132
- Icon: ListChecks,
4133
- title: "Task list",
4134
- getState: (s) => s.listStyle === "task",
4135
- onClick: (s) => ({
4136
- type: "list-tasks",
4137
- data: s ? s.listStyle !== "task" : null
4138
- })
4139
- }));
4140
- var MarkdownBlocks = () => /* @__PURE__ */ React2.createElement("div", {
4141
- role: "none"
4142
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4143
- Icon: CaretRight,
4144
- title: "Block quote",
4145
- getState: (s) => s.blockQuote,
4146
- onClick: (s) => ({
4147
- type: "blockquote",
4148
- data: s ? !s.blockQuote : null
4149
- })
4150
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4151
- Icon: CodeBlock,
4152
- title: "Code block",
4153
- disable: (s) => !s.blankLine,
4154
- getState: (s) => s.blockType === "codeblock",
4155
- onClick: (s) => ({
4156
- type: "codeblock",
4157
- data: s ? s.blockType !== "codeblock" : null
4158
- })
4159
- }), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4160
- Icon: Table2,
4161
- title: "Table",
4162
- disable: (s) => !s.blankLine,
4163
- onClick: () => ({
4164
- type: "table"
4165
- })
4166
- }));
4167
- var MarkdownLinks = () => /* @__PURE__ */ React2.createElement("div", {
4168
- role: "none"
4169
- }, /* @__PURE__ */ React2.createElement(ToolbarButton, {
4170
- Icon: Link,
4171
- title: "Link",
4172
- getState: (s) => s.link,
4173
- onClick: (s) => ({
4174
- type: "link",
4175
- data: s ? !s.link : null
4176
- })
4177
- }));
4178
- 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));
4179
- var MarkdownExtended = () => /* @__PURE__ */ React2.createElement(Toolbar.Button, {
4180
- Icon: ChatText,
4181
- title: "Create comment",
4182
- onClick: () => ({
4183
- type: "comment"
4184
- })
4185
- });
4186
4243
  var Toolbar = {
4187
4244
  Root: ToolbarRoot,
4188
4245
  Button: ToolbarButton,
@@ -4586,6 +4643,7 @@ export {
4586
4643
  defaultSlots,
4587
4644
  defaultTextSlots,
4588
4645
  defaultTheme,
4646
+ editorWithToolbarLayout,
4589
4647
  focusComment,
4590
4648
  formatting,
4591
4649
  getFormatting,