@pibit.ai/cure-design-system 0.6.48 → 0.6.49
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/_virtual/index.js +2 -3
- package/dist/_virtual/index2.js +3 -2
- package/dist/node_modules/recharts/es6/util/ReactUtils.js +1 -1
- package/dist/node_modules/use-sync-external-store/shim/index.js +1 -1
- package/dist/rich-text/index.d.ts +9 -0
- package/dist/rich-text/index.d.ts.map +1 -1
- package/dist/rich-text/index.js +37 -1
- package/dist/rich-text/platform.d.ts +9 -0
- package/dist/rich-text/platform.d.ts.map +1 -0
- package/dist/rich-text/platform.js +35 -0
- package/dist/rich-text/text-editor-button.d.ts +7 -0
- package/dist/rich-text/text-editor-button.d.ts.map +1 -0
- package/dist/rich-text/text-editor-button.js +33 -0
- package/dist/rich-text/text-editor-character-count.d.ts +50 -0
- package/dist/rich-text/text-editor-character-count.d.ts.map +1 -0
- package/dist/rich-text/text-editor-character-count.js +34 -0
- package/dist/rich-text/text-editor-extensions.d.ts +95 -0
- package/dist/rich-text/text-editor-extensions.d.ts.map +1 -0
- package/dist/rich-text/text-editor-extensions.js +553 -0
- package/dist/rich-text/text-editor-heading-refocus.d.ts +21 -0
- package/dist/rich-text/text-editor-heading-refocus.d.ts.map +1 -0
- package/dist/rich-text/text-editor-heading-refocus.js +24 -0
- package/dist/rich-text/text-editor-line-utils.d.ts +8 -0
- package/dist/rich-text/text-editor-line-utils.d.ts.map +1 -0
- package/dist/rich-text/text-editor-line-utils.js +29 -0
- package/dist/rich-text/text-editor-mention.d.ts +32 -0
- package/dist/rich-text/text-editor-mention.d.ts.map +1 -0
- package/dist/rich-text/text-editor-mention.js +92 -0
- package/dist/rich-text/text-editor-shortcuts.d.ts +9 -0
- package/dist/rich-text/text-editor-shortcuts.d.ts.map +1 -0
- package/dist/rich-text/text-editor-shortcuts.js +6 -0
- package/dist/rich-text/text-editor-toolbar.d.ts +15 -0
- package/dist/rich-text/text-editor-toolbar.d.ts.map +1 -0
- package/dist/rich-text/text-editor-toolbar.js +104 -0
- package/dist/rich-text/text-editor-tooltip.d.ts +5 -0
- package/dist/rich-text/text-editor-tooltip.d.ts.map +1 -0
- package/dist/rich-text/text-editor-tooltip.js +31 -0
- package/dist/rich-text/text-editor.d.ts +55 -0
- package/dist/rich-text/text-editor.d.ts.map +1 -0
- package/dist/rich-text/text-editor.js +324 -0
- package/dist/styles/components.css +1 -1
- package/package.json +12 -2
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { jsx as s, jsxs as u } from "react/jsx-runtime";
|
|
2
|
+
import { ReactRenderer as f } from "@tiptap/react";
|
|
3
|
+
import g from "tippy.js";
|
|
4
|
+
import { forwardRef as y, useState as x, useEffect as h, useImperativeHandle as w } from "react";
|
|
5
|
+
import { cx as b } from "../utils/cn.js";
|
|
6
|
+
import { Avatar as R } from "../primitives/avatar/avatar.js";
|
|
7
|
+
const l = y(
|
|
8
|
+
(r, n) => {
|
|
9
|
+
const [t, e] = x(0), a = (i) => {
|
|
10
|
+
const o = r.items[i];
|
|
11
|
+
o && r.command({ id: o.id, label: o.name });
|
|
12
|
+
}, c = () => {
|
|
13
|
+
e(
|
|
14
|
+
(t + r.items.length - 1) % r.items.length
|
|
15
|
+
);
|
|
16
|
+
}, d = () => {
|
|
17
|
+
e((t + 1) % r.items.length);
|
|
18
|
+
}, m = () => {
|
|
19
|
+
a(t);
|
|
20
|
+
};
|
|
21
|
+
return h(() => {
|
|
22
|
+
e(0);
|
|
23
|
+
}, [r.items]), w(n, () => ({
|
|
24
|
+
onKeyDown: ({ event: i }) => i.key === "ArrowUp" ? (c(), !0) : i.key === "ArrowDown" ? (d(), !0) : i.key === "Enter" ? (m(), !0) : !1
|
|
25
|
+
})), r.items.length === 0 ? /* @__PURE__ */ s("div", { className: "bg-white rounded-md shadow-lg ring-1 ring-secondary p-2", children: /* @__PURE__ */ s("div", { className: "text-sm text-gray-500 px-3 py-2", children: "No users found" }) }) : /* @__PURE__ */ s("div", { className: "bg-white rounded-md shadow-lg ring-1 ring-secondary py-1 max-h-64 overflow-y-auto", children: r.items.map((i, o) => /* @__PURE__ */ u(
|
|
26
|
+
"button",
|
|
27
|
+
{
|
|
28
|
+
onClick: () => a(o),
|
|
29
|
+
className: b(
|
|
30
|
+
"flex items-center gap-3 w-full px-3 py-2 text-left text-sm transition-colors",
|
|
31
|
+
o === t ? "bg-blue-50 text-gray-900" : "text-gray-700 hover:bg-gray-50"
|
|
32
|
+
),
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ s(
|
|
35
|
+
R,
|
|
36
|
+
{
|
|
37
|
+
size: "xs",
|
|
38
|
+
initials: (i.name ?? "?").charAt(0).toUpperCase(),
|
|
39
|
+
className: "bg-blue-100 text-[var(--color-brand-600)]"
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ s("span", { className: "font-medium", children: i.name })
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
i.id
|
|
46
|
+
)) });
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
l.displayName = "MentionList";
|
|
50
|
+
const D = (r) => ({
|
|
51
|
+
items: ({ query: n }) => {
|
|
52
|
+
const t = r(), e = (n ?? "").toLowerCase();
|
|
53
|
+
return t.filter((a) => (a.name ?? "").toLowerCase().includes(e));
|
|
54
|
+
},
|
|
55
|
+
render: () => {
|
|
56
|
+
let n, t;
|
|
57
|
+
return {
|
|
58
|
+
onStart: (e) => {
|
|
59
|
+
n = new f(l, {
|
|
60
|
+
props: e,
|
|
61
|
+
editor: e.editor
|
|
62
|
+
}), e.clientRect && (t = g("body", {
|
|
63
|
+
getReferenceClientRect: e.clientRect,
|
|
64
|
+
appendTo: () => document.body,
|
|
65
|
+
content: n.element,
|
|
66
|
+
showOnCreate: !0,
|
|
67
|
+
interactive: !0,
|
|
68
|
+
trigger: "manual",
|
|
69
|
+
placement: "bottom-start",
|
|
70
|
+
zIndex: 99999
|
|
71
|
+
}));
|
|
72
|
+
},
|
|
73
|
+
onUpdate(e) {
|
|
74
|
+
n.updateProps(e), !(!e.clientRect || !(t != null && t[0])) && t[0].setProps({
|
|
75
|
+
getReferenceClientRect: e.clientRect
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
onKeyDown(e) {
|
|
79
|
+
var a, c;
|
|
80
|
+
return e.event.key === "Escape" ? ((a = t == null ? void 0 : t[0]) == null || a.hide(), !0) : ((c = n.ref) == null ? void 0 : c.onKeyDown(e)) ?? !1;
|
|
81
|
+
},
|
|
82
|
+
onExit() {
|
|
83
|
+
var e;
|
|
84
|
+
(e = t == null ? void 0 : t[0]) == null || e.destroy(), n == null || n.destroy();
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
export {
|
|
90
|
+
l as MentionList,
|
|
91
|
+
D as createMentionSuggestion
|
|
92
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type ShortcutKeyEvent = Pick<KeyboardEvent, "metaKey" | "ctrlKey" | "altKey" | "shiftKey" | "code">;
|
|
2
|
+
/**
|
|
3
|
+
* Strikethrough: ⌘⇧X on Mac, Ctrl+Shift+X elsewhere (matches the toolbar tooltip label).
|
|
4
|
+
* On Windows `metaKey` is the Windows key, so it must not count. Uses `code` ("KeyX") so the
|
|
5
|
+
* chord is detected regardless of keyboard layout.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isStrikethroughShortcut(e: ShortcutKeyEvent, isMac: boolean): boolean;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=text-editor-shortcuts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-editor-shortcuts.d.ts","sourceRoot":"","sources":["../../src/rich-text/text-editor-shortcuts.ts"],"names":[],"mappings":"AAAA,KAAK,gBAAgB,GAAG,IAAI,CAC1B,aAAa,EACb,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CACvD,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,CAAC,EAAE,gBAAgB,EACnB,KAAK,EAAE,OAAO,GACb,OAAO,CAGT"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RefAttributes } from 'react';
|
|
2
|
+
type ToolbarItem = "bold" | "italic" | "underline" | "strikethrough" | "bulletList" | "orderedList" | "blockquote" | "heading" | "link" | "image" | "generate" | "alignLeft" | "alignCenter";
|
|
3
|
+
export interface RichTextEditorToolbarProps extends RefAttributes<HTMLDivElement> {
|
|
4
|
+
className?: string;
|
|
5
|
+
type?: "simple" | "advanced";
|
|
6
|
+
floating?: boolean;
|
|
7
|
+
hideFontSize?: boolean;
|
|
8
|
+
hideFontFamily?: boolean;
|
|
9
|
+
hideGenerate?: boolean;
|
|
10
|
+
hideImage?: boolean;
|
|
11
|
+
toolbarList?: ToolbarItem[];
|
|
12
|
+
}
|
|
13
|
+
export declare const RichTextEditorToolbar: ({ className, ref, type, floating, hideFontSize, hideFontFamily, hideGenerate, hideImage, toolbarList, }: RichTextEditorToolbarProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=text-editor-toolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-editor-toolbar.d.ts","sourceRoot":"","sources":["../../src/rich-text/text-editor-toolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AA+BhE,KAAK,WAAW,GACZ,MAAM,GACN,QAAQ,GACR,WAAW,GACX,eAAe,GACf,YAAY,GACZ,aAAa,GACb,YAAY,GACZ,SAAS,GACT,MAAM,GACN,OAAO,GACP,UAAU,GACV,WAAW,GACX,aAAa,CAAC;AAElB,MAAM,WAAW,0BAA2B,SAAQ,aAAa,CAAC,cAAc,CAAC;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED,eAAO,MAAM,qBAAqB,GAAI,yGAqBnC,0BAA0B,4CA+I5B,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsxs as d, jsx as e, Fragment as R } from "react/jsx-runtime";
|
|
2
|
+
import { cx as c } from "../utils/cn.js";
|
|
3
|
+
import { getPlatformShortcutLabel as t } from "./platform.js";
|
|
4
|
+
import { RichTextEditorHeading as N, RichTextEditorBold as a, RichTextEditorItalic as o, RichTextEditorUnderline as h, RichTextEditorStrikethrough as v, RichTextEditorAlignLeft as s, RichTextEditorAlignCenter as m, RichTextEditorBulletList as u, RichTextEditorOrderedList as w, RichTextEditorBlockquote as y, RichTextEditorFontFamily as b, RichTextEditorFontSize as k, RichTextEditorColor as B, RichTextEditorLink as $, RichTextEditorImage as C, RichTextEditorGenerate as I } from "./text-editor-extensions.js";
|
|
5
|
+
import { Tooltip as U } from "../primitives/tooltip/tooltip.js";
|
|
6
|
+
const i = (r) => /* @__PURE__ */ e(
|
|
7
|
+
U,
|
|
8
|
+
{
|
|
9
|
+
...r,
|
|
10
|
+
contentClassName: `text-editor-tooltip ${r.contentClassName ?? ""}`.trim()
|
|
11
|
+
}
|
|
12
|
+
), A = ({
|
|
13
|
+
className: r,
|
|
14
|
+
ref: x,
|
|
15
|
+
type: g = "simple",
|
|
16
|
+
floating: n = !1,
|
|
17
|
+
hideFontSize: p,
|
|
18
|
+
hideFontFamily: f,
|
|
19
|
+
hideGenerate: T,
|
|
20
|
+
hideImage: E,
|
|
21
|
+
toolbarList: l = [
|
|
22
|
+
"bold",
|
|
23
|
+
"italic",
|
|
24
|
+
"underline",
|
|
25
|
+
"strikethrough",
|
|
26
|
+
"bulletList",
|
|
27
|
+
"link",
|
|
28
|
+
"image",
|
|
29
|
+
"generate",
|
|
30
|
+
"alignLeft",
|
|
31
|
+
"alignCenter"
|
|
32
|
+
]
|
|
33
|
+
}) => g === "simple" ? /* @__PURE__ */ d(
|
|
34
|
+
"div",
|
|
35
|
+
{
|
|
36
|
+
className: c(
|
|
37
|
+
"flex w-max flex-wrap md:flex-nowrap",
|
|
38
|
+
n && "rounded-lg bg-primary p-1 shadow-lg ring-1 ring-secondary_alt",
|
|
39
|
+
r
|
|
40
|
+
),
|
|
41
|
+
children: [
|
|
42
|
+
l.includes("heading") && /* @__PURE__ */ e(N, {}),
|
|
43
|
+
l.includes("bold") && /* @__PURE__ */ e(i, { title: `Bold ${t(["meta"], "B")}`, children: /* @__PURE__ */ e(a, {}) }),
|
|
44
|
+
l.includes("italic") && /* @__PURE__ */ e(i, { title: `Italic ${t(["meta"], "I")}`, children: /* @__PURE__ */ e(o, {}) }),
|
|
45
|
+
l.includes("underline") && /* @__PURE__ */ e(
|
|
46
|
+
i,
|
|
47
|
+
{
|
|
48
|
+
title: `Underline ${t(["meta"], "U")}`,
|
|
49
|
+
children: /* @__PURE__ */ e(h, {})
|
|
50
|
+
}
|
|
51
|
+
),
|
|
52
|
+
l.includes("strikethrough") && /* @__PURE__ */ e(
|
|
53
|
+
i,
|
|
54
|
+
{
|
|
55
|
+
title: `Strikethrough ${t(["meta", "shift"], "X")}`,
|
|
56
|
+
children: /* @__PURE__ */ e(v, {})
|
|
57
|
+
}
|
|
58
|
+
),
|
|
59
|
+
/* @__PURE__ */ e("div", { className: "p-1", children: /* @__PURE__ */ e("div", { className: "h-full w-px rounded-full bg-border-primary" }) }),
|
|
60
|
+
l.includes("alignLeft") && /* @__PURE__ */ e(i, { title: "Left align", children: /* @__PURE__ */ e(s, {}) }),
|
|
61
|
+
l.includes("alignCenter") && /* @__PURE__ */ e(i, { title: "Center align", children: /* @__PURE__ */ e(m, {}) }),
|
|
62
|
+
l.includes("bulletList") && /* @__PURE__ */ e(i, { title: "Bullet list", children: /* @__PURE__ */ e(u, {}) }),
|
|
63
|
+
l.includes("orderedList") && /* @__PURE__ */ e(i, { title: "Numbered list", children: /* @__PURE__ */ e(w, {}) }),
|
|
64
|
+
l.includes("blockquote") && /* @__PURE__ */ e(i, { title: "Block quote", children: /* @__PURE__ */ e(y, {}) })
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
) : /* @__PURE__ */ d(
|
|
68
|
+
"div",
|
|
69
|
+
{
|
|
70
|
+
ref: x,
|
|
71
|
+
className: c(
|
|
72
|
+
"flex w-max flex-col items-start justify-center gap-2 md:flex-row md:items-center md:justify-start md:gap-3",
|
|
73
|
+
n && "rounded-xl bg-primary p-2 shadow-lg ring-1 ring-secondary_alt",
|
|
74
|
+
r
|
|
75
|
+
),
|
|
76
|
+
children: [
|
|
77
|
+
!n && /* @__PURE__ */ d("div", { className: "flex gap-2", children: [
|
|
78
|
+
!f && /* @__PURE__ */ e(b, {}),
|
|
79
|
+
!p && /* @__PURE__ */ e(k, {})
|
|
80
|
+
] }),
|
|
81
|
+
/* @__PURE__ */ d("div", { className: "flex flex-wrap gap-0.5 md:flex-nowrap", children: [
|
|
82
|
+
/* @__PURE__ */ e(i, { title: `Bold ${t(["meta"], "B")}`, children: /* @__PURE__ */ e(a, {}) }),
|
|
83
|
+
/* @__PURE__ */ e(i, { title: `Italic ${t(["meta"], "I")}`, children: /* @__PURE__ */ e(o, {}) }),
|
|
84
|
+
/* @__PURE__ */ e(i, { title: `Underline ${t(["meta"], "U")}`, children: /* @__PURE__ */ e(h, {}) }),
|
|
85
|
+
/* @__PURE__ */ e("div", { className: "p-1.5", children: /* @__PURE__ */ e("div", { className: "h-full w-px rounded-full bg-border-primary" }) }),
|
|
86
|
+
/* @__PURE__ */ e(B, {}),
|
|
87
|
+
/* @__PURE__ */ e("div", { className: "p-1.5", children: /* @__PURE__ */ e("div", { className: "h-full w-px rounded-full bg-border-primary" }) }),
|
|
88
|
+
/* @__PURE__ */ e(i, { title: "Left align", children: /* @__PURE__ */ e(s, {}) }),
|
|
89
|
+
/* @__PURE__ */ e(i, { title: "Center align", children: /* @__PURE__ */ e(m, {}) }),
|
|
90
|
+
/* @__PURE__ */ e(i, { title: "Bullet list", children: /* @__PURE__ */ e(u, {}) }),
|
|
91
|
+
/* @__PURE__ */ e("div", { className: "p-1.5", children: /* @__PURE__ */ e("div", { className: "h-full w-px rounded-full bg-border-primary" }) }),
|
|
92
|
+
/* @__PURE__ */ e(i, { title: `Link ${t(["meta"], "K")}`, children: /* @__PURE__ */ e($, {}) }),
|
|
93
|
+
!E && /* @__PURE__ */ d(R, { children: [
|
|
94
|
+
/* @__PURE__ */ e(i, { title: "Insert image", children: /* @__PURE__ */ e(C, {}) }),
|
|
95
|
+
/* @__PURE__ */ e("div", { className: "p-1.5", children: /* @__PURE__ */ e("div", { className: "h-full w-px rounded-full bg-border-primary" }) })
|
|
96
|
+
] }),
|
|
97
|
+
!T && /* @__PURE__ */ e(i, { title: "Generate", children: /* @__PURE__ */ e(I, {}) })
|
|
98
|
+
] })
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
export {
|
|
103
|
+
A as RichTextEditorToolbar
|
|
104
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-editor-tooltip.d.ts","sourceRoot":"","sources":["../../src/rich-text/text-editor-tooltip.tsx"],"names":[],"mappings":"AAYA,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,qBAAqB,GAAI,gBAEnC,0BAA0B,4CAmB5B,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsxs as r, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import { BubbleMenu as e } from "@tiptap/react/menus";
|
|
3
|
+
import { cx as n } from "../utils/cn.js";
|
|
4
|
+
import { useRichTextEditorContext as d } from "./text-editor.js";
|
|
5
|
+
import { RichTextEditorBold as m, RichTextEditorItalic as x, RichTextEditorUnderline as c, RichTextEditorAlignLeft as l, RichTextEditorAlignCenter as a, RichTextEditorLink as p } from "./text-editor-extensions.js";
|
|
6
|
+
const E = ({
|
|
7
|
+
className: o
|
|
8
|
+
}) => {
|
|
9
|
+
const { editor: t } = d();
|
|
10
|
+
return /* @__PURE__ */ r(
|
|
11
|
+
e,
|
|
12
|
+
{
|
|
13
|
+
editor: t,
|
|
14
|
+
className: n(
|
|
15
|
+
"dark-mode z-10 flex origin-bottom flex-wrap gap-0.5 rounded-xl bg-primary p-1.5 shadow-lg ring-1 ring-secondary duration-100 animate-in fade-in ring-inset slide-in-from-bottom-0.5 zoom-in-95 md:flex-nowrap",
|
|
16
|
+
o
|
|
17
|
+
),
|
|
18
|
+
children: [
|
|
19
|
+
/* @__PURE__ */ i(m, {}),
|
|
20
|
+
/* @__PURE__ */ i(x, {}),
|
|
21
|
+
/* @__PURE__ */ i(c, {}),
|
|
22
|
+
/* @__PURE__ */ i(l, {}),
|
|
23
|
+
/* @__PURE__ */ i(a, {}),
|
|
24
|
+
/* @__PURE__ */ i(p, {})
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
export {
|
|
30
|
+
E as RichTextEditorTooltip
|
|
31
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ComponentProps, HTMLAttributes, MutableRefObject, ReactNode, Ref } from 'react';
|
|
2
|
+
import { AnyExtension, Editor, EditorContentProps, EditorOptions } from '@tiptap/react';
|
|
3
|
+
import { MentionUser } from './text-editor-mention';
|
|
4
|
+
import { Label } from '../primitives/input';
|
|
5
|
+
type EditorContextType = {
|
|
6
|
+
editor: Editor;
|
|
7
|
+
editorId: string;
|
|
8
|
+
isDisabled?: boolean;
|
|
9
|
+
limit?: number;
|
|
10
|
+
isInvalid?: boolean;
|
|
11
|
+
/** When "paragraph", each line is a block so list toggles affect the current line only. */
|
|
12
|
+
lineBreakMode?: "paragraph" | "hardBreak";
|
|
13
|
+
};
|
|
14
|
+
export declare const useRichTextEditorContext: () => EditorContextType;
|
|
15
|
+
export interface RichTextEditorRootProps extends Partial<EditorOptions> {
|
|
16
|
+
className?: string;
|
|
17
|
+
isDisabled?: boolean;
|
|
18
|
+
limit?: number;
|
|
19
|
+
placeholder?: string;
|
|
20
|
+
isInvalid?: boolean;
|
|
21
|
+
children?: ReactNode;
|
|
22
|
+
inputClassName?: string;
|
|
23
|
+
ref?: Ref<HTMLDivElement>;
|
|
24
|
+
mentionUsers?: MentionUser[];
|
|
25
|
+
onMentionSelect?: (users: MentionUser[]) => void;
|
|
26
|
+
/** When set, Shift+Enter in the editor calls `onSendRef` if `canSendRef.current` is true. */
|
|
27
|
+
shiftEnterToSend?: {
|
|
28
|
+
canSendRef: MutableRefObject<boolean>;
|
|
29
|
+
onSendRef: MutableRefObject<() => void>;
|
|
30
|
+
};
|
|
31
|
+
/** When set, Enter submits and Shift+Enter creates a new paragraph/list item (TipTap splitBlock / splitListItem). */
|
|
32
|
+
enterToSubmit?: {
|
|
33
|
+
canSendRef: MutableRefObject<boolean>;
|
|
34
|
+
onSendRef: MutableRefObject<() => void>;
|
|
35
|
+
};
|
|
36
|
+
/** Extra TipTap extensions appended after the defaults (keep the array stable, e.g. via useMemo). */
|
|
37
|
+
extraExtensions?: AnyExtension[];
|
|
38
|
+
}
|
|
39
|
+
export interface RichTextEditorContentProps extends Omit<EditorContentProps, "editor"> {
|
|
40
|
+
ref?: Ref<HTMLDivElement>;
|
|
41
|
+
}
|
|
42
|
+
export interface RichTextEditorLabelProps extends ComponentProps<typeof Label> {
|
|
43
|
+
}
|
|
44
|
+
export interface RichTextEditorHintTextProps extends HTMLAttributes<HTMLElement> {
|
|
45
|
+
}
|
|
46
|
+
export declare const RichTextEditor: {
|
|
47
|
+
Root: ({ className, inputClassName, children, isInvalid, isDisabled, limit, placeholder, mentionUsers, onMentionSelect, shiftEnterToSend, enterToSubmit, extraExtensions, ...editorOptions }: RichTextEditorRootProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
48
|
+
Toolbar: ({ className, ref, type, floating, hideFontSize, hideFontFamily, hideGenerate, hideImage, toolbarList, }: import('./text-editor-toolbar').RichTextEditorToolbarProps) => import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
Tooltip: ({ className, }: import('./text-editor-tooltip').RichTextEditorTooltipProps) => import("react/jsx-runtime").JSX.Element;
|
|
50
|
+
Content: ({ ...props }: RichTextEditorContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
Label: ({ children, ...props }: RichTextEditorLabelProps) => import("react/jsx-runtime").JSX.Element;
|
|
52
|
+
HintText: ({ children, ...props }: RichTextEditorHintTextProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
53
|
+
};
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=text-editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-editor.d.ts","sourceRoot":"","sources":["../../src/rich-text/text-editor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,GAAG,EACJ,MAAM,OAAO,CAAC;AAef,OAAO,KAAK,EACV,YAAY,EACZ,MAAM,EACN,kBAAkB,EAClB,aAAa,EACd,MAAM,eAAe,CAAC;AASvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAY,KAAK,EAAE,MAAM,oBAAoB,CAAC;AASrD,KAAK,iBAAiB,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2FAA2F;IAC3F,aAAa,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;CAC3C,CAAC;AAIF,eAAO,MAAM,wBAAwB,yBAQpC,CAAC;AA8HF,MAAM,WAAW,uBAAwB,SAAQ,OAAO,CAAC,aAAa,CAAC;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1B,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;IACjD,6FAA6F;IAC7F,gBAAgB,CAAC,EAAE;QACjB,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACtC,SAAS,EAAE,gBAAgB,CAAC,MAAM,IAAI,CAAC,CAAC;KACzC,CAAC;IACF,qHAAqH;IACrH,aAAa,CAAC,EAAE;QACd,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACtC,SAAS,EAAE,gBAAgB,CAAC,MAAM,IAAI,CAAC,CAAC;KACzC,CAAC;IACF,qGAAqG;IACrG,eAAe,CAAC,EAAE,YAAY,EAAE,CAAC;CAClC;AA2QD,MAAM,WAAW,0BAA2B,SAAQ,IAAI,CACtD,kBAAkB,EAClB,QAAQ,CACT;IACC,GAAG,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;CAC3B;AAeD,MAAM,WAAW,wBAAyB,SAAQ,cAAc,CAAC,OAAO,KAAK,CAAC;CAAG;AAqBjF,MAAM,WAAW,2BAA4B,SAAQ,cAAc,CAAC,WAAW,CAAC;CAAG;AA6BnF,eAAO,MAAM,cAAc;kMAjUxB,uBAAuB;;;4BAkQmB,0BAA0B;oCAkBpE,wBAAwB;uCAqBxB,2BAA2B;CA+B7B,CAAC"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { jsx as u, jsxs as H } from "react/jsx-runtime";
|
|
2
|
+
import { useId as P, useRef as $, useMemo as E, useEffect as f, createContext as D, useContext as I } from "react";
|
|
3
|
+
import { Image as z } from "@tiptap/extension-image";
|
|
4
|
+
import { Placeholder as B } from "@tiptap/extension-placeholder";
|
|
5
|
+
import { Strike as j } from "@tiptap/extension-strike";
|
|
6
|
+
import { TextAlign as N } from "@tiptap/extension-text-align";
|
|
7
|
+
import { TextStyleKit as U } from "@tiptap/extension-text-style";
|
|
8
|
+
import O from "@tiptap/extension-mention";
|
|
9
|
+
import { EditorContent as _, useEditor as q } from "@tiptap/react";
|
|
10
|
+
import { StarterKit as F } from "@tiptap/starter-kit";
|
|
11
|
+
import { cx as x } from "../utils/cn.js";
|
|
12
|
+
import { isMacPlatform as W } from "./platform.js";
|
|
13
|
+
import { CharacterCount as G } from "./text-editor-character-count.js";
|
|
14
|
+
import { isStrikethroughShortcut as J } from "./text-editor-shortcuts.js";
|
|
15
|
+
import { RichTextEditorToolbar as Q } from "./text-editor-toolbar.js";
|
|
16
|
+
import { RichTextEditorTooltip as V } from "./text-editor-tooltip.js";
|
|
17
|
+
import { createMentionSuggestion as X } from "./text-editor-mention.js";
|
|
18
|
+
import { HintText as Y } from "../primitives/input/hint-text.js";
|
|
19
|
+
import { Label as Z } from "../primitives/input/label.js";
|
|
20
|
+
const T = (t) => `url(data:image/svg+xml;base64,${btoa(
|
|
21
|
+
`<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10 2L2 10" stroke="${t}" stroke-linecap="round"/><path d="M11 7L7 11" stroke="${t}" stroke-linecap="round"/></svg>`
|
|
22
|
+
)})`, R = D(null), L = () => {
|
|
23
|
+
const t = I(R);
|
|
24
|
+
if (!t)
|
|
25
|
+
throw new Error(
|
|
26
|
+
"useRichTextEditorContext must be used within a EditorProvider"
|
|
27
|
+
);
|
|
28
|
+
return t;
|
|
29
|
+
};
|
|
30
|
+
function tt(t) {
|
|
31
|
+
for (const n of t.state.plugins) {
|
|
32
|
+
const e = n.getState(t.state);
|
|
33
|
+
if (e && typeof e == "object" && "active" in e && e.active)
|
|
34
|
+
return !0;
|
|
35
|
+
}
|
|
36
|
+
return !1;
|
|
37
|
+
}
|
|
38
|
+
function et({
|
|
39
|
+
editor: t,
|
|
40
|
+
canSendRef: n,
|
|
41
|
+
onSendRef: e
|
|
42
|
+
}) {
|
|
43
|
+
return f(() => {
|
|
44
|
+
if (!t || t.isDestroyed) return;
|
|
45
|
+
const a = t.view.dom, s = (r) => {
|
|
46
|
+
if (r.key === "Enter" && !(r.metaKey || r.ctrlKey || r.altKey)) {
|
|
47
|
+
if (r.shiftKey) {
|
|
48
|
+
r.preventDefault(), r.stopPropagation(), t.isActive("bulletList") || t.isActive("orderedList") ? t.chain().focus().splitListItem("listItem").run() : t.chain().focus().splitBlock().run();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
n.current && (tt(t) || (r.preventDefault(), r.stopPropagation(), e.current()));
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
return a.addEventListener("keydown", s, !0), () => a.removeEventListener("keydown", s, !0);
|
|
55
|
+
}, [t, n, e]), null;
|
|
56
|
+
}
|
|
57
|
+
function rt({
|
|
58
|
+
editor: t,
|
|
59
|
+
canSendRef: n,
|
|
60
|
+
onSendRef: e
|
|
61
|
+
}) {
|
|
62
|
+
return f(() => {
|
|
63
|
+
if (!t || t.isDestroyed) return;
|
|
64
|
+
const a = t.view.dom, s = (r) => {
|
|
65
|
+
r.key !== "Enter" || !r.shiftKey || r.metaKey || r.ctrlKey || r.altKey || n.current && (r.preventDefault(), r.stopPropagation(), e.current());
|
|
66
|
+
};
|
|
67
|
+
return a.addEventListener("keydown", s, !0), () => a.removeEventListener("keydown", s, !0);
|
|
68
|
+
}, [t, n, e]), null;
|
|
69
|
+
}
|
|
70
|
+
function nt(t) {
|
|
71
|
+
t.chain().focus().toggleStrike().run();
|
|
72
|
+
}
|
|
73
|
+
const ot = W();
|
|
74
|
+
function it({ editor: t }) {
|
|
75
|
+
return f(() => {
|
|
76
|
+
if (!t || t.isDestroyed) return;
|
|
77
|
+
const n = t.view.dom, e = (a) => {
|
|
78
|
+
t.isEditable && J(a, ot) && (a.preventDefault(), a.stopPropagation(), nt(t));
|
|
79
|
+
};
|
|
80
|
+
return n.addEventListener("keydown", e, !0), () => n.removeEventListener("keydown", e, !0);
|
|
81
|
+
}, [t]), null;
|
|
82
|
+
}
|
|
83
|
+
const st = ({
|
|
84
|
+
className: t,
|
|
85
|
+
inputClassName: n,
|
|
86
|
+
children: e,
|
|
87
|
+
isInvalid: a,
|
|
88
|
+
isDisabled: s,
|
|
89
|
+
limit: r,
|
|
90
|
+
placeholder: l = "Write something...",
|
|
91
|
+
mentionUsers: b = [],
|
|
92
|
+
onMentionSelect: k,
|
|
93
|
+
shiftEnterToSend: c,
|
|
94
|
+
enterToSubmit: h,
|
|
95
|
+
extraExtensions: v,
|
|
96
|
+
...M
|
|
97
|
+
}) => {
|
|
98
|
+
const m = `editor-${P()}`, S = h ? "paragraph" : "hardBreak", w = $(b);
|
|
99
|
+
w.current = b;
|
|
100
|
+
const { content: d, ...A } = M, C = E(
|
|
101
|
+
() => ({
|
|
102
|
+
attributes: {
|
|
103
|
+
id: m,
|
|
104
|
+
"aria-labelledby": `${m}-label`,
|
|
105
|
+
"aria-describedby": `${m}-hint`,
|
|
106
|
+
style: `
|
|
107
|
+
--resize-handle-bg: ${T("#D5D7DA")};
|
|
108
|
+
--resize-handle-bg-dark: ${T("#373A41")};
|
|
109
|
+
`,
|
|
110
|
+
class: x(
|
|
111
|
+
"w-full resize scroll-py-3 overflow-auto rounded-lg bg-primary text-md leading-[1.5] text-primary caret-fg-brand-primary transition duration-100 ease-linear selection:bg-fg-brand-primary/10 placeholder:text-placeholder autofill:rounded-lg autofill:text-primary focus:ring-0 focus:ring-brand focus:outline-hidden",
|
|
112
|
+
"[&::-webkit-resizer]:bg-(image:--resize-handle-bg) [&::-webkit-resizer]:bg-contain dark:[&::-webkit-resizer]:bg-(image:--resize-handle-bg-dark)",
|
|
113
|
+
s && "cursor-not-allowed bg-disabled_subtle text-disabled",
|
|
114
|
+
n
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
}),
|
|
118
|
+
[m, s, n]
|
|
119
|
+
), K = E(
|
|
120
|
+
() => [
|
|
121
|
+
F.configure({
|
|
122
|
+
blockquote: {
|
|
123
|
+
HTMLAttributes: {
|
|
124
|
+
class: "my-3.5 border-l-4 border-secondary pl-4"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
bulletList: {
|
|
128
|
+
HTMLAttributes: {
|
|
129
|
+
class: "list-disc ml-7"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
orderedList: {
|
|
133
|
+
HTMLAttributes: {
|
|
134
|
+
class: "list-decimal ml-7"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
link: {
|
|
138
|
+
openOnClick: !1,
|
|
139
|
+
autolink: !0,
|
|
140
|
+
defaultProtocol: "https",
|
|
141
|
+
HTMLAttributes: {
|
|
142
|
+
class: "text-primary underline"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
// Strike shortcuts are handled on the editor DOM (see RichTextEditorStrikethroughShortcut).
|
|
146
|
+
strike: !1
|
|
147
|
+
}),
|
|
148
|
+
j.extend({
|
|
149
|
+
addKeyboardShortcuts() {
|
|
150
|
+
return {};
|
|
151
|
+
}
|
|
152
|
+
}),
|
|
153
|
+
U,
|
|
154
|
+
N.configure({
|
|
155
|
+
types: ["heading", "paragraph"]
|
|
156
|
+
}),
|
|
157
|
+
z.configure({
|
|
158
|
+
HTMLAttributes: {
|
|
159
|
+
class: "my-3"
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
B.configure({
|
|
163
|
+
placeholder: ({ node: i }) => i.type.name === "bulletList" || i.type.name === "orderedList" ? "" : l,
|
|
164
|
+
emptyEditorClass: "first:before:text-placeholder first:before:float-left first:before:content-[attr(data-placeholder)] first:before:pointer-events-none first:before:absolute"
|
|
165
|
+
}),
|
|
166
|
+
G,
|
|
167
|
+
O.configure({
|
|
168
|
+
HTMLAttributes: {
|
|
169
|
+
class: "mention text-[var(--color-brand-600)] font-semibold",
|
|
170
|
+
"data-mention-type": "user"
|
|
171
|
+
},
|
|
172
|
+
renderLabel({ node: i }) {
|
|
173
|
+
return `@${i.attrs.label ?? i.attrs.id}`;
|
|
174
|
+
},
|
|
175
|
+
suggestion: {
|
|
176
|
+
...X(() => w.current),
|
|
177
|
+
allowedPrefixes: [" ", `
|
|
178
|
+
`]
|
|
179
|
+
}
|
|
180
|
+
}).extend({
|
|
181
|
+
addAttributes() {
|
|
182
|
+
return {
|
|
183
|
+
id: {
|
|
184
|
+
default: null,
|
|
185
|
+
parseHTML: (i) => i.getAttribute("data-mention-id"),
|
|
186
|
+
renderHTML: (i) => i.id ? {
|
|
187
|
+
"data-mention-id": i.id
|
|
188
|
+
} : {}
|
|
189
|
+
},
|
|
190
|
+
label: {
|
|
191
|
+
default: null,
|
|
192
|
+
parseHTML: (i) => i.getAttribute("data-label"),
|
|
193
|
+
renderHTML: (i) => i.label ? {
|
|
194
|
+
"data-label": i.label
|
|
195
|
+
} : {}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}),
|
|
200
|
+
...v ?? []
|
|
201
|
+
],
|
|
202
|
+
[l, v]
|
|
203
|
+
), o = q(
|
|
204
|
+
{
|
|
205
|
+
...A,
|
|
206
|
+
content: "",
|
|
207
|
+
editable: !s,
|
|
208
|
+
immediatelyRender: !1,
|
|
209
|
+
extensions: K,
|
|
210
|
+
editorProps: C
|
|
211
|
+
},
|
|
212
|
+
[]
|
|
213
|
+
);
|
|
214
|
+
return f(() => {
|
|
215
|
+
if (!o || o.isDestroyed) return;
|
|
216
|
+
const i = o.getHTML();
|
|
217
|
+
if (typeof d == "string") {
|
|
218
|
+
const p = d || "";
|
|
219
|
+
i !== p && o.commands.setContent(p, { emitUpdate: !1 });
|
|
220
|
+
} else d != null && typeof d == "object" && o.commands.setContent(d, {
|
|
221
|
+
emitUpdate: !1
|
|
222
|
+
});
|
|
223
|
+
}, [o, d]), f(() => {
|
|
224
|
+
!o || o.isDestroyed || o.setEditable(!s);
|
|
225
|
+
}, [o, s]), f(() => {
|
|
226
|
+
const i = () => {
|
|
227
|
+
if (!o) return;
|
|
228
|
+
const g = o.getAttributes("link").href, y = window.prompt("Please enter a link", g);
|
|
229
|
+
if (y !== null) {
|
|
230
|
+
if (y === "") {
|
|
231
|
+
o.chain().focus().extendMarkRange("link").unsetLink().run();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
o.chain().focus().extendMarkRange("link").setLink({ href: y }).run();
|
|
235
|
+
}
|
|
236
|
+
}, p = (g) => {
|
|
237
|
+
(g.metaKey || g.ctrlKey) && g.key === "k" && i();
|
|
238
|
+
};
|
|
239
|
+
return document.addEventListener("keydown", p), () => {
|
|
240
|
+
document.removeEventListener("keydown", p);
|
|
241
|
+
};
|
|
242
|
+
}, [o]), o ? /* @__PURE__ */ H(
|
|
243
|
+
R.Provider,
|
|
244
|
+
{
|
|
245
|
+
value: { editor: o, isDisabled: s, limit: r, isInvalid: a, editorId: m, lineBreakMode: S },
|
|
246
|
+
children: [
|
|
247
|
+
h && /* @__PURE__ */ u(
|
|
248
|
+
et,
|
|
249
|
+
{
|
|
250
|
+
editor: o,
|
|
251
|
+
canSendRef: h.canSendRef,
|
|
252
|
+
onSendRef: h.onSendRef
|
|
253
|
+
}
|
|
254
|
+
),
|
|
255
|
+
c && /* @__PURE__ */ u(
|
|
256
|
+
rt,
|
|
257
|
+
{
|
|
258
|
+
editor: o,
|
|
259
|
+
canSendRef: c.canSendRef,
|
|
260
|
+
onSendRef: c.onSendRef
|
|
261
|
+
}
|
|
262
|
+
),
|
|
263
|
+
/* @__PURE__ */ u(it, { editor: o }),
|
|
264
|
+
/* @__PURE__ */ u("div", { className: x("flex w-full flex-col gap-3", t), children: e })
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
) : null;
|
|
268
|
+
}, at = ({ ...t }) => {
|
|
269
|
+
const { editor: n, isDisabled: e } = L();
|
|
270
|
+
return /* @__PURE__ */ u(
|
|
271
|
+
_,
|
|
272
|
+
{
|
|
273
|
+
disabled: e,
|
|
274
|
+
...t,
|
|
275
|
+
editor: n,
|
|
276
|
+
className: x("text-sm ring-0 outline-hidden", t.className)
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
}, lt = ({
|
|
280
|
+
children: t,
|
|
281
|
+
...n
|
|
282
|
+
}) => {
|
|
283
|
+
const { editor: e, editorId: a } = L();
|
|
284
|
+
return /* @__PURE__ */ u(
|
|
285
|
+
Z,
|
|
286
|
+
{
|
|
287
|
+
...n,
|
|
288
|
+
id: `${a}-label`,
|
|
289
|
+
onClick: () => {
|
|
290
|
+
e.chain().focus().run();
|
|
291
|
+
},
|
|
292
|
+
children: t
|
|
293
|
+
}
|
|
294
|
+
);
|
|
295
|
+
}, ut = ({
|
|
296
|
+
children: t,
|
|
297
|
+
...n
|
|
298
|
+
}) => {
|
|
299
|
+
var k, c;
|
|
300
|
+
const { editor: e, editorId: a, limit: s, isInvalid: r } = L();
|
|
301
|
+
if (!t && !s) return null;
|
|
302
|
+
const l = typeof s == "number" ? s - ((c = (k = e.storage) == null ? void 0 : k.characterCount) == null ? void 0 : c.characters()) : 0, b = l < 0;
|
|
303
|
+
return /* @__PURE__ */ u(
|
|
304
|
+
Y,
|
|
305
|
+
{
|
|
306
|
+
...n,
|
|
307
|
+
id: `${a}-hint`,
|
|
308
|
+
isInvalid: r || b,
|
|
309
|
+
className: x(s && "tabular-nums", n.className),
|
|
310
|
+
children: t || `${l.toLocaleString()} character${l === 1 ? "" : "s"} left`
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
}, Ct = {
|
|
314
|
+
Root: st,
|
|
315
|
+
Toolbar: Q,
|
|
316
|
+
Tooltip: V,
|
|
317
|
+
Content: at,
|
|
318
|
+
Label: lt,
|
|
319
|
+
HintText: ut
|
|
320
|
+
};
|
|
321
|
+
export {
|
|
322
|
+
Ct as RichTextEditor,
|
|
323
|
+
L as useRichTextEditorContext
|
|
324
|
+
};
|