@luscii-healthtech/web-ui 46.2.2 → 46.2.3
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.
- package/dist/index.development.js +160 -23
- package/dist/index.development.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/components/TextEditor/LinkTooltip.d.ts +9 -0
- package/dist/src/components/TextEditor/TextEditor.d.ts +1 -6
- package/dist/src/components/TextEditor/TextEditorToolbar.d.ts +13 -0
- package/dist/src/components/TextEditor/TextEditorToolbarButton.d.ts +8 -0
- package/dist/src/generated/components/TextEditor/LinkTooltip.d.ts +9 -0
- package/dist/src/generated/components/TextEditor/TextEditor.d.ts +1 -6
- package/dist/src/generated/components/TextEditor/TextEditorToolbar.d.ts +13 -0
- package/dist/src/generated/components/TextEditor/TextEditorToolbarButton.d.ts +8 -0
- package/dist/stories/TextEditor.stories.d.ts +1 -5
- package/dist/web-ui-tailwind.css +23 -0
- package/dist/web-ui.esm.js +1 -1
- package/dist/web-ui.esm.js.map +1 -1
- package/package.json +1 -1
|
@@ -32,11 +32,10 @@ var ReactSelect = require('react-select');
|
|
|
32
32
|
var RadixSwitch = require('@radix-ui/react-switch');
|
|
33
33
|
var Quill = require('quill');
|
|
34
34
|
require('quill-paste-smart');
|
|
35
|
-
require('
|
|
35
|
+
var solid = require('@heroicons/react/20/solid');
|
|
36
36
|
var isFunction = require('lodash/isFunction');
|
|
37
37
|
var isObjectLike = require('lodash/isObjectLike');
|
|
38
38
|
var react = require('@headlessui/react');
|
|
39
|
-
var solid = require('@heroicons/react/20/solid');
|
|
40
39
|
var ToggleGroup = require('@radix-ui/react-toggle-group');
|
|
41
40
|
|
|
42
41
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -5231,7 +5230,119 @@ const Textarea = React__namespace.default.forwardRef((_a, ref) => {
|
|
|
5231
5230
|
]), style, ref }));
|
|
5232
5231
|
});
|
|
5233
5232
|
|
|
5234
|
-
|
|
5233
|
+
const LinkTooltip = ({ linkElement, quillInstance, onClose }) => {
|
|
5234
|
+
const dialogRef = React.useRef(null);
|
|
5235
|
+
const anchorName = React.useRef(`link-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`);
|
|
5236
|
+
React.useEffect(() => {
|
|
5237
|
+
var _a;
|
|
5238
|
+
linkElement.style.setProperty("anchor-name", `--${anchorName.current}`);
|
|
5239
|
+
(_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.show();
|
|
5240
|
+
return () => {
|
|
5241
|
+
linkElement.style.removeProperty("anchor-name");
|
|
5242
|
+
};
|
|
5243
|
+
}, [linkElement]);
|
|
5244
|
+
React.useEffect(() => {
|
|
5245
|
+
const handleClickOutside = (event) => {
|
|
5246
|
+
var _a, _b;
|
|
5247
|
+
const target = event.target;
|
|
5248
|
+
if (linkElement.contains(target) || ((_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.contains(target))) {
|
|
5249
|
+
return;
|
|
5250
|
+
}
|
|
5251
|
+
(_b = dialogRef.current) === null || _b === void 0 ? void 0 : _b.close();
|
|
5252
|
+
onClose();
|
|
5253
|
+
};
|
|
5254
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
5255
|
+
return () => {
|
|
5256
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
5257
|
+
};
|
|
5258
|
+
}, [linkElement, onClose]);
|
|
5259
|
+
const handleEditLink = () => {
|
|
5260
|
+
const currentUrl = linkElement.getAttribute("href") || "";
|
|
5261
|
+
const newUrl = prompt("Link URL:", currentUrl);
|
|
5262
|
+
if (newUrl !== null) {
|
|
5263
|
+
const blot = quillInstance.scroll.find(linkElement);
|
|
5264
|
+
if (blot) {
|
|
5265
|
+
const index = quillInstance.getIndex(blot);
|
|
5266
|
+
const length = blot.length();
|
|
5267
|
+
quillInstance.setSelection(index, length);
|
|
5268
|
+
quillInstance.format("link", newUrl || false);
|
|
5269
|
+
}
|
|
5270
|
+
}
|
|
5271
|
+
onClose();
|
|
5272
|
+
};
|
|
5273
|
+
const handleRemoveLink = () => {
|
|
5274
|
+
const blot = quillInstance.scroll.find(linkElement);
|
|
5275
|
+
if (blot) {
|
|
5276
|
+
const index = quillInstance.getIndex(blot);
|
|
5277
|
+
const length = blot.length();
|
|
5278
|
+
quillInstance.setSelection(index, length);
|
|
5279
|
+
quillInstance.format("link", false);
|
|
5280
|
+
}
|
|
5281
|
+
onClose();
|
|
5282
|
+
};
|
|
5283
|
+
const url = linkElement.getAttribute("href") || "";
|
|
5284
|
+
return jsxRuntime.jsx("dialog", { ref: dialogRef, className: "ui:m-0 ui:p-0 ui:border-0 ui:bg-transparent", style: {
|
|
5285
|
+
position: "absolute",
|
|
5286
|
+
// @ts-expect-error - CSS anchor positioning is not yet in TypeScript types
|
|
5287
|
+
positionAnchor: `--${anchorName.current}`,
|
|
5288
|
+
top: "anchor(bottom)",
|
|
5289
|
+
left: "anchor(left)",
|
|
5290
|
+
marginTop: "8px"
|
|
5291
|
+
}, 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" })] })] }) }) });
|
|
5292
|
+
};
|
|
5293
|
+
|
|
5294
|
+
const TextEditorToolbarButton = ({ option, hasTextSelected }) => {
|
|
5295
|
+
const buttonClasses = "ui:aria-pressed:bg-primary-background ui:aria-disabled:cursor-not-allowed";
|
|
5296
|
+
if (typeof option === "string") {
|
|
5297
|
+
switch (option) {
|
|
5298
|
+
case "bold":
|
|
5299
|
+
return jsxRuntime.jsx(TertiaryIconButton, { label: "bold", className: `ql-bold ${buttonClasses}`, children: jsxRuntime.jsx(solid.BoldIcon, { width: 16 }) });
|
|
5300
|
+
case "italic":
|
|
5301
|
+
return jsxRuntime.jsx(TertiaryIconButton, { label: "italic", className: `ql-italic ${buttonClasses}`, children: jsxRuntime.jsx(solid.ItalicIcon, { width: 16 }) });
|
|
5302
|
+
case "underline":
|
|
5303
|
+
return jsxRuntime.jsx(TertiaryIconButton, { label: "underline", className: `ql-underline ${buttonClasses}`, children: jsxRuntime.jsx(solid.UnderlineIcon, { width: 16 }) });
|
|
5304
|
+
case "strike":
|
|
5305
|
+
return jsxRuntime.jsx(TertiaryIconButton, { label: "strike", className: `ql-strike ${buttonClasses}`, children: jsxRuntime.jsx(solid.StrikethroughIcon, { width: 16 }) });
|
|
5306
|
+
case "link":
|
|
5307
|
+
return jsxRuntime.jsx(TertiaryIconButton, { label: "link", className: `ql-link ${buttonClasses}`, disabled: !hasTextSelected, children: jsxRuntime.jsx(solid.LinkIcon, { width: 16 }) });
|
|
5308
|
+
case "video":
|
|
5309
|
+
return jsxRuntime.jsx(TertiaryIconButton, { label: "video", className: `ql-video ${buttonClasses}`, children: jsxRuntime.jsx(solid.VideoCameraIcon, { width: 16 }) });
|
|
5310
|
+
default:
|
|
5311
|
+
return null;
|
|
5312
|
+
}
|
|
5313
|
+
} else if (typeof option === "object" && "list" in option) {
|
|
5314
|
+
if (option.list === "ordered") {
|
|
5315
|
+
return jsxRuntime.jsx(TertiaryIconButton, { label: "ordered list", className: `ql-list ${buttonClasses}`, value: "ordered", children: jsxRuntime.jsx(solid.NumberedListIcon, { width: 16 }) });
|
|
5316
|
+
} else if (option.list === "bullet") {
|
|
5317
|
+
return jsxRuntime.jsx(TertiaryIconButton, { label: "bullet list", className: `ql-list ${buttonClasses}`, value: "bullet", children: jsxRuntime.jsx(solid.ListBulletIcon, { width: 16 }) });
|
|
5318
|
+
}
|
|
5319
|
+
}
|
|
5320
|
+
return null;
|
|
5321
|
+
};
|
|
5322
|
+
|
|
5323
|
+
const getOptionKey = (option, index) => {
|
|
5324
|
+
if (typeof option === "string") {
|
|
5325
|
+
return option;
|
|
5326
|
+
} else if (typeof option === "object" && "list" in option) {
|
|
5327
|
+
return `list-${option.list}`;
|
|
5328
|
+
}
|
|
5329
|
+
return `option-${index}`;
|
|
5330
|
+
};
|
|
5331
|
+
const getGroupKey = (group) => {
|
|
5332
|
+
return group.map((option) => {
|
|
5333
|
+
if (typeof option === "string") {
|
|
5334
|
+
return option;
|
|
5335
|
+
} else if (typeof option === "object" && "list" in option) {
|
|
5336
|
+
return `list-${option.list}`;
|
|
5337
|
+
}
|
|
5338
|
+
return "";
|
|
5339
|
+
}).join("-");
|
|
5340
|
+
};
|
|
5341
|
+
const TextEditorToolbar = ({ toolbarId, toolbar, hasTextSelected }) => {
|
|
5342
|
+
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))) });
|
|
5343
|
+
};
|
|
5344
|
+
|
|
5345
|
+
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}";
|
|
5235
5346
|
styleInject(css_248z$1);
|
|
5236
5347
|
|
|
5237
5348
|
const TextEditor = (_a) => {
|
|
@@ -5240,36 +5351,62 @@ const TextEditor = (_a) => {
|
|
|
5240
5351
|
[{ list: "ordered" }, { list: "bullet" }],
|
|
5241
5352
|
["link"]
|
|
5242
5353
|
], placeholder, onValueChange } = _a, attrs = __rest(_a, ["defaultValue", "formats", "toolbar", "placeholder", "onValueChange"]);
|
|
5354
|
+
const rawId = React.useId();
|
|
5355
|
+
const toolbarId = `toolbar-${rawId.replace(/:/g, "")}`;
|
|
5243
5356
|
const defaultValueRef = React.useRef(defaultValue);
|
|
5244
5357
|
const onTextChangeRef = React.useRef(onValueChange);
|
|
5245
5358
|
const editorRef = React.useRef(null);
|
|
5246
5359
|
const quillRef = React.useRef(null);
|
|
5360
|
+
const [linkTooltip, setLinkTooltip] = React.useState(null);
|
|
5361
|
+
const [hasTextSelected, setHasTextSelected] = React.useState(false);
|
|
5247
5362
|
React.useLayoutEffect(() => {
|
|
5248
5363
|
onTextChangeRef.current = onValueChange;
|
|
5249
5364
|
});
|
|
5250
5365
|
React.useEffect(() => {
|
|
5251
|
-
if (editorRef.current) {
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
}
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5366
|
+
if (!editorRef.current || quillRef.current) {
|
|
5367
|
+
return void 0;
|
|
5368
|
+
}
|
|
5369
|
+
const editor = editorRef.current;
|
|
5370
|
+
const quill = new Quill__default.default(editor, {
|
|
5371
|
+
formats,
|
|
5372
|
+
modules: {
|
|
5373
|
+
toolbar: `#${toolbarId}`
|
|
5374
|
+
},
|
|
5375
|
+
placeholder
|
|
5376
|
+
});
|
|
5377
|
+
quill.on(Quill__default.default.events.TEXT_CHANGE, (value, _, source) => {
|
|
5378
|
+
var _a2;
|
|
5379
|
+
(_a2 = onTextChangeRef.current) === null || _a2 === void 0 ? void 0 : _a2.call(onTextChangeRef, quill.getSemanticHTML(), value, source);
|
|
5380
|
+
});
|
|
5381
|
+
const handleSelectionChange = () => {
|
|
5382
|
+
const selection = quill.getSelection();
|
|
5383
|
+
setHasTextSelected(selection ? selection.length > 0 : false);
|
|
5384
|
+
};
|
|
5385
|
+
quill.on(Quill__default.default.events.SELECTION_CHANGE, handleSelectionChange);
|
|
5386
|
+
if (defaultValueRef.current) {
|
|
5387
|
+
quill.setContents(quill.clipboard.convert({
|
|
5388
|
+
html: defaultValueRef.current
|
|
5389
|
+
}));
|
|
5270
5390
|
}
|
|
5391
|
+
quillRef.current = quill;
|
|
5392
|
+
const qlEditor = editor.querySelector(".ql-editor");
|
|
5393
|
+
if (qlEditor) {
|
|
5394
|
+
qlEditor.classList.add("ui:overflow-auto", "ui:resize-y", "ui:min-h-40");
|
|
5395
|
+
}
|
|
5396
|
+
const handleEditorClick = (e) => {
|
|
5397
|
+
const target = e.target;
|
|
5398
|
+
if (target.tagName === "A") {
|
|
5399
|
+
e.preventDefault();
|
|
5400
|
+
const anchor = target;
|
|
5401
|
+
setLinkTooltip(anchor);
|
|
5402
|
+
}
|
|
5403
|
+
};
|
|
5404
|
+
editor.addEventListener("click", handleEditorClick);
|
|
5405
|
+
return () => {
|
|
5406
|
+
editor.removeEventListener("click", handleEditorClick);
|
|
5407
|
+
};
|
|
5271
5408
|
}, []);
|
|
5272
|
-
return jsxRuntime.
|
|
5409
|
+
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) }) })] }));
|
|
5273
5410
|
};
|
|
5274
5411
|
|
|
5275
5412
|
const TextLink = (props) => {
|