@luscii-healthtech/web-ui 51.4.0 → 52.0.1

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.
@@ -26,10 +26,10 @@ var TabsPrimitive = require('@radix-ui/react-tabs');
26
26
  var PropTypes = require('prop-types');
27
27
  var ReactSelect = require('react-select');
28
28
  var RadixSwitch = require('@radix-ui/react-switch');
29
- var Quill = require('quill');
30
- require('quill-paste-smart');
29
+ var react = require('@tiptap/react');
30
+ var StarterKit = require('@tiptap/starter-kit');
31
31
  var solid = require('@heroicons/react/20/solid');
32
- var react = require('@headlessui/react');
32
+ var react$1 = require('@headlessui/react');
33
33
  var ToggleGroup = require('@radix-ui/react-toggle-group');
34
34
  var d3 = require('d3-scale');
35
35
 
@@ -65,7 +65,7 @@ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
65
65
  var PropTypes__default = /*#__PURE__*/_interopDefault(PropTypes);
66
66
  var ReactSelect__default = /*#__PURE__*/_interopDefault(ReactSelect);
67
67
  var RadixSwitch__namespace = /*#__PURE__*/_interopNamespace(RadixSwitch);
68
- var Quill__default = /*#__PURE__*/_interopDefault(Quill);
68
+ var StarterKit__default = /*#__PURE__*/_interopDefault(StarterKit);
69
69
  var ToggleGroup__namespace = /*#__PURE__*/_interopNamespace(ToggleGroup);
70
70
  var d3__namespace = /*#__PURE__*/_interopNamespace(d3);
71
71
 
@@ -224,8 +224,8 @@ function styleInject(css, ref) {
224
224
  }
225
225
  }
226
226
 
227
- var css_248z$e = "/* https://stackoverflow.com/a/13924997 */\n.ui\\:text-two-lines-max {\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n /* number of lines to show */\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n";
228
- styleInject(css_248z$e);
227
+ var css_248z$d = "/* https://stackoverflow.com/a/13924997 */\n.ui\\:text-two-lines-max {\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n /* number of lines to show */\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n";
228
+ styleInject(css_248z$d);
229
229
 
230
230
  const newVariants = /* @__PURE__ */ new Set([
231
231
  "body-base-light",
@@ -1009,8 +1009,8 @@ toast.info = (message) => {
1009
1009
  showToaster({ message, type: "success", showIcon: true, title: "" });
1010
1010
  };
1011
1011
 
1012
- var css_248z$d = "/**\n * --- DEPRECATED ---\n * DON'T USE ANYTHING FROM THIS FILE IN FUTURE CHANGES. WE SHOULD BE\n * USING TAILWIND CLASSES DIRECTLY IN OUR COMPONENTS.\n */\n/** Load Avenir fonts for titles */\n@font-face {\n font-family: \"AvenirNextLTPro-Regular\";\n src: url(\"../../../public/fonts/avenir/3A0AF8_1_0.eot\");\n src: url(\"../../../public/fonts/avenir/3A0AF8_1_0.eot\") format(\"embedded-opentype\"), url(\"../../../public/fonts/avenir/3A0AF8_1_0.woff2\") format(\"woff2\"), url(\"../../../public/fonts/avenir/3A0AF8_1_0.woff\") format(\"woff\"), url(\"../../../public/fonts/avenir/3A0AF8_1_0.ttf\") format(\"truetype\");\n}\n@font-face {\n font-family: \"AvenirNextLTPro-Bold\";\n src: url(\"../../../public/fonts/avenir/3A0AF8_0_0.eot\");\n src: url(\"../../../public/fonts/avenir/3A0AF8_0_0.eot\") format(\"embedded-opentype\"), url(\"../../../public/fonts/avenir/3A0AF8_0_0.woff2\") format(\"woff2\"), url(\"../../../public/fonts/avenir/3A0AF8_0_0.woff\") format(\"woff\"), url(\"../../../public/fonts/avenir/3A0AF8_0_0.ttf\") format(\"truetype\");\n}\n.title-avenir {\n font-family: \"AvenirNextLTPro-Bold\", \"Roboto\", sans-serif;\n}\n\n.title-inter {\n font-family: \"Inter\", \"Roboto\", \"Helvetica\", sans-serif;\n}";
1013
- styleInject(css_248z$d);
1012
+ var css_248z$c = "/**\n * --- DEPRECATED ---\n * DON'T USE ANYTHING FROM THIS FILE IN FUTURE CHANGES. WE SHOULD BE\n * USING TAILWIND CLASSES DIRECTLY IN OUR COMPONENTS.\n */\n/** Load Avenir fonts for titles */\n@font-face {\n font-family: \"AvenirNextLTPro-Regular\";\n src: url(\"../../../public/fonts/avenir/3A0AF8_1_0.eot\");\n src: url(\"../../../public/fonts/avenir/3A0AF8_1_0.eot\") format(\"embedded-opentype\"), url(\"../../../public/fonts/avenir/3A0AF8_1_0.woff2\") format(\"woff2\"), url(\"../../../public/fonts/avenir/3A0AF8_1_0.woff\") format(\"woff\"), url(\"../../../public/fonts/avenir/3A0AF8_1_0.ttf\") format(\"truetype\");\n}\n@font-face {\n font-family: \"AvenirNextLTPro-Bold\";\n src: url(\"../../../public/fonts/avenir/3A0AF8_0_0.eot\");\n src: url(\"../../../public/fonts/avenir/3A0AF8_0_0.eot\") format(\"embedded-opentype\"), url(\"../../../public/fonts/avenir/3A0AF8_0_0.woff2\") format(\"woff2\"), url(\"../../../public/fonts/avenir/3A0AF8_0_0.woff\") format(\"woff\"), url(\"../../../public/fonts/avenir/3A0AF8_0_0.ttf\") format(\"truetype\");\n}\n.title-avenir {\n font-family: \"AvenirNextLTPro-Bold\", \"Roboto\", sans-serif;\n}\n\n.title-inter {\n font-family: \"Inter\", \"Roboto\", \"Helvetica\", sans-serif;\n}";
1013
+ styleInject(css_248z$c);
1014
1014
 
1015
1015
  const Title = (props) => {
1016
1016
  const { variant: variantFromProps = "base", type, className, text, children, color, level, ref } = props, rest = __rest(props, ["variant", "type", "className", "text", "children", "color", "level", "ref"]);
@@ -1086,8 +1086,8 @@ const isSubstring = (string, searchTerm, caseSensitive = false) => {
1086
1086
  return (stringToSearch === null || stringToSearch === void 0 ? void 0 : stringToSearch.indexOf(searchTermWithCase)) > -1;
1087
1087
  };
1088
1088
 
1089
- var css_248z$c = ".list-skeleton .skeleton-box {\n display: inline-block;\n height: 1em;\n position: relative;\n overflow: hidden;\n background-color: #cbd5e1;\n border-radius: 3px;\n}\n.list-skeleton .skeleton-box::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n transform: translateX(-100%);\n background-image: linear-gradient(90deg, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 0.2) 20%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0));\n animation: shimmer 800ms infinite;\n content: \"\";\n}\n.list-skeleton .skeleton-box.is-circle {\n border-radius: 50%;\n}\n.list-skeleton .skeleton-box.is-button::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n transform: translateX(-100%);\n background-image: linear-gradient(90deg, rgba(221, 221, 221, 0) 0, rgba(221, 221, 221, 0.2) 20%, rgba(221, 221, 221, 0.5) 60%, rgba(221, 221, 221, 0));\n animation: shimmer 800ms infinite;\n content: \"\";\n}\n@keyframes shimmer {\n 100% {\n transform: translateX(100%);\n }\n}";
1090
- styleInject(css_248z$c);
1089
+ var css_248z$b = ".list-skeleton .skeleton-box {\n display: inline-block;\n height: 1em;\n position: relative;\n overflow: hidden;\n background-color: #cbd5e1;\n border-radius: 3px;\n}\n.list-skeleton .skeleton-box::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n transform: translateX(-100%);\n background-image: linear-gradient(90deg, rgba(255, 255, 255, 0) 0, rgba(255, 255, 255, 0.2) 20%, rgba(255, 255, 255, 0.5) 60%, rgba(255, 255, 255, 0));\n animation: shimmer 800ms infinite;\n content: \"\";\n}\n.list-skeleton .skeleton-box.is-circle {\n border-radius: 50%;\n}\n.list-skeleton .skeleton-box.is-button::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n transform: translateX(-100%);\n background-image: linear-gradient(90deg, rgba(221, 221, 221, 0) 0, rgba(221, 221, 221, 0.2) 20%, rgba(221, 221, 221, 0.5) 60%, rgba(221, 221, 221, 0));\n animation: shimmer 800ms infinite;\n content: \"\";\n}\n@keyframes shimmer {\n 100% {\n transform: translateX(100%);\n }\n}";
1090
+ styleInject(css_248z$b);
1091
1091
 
1092
1092
  const ListItemSkeleton = () => {
1093
1093
  return jsxRuntime.jsxs("div", { className: "ui:flex ui:flex-row ui:items-center ui:p-4", children: [jsxRuntime.jsx("div", { className: "skeleton-box is-circle ui:mr-2", style: { width: `${32}px`, height: `${32}px` } }), jsxRuntime.jsxs("div", { className: "ui:flex ui:flex-col", children: [jsxRuntime.jsx("div", { className: "skeleton-box ui:mb-1", style: { width: `${160}px`, height: `${14}px` } }), jsxRuntime.jsx("div", { className: "skeleton-box", style: { width: `${110}px`, height: `${14}px` } })] }), jsxRuntime.jsx("div", { className: "skeleton-box is-button ui:ml-auto ui:rounded-full", style: { width: `${24}px`, height: `${24}px` } })] });
@@ -1587,9 +1587,6 @@ const ListItem = (props) => {
1587
1587
  return jsxRuntime.jsx(BaseListItem, Object.assign({}, props));
1588
1588
  };
1589
1589
 
1590
- var css_248z$b = "/*! tailwindcss v4.1.12 | MIT License | https://tailwindcss.com */\n@layer properties;\nli.gu-mirror {\n position: fixed;\n z-index: 9999;\n margin: calc(var(--ui-spacing, 0.25rem) * 0);\n --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n}\nli.gu-hide {\n display: none;\n}\nli.gu-unselectable {\n user-select: none;\n}\nli.gu-transit {\n background-color: var(--ui-color-blue-50, #eff6ff);\n filter: none;\n border-radius: 0;\n --tw-border-style: none;\n border-style: none;\n opacity: 100%;\n}\nli.gu-transit > * {\n visibility: hidden;\n}\n@property --tw-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: \"<length>\";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: \"*\";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n }\n }\n}";
1591
- styleInject(css_248z$b);
1592
-
1593
1590
  const DefaultList = (_a) => {
1594
1591
  var { items, onDragEnd, onAssetLoadError, subtitle } = _a, props = __rest(_a, ["items", "onDragEnd", "onAssetLoadError", "subtitle"]);
1595
1592
  const sensor = core.useSensor(core.MouseSensor);
@@ -5041,7 +5038,7 @@ const Textarea = React__namespace.default.forwardRef((_a, ref) => {
5041
5038
  ]), style, ref }));
5042
5039
  });
5043
5040
 
5044
- const LinkTooltip = ({ linkElement, quillInstance, onClose }) => {
5041
+ const LinkTooltip = ({ linkElement, editorInstance, onClose, translations }) => {
5045
5042
  const dialogRef = React.useRef(null);
5046
5043
  const anchorName = React.useRef(`link-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`);
5047
5044
  React.useEffect(() => {
@@ -5069,25 +5066,23 @@ const LinkTooltip = ({ linkElement, quillInstance, onClose }) => {
5069
5066
  }, [linkElement, onClose]);
5070
5067
  const handleEditLink = () => {
5071
5068
  const currentUrl = linkElement.getAttribute("href") || "";
5072
- const newUrl = prompt("Link URL:", currentUrl);
5069
+ const newUrl = prompt(translations.linkUrlPrompt, currentUrl);
5073
5070
  if (newUrl !== null) {
5074
- const blot = quillInstance.scroll.find(linkElement);
5075
- if (blot) {
5076
- const index = quillInstance.getIndex(blot);
5077
- const length = blot.length();
5078
- quillInstance.setSelection(index, length);
5079
- quillInstance.format("link", newUrl || false);
5071
+ const { view } = editorInstance;
5072
+ const pos = view.posAtDOM(linkElement, 0);
5073
+ const node = view.state.doc.nodeAt(pos);
5074
+ if (node) {
5075
+ editorInstance.chain().focus().setTextSelection({ from: pos, to: pos + node.nodeSize }).setLink({ href: newUrl || "" }).run();
5080
5076
  }
5081
5077
  }
5082
5078
  onClose();
5083
5079
  };
5084
5080
  const handleRemoveLink = () => {
5085
- const blot = quillInstance.scroll.find(linkElement);
5086
- if (blot) {
5087
- const index = quillInstance.getIndex(blot);
5088
- const length = blot.length();
5089
- quillInstance.setSelection(index, length);
5090
- quillInstance.format("link", false);
5081
+ const { view } = editorInstance;
5082
+ const pos = view.posAtDOM(linkElement, 0);
5083
+ const node = view.state.doc.nodeAt(pos);
5084
+ if (node) {
5085
+ editorInstance.chain().focus().setTextSelection({ from: pos, to: pos + node.nodeSize }).unsetLink().run();
5091
5086
  }
5092
5087
  onClose();
5093
5088
  };
@@ -5099,33 +5094,57 @@ const LinkTooltip = ({ linkElement, quillInstance, onClose }) => {
5099
5094
  top: "anchor(bottom)",
5100
5095
  left: "anchor(left)",
5101
5096
  marginTop: "8px"
5102
- }, children: jsxRuntime.jsx(Card, { borderRadius: "s", elevation: "large", className: "ui:max-w-80", padding: false, border: true, children: jsxRuntime.jsxs(Stack, { width: "full", align: "stretch", children: [jsxRuntime.jsx(Box, { p: "xs", children: jsxRuntime.jsxs(Text, { children: ["Visit URL:", " ", jsxRuntime.jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "ui:text-blue-600 ui:underline ui:text-sm ui:overflow-hidden ui:text-ellipsis ui:whitespace-nowrap hover:ui:text-blue-700", children: url })] }) }), jsxRuntime.jsx(Divider, { version: "v2" }), jsxRuntime.jsxs(Stack, { axis: "x", gap: "xxs", p: "xs", children: [jsxRuntime.jsx(TertiaryButton, { onClick: handleEditLink, text: "Edit", size: "medium" }), jsxRuntime.jsx(TertiaryButton, { onClick: handleRemoveLink, text: "Remove", size: "medium" }), jsxRuntime.jsx(TertiaryButton, { onClick: onClose, text: "Close", size: "medium" })] })] }) }) });
5097
+ }, children: jsxRuntime.jsx(Card, { borderRadius: "s", elevation: "large", className: "ui:max-w-80", padding: false, border: true, children: jsxRuntime.jsxs(Stack, { width: "full", align: "stretch", children: [jsxRuntime.jsx(Box, { p: "xs", children: jsxRuntime.jsxs(Text, { children: [translations.visitUrlLabel, " ", jsxRuntime.jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "ui:text-blue-600 ui:underline ui:text-sm ui:overflow-hidden ui:text-ellipsis ui:whitespace-nowrap hover:ui:text-blue-700", children: url })] }) }), jsxRuntime.jsx(Divider, { version: "v2" }), jsxRuntime.jsxs(Stack, { axis: "x", gap: "xxs", p: "xs", children: [jsxRuntime.jsx(TertiaryButton, { onClick: handleEditLink, text: translations.editButtonText, size: "medium" }), jsxRuntime.jsx(TertiaryButton, { onClick: handleRemoveLink, text: translations.removeButtonText, size: "medium" }), jsxRuntime.jsx(TertiaryButton, { onClick: onClose, text: translations.closeButtonText, size: "medium" })] })] }) }) });
5103
5098
  };
5104
5099
 
5105
- const TextEditorToolbarButton = ({ option, hasTextSelected }) => {
5100
+ const TextEditorToolbarButton = ({ option, hasTextSelected, editor, translations }) => {
5101
+ const [, forceUpdate] = React.useState(0);
5102
+ React.useEffect(() => {
5103
+ if (!editor) {
5104
+ return void 0;
5105
+ }
5106
+ const handleUpdate = () => {
5107
+ forceUpdate((n) => n + 1);
5108
+ };
5109
+ editor.on("transaction", handleUpdate);
5110
+ editor.on("selectionUpdate", handleUpdate);
5111
+ return () => {
5112
+ editor.off("transaction", handleUpdate);
5113
+ editor.off("selectionUpdate", handleUpdate);
5114
+ };
5115
+ }, [editor]);
5106
5116
  const buttonClasses = "ui:aria-pressed:bg-primary-background ui:aria-disabled:cursor-not-allowed";
5117
+ if (!editor) {
5118
+ return null;
5119
+ }
5107
5120
  if (typeof option === "string") {
5108
5121
  switch (option) {
5109
5122
  case "bold":
5110
- return jsxRuntime.jsx(TertiaryIconButton, { label: "bold", className: `ql-bold ${buttonClasses}`, children: jsxRuntime.jsx(solid.BoldIcon, { width: 16 }) });
5123
+ return jsxRuntime.jsx(TertiaryIconButton, { label: translations.boldLabel, className: buttonClasses, onClick: () => editor.chain().focus().toggleBold().run(), "aria-pressed": editor.isActive("bold"), children: jsxRuntime.jsx(solid.BoldIcon, { width: 16 }) });
5111
5124
  case "italic":
5112
- return jsxRuntime.jsx(TertiaryIconButton, { label: "italic", className: `ql-italic ${buttonClasses}`, children: jsxRuntime.jsx(solid.ItalicIcon, { width: 16 }) });
5125
+ return jsxRuntime.jsx(TertiaryIconButton, { label: translations.italicLabel, className: buttonClasses, onClick: () => editor.chain().focus().toggleItalic().run(), "aria-pressed": editor.isActive("italic"), children: jsxRuntime.jsx(solid.ItalicIcon, { width: 16 }) });
5113
5126
  case "underline":
5114
- return jsxRuntime.jsx(TertiaryIconButton, { label: "underline", className: `ql-underline ${buttonClasses}`, children: jsxRuntime.jsx(solid.UnderlineIcon, { width: 16 }) });
5127
+ return jsxRuntime.jsx(TertiaryIconButton, { label: translations.underlineLabel, className: buttonClasses, onClick: () => editor.chain().focus().toggleUnderline().run(), "aria-pressed": editor.isActive("underline"), children: jsxRuntime.jsx(solid.UnderlineIcon, { width: 16 }) });
5115
5128
  case "strike":
5116
- return jsxRuntime.jsx(TertiaryIconButton, { label: "strike", className: `ql-strike ${buttonClasses}`, children: jsxRuntime.jsx(solid.StrikethroughIcon, { width: 16 }) });
5129
+ return jsxRuntime.jsx(TertiaryIconButton, { label: translations.strikeLabel, className: buttonClasses, onClick: () => editor.chain().focus().toggleStrike().run(), "aria-pressed": editor.isActive("strike"), children: jsxRuntime.jsx(solid.StrikethroughIcon, { width: 16 }) });
5117
5130
  case "link":
5118
- return jsxRuntime.jsx(TertiaryIconButton, { label: "link", className: `ql-link ${buttonClasses}`, disabled: !hasTextSelected, children: jsxRuntime.jsx(solid.LinkIcon, { width: 16 }) });
5119
- case "video":
5120
- return jsxRuntime.jsx(TertiaryIconButton, { label: "video", className: `ql-video ${buttonClasses}`, children: jsxRuntime.jsx(solid.VideoCameraIcon, { width: 16 }) });
5131
+ return jsxRuntime.jsx(TertiaryIconButton, { label: translations.linkLabel, className: buttonClasses, disabled: !hasTextSelected, onClick: () => {
5132
+ if (!hasTextSelected) {
5133
+ return;
5134
+ }
5135
+ const url = prompt(translations.enterUrlPrompt);
5136
+ if (url) {
5137
+ editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
5138
+ }
5139
+ }, "aria-pressed": editor.isActive("link"), children: jsxRuntime.jsx(solid.LinkIcon, { width: 16 }) });
5121
5140
  default:
5122
5141
  return null;
5123
5142
  }
5124
5143
  } else if (typeof option === "object" && "list" in option) {
5125
5144
  if (option.list === "ordered") {
5126
- return jsxRuntime.jsx(TertiaryIconButton, { label: "ordered list", className: `ql-list ${buttonClasses}`, value: "ordered", children: jsxRuntime.jsx(solid.NumberedListIcon, { width: 16 }) });
5145
+ return jsxRuntime.jsx(TertiaryIconButton, { label: translations.orderedListLabel, className: buttonClasses, onClick: () => editor.chain().focus().toggleOrderedList().run(), "aria-pressed": editor.isActive("orderedList"), children: jsxRuntime.jsx(solid.NumberedListIcon, { width: 16 }) });
5127
5146
  } else if (option.list === "bullet") {
5128
- return jsxRuntime.jsx(TertiaryIconButton, { label: "bullet list", className: `ql-list ${buttonClasses}`, value: "bullet", children: jsxRuntime.jsx(solid.ListBulletIcon, { width: 16 }) });
5147
+ return jsxRuntime.jsx(TertiaryIconButton, { label: translations.bulletListLabel, className: buttonClasses, onClick: () => editor.chain().focus().toggleBulletList().run(), "aria-pressed": editor.isActive("bulletList"), children: jsxRuntime.jsx(solid.ListBulletIcon, { width: 16 }) });
5129
5148
  }
5130
5149
  }
5131
5150
  return null;
@@ -5149,11 +5168,92 @@ const getGroupKey = (group) => {
5149
5168
  return "";
5150
5169
  }).join("-");
5151
5170
  };
5152
- const TextEditorToolbar = ({ toolbarId, toolbar, hasTextSelected }) => {
5153
- return jsxRuntime.jsx(Stack, { axis: "x", gap: "m", px: "xxxs", id: toolbarId, children: toolbar.map((group) => jsxRuntime.jsx(Stack, { axis: "x", gap: "xxxxs", children: group.map((option, optionIndex) => jsxRuntime.jsx(TextEditorToolbarButton, { option, hasTextSelected }, getOptionKey(option, optionIndex))) }, getGroupKey(group))) });
5171
+ const TextEditorToolbar = ({ toolbarId, toolbar, hasTextSelected, editor, translations }) => {
5172
+ return jsxRuntime.jsx(Stack, { axis: "x", gap: "m", _px: "xs", id: toolbarId, children: toolbar.map((group) => jsxRuntime.jsx(Stack, { axis: "x", _gap: "xs", children: group.map((option, optionIndex) => jsxRuntime.jsx(TextEditorToolbarButton, { option, hasTextSelected, editor, translations }, getOptionKey(option, optionIndex))) }, getGroupKey(group))) });
5173
+ };
5174
+
5175
+ const TEXT_EDITOR_TRANSLATIONS = {
5176
+ "en-GB": {
5177
+ boldLabel: "bold",
5178
+ italicLabel: "italic",
5179
+ underlineLabel: "underline",
5180
+ strikeLabel: "strike",
5181
+ linkLabel: "link",
5182
+ orderedListLabel: "ordered list",
5183
+ bulletListLabel: "bullet list",
5184
+ enterUrlPrompt: "Enter URL:",
5185
+ linkUrlPrompt: "Link URL:",
5186
+ visitUrlLabel: "Visit URL:",
5187
+ editButtonText: "Edit",
5188
+ removeButtonText: "Remove",
5189
+ closeButtonText: "Close"
5190
+ },
5191
+ "nl-NL": {
5192
+ boldLabel: "vetgedrukt",
5193
+ italicLabel: "cursief",
5194
+ underlineLabel: "onderstreept",
5195
+ strikeLabel: "doorgestreept",
5196
+ linkLabel: "link",
5197
+ orderedListLabel: "genummerde lijst",
5198
+ bulletListLabel: "opsommingslijst",
5199
+ enterUrlPrompt: "Voer URL in:",
5200
+ linkUrlPrompt: "Link URL:",
5201
+ visitUrlLabel: "Bezoek URL:",
5202
+ editButtonText: "Bewerken",
5203
+ removeButtonText: "Verwijderen",
5204
+ closeButtonText: "Sluiten"
5205
+ },
5206
+ "de-DE": {
5207
+ boldLabel: "fett",
5208
+ italicLabel: "kursiv",
5209
+ underlineLabel: "unterstrichen",
5210
+ strikeLabel: "durchgestrichen",
5211
+ linkLabel: "Link",
5212
+ orderedListLabel: "nummerierte Liste",
5213
+ bulletListLabel: "Aufz\xE4hlungsliste",
5214
+ enterUrlPrompt: "URL eingeben:",
5215
+ linkUrlPrompt: "Link-URL:",
5216
+ visitUrlLabel: "URL besuchen:",
5217
+ editButtonText: "Bearbeiten",
5218
+ removeButtonText: "Entfernen",
5219
+ closeButtonText: "Schlie\xDFen"
5220
+ },
5221
+ "fr-FR": {
5222
+ boldLabel: "gras",
5223
+ italicLabel: "italique",
5224
+ underlineLabel: "soulign\xE9",
5225
+ strikeLabel: "barr\xE9",
5226
+ linkLabel: "lien",
5227
+ orderedListLabel: "liste num\xE9rot\xE9e",
5228
+ bulletListLabel: "liste \xE0 puces",
5229
+ enterUrlPrompt: "Entrer l'URL :",
5230
+ linkUrlPrompt: "URL du lien :",
5231
+ visitUrlLabel: "Visiter l'URL :",
5232
+ editButtonText: "Modifier",
5233
+ removeButtonText: "Supprimer",
5234
+ closeButtonText: "Fermer"
5235
+ },
5236
+ "pt-PT": {
5237
+ boldLabel: "negrito",
5238
+ italicLabel: "it\xE1lico",
5239
+ underlineLabel: "sublinhado",
5240
+ strikeLabel: "riscado",
5241
+ linkLabel: "liga\xE7\xE3o",
5242
+ orderedListLabel: "lista numerada",
5243
+ bulletListLabel: "lista com marcadores",
5244
+ enterUrlPrompt: "Introduzir URL:",
5245
+ linkUrlPrompt: "URL da liga\xE7\xE3o:",
5246
+ visitUrlLabel: "Visitar URL:",
5247
+ editButtonText: "Editar",
5248
+ removeButtonText: "Remover",
5249
+ closeButtonText: "Fechar"
5250
+ }
5251
+ };
5252
+ const getTextEditorTranslations = (locale) => {
5253
+ return TEXT_EDITOR_TRANSLATIONS[locale] || TEXT_EDITOR_TRANSLATIONS["en-GB"];
5154
5254
  };
5155
5255
 
5156
- var css_248z$1 = "/**\n * --- DEPRECATED ---\n * DON'T USE ANYTHING FROM THIS FILE IN FUTURE CHANGES. WE SHOULD BE\n * USING TAILWIND CLASSES DIRECTLY IN OUR COMPONENTS.\n */\n.ql-editor {\n resize: vertical;\n min-height: 10rem;\n padding: 1rem;\n font-size: 0.8rem;\n line-height: 1.5;\n}\n.ql-editor a {\n color: var(--ui-color-text-brand-primary-default);\n text-decoration: underline;\n cursor: pointer;\n}\n.ql-editor ul,\n.ql-editor ol {\n padding-left: 1.5rem;\n}\n.ql-editor ul {\n list-style-type: disc;\n}\n.ql-editor ol {\n list-style-type: decimal;\n}\n.ql-editor li {\n margin-bottom: 0.25rem;\n}\n.ql-editor strong {\n font-weight: 600;\n}\n.ql-editor em {\n font-style: italic;\n}\n.ql-editor u {\n text-decoration: underline;\n}\n.ql-editor s {\n text-decoration: line-through;\n}\n.ql-editor h1,\n.ql-editor h2,\n.ql-editor h3,\n.ql-editor h4,\n.ql-editor h5,\n.ql-editor h6 {\n font-weight: 600;\n margin-bottom: 0.75rem;\n margin-top: 1rem;\n}\n.ql-editor h1:first-child,\n.ql-editor h2:first-child,\n.ql-editor h3:first-child,\n.ql-editor h4:first-child,\n.ql-editor h5:first-child,\n.ql-editor h6:first-child {\n margin-top: 0;\n}\n.ql-editor h1 {\n font-size: 2rem;\n}\n.ql-editor h2 {\n font-size: 1.5rem;\n}\n.ql-editor h3 {\n font-size: 1.25rem;\n}\n.ql-editor h4 {\n font-size: 1.125rem;\n}\n.ql-editor h5,\n.ql-editor h6 {\n font-size: 1rem;\n}";
5256
+ var css_248z$1 = "/**\n * --- DEPRECATED ---\n * DON'T USE ANYTHING FROM THIS FILE IN FUTURE CHANGES. WE SHOULD BE\n * USING TAILWIND CLASSES DIRECTLY IN OUR COMPONENTS.\n */\n.web-ui-text-editor {\n resize: vertical;\n min-height: 10rem;\n padding: 1rem;\n font-size: 0.8rem;\n line-height: 1.5;\n outline: none;\n}\n.web-ui-text-editor.tiptap.ProseMirror p.is-editor-empty:first-child::before {\n color: var(--ui-color-text-neutral-primary-disabled);\n content: attr(data-placeholder);\n float: left;\n height: 0;\n pointer-events: none;\n}\n.web-ui-text-editor a {\n color: var(--ui-color-text-brand-primary-default);\n text-decoration: underline;\n cursor: pointer;\n}\n.web-ui-text-editor ul,\n.web-ui-text-editor ol {\n padding-left: 1.5rem;\n}\n.web-ui-text-editor ul {\n list-style-type: disc;\n}\n.web-ui-text-editor ol {\n list-style-type: decimal;\n}\n.web-ui-text-editor li {\n margin-bottom: 0.25rem;\n}\n.web-ui-text-editor strong {\n font-weight: 600;\n}\n.web-ui-text-editor em {\n font-style: italic;\n}\n.web-ui-text-editor u {\n text-decoration: underline;\n}\n.web-ui-text-editor s {\n text-decoration: line-through;\n}\n.web-ui-text-editor h1,\n.web-ui-text-editor h2,\n.web-ui-text-editor h3,\n.web-ui-text-editor h4,\n.web-ui-text-editor h5,\n.web-ui-text-editor h6 {\n font-weight: 600;\n margin-bottom: 0.75rem;\n margin-top: 1rem;\n}\n.web-ui-text-editor h1:first-child,\n.web-ui-text-editor h2:first-child,\n.web-ui-text-editor h3:first-child,\n.web-ui-text-editor h4:first-child,\n.web-ui-text-editor h5:first-child,\n.web-ui-text-editor h6:first-child {\n margin-top: 0;\n}\n.web-ui-text-editor h1 {\n font-size: 2rem;\n}\n.web-ui-text-editor h2 {\n font-size: 1.5rem;\n}\n.web-ui-text-editor h3 {\n font-size: 1.25rem;\n}\n.web-ui-text-editor h4 {\n font-size: 1.125rem;\n}\n.web-ui-text-editor h5,\n.web-ui-text-editor h6 {\n font-size: 1rem;\n}";
5157
5257
  styleInject(css_248z$1);
5158
5258
 
5159
5259
  const sanitize = (html) => DOMPurify__default.default.sanitize(html, {
@@ -5161,7 +5261,7 @@ const sanitize = (html) => DOMPurify__default.default.sanitize(html, {
5161
5261
  ALLOWED_ATTR: ["href", "target"]
5162
5262
  });
5163
5263
  const TextEditor = (_a) => {
5164
- var { defaultValue, formats, toolbar = [
5264
+ var { defaultValue, formats = ["bold", "italic", "underline", "strike", "list", "link"], toolbar = [
5165
5265
  ["bold", "italic", "underline", "strike"],
5166
5266
  [{ list: "ordered" }, { list: "bullet" }],
5167
5267
  ["link"]
@@ -5170,58 +5270,75 @@ const TextEditor = (_a) => {
5170
5270
  const toolbarId = `toolbar-${rawId.replace(/:/g, "")}`;
5171
5271
  const defaultValueRef = React.useRef(sanitize(defaultValue !== null && defaultValue !== void 0 ? defaultValue : ""));
5172
5272
  const onTextChangeRef = React.useRef(onValueChange);
5173
- const editorRef = React.useRef(null);
5174
- const quillRef = React.useRef(null);
5175
5273
  const [linkTooltip, setLinkTooltip] = React.useState(null);
5176
5274
  const [hasTextSelected, setHasTextSelected] = React.useState(false);
5275
+ const locale = useLocaleContext();
5276
+ const translations = getTextEditorTranslations(locale);
5177
5277
  React.useLayoutEffect(() => {
5178
5278
  onTextChangeRef.current = onValueChange;
5179
5279
  });
5180
- React.useEffect(() => {
5181
- if (!editorRef.current || quillRef.current) {
5182
- return void 0;
5183
- }
5184
- const editor = editorRef.current;
5185
- const quill = new Quill__default.default(editor, {
5186
- formats,
5187
- modules: {
5188
- toolbar: `#${toolbarId}`
5280
+ const editor = react.useEditor({
5281
+ extensions: [
5282
+ StarterKit__default.default.configure({
5283
+ // Configure extensions based on formats prop
5284
+ blockquote: (formats === null || formats === void 0 ? void 0 : formats.includes("blockquote")) ? {} : false,
5285
+ bold: (formats === null || formats === void 0 ? void 0 : formats.includes("bold")) ? {} : false,
5286
+ bulletList: (formats === null || formats === void 0 ? void 0 : formats.includes("list")) ? {} : false,
5287
+ code: (formats === null || formats === void 0 ? void 0 : formats.includes("code")) ? {} : false,
5288
+ heading: (formats === null || formats === void 0 ? void 0 : formats.includes("header")) ? {} : false,
5289
+ italic: (formats === null || formats === void 0 ? void 0 : formats.includes("italic")) ? {} : false,
5290
+ link: (formats === null || formats === void 0 ? void 0 : formats.includes("link")) ? {
5291
+ openOnClick: false,
5292
+ defaultProtocol: "https",
5293
+ HTMLAttributes: {
5294
+ rel: "noopener noreferrer"
5295
+ }
5296
+ } : false,
5297
+ orderedList: (formats === null || formats === void 0 ? void 0 : formats.includes("list")) ? {} : false,
5298
+ strike: (formats === null || formats === void 0 ? void 0 : formats.includes("strike")) ? {} : false,
5299
+ underline: (formats === null || formats === void 0 ? void 0 : formats.includes("underline")) ? {
5300
+ HTMLAttributes: {
5301
+ class: ""
5302
+ }
5303
+ } : false,
5304
+ codeBlock: (formats === null || formats === void 0 ? void 0 : formats.includes("code")) ? {} : false
5305
+ })
5306
+ ],
5307
+ content: defaultValueRef.current,
5308
+ editorProps: {
5309
+ attributes: {
5310
+ class: "web-ui-text-editor ui:overflow-auto ui:resize-y ui:min-h-40",
5311
+ "data-placeholder": placeholder || ""
5189
5312
  },
5190
- placeholder
5191
- });
5192
- quill.on(Quill__default.default.events.TEXT_CHANGE, (value, _, source) => {
5313
+ transformPastedHTML: (html) => sanitize(html),
5314
+ handleClick: (view, pos, event) => {
5315
+ const { doc } = view.state;
5316
+ const $pos = doc.resolve(pos);
5317
+ const marks = $pos.marks();
5318
+ const linkMark = marks.find((mark) => mark.type.name === "link");
5319
+ if (linkMark) {
5320
+ event.preventDefault();
5321
+ const anchor = event.target.closest("a");
5322
+ if (anchor) {
5323
+ setLinkTooltip(anchor);
5324
+ }
5325
+ return true;
5326
+ }
5327
+ return false;
5328
+ }
5329
+ },
5330
+ onUpdate: ({ editor: ed }) => {
5193
5331
  var _a2;
5194
- (_a2 = onTextChangeRef.current) === null || _a2 === void 0 ? void 0 : _a2.call(onTextChangeRef, sanitize(quill.getSemanticHTML()), value, source);
5195
- });
5196
- const handleSelectionChange = () => {
5197
- const selection = quill.getSelection();
5198
- setHasTextSelected(selection ? selection.length > 0 : false);
5199
- };
5200
- quill.on(Quill__default.default.events.SELECTION_CHANGE, handleSelectionChange);
5201
- if (defaultValueRef.current) {
5202
- quill.setContents(quill.clipboard.convert({
5203
- html: defaultValueRef.current
5204
- }));
5205
- }
5206
- quillRef.current = quill;
5207
- const qlEditor = editor.querySelector(".ql-editor");
5208
- if (qlEditor) {
5209
- qlEditor.classList.add("ui:overflow-auto", "ui:resize-y", "ui:min-h-40");
5332
+ const html = ed.getHTML();
5333
+ const json = ed.getJSON();
5334
+ (_a2 = onTextChangeRef.current) === null || _a2 === void 0 ? void 0 : _a2.call(onTextChangeRef, sanitize(html), json, "user");
5335
+ },
5336
+ onSelectionUpdate: ({ editor: ed }) => {
5337
+ const { from, to } = ed.state.selection;
5338
+ setHasTextSelected(from !== to);
5210
5339
  }
5211
- const handleEditorClick = (e) => {
5212
- const target = e.target;
5213
- if (target.tagName === "A") {
5214
- e.preventDefault();
5215
- const anchor = target;
5216
- setLinkTooltip(anchor);
5217
- }
5218
- };
5219
- editor.addEventListener("click", handleEditorClick);
5220
- return () => {
5221
- editor.removeEventListener("click", handleEditorClick);
5222
- };
5223
- }, []);
5224
- return jsxRuntime.jsxs(Card, Object.assign({ padding: false, border: true, borderRadius: "xs", backgroundColor: "base" }, attrs, { children: [jsxRuntime.jsx(Card.TopBar, { children: jsxRuntime.jsx(Card.Actions, { className: "ui:justify-start", children: jsxRuntime.jsx(TextEditorToolbar, { toolbarId, toolbar, hasTextSelected }) }) }), jsxRuntime.jsx(Divider, { version: "v2" }), jsxRuntime.jsx("div", { className: "editor", ref: editorRef }), jsxRuntime.jsx("div", { children: linkTooltip && quillRef.current && jsxRuntime.jsx(LinkTooltip, { linkElement: linkTooltip, quillInstance: quillRef.current, onClose: () => setLinkTooltip(null) }) })] }));
5340
+ });
5341
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs(Card, Object.assign({ padding: false, border: true, borderRadius: "xs", backgroundColor: "base" }, attrs, { children: [jsxRuntime.jsx(Card.TopBar, { children: jsxRuntime.jsx(Card.Actions, { className: "ui:justify-start", children: jsxRuntime.jsx(TextEditorToolbar, { toolbarId, toolbar, hasTextSelected, editor, translations }) }) }), jsxRuntime.jsx(Divider, { version: "v2" }), jsxRuntime.jsx(react.EditorContent, { editor }), jsxRuntime.jsx("div", {})] })), linkTooltip && editor && jsxRuntime.jsx(LinkTooltip, { linkElement: linkTooltip, editorInstance: editor, onClose: () => setLinkTooltip(null), translations })] });
5225
5342
  };
5226
5343
 
5227
5344
  const TextLink = (props) => {
@@ -5617,7 +5734,7 @@ const FilterMenu = (props) => {
5617
5734
  const { showCheckedAmount = false, alignPopover = "left", categorizedFilter, singleSelection = false } = props;
5618
5735
  const multiSelection = !singleSelection;
5619
5736
  const amountOfCheckedItems = categorizedFilter.options.filter((option) => option.isChecked).length;
5620
- return jsxRuntime.jsxs(react.Popover, { className: "ui:relative ui:inline-block ui:px-4 ui:text-left", children: [jsxRuntime.jsxs(react.PopoverButton, { className: "ui:group ui:inline-flex ui:justify-center ui:text-sm ui:font-medium ui:text-slate-700 ui:hover:text-slate-900", children: [jsxRuntime.jsx("span", { children: categorizedFilter.label }), amountOfCheckedItems > 0 && showCheckedAmount ? jsxRuntime.jsx("span", { className: "ui:ml-1.5 ui:rounded ui:bg-slate-200 ui:px-1.5 ui:py-0.5 ui:text-xs ui:font-semibold ui:tabular-nums ui:text-slate-700", children: amountOfCheckedItems }) : null, jsxRuntime.jsx(solid.ChevronDownIcon, { className: "ui:-mr-1 ui:ml-1 ui:h-5 ui:w-5 ui:shrink-0 ui:text-slate-400 ui:group-hover:text-slate-500", "aria-hidden": "true" })] }), jsxRuntime.jsx(react.Transition, { enter: "ui:transition ui:ease-out ui:duration-100", enterFrom: "ui:transform ui:opacity-0 ui:scale-95", enterTo: "ui:transform ui:opacity-100 ui:scale-100", leave: "ui:transition ui:ease-in ui:duration-75", leaveFrom: "ui:transform ui:opacity-100 ui:scale-100", leaveTo: "ui:transform ui:opacity-0 ui:scale-95", children: jsxRuntime.jsx(react.PopoverPanel, { className: classNames__default.default("ui:min-w-58", "ui:absolute ui:z-10 ui:mt-2", "ui:rounded-2xl ui:bg-white ui:shadow-2xl ui:ring-1 ui:ring-black ui:ring-opacity-5", "ui:focus:outline-none", "ui:border ui:border-neutral-border-high-contrast", {
5737
+ return jsxRuntime.jsxs(react$1.Popover, { className: "ui:relative ui:inline-block ui:px-4 ui:text-left", children: [jsxRuntime.jsxs(react$1.PopoverButton, { className: "ui:group ui:inline-flex ui:justify-center ui:text-sm ui:font-medium ui:text-slate-700 ui:hover:text-slate-900", children: [jsxRuntime.jsx("span", { children: categorizedFilter.label }), amountOfCheckedItems > 0 && showCheckedAmount ? jsxRuntime.jsx("span", { className: "ui:ml-1.5 ui:rounded ui:bg-slate-200 ui:px-1.5 ui:py-0.5 ui:text-xs ui:font-semibold ui:tabular-nums ui:text-slate-700", children: amountOfCheckedItems }) : null, jsxRuntime.jsx(solid.ChevronDownIcon, { className: "ui:-mr-1 ui:ml-1 ui:h-5 ui:w-5 ui:shrink-0 ui:text-slate-400 ui:group-hover:text-slate-500", "aria-hidden": "true" })] }), jsxRuntime.jsx(react$1.Transition, { enter: "ui:transition ui:ease-out ui:duration-100", enterFrom: "ui:transform ui:opacity-0 ui:scale-95", enterTo: "ui:transform ui:opacity-100 ui:scale-100", leave: "ui:transition ui:ease-in ui:duration-75", leaveFrom: "ui:transform ui:opacity-100 ui:scale-100", leaveTo: "ui:transform ui:opacity-0 ui:scale-95", children: jsxRuntime.jsx(react$1.PopoverPanel, { className: classNames__default.default("ui:min-w-58", "ui:absolute ui:z-10 ui:mt-2", "ui:rounded-2xl ui:bg-white ui:shadow-2xl ui:ring-1 ui:ring-black ui:ring-opacity-5", "ui:focus:outline-none", "ui:border ui:border-neutral-border-high-contrast", {
5621
5738
  // Align popover to the left side of the button label
5622
5739
  "ui:left-4 ui:origin-top-left": alignPopover === "left",
5623
5740
  // Align popover to the right side of the chevron icon
@@ -5666,7 +5783,7 @@ const SortMenu = (props) => {
5666
5783
 
5667
5784
  const FiltersMenus = (props) => {
5668
5785
  const { filters, singleSelection } = props;
5669
- return jsxRuntime.jsx("div", { className: "ui:hidden ui:sm:block", children: jsxRuntime.jsx("div", { className: "ui:flow-root", children: jsxRuntime.jsx(react.PopoverGroup, { className: "ui:-mx-4 ui:flex ui:items-center ui:divide-x ui:divide-slate-200", children: filters.map((categorizedFilter) => jsxRuntime.jsx(FilterMenu, { alignPopover: "right", showCheckedAmount: true, categorizedFilter, onFilterOptionChange: props.onFilterOptionChange, singleSelection }, `filter-menu-${categorizedFilter.key}`)) }) }) });
5786
+ return jsxRuntime.jsx("div", { className: "ui:hidden ui:sm:block", children: jsxRuntime.jsx("div", { className: "ui:flow-root", children: jsxRuntime.jsx(react$1.PopoverGroup, { className: "ui:-mx-4 ui:flex ui:items-center ui:divide-x ui:divide-slate-200", children: filters.map((categorizedFilter) => jsxRuntime.jsx(FilterMenu, { alignPopover: "right", showCheckedAmount: true, categorizedFilter, onFilterOptionChange: props.onFilterOptionChange, singleSelection }, `filter-menu-${categorizedFilter.key}`)) }) }) });
5670
5787
  };
5671
5788
 
5672
5789
  const isPresetFilterOption = (option) => {