@jbpark/ui-kit 7.0.0 → 7.1.0
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/components/atoms/index.d.mts +3 -1
- package/dist/components/atoms/rich-text-editor/content-classes.mjs +7 -0
- package/dist/components/atoms/rich-text-editor/content-classes.mjs.map +1 -0
- package/dist/components/atoms/rich-text-editor/index.d.mts +3 -0
- package/dist/components/atoms/rich-text-editor/rich-text-editor.d.mts +24 -0
- package/dist/components/atoms/rich-text-editor/rich-text-editor.d.mts.map +1 -0
- package/dist/components/atoms/rich-text-editor/rich-text-editor.mjs +55 -0
- package/dist/components/atoms/rich-text-editor/rich-text-editor.mjs.map +1 -0
- package/dist/components/atoms/rich-text-editor/toolbar-button.mjs +16 -0
- package/dist/components/atoms/rich-text-editor/toolbar-button.mjs.map +1 -0
- package/dist/components/atoms/rich-text-editor/toolbar-presets.mjs +209 -0
- package/dist/components/atoms/rich-text-editor/toolbar-presets.mjs.map +1 -0
- package/dist/components/atoms/rich-text-editor/toolbar.mjs +21 -0
- package/dist/components/atoms/rich-text-editor/toolbar.mjs.map +1 -0
- package/dist/components/atoms/rich-text-editor/types.d.mts +14 -0
- package/dist/components/atoms/rich-text-editor/types.d.mts.map +1 -0
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/style.css +219 -0
- package/package.json +6 -1
|
@@ -9,9 +9,11 @@ import Input from "./input/index.mjs";
|
|
|
9
9
|
import Popover from "./popover.mjs";
|
|
10
10
|
import Progress from "./progress.mjs";
|
|
11
11
|
import Radio from "./radio/index.mjs";
|
|
12
|
+
import RichTextEditor from "./rich-text-editor/rich-text-editor.mjs";
|
|
13
|
+
import "./rich-text-editor/index.mjs";
|
|
12
14
|
import Select from "./select.mjs";
|
|
13
15
|
import Skeleton from "./skeleton/index.mjs";
|
|
14
16
|
import Slider from "./slider/slider.mjs";
|
|
15
17
|
import Spin from "./spin.mjs";
|
|
16
18
|
import Switch from "./switch.mjs";
|
|
17
|
-
export { Button, Checkbox, ColorPicker, DatePicker, FloatButton, Input, Popover, Progress, Radio, Select, Skeleton, Slider, Spin, Switch, Tag, Typography };
|
|
19
|
+
export { Button, Checkbox, ColorPicker, DatePicker, FloatButton, Input, Popover, Progress, Radio, RichTextEditor, Select, Skeleton, Slider, Spin, Switch, Tag, Typography };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { cn } from "../../../utils.mjs";
|
|
2
|
+
//#region src/components/atoms/rich-text-editor/content-classes.ts
|
|
3
|
+
const RICH_TEXT_CONTENT_CLASSES = cn("[&_.tiptap]:outline-none", "[&_.tiptap>*:first-child]:mt-0", "[&_.tiptap_h1]:mt-6", "[&_.tiptap_h1]:mb-2", "[&_.tiptap_h1]:text-2xl", "[&_.tiptap_h1]:font-bold", "[&_.tiptap_h2]:mt-5", "[&_.tiptap_h2]:mb-2", "[&_.tiptap_h2]:text-xl", "[&_.tiptap_h2]:font-bold", "[&_.tiptap_h3]:mt-4", "[&_.tiptap_h3]:mb-2", "[&_.tiptap_h3]:text-lg", "[&_.tiptap_h3]:font-semibold", "[&_.tiptap_h4]:mt-3", "[&_.tiptap_h4]:mb-1", "[&_.tiptap_h4]:text-base", "[&_.tiptap_h4]:font-semibold", "[&_.tiptap_ul]:my-2", "[&_.tiptap_ul]:list-disc", "[&_.tiptap_ul]:pl-5", "[&_.tiptap_ol]:my-2", "[&_.tiptap_ol]:list-decimal", "[&_.tiptap_ol]:pl-5", "[&_.tiptap_li]:my-1", "[&_.tiptap_blockquote]:my-2", "[&_.tiptap_blockquote]:border-l-2", "[&_.tiptap_blockquote]:border-gray-300", "[&_.tiptap_blockquote]:pl-3", "[&_.tiptap_blockquote]:text-gray-600", "[&_.tiptap_blockquote]:italic", "[&_.tiptap_pre]:overflow-x-auto", "[&_.tiptap_pre]:my-2", "[&_.tiptap_pre]:rounded", "[&_.tiptap_pre]:bg-gray-900", "[&_.tiptap_pre]:p-3", "[&_.tiptap_pre]:font-mono", "[&_.tiptap_pre]:text-sm", "[&_.tiptap_pre]:text-gray-100", "[&_.tiptap_pre_code]:bg-transparent", "[&_.tiptap_pre_code]:p-0", "[&_.tiptap_pre_code]:text-inherit", "[&_.tiptap_code]:rounded", "[&_.tiptap_code]:bg-gray-100", "[&_.tiptap_code]:px-1", "[&_.tiptap_code]:py-0.5", "[&_.tiptap_code]:font-mono", "[&_.tiptap_code]:text-[0.85em]", "[&_.tiptap_hr]:my-4", "[&_.tiptap_hr]:border-gray-200", "[&_.tiptap_a]:text-blue-600", "[&_.tiptap_a]:underline", "[&_.tiptap_a]:underline-offset-2", "[&_.tiptap_p.is-editor-empty:first-child::before]:pointer-events-none", "[&_.tiptap_p.is-editor-empty:first-child::before]:float-left", "[&_.tiptap_p.is-editor-empty:first-child::before]:h-0", "[&_.tiptap_p.is-editor-empty:first-child::before]:text-gray-400", "[&_.tiptap_p.is-editor-empty:first-child::before]:content-[attr(data-placeholder)]");
|
|
4
|
+
//#endregion
|
|
5
|
+
export { RICH_TEXT_CONTENT_CLASSES };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=content-classes.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-classes.mjs","names":[],"sources":["../../../../src/components/atoms/rich-text-editor/content-classes.ts"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\n// The package ships no global Tailwind preflight (see src/globals.css), and a\n// host that runs its own preflight (most do) resets bare h1-h6/ul/ol/blockquote\n// to look like plain text. Since the toolbar can now produce all of these\n// nodes, they need their own scoped typography here or toggling them would be\n// visibly a no-op. Selectors are written out per Tailwind utility (not built\n// via string interpolation) because v4 only extracts class candidates that\n// appear as literal strings in source (see popover.tsx's arrow-class comment).\nexport const RICH_TEXT_CONTENT_CLASSES = cn(\n '[&_.tiptap]:outline-none',\n // Every block element (p/h1/ul/blockquote/...) carries its own UA top\n // margin — without this, the first one stacks on top of the box's own\n // py-2, doubling the padding visually.\n '[&_.tiptap>*:first-child]:mt-0',\n\n '[&_.tiptap_h1]:mt-6',\n '[&_.tiptap_h1]:mb-2',\n '[&_.tiptap_h1]:text-2xl',\n '[&_.tiptap_h1]:font-bold',\n '[&_.tiptap_h2]:mt-5',\n '[&_.tiptap_h2]:mb-2',\n '[&_.tiptap_h2]:text-xl',\n '[&_.tiptap_h2]:font-bold',\n '[&_.tiptap_h3]:mt-4',\n '[&_.tiptap_h3]:mb-2',\n '[&_.tiptap_h3]:text-lg',\n '[&_.tiptap_h3]:font-semibold',\n '[&_.tiptap_h4]:mt-3',\n '[&_.tiptap_h4]:mb-1',\n '[&_.tiptap_h4]:text-base',\n '[&_.tiptap_h4]:font-semibold',\n\n '[&_.tiptap_ul]:my-2',\n '[&_.tiptap_ul]:list-disc',\n '[&_.tiptap_ul]:pl-5',\n '[&_.tiptap_ol]:my-2',\n '[&_.tiptap_ol]:list-decimal',\n '[&_.tiptap_ol]:pl-5',\n '[&_.tiptap_li]:my-1',\n\n '[&_.tiptap_blockquote]:my-2',\n '[&_.tiptap_blockquote]:border-l-2',\n '[&_.tiptap_blockquote]:border-gray-300',\n '[&_.tiptap_blockquote]:pl-3',\n '[&_.tiptap_blockquote]:text-gray-600',\n '[&_.tiptap_blockquote]:italic',\n\n // A long unwrapped code line would otherwise blow out the box width.\n '[&_.tiptap_pre]:overflow-x-auto',\n '[&_.tiptap_pre]:my-2',\n '[&_.tiptap_pre]:rounded',\n '[&_.tiptap_pre]:bg-gray-900',\n '[&_.tiptap_pre]:p-3',\n '[&_.tiptap_pre]:font-mono',\n '[&_.tiptap_pre]:text-sm',\n '[&_.tiptap_pre]:text-gray-100',\n // Reset the inline `code` treatment below when it's nested inside `pre`,\n // so a code block doesn't get a second (redundant) chip background.\n '[&_.tiptap_pre_code]:bg-transparent',\n '[&_.tiptap_pre_code]:p-0',\n '[&_.tiptap_pre_code]:text-inherit',\n '[&_.tiptap_code]:rounded',\n '[&_.tiptap_code]:bg-gray-100',\n '[&_.tiptap_code]:px-1',\n '[&_.tiptap_code]:py-0.5',\n '[&_.tiptap_code]:font-mono',\n '[&_.tiptap_code]:text-[0.85em]',\n\n '[&_.tiptap_hr]:my-4',\n '[&_.tiptap_hr]:border-gray-200',\n\n '[&_.tiptap_a]:text-blue-600',\n '[&_.tiptap_a]:underline',\n '[&_.tiptap_a]:underline-offset-2',\n\n '[&_.tiptap_p.is-editor-empty:first-child::before]:pointer-events-none',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:float-left',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:h-0',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:text-gray-400',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:content-[attr(data-placeholder)]',\n);\n"],"mappings":";;AASA,MAAa,4BAA4B,GACvC,4BAIA,kCAEA,uBACA,uBACA,2BACA,4BACA,uBACA,uBACA,0BACA,4BACA,uBACA,uBACA,0BACA,gCACA,uBACA,uBACA,4BACA,gCAEA,uBACA,4BACA,uBACA,uBACA,+BACA,uBACA,uBAEA,+BACA,qCACA,0CACA,+BACA,wCACA,iCAGA,mCACA,wBACA,2BACA,+BACA,uBACA,6BACA,2BACA,iCAGA,uCACA,4BACA,qCACA,4BACA,gCACA,yBACA,2BACA,8BACA,kCAEA,uBACA,kCAEA,+BACA,2BACA,oCAEA,yEACA,gEACA,yDACA,mEACA,oFACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ToolbarItem, ToolbarPreset } from "./types.mjs";
|
|
2
|
+
//#region src/components/atoms/rich-text-editor/rich-text-editor.d.ts
|
|
3
|
+
interface Props {
|
|
4
|
+
value?: string;
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
classNames?: {
|
|
8
|
+
toolbar?: string;
|
|
9
|
+
content?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* `true` shows every built-in preset; an array shows only the listed
|
|
13
|
+
* presets, in the given order. Omitted or `false` renders no toolbar,
|
|
14
|
+
* matching the original (toolbar-less) output.
|
|
15
|
+
*/
|
|
16
|
+
toolbar?: boolean | ToolbarPreset[];
|
|
17
|
+
/** Extra buttons appended after the built-in presets. */
|
|
18
|
+
toolbarItems?: ToolbarItem[];
|
|
19
|
+
onChange?: (value: string) => void;
|
|
20
|
+
}
|
|
21
|
+
declare const RichTextEditor: ({ value, placeholder, className, classNames, toolbar, toolbarItems, onChange }: Props) => import("react").JSX.Element;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Props, RichTextEditor as default };
|
|
24
|
+
//# sourceMappingURL=rich-text-editor.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rich-text-editor.d.mts","names":[],"sources":["../../../../src/components/atoms/rich-text-editor/rich-text-editor.tsx"],"mappings":";;UAgBiB;EACf;EACA;EACA;EACA;IACE;IACA;;;;;;;EAOF,oBAAoB;;EAEpB,eAAe;EACf,YAAY;;cAGR,mBAAkB,OAAA,aAAA,WAAA,YAAA,SAAA,cAAA,YAQrB,0BAAK,IAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../../utils.mjs";
|
|
3
|
+
import { RICH_TEXT_CONTENT_CLASSES } from "./content-classes.mjs";
|
|
4
|
+
import { DEFAULT_TOOLBAR_PRESETS } from "./toolbar-presets.mjs";
|
|
5
|
+
import Toolbar from "./toolbar.mjs";
|
|
6
|
+
import { useEffect } from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import Placeholder from "@tiptap/extension-placeholder";
|
|
9
|
+
import { TextStyleKit } from "@tiptap/extension-text-style";
|
|
10
|
+
import { EditorContent, useEditor } from "@tiptap/react";
|
|
11
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
12
|
+
//#region src/components/atoms/rich-text-editor/rich-text-editor.tsx
|
|
13
|
+
const RichTextEditor = ({ value = "", placeholder = "Enter text...", className, classNames, toolbar = false, toolbarItems, onChange }) => {
|
|
14
|
+
const presets = toolbar === true ? DEFAULT_TOOLBAR_PRESETS : toolbar || [];
|
|
15
|
+
const showToolbar = presets.length > 0 || (toolbarItems?.length ?? 0) > 0;
|
|
16
|
+
const editor = useEditor({
|
|
17
|
+
immediatelyRender: false,
|
|
18
|
+
extensions: [
|
|
19
|
+
StarterKit,
|
|
20
|
+
Placeholder.configure({ placeholder }),
|
|
21
|
+
TextStyleKit.configure({
|
|
22
|
+
fontFamily: false,
|
|
23
|
+
lineHeight: false,
|
|
24
|
+
backgroundColor: false
|
|
25
|
+
})
|
|
26
|
+
],
|
|
27
|
+
content: value,
|
|
28
|
+
onBlur: ({ editor: e }) => {
|
|
29
|
+
onChange?.(e.getHTML());
|
|
30
|
+
},
|
|
31
|
+
shouldRerenderOnTransaction: showToolbar
|
|
32
|
+
});
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (!editor) return;
|
|
35
|
+
if (editor.getHTML() !== value) editor.commands.setContent(value, { emitUpdate: false });
|
|
36
|
+
}, [value, editor]);
|
|
37
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
38
|
+
"data-slot": "rich-text-editor",
|
|
39
|
+
className: cn("rounded border border-gray-200 bg-white text-sm text-gray-800", className),
|
|
40
|
+
children: [showToolbar && editor && /* @__PURE__ */ jsx(Toolbar, {
|
|
41
|
+
editor,
|
|
42
|
+
presets,
|
|
43
|
+
items: toolbarItems,
|
|
44
|
+
className: classNames?.toolbar
|
|
45
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
46
|
+
"data-slot": "rich-text-editor-content",
|
|
47
|
+
className: cn("min-h-20 px-3 py-2", RICH_TEXT_CONTENT_CLASSES, classNames?.content),
|
|
48
|
+
children: /* @__PURE__ */ jsx(EditorContent, { editor })
|
|
49
|
+
})]
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { RichTextEditor as default };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=rich-text-editor.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rich-text-editor.mjs","names":[],"sources":["../../../../src/components/atoms/rich-text-editor/rich-text-editor.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\n\nimport Placeholder from '@tiptap/extension-placeholder';\nimport { TextStyleKit } from '@tiptap/extension-text-style';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { RICH_TEXT_CONTENT_CLASSES } from './content-classes';\nimport Toolbar from './toolbar';\nimport { DEFAULT_TOOLBAR_PRESETS } from './toolbar-presets';\nimport type { ToolbarItem, ToolbarPreset } from './types';\n\nexport interface Props {\n value?: string;\n placeholder?: string;\n className?: string;\n classNames?: {\n toolbar?: string;\n content?: string;\n };\n /**\n * `true` shows every built-in preset; an array shows only the listed\n * presets, in the given order. Omitted or `false` renders no toolbar,\n * matching the original (toolbar-less) output.\n */\n toolbar?: boolean | ToolbarPreset[];\n /** Extra buttons appended after the built-in presets. */\n toolbarItems?: ToolbarItem[];\n onChange?: (value: string) => void;\n}\n\nconst RichTextEditor = ({\n value = '',\n placeholder = 'Enter text...',\n className,\n classNames,\n toolbar = false,\n toolbarItems,\n onChange,\n}: Props) => {\n const presets = toolbar === true ? DEFAULT_TOOLBAR_PRESETS : toolbar || [];\n const showToolbar = presets.length > 0 || (toolbarItems?.length ?? 0) > 0;\n\n const editor = useEditor({\n // SSR renders every exported component without effects running, so the\n // editor must not touch the DOM during that first pass — deferring\n // creation to mount keeps `renderToStaticMarkup` from throwing.\n immediatelyRender: false,\n extensions: [\n StarterKit,\n Placeholder.configure({ placeholder }),\n TextStyleKit.configure({\n fontFamily: false,\n lineHeight: false,\n backgroundColor: false,\n }),\n ],\n content: value,\n onBlur: ({ editor: e }) => {\n onChange?.(e.getHTML());\n },\n // @tiptap/react v3 only re-renders on selection/transaction changes when\n // explicitly opted in — the toolbar's isActive()/getAttributes() reads\n // need that to reflect the caret position live.\n shouldRerenderOnTransaction: showToolbar,\n });\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const current = editor.getHTML();\n\n if (current !== value) {\n editor.commands.setContent(value, { emitUpdate: false });\n }\n }, [value, editor]);\n\n return (\n <div\n data-slot=\"rich-text-editor\"\n className={cn(\n 'rounded border border-gray-200 bg-white text-sm text-gray-800',\n className,\n //\n )}\n >\n {showToolbar && editor && (\n <Toolbar\n editor={editor}\n presets={presets}\n items={toolbarItems}\n className={classNames?.toolbar}\n />\n )}\n <div\n data-slot=\"rich-text-editor-content\"\n className={cn(\n 'min-h-20 px-3 py-2',\n RICH_TEXT_CONTENT_CLASSES,\n classNames?.content,\n //\n )}\n >\n <EditorContent editor={editor} />\n </div>\n </div>\n );\n};\n\nexport default RichTextEditor;\n"],"mappings":";;;;;;;;;;;;AAmCA,MAAM,kBAAkB,EACtB,QAAQ,IACR,cAAc,iBACd,WACA,YACA,UAAU,OACV,cACA,eACW;CACX,MAAM,UAAU,YAAY,OAAO,0BAA0B,WAAW,CAAC;CACzE,MAAM,cAAc,QAAQ,SAAS,MAAM,cAAc,UAAU,KAAK;CAExE,MAAM,SAAS,UAAU;EAIvB,mBAAmB;EACnB,YAAY;GACV;GACA,YAAY,UAAU,EAAE,YAAY,CAAC;GACrC,aAAa,UAAU;IACrB,YAAY;IACZ,YAAY;IACZ,iBAAiB;GACnB,CAAC;EACH;EACA,SAAS;EACT,SAAS,EAAE,QAAQ,QAAQ;GACzB,WAAW,EAAE,QAAQ,CAAC;EACxB;EAIA,6BAA6B;CAC/B,CAAC;CAED,gBAAgB;EACd,IAAI,CAAC,QACH;EAKF,IAFgB,OAAO,QAEb,MAAM,OACd,OAAO,SAAS,WAAW,OAAO,EAAE,YAAY,MAAM,CAAC;CAE3D,GAAG,CAAC,OAAO,MAAM,CAAC;CAElB,OACE,qBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,iEACA,SAEF;EANF,UAAA,CAQG,eAAe,UACd,oBAAC,SAAD;GACU;GACC;GACT,OAAO;GACP,WAAW,YAAY;EACxB,CAAA,GAEH,oBAAC,OAAD;GACE,aAAU;GACV,WAAW,GACT,sBACA,2BACA,YAAY,OAEd;GAEA,UAAA,oBAAC,eAAD,EAAuB,OAAS,CAAA;EAC7B,CAAA,CACF;;AAET"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { cn } from "../../../utils.mjs";
|
|
2
|
+
import Button from "../../../Button.mjs";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/atoms/rich-text-editor/toolbar-button.tsx
|
|
5
|
+
const ToolbarButton = ({ active, className, ...props }) => /* @__PURE__ */ jsx(Button, {
|
|
6
|
+
...props,
|
|
7
|
+
type: "text",
|
|
8
|
+
size: "small",
|
|
9
|
+
shape: "default",
|
|
10
|
+
"aria-pressed": active,
|
|
11
|
+
className: cn(active && "bg-accent", className)
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ToolbarButton as default };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=toolbar-button.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolbar-button.mjs","names":[],"sources":["../../../../src/components/atoms/rich-text-editor/toolbar-button.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nimport Button, { type Props as ButtonProps } from '../button';\n\nexport interface ToolbarButtonProps extends Omit<\n ButtonProps,\n 'type' | 'shape' | 'size'\n> {\n active?: boolean;\n}\n\nconst ToolbarButton = ({ active, className, ...props }: ToolbarButtonProps) => (\n <Button\n // Spread first: when this button sits inside a `Popover` trigger\n // (`asChild`), Radix injects its own native `type=\"button\"` onto us for\n // form-submit safety — that's a different `type` than Button's own\n // antd-style color/variant switch, and if it landed after these three,\n // it would silently override `type=\"text\"` and fall through to the\n // `outlined` variant's border.\n {...props}\n type=\"text\"\n size=\"small\"\n shape=\"default\"\n aria-pressed={active}\n className={cn(active && 'bg-accent', className)}\n />\n);\n\nexport default ToolbarButton;\n"],"mappings":";;;;AAWA,MAAM,iBAAiB,EAAE,QAAQ,WAAW,GAAG,YAC7C,oBAAC,QAAD;CAOE,GAAI;CACJ,MAAK;CACL,MAAK;CACL,OAAM;CACN,gBAAc;CACd,WAAW,GAAG,UAAU,aAAa,SAAS;AAC/C,CAAA"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import Button from "../../../Button.mjs";
|
|
3
|
+
import Popover from "../popover.mjs";
|
|
4
|
+
import ColorPicker from "../color-picker.mjs";
|
|
5
|
+
import Input from "../input/index.mjs";
|
|
6
|
+
import ToolbarButton from "./toolbar-button.mjs";
|
|
7
|
+
import Select from "../select.mjs";
|
|
8
|
+
import { useState } from "react";
|
|
9
|
+
import { Bold, Code, Code2, Italic, Link, List, ListOrdered, Minus, Quote, Redo2, Strikethrough, Underline, Undo2 } from "lucide-react";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
//#region src/components/atoms/rich-text-editor/toolbar-presets.tsx
|
|
12
|
+
const FONT_SIZE_OPTIONS = [
|
|
13
|
+
{
|
|
14
|
+
label: "12",
|
|
15
|
+
value: "12px"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
label: "14",
|
|
19
|
+
value: "14px"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: "16",
|
|
23
|
+
value: "16px"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: "18",
|
|
27
|
+
value: "18px"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
label: "24",
|
|
31
|
+
value: "24px"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
label: "32",
|
|
35
|
+
value: "32px"
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
const HEADING_LEVELS = [
|
|
39
|
+
1,
|
|
40
|
+
2,
|
|
41
|
+
3,
|
|
42
|
+
4
|
|
43
|
+
];
|
|
44
|
+
const HEADING_OPTIONS = [{
|
|
45
|
+
label: "Paragraph",
|
|
46
|
+
value: "paragraph"
|
|
47
|
+
}, ...HEADING_LEVELS.map((level) => ({
|
|
48
|
+
label: `Heading ${level}`,
|
|
49
|
+
value: String(level)
|
|
50
|
+
}))];
|
|
51
|
+
const LinkControl = ({ editor }) => {
|
|
52
|
+
const [open, setOpen] = useState(false);
|
|
53
|
+
const [href, setHref] = useState("");
|
|
54
|
+
const apply = () => {
|
|
55
|
+
const next = href.trim();
|
|
56
|
+
if (next) editor.chain().focus().extendMarkRange("link").setLink({ href: next }).run();
|
|
57
|
+
else editor.chain().focus().unsetLink().run();
|
|
58
|
+
setOpen(false);
|
|
59
|
+
};
|
|
60
|
+
return /* @__PURE__ */ jsx(Popover, {
|
|
61
|
+
placement: "bottom",
|
|
62
|
+
open,
|
|
63
|
+
onOpenChange: (next) => {
|
|
64
|
+
if (next) setHref(editor.getAttributes("link").href ?? "");
|
|
65
|
+
setOpen(next);
|
|
66
|
+
},
|
|
67
|
+
content: /* @__PURE__ */ jsxs("div", {
|
|
68
|
+
className: "flex items-center gap-2",
|
|
69
|
+
children: [/* @__PURE__ */ jsx(Input, {
|
|
70
|
+
value: href,
|
|
71
|
+
placeholder: "https://",
|
|
72
|
+
className: "w-48",
|
|
73
|
+
onChange: (e) => setHref(e.target.value),
|
|
74
|
+
onKeyDown: (e) => {
|
|
75
|
+
if (e.key === "Enter") {
|
|
76
|
+
e.preventDefault();
|
|
77
|
+
apply();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
81
|
+
size: "small",
|
|
82
|
+
onClick: apply,
|
|
83
|
+
children: "Apply"
|
|
84
|
+
})]
|
|
85
|
+
}),
|
|
86
|
+
children: /* @__PURE__ */ jsx(ToolbarButton, {
|
|
87
|
+
icon: /* @__PURE__ */ jsx(Link, {}),
|
|
88
|
+
"aria-label": "Link",
|
|
89
|
+
active: editor.isActive("link")
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
const TOOLBAR_PRESET_RENDERERS = {
|
|
94
|
+
undo: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
95
|
+
icon: /* @__PURE__ */ jsx(Undo2, {}),
|
|
96
|
+
"aria-label": "Undo",
|
|
97
|
+
disabled: !editor.can().undo(),
|
|
98
|
+
onClick: () => editor.chain().focus().undo().run()
|
|
99
|
+
}, "undo"),
|
|
100
|
+
redo: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
101
|
+
icon: /* @__PURE__ */ jsx(Redo2, {}),
|
|
102
|
+
"aria-label": "Redo",
|
|
103
|
+
disabled: !editor.can().redo(),
|
|
104
|
+
onClick: () => editor.chain().focus().redo().run()
|
|
105
|
+
}, "redo"),
|
|
106
|
+
heading: (editor) => {
|
|
107
|
+
const activeLevel = HEADING_LEVELS.find((level) => editor.isActive("heading", { level }));
|
|
108
|
+
return /* @__PURE__ */ jsx(Select, {
|
|
109
|
+
className: "h-6 w-28",
|
|
110
|
+
placeholder: "Style",
|
|
111
|
+
options: HEADING_OPTIONS,
|
|
112
|
+
value: activeLevel ? String(activeLevel) : "paragraph",
|
|
113
|
+
onChange: (value) => value === "paragraph" ? editor.chain().setParagraph().run() : editor.chain().setHeading({ level: Number(value) }).run()
|
|
114
|
+
}, "heading");
|
|
115
|
+
},
|
|
116
|
+
bold: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
117
|
+
icon: /* @__PURE__ */ jsx(Bold, {}),
|
|
118
|
+
"aria-label": "Bold",
|
|
119
|
+
active: editor.isActive("bold"),
|
|
120
|
+
onClick: () => editor.chain().focus().toggleBold().run()
|
|
121
|
+
}, "bold"),
|
|
122
|
+
italic: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
123
|
+
icon: /* @__PURE__ */ jsx(Italic, {}),
|
|
124
|
+
"aria-label": "Italic",
|
|
125
|
+
active: editor.isActive("italic"),
|
|
126
|
+
onClick: () => editor.chain().focus().toggleItalic().run()
|
|
127
|
+
}, "italic"),
|
|
128
|
+
underline: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
129
|
+
icon: /* @__PURE__ */ jsx(Underline, {}),
|
|
130
|
+
"aria-label": "Underline",
|
|
131
|
+
active: editor.isActive("underline"),
|
|
132
|
+
onClick: () => editor.chain().focus().toggleUnderline().run()
|
|
133
|
+
}, "underline"),
|
|
134
|
+
strike: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
135
|
+
icon: /* @__PURE__ */ jsx(Strikethrough, {}),
|
|
136
|
+
"aria-label": "Strikethrough",
|
|
137
|
+
active: editor.isActive("strike"),
|
|
138
|
+
onClick: () => editor.chain().focus().toggleStrike().run()
|
|
139
|
+
}, "strike"),
|
|
140
|
+
code: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
141
|
+
icon: /* @__PURE__ */ jsx(Code, {}),
|
|
142
|
+
"aria-label": "Inline code",
|
|
143
|
+
active: editor.isActive("code"),
|
|
144
|
+
onClick: () => editor.chain().focus().toggleCode().run()
|
|
145
|
+
}, "code"),
|
|
146
|
+
bulletList: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
147
|
+
icon: /* @__PURE__ */ jsx(List, {}),
|
|
148
|
+
"aria-label": "Bullet list",
|
|
149
|
+
active: editor.isActive("bulletList"),
|
|
150
|
+
onClick: () => editor.chain().focus().toggleBulletList().run()
|
|
151
|
+
}, "bulletList"),
|
|
152
|
+
orderedList: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
153
|
+
icon: /* @__PURE__ */ jsx(ListOrdered, {}),
|
|
154
|
+
"aria-label": "Ordered list",
|
|
155
|
+
active: editor.isActive("orderedList"),
|
|
156
|
+
onClick: () => editor.chain().focus().toggleOrderedList().run()
|
|
157
|
+
}, "orderedList"),
|
|
158
|
+
blockquote: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
159
|
+
icon: /* @__PURE__ */ jsx(Quote, {}),
|
|
160
|
+
"aria-label": "Blockquote",
|
|
161
|
+
active: editor.isActive("blockquote"),
|
|
162
|
+
onClick: () => editor.chain().focus().toggleBlockquote().run()
|
|
163
|
+
}, "blockquote"),
|
|
164
|
+
codeBlock: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
165
|
+
icon: /* @__PURE__ */ jsx(Code2, {}),
|
|
166
|
+
"aria-label": "Code block",
|
|
167
|
+
active: editor.isActive("codeBlock"),
|
|
168
|
+
onClick: () => editor.chain().focus().toggleCodeBlock().run()
|
|
169
|
+
}, "codeBlock"),
|
|
170
|
+
horizontalRule: (editor) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
171
|
+
icon: /* @__PURE__ */ jsx(Minus, {}),
|
|
172
|
+
"aria-label": "Horizontal rule",
|
|
173
|
+
onClick: () => editor.chain().focus().setHorizontalRule().run()
|
|
174
|
+
}, "horizontalRule"),
|
|
175
|
+
link: (editor) => /* @__PURE__ */ jsx(LinkControl, { editor }, "link"),
|
|
176
|
+
fontSize: (editor) => /* @__PURE__ */ jsx(Select, {
|
|
177
|
+
className: "h-6 w-20",
|
|
178
|
+
placeholder: "Size",
|
|
179
|
+
options: FONT_SIZE_OPTIONS,
|
|
180
|
+
value: editor.getAttributes("textStyle").fontSize ?? void 0,
|
|
181
|
+
onChange: (value) => editor.chain().setFontSize(value).run()
|
|
182
|
+
}, "fontSize"),
|
|
183
|
+
color: (editor) => /* @__PURE__ */ jsx(ColorPicker, {
|
|
184
|
+
value: editor.getAttributes("textStyle").color || "#000000",
|
|
185
|
+
onChange: (value) => editor.chain().setColor(value).run()
|
|
186
|
+
}, "color")
|
|
187
|
+
};
|
|
188
|
+
const DEFAULT_TOOLBAR_PRESETS = [
|
|
189
|
+
"undo",
|
|
190
|
+
"redo",
|
|
191
|
+
"heading",
|
|
192
|
+
"bold",
|
|
193
|
+
"italic",
|
|
194
|
+
"underline",
|
|
195
|
+
"strike",
|
|
196
|
+
"code",
|
|
197
|
+
"bulletList",
|
|
198
|
+
"orderedList",
|
|
199
|
+
"blockquote",
|
|
200
|
+
"codeBlock",
|
|
201
|
+
"horizontalRule",
|
|
202
|
+
"link",
|
|
203
|
+
"fontSize",
|
|
204
|
+
"color"
|
|
205
|
+
];
|
|
206
|
+
//#endregion
|
|
207
|
+
export { DEFAULT_TOOLBAR_PRESETS, TOOLBAR_PRESET_RENDERERS };
|
|
208
|
+
|
|
209
|
+
//# sourceMappingURL=toolbar-presets.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolbar-presets.mjs","names":["LinkIcon"],"sources":["../../../../src/components/atoms/rich-text-editor/toolbar-presets.tsx"],"sourcesContent":["'use client';\n\nimport { type ReactNode, useState } from 'react';\n\nimport type { Editor } from '@tiptap/core';\nimport {\n Bold,\n Code,\n Code2,\n Italic,\n Link as LinkIcon,\n List,\n ListOrdered,\n Minus,\n Quote,\n Redo2,\n Strikethrough,\n Underline,\n Undo2,\n} from 'lucide-react';\n\nimport Button from '../button';\nimport ColorPicker from '../color-picker';\nimport Input from '../input';\nimport Popover from '../popover';\nimport Select from '../select';\nimport ToolbarButton from './toolbar-button';\nimport type { ToolbarPreset } from './types';\n\nconst FONT_SIZE_OPTIONS = [\n { label: '12', value: '12px' },\n { label: '14', value: '14px' },\n { label: '16', value: '16px' },\n { label: '18', value: '18px' },\n { label: '24', value: '24px' },\n { label: '32', value: '32px' },\n];\n\nconst HEADING_LEVELS = [1, 2, 3, 4] as const;\n\nconst HEADING_OPTIONS = [\n { label: 'Paragraph', value: 'paragraph' },\n ...HEADING_LEVELS.map(level => ({\n label: `Heading ${level}`,\n value: String(level),\n })),\n];\n\n// Owns its own open/href state, so it has to be a real component (not a\n// plain render function like the other presets) for the hooks below to be\n// valid.\nconst LinkControl = ({ editor }: { editor: Editor }) => {\n const [open, setOpen] = useState(false);\n const [href, setHref] = useState('');\n\n const apply = () => {\n const next = href.trim();\n\n if (next) {\n editor\n .chain()\n .focus()\n .extendMarkRange('link')\n .setLink({ href: next })\n .run();\n } else {\n editor.chain().focus().unsetLink().run();\n }\n setOpen(false);\n };\n\n return (\n <Popover\n placement=\"bottom\"\n open={open}\n onOpenChange={next => {\n if (next) {\n setHref(editor.getAttributes('link').href ?? '');\n }\n setOpen(next);\n }}\n content={\n <div className=\"flex items-center gap-2\">\n <Input\n value={href}\n placeholder=\"https://\"\n className=\"w-48\"\n onChange={e => setHref(e.target.value)}\n onKeyDown={e => {\n if (e.key === 'Enter') {\n e.preventDefault();\n apply();\n }\n }}\n />\n <Button size=\"small\" onClick={apply}>\n Apply\n </Button>\n </div>\n }\n >\n <ToolbarButton\n icon={<LinkIcon />}\n aria-label=\"Link\"\n active={editor.isActive('link')}\n />\n </Popover>\n );\n};\n\nexport const TOOLBAR_PRESET_RENDERERS: Record<\n ToolbarPreset,\n (editor: Editor) => ReactNode\n> = {\n undo: editor => (\n <ToolbarButton\n key=\"undo\"\n icon={<Undo2 />}\n aria-label=\"Undo\"\n disabled={!editor.can().undo()}\n onClick={() => editor.chain().focus().undo().run()}\n />\n ),\n redo: editor => (\n <ToolbarButton\n key=\"redo\"\n icon={<Redo2 />}\n aria-label=\"Redo\"\n disabled={!editor.can().redo()}\n onClick={() => editor.chain().focus().redo().run()}\n />\n ),\n heading: editor => {\n const activeLevel = HEADING_LEVELS.find(level =>\n editor.isActive('heading', { level }),\n );\n\n return (\n <Select\n key=\"heading\"\n className=\"h-6 w-28\"\n placeholder=\"Style\"\n options={HEADING_OPTIONS}\n value={activeLevel ? String(activeLevel) : 'paragraph'}\n // No `.focus()` here — the Select is still open when this fires,\n // and refocusing the editor mid-selection dismisses it early (same\n // class of bug as the color picker below).\n onChange={value =>\n value === 'paragraph'\n ? editor.chain().setParagraph().run()\n : editor\n .chain()\n .setHeading({ level: Number(value) as 1 | 2 | 3 | 4 })\n .run()\n }\n />\n );\n },\n bold: editor => (\n <ToolbarButton\n key=\"bold\"\n icon={<Bold />}\n aria-label=\"Bold\"\n active={editor.isActive('bold')}\n onClick={() => editor.chain().focus().toggleBold().run()}\n />\n ),\n italic: editor => (\n <ToolbarButton\n key=\"italic\"\n icon={<Italic />}\n aria-label=\"Italic\"\n active={editor.isActive('italic')}\n onClick={() => editor.chain().focus().toggleItalic().run()}\n />\n ),\n underline: editor => (\n <ToolbarButton\n key=\"underline\"\n icon={<Underline />}\n aria-label=\"Underline\"\n active={editor.isActive('underline')}\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n />\n ),\n strike: editor => (\n <ToolbarButton\n key=\"strike\"\n icon={<Strikethrough />}\n aria-label=\"Strikethrough\"\n active={editor.isActive('strike')}\n onClick={() => editor.chain().focus().toggleStrike().run()}\n />\n ),\n code: editor => (\n <ToolbarButton\n key=\"code\"\n icon={<Code />}\n aria-label=\"Inline code\"\n active={editor.isActive('code')}\n onClick={() => editor.chain().focus().toggleCode().run()}\n />\n ),\n bulletList: editor => (\n <ToolbarButton\n key=\"bulletList\"\n icon={<List />}\n aria-label=\"Bullet list\"\n active={editor.isActive('bulletList')}\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n />\n ),\n orderedList: editor => (\n <ToolbarButton\n key=\"orderedList\"\n icon={<ListOrdered />}\n aria-label=\"Ordered list\"\n active={editor.isActive('orderedList')}\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n />\n ),\n blockquote: editor => (\n <ToolbarButton\n key=\"blockquote\"\n icon={<Quote />}\n aria-label=\"Blockquote\"\n active={editor.isActive('blockquote')}\n onClick={() => editor.chain().focus().toggleBlockquote().run()}\n />\n ),\n codeBlock: editor => (\n <ToolbarButton\n key=\"codeBlock\"\n icon={<Code2 />}\n aria-label=\"Code block\"\n active={editor.isActive('codeBlock')}\n onClick={() => editor.chain().focus().toggleCodeBlock().run()}\n />\n ),\n horizontalRule: editor => (\n <ToolbarButton\n key=\"horizontalRule\"\n icon={<Minus />}\n aria-label=\"Horizontal rule\"\n onClick={() => editor.chain().focus().setHorizontalRule().run()}\n />\n ),\n link: editor => <LinkControl key=\"link\" editor={editor} />,\n fontSize: editor => (\n <Select\n key=\"fontSize\"\n className=\"h-6 w-20\"\n placeholder=\"Size\"\n options={FONT_SIZE_OPTIONS}\n value={editor.getAttributes('textStyle').fontSize ?? undefined}\n // No `.focus()` — see the `heading` preset above.\n onChange={value => editor.chain().setFontSize(value).run()}\n />\n ),\n color: editor => (\n <ColorPicker\n key=\"color\"\n value={editor.getAttributes('textStyle').color || '#000000'}\n // No `.focus()`: react-colorful fires `onChange` continuously while\n // dragging, and refocusing the editor on every tick moves DOM focus\n // out from under the still-open popover, which Radix reads as an\n // outside interaction and dismisses immediately (ui-kit reported\n // symptom: \"picker closes as soon as you try to change the color\").\n // The mark still applies to the stored selection without it.\n onChange={value => editor.chain().setColor(value).run()}\n />\n ),\n};\n\nexport const DEFAULT_TOOLBAR_PRESETS: ToolbarPreset[] = [\n 'undo',\n 'redo',\n 'heading',\n 'bold',\n 'italic',\n 'underline',\n 'strike',\n 'code',\n 'bulletList',\n 'orderedList',\n 'blockquote',\n 'codeBlock',\n 'horizontalRule',\n 'link',\n 'fontSize',\n 'color',\n];\n"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { cn } from "../../../utils.mjs";
|
|
2
|
+
import ToolbarButton from "./toolbar-button.mjs";
|
|
3
|
+
import { TOOLBAR_PRESET_RENDERERS } from "./toolbar-presets.mjs";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/atoms/rich-text-editor/toolbar.tsx
|
|
6
|
+
const Toolbar = ({ editor, presets, items, className }) => {
|
|
7
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8
|
+
"data-slot": "rich-text-editor-toolbar",
|
|
9
|
+
className: cn("flex flex-wrap items-center gap-1 border-b border-gray-200 px-2 py-1", className),
|
|
10
|
+
children: [presets.map((preset) => TOOLBAR_PRESET_RENDERERS[preset](editor)), items?.map((item) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
11
|
+
icon: item.icon,
|
|
12
|
+
"aria-label": item.label,
|
|
13
|
+
active: item.isActive?.(editor),
|
|
14
|
+
onClick: () => item.onClick(editor)
|
|
15
|
+
}, item.key))]
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { Toolbar as default };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=toolbar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolbar.mjs","names":[],"sources":["../../../../src/components/atoms/rich-text-editor/toolbar.tsx"],"sourcesContent":["import type { Editor } from '@tiptap/core';\n\nimport { cn } from '@repo/ui/utils';\n\nimport ToolbarButton from './toolbar-button';\nimport { TOOLBAR_PRESET_RENDERERS } from './toolbar-presets';\nimport type { ToolbarItem, ToolbarPreset } from './types';\n\nexport interface ToolbarProps {\n editor: Editor;\n presets: ToolbarPreset[];\n items?: ToolbarItem[];\n className?: string;\n}\n\nconst Toolbar = ({ editor, presets, items, className }: ToolbarProps) => {\n return (\n <div\n data-slot=\"rich-text-editor-toolbar\"\n className={cn(\n 'flex flex-wrap items-center gap-1 border-b border-gray-200 px-2 py-1',\n className,\n //\n )}\n >\n {presets.map(preset => TOOLBAR_PRESET_RENDERERS[preset](editor))}\n {items?.map(item => (\n <ToolbarButton\n key={item.key}\n icon={item.icon}\n aria-label={item.label}\n active={item.isActive?.(editor)}\n onClick={() => item.onClick(editor)}\n />\n ))}\n </div>\n );\n};\n\nexport default Toolbar;\n"],"mappings":";;;;;AAeA,MAAM,WAAW,EAAE,QAAQ,SAAS,OAAO,gBAA8B;CACvE,OACE,qBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,wEACA,SAEF;EANF,UAAA,CAQG,QAAQ,KAAI,WAAU,yBAAyB,OAAO,CAAC,MAAM,CAAC,GAC9D,OAAO,KAAI,SACV,oBAAC,eAAD;GAEE,MAAM,KAAK;GACX,cAAY,KAAK;GACjB,QAAQ,KAAK,WAAW,MAAM;GAC9B,eAAe,KAAK,QAAQ,MAAM;EACnC,GALM,KAAK,GAKX,CACF,CACE;;AAET"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { Editor } from "@tiptap/core";
|
|
3
|
+
//#region src/components/atoms/rich-text-editor/types.d.ts
|
|
4
|
+
type ToolbarPreset = 'undo' | 'redo' | 'heading' | 'bold' | 'italic' | 'underline' | 'strike' | 'code' | 'bulletList' | 'orderedList' | 'blockquote' | 'codeBlock' | 'horizontalRule' | 'link' | 'fontSize' | 'color';
|
|
5
|
+
interface ToolbarItem {
|
|
6
|
+
key: string;
|
|
7
|
+
icon: ReactNode;
|
|
8
|
+
label?: string;
|
|
9
|
+
isActive?: (editor: Editor) => boolean;
|
|
10
|
+
onClick: (editor: Editor) => void;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { ToolbarItem, ToolbarPreset };
|
|
14
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../../src/components/atoms/rich-text-editor/types.ts"],"mappings":";;;KAIY;UAkBK;EACf;EACA,MAAM;EACN;EACA,YAAY,QAAQ;EACpB,UAAU,QAAQ"}
|
package/dist/index.d.mts
CHANGED
|
@@ -20,6 +20,7 @@ import Input from "./components/atoms/input/index.mjs";
|
|
|
20
20
|
import Popover from "./components/atoms/popover.mjs";
|
|
21
21
|
import Progress from "./components/atoms/progress.mjs";
|
|
22
22
|
import Radio from "./components/atoms/radio/index.mjs";
|
|
23
|
+
import RichTextEditor from "./components/atoms/rich-text-editor/rich-text-editor.mjs";
|
|
23
24
|
import Select from "./components/atoms/select.mjs";
|
|
24
25
|
import Skeleton from "./components/atoms/skeleton/index.mjs";
|
|
25
26
|
import Slider from "./components/atoms/slider/slider.mjs";
|
|
@@ -52,4 +53,4 @@ import { ComponentSize, DefaultProps, Locale, ThemeConfig, ThemeToken } from "./
|
|
|
52
53
|
import { DEFAULT_LOCALE, useConfig } from "./providers/config/context.mjs";
|
|
53
54
|
import Config, { Props as Props$3 } from "./providers/config/config.mjs";
|
|
54
55
|
import { ConfigSnapshotProvider, getRootConfigValue } from "./providers/config/registry.mjs";
|
|
55
|
-
export { Button, Card, type Props as CardProps, Checkbox, Col, type Props$1 as ColProps, Collapse, type Props$2 as CollapseProps, ColorPicker, type ComponentSize, Config, type Props$3 as ConfigProps, ConfigSnapshotProvider, Container, type Props$4 as ContainerProps, type Props$5 as ContentProps, DEFAULT_LOCALE, DatePicker, type DefaultProps, Drawer, type Props$6 as DrawerProps, Dropdown, type Props$7 as DropdownProps, Empty, type Props$8 as EmptyProps, FloatButton, type Props$9 as FooterProps, type Props$10 as HeaderProps, Input, Layout, type Props$11 as LayoutProps, List, type Props$12 as ListProps, type Locale, Marquees, type Props$13 as MarqueesProps, Menu, type Props$14 as MenuProps, Modal, type Props$15 as ModalProps, PageHeader, type Props$16 as PageHeaderProps, Popover, Progress, Radio, Result, type Props$17 as ResultProps, Reveals, type Props$18 as RevealsProps, Row, type Props$19 as RowProps, Select, type Props$20 as SiderProps, Skeleton, Slider, Space, type Props$21 as SpaceProps, Spin, Splitter, type Props$22 as SplitterProps, Swiper, type Props$23 as SwiperProps, Switch, Tag, type ThemeConfig, type ThemeToken, Toast, type StaticProps as ToastOptions, Typography, Upload, type UploadFile, type Props$24 as UploadProps, getRootConfigValue, useConfig };
|
|
56
|
+
export { Button, Card, type Props as CardProps, Checkbox, Col, type Props$1 as ColProps, Collapse, type Props$2 as CollapseProps, ColorPicker, type ComponentSize, Config, type Props$3 as ConfigProps, ConfigSnapshotProvider, Container, type Props$4 as ContainerProps, type Props$5 as ContentProps, DEFAULT_LOCALE, DatePicker, type DefaultProps, Drawer, type Props$6 as DrawerProps, Dropdown, type Props$7 as DropdownProps, Empty, type Props$8 as EmptyProps, FloatButton, type Props$9 as FooterProps, type Props$10 as HeaderProps, Input, Layout, type Props$11 as LayoutProps, List, type Props$12 as ListProps, type Locale, Marquees, type Props$13 as MarqueesProps, Menu, type Props$14 as MenuProps, Modal, type Props$15 as ModalProps, PageHeader, type Props$16 as PageHeaderProps, Popover, Progress, Radio, Result, type Props$17 as ResultProps, Reveals, type Props$18 as RevealsProps, RichTextEditor, Row, type Props$19 as RowProps, Select, type Props$20 as SiderProps, Skeleton, Slider, Space, type Props$21 as SpaceProps, Spin, Splitter, type Props$22 as SplitterProps, Swiper, type Props$23 as SwiperProps, Switch, Tag, type ThemeConfig, type ThemeToken, Toast, type StaticProps as ToastOptions, Typography, Upload, type UploadFile, type Props$24 as UploadProps, getRootConfigValue, useConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -13,6 +13,7 @@ import Input from "./components/atoms/input/index.mjs";
|
|
|
13
13
|
import Progress from "./components/atoms/progress.mjs";
|
|
14
14
|
import Radio from "./components/atoms/radio/index.mjs";
|
|
15
15
|
import Select from "./components/atoms/select.mjs";
|
|
16
|
+
import RichTextEditor from "./components/atoms/rich-text-editor/rich-text-editor.mjs";
|
|
16
17
|
import Skeleton from "./components/atoms/skeleton/index.mjs";
|
|
17
18
|
import slider_default from "./components/atoms/slider/index.mjs";
|
|
18
19
|
import Spin from "./components/atoms/spin.mjs";
|
|
@@ -39,4 +40,4 @@ import Result from "./components/templates/result.mjs";
|
|
|
39
40
|
import PageHeader from "./components/templates/page-header.mjs";
|
|
40
41
|
import Row from "./components/templates/grid/row.mjs";
|
|
41
42
|
import Col from "./components/templates/grid/col.mjs";
|
|
42
|
-
export { Button, Card, Checkbox, Col, Collapse, ColorPicker, Config, ConfigSnapshotProvider, Container, DEFAULT_LOCALE, DatePicker, Drawer, Dropdown, Empty, FloatButton, Input, Layout, List, Marquees, Menu, Modal, PageHeader, Popover, Progress, Radio, Result, Reveals, Row, Select, Skeleton, slider_default as Slider, Space, Spin, Splitter, Swiper, Switch, Tag, Toast, Typography, Upload, getRootConfigValue, useConfig };
|
|
43
|
+
export { Button, Card, Checkbox, Col, Collapse, ColorPicker, Config, ConfigSnapshotProvider, Container, DEFAULT_LOCALE, DatePicker, Drawer, Dropdown, Empty, FloatButton, Input, Layout, List, Marquees, Menu, Modal, PageHeader, Popover, Progress, Radio, Result, Reveals, RichTextEditor, Row, Select, Skeleton, slider_default as Slider, Space, Spin, Splitter, Swiper, Switch, Tag, Toast, Typography, Upload, getRootConfigValue, useConfig };
|
package/dist/style.css
CHANGED
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
--color-yellow-400: oklch(85.2% .199 91.936);
|
|
9
9
|
--color-green-400: oklch(79.2% .209 151.711);
|
|
10
10
|
--color-blue-400: oklch(70.7% .165 254.624);
|
|
11
|
+
--color-blue-600: oklch(54.6% .245 262.881);
|
|
12
|
+
--color-gray-100: oklch(96.7% .003 264.542);
|
|
13
|
+
--color-gray-200: oklch(92.8% .006 264.531);
|
|
14
|
+
--color-gray-300: oklch(87.2% .01 258.338);
|
|
15
|
+
--color-gray-400: oklch(70.7% .022 261.325);
|
|
16
|
+
--color-gray-600: oklch(44.6% .03 256.802);
|
|
17
|
+
--color-gray-800: oklch(27.8% .033 256.848);
|
|
18
|
+
--color-gray-900: oklch(21% .034 264.665);
|
|
11
19
|
--color-black: #000;
|
|
12
20
|
--color-white: #fff;
|
|
13
21
|
--spacing: .25rem;
|
|
@@ -629,6 +637,9 @@
|
|
|
629
637
|
.min-h-16 {
|
|
630
638
|
min-height: calc(var(--spacing) * 16);
|
|
631
639
|
}
|
|
640
|
+
.min-h-20 {
|
|
641
|
+
min-height: calc(var(--spacing) * 20);
|
|
642
|
+
}
|
|
632
643
|
.min-h-screen {
|
|
633
644
|
min-height: 100vh;
|
|
634
645
|
}
|
|
@@ -653,9 +664,15 @@
|
|
|
653
664
|
.w-15 {
|
|
654
665
|
width: calc(var(--spacing) * 15);
|
|
655
666
|
}
|
|
667
|
+
.w-20 {
|
|
668
|
+
width: calc(var(--spacing) * 20);
|
|
669
|
+
}
|
|
656
670
|
.w-25 {
|
|
657
671
|
width: calc(var(--spacing) * 25);
|
|
658
672
|
}
|
|
673
|
+
.w-28 {
|
|
674
|
+
width: calc(var(--spacing) * 28);
|
|
675
|
+
}
|
|
659
676
|
.w-48 {
|
|
660
677
|
width: calc(var(--spacing) * 48);
|
|
661
678
|
}
|
|
@@ -1127,6 +1144,9 @@
|
|
|
1127
1144
|
.border-current {
|
|
1128
1145
|
border-color: currentcolor;
|
|
1129
1146
|
}
|
|
1147
|
+
.border-gray-200 {
|
|
1148
|
+
border-color: var(--color-gray-200);
|
|
1149
|
+
}
|
|
1130
1150
|
.border-input {
|
|
1131
1151
|
border-color: var(--input);
|
|
1132
1152
|
}
|
|
@@ -1202,6 +1222,9 @@
|
|
|
1202
1222
|
.bg-transparent {
|
|
1203
1223
|
background-color: transparent;
|
|
1204
1224
|
}
|
|
1225
|
+
.bg-white {
|
|
1226
|
+
background-color: var(--color-white);
|
|
1227
|
+
}
|
|
1205
1228
|
.fill-primary {
|
|
1206
1229
|
fill: var(--primary);
|
|
1207
1230
|
}
|
|
@@ -1431,6 +1454,9 @@
|
|
|
1431
1454
|
.text-foreground {
|
|
1432
1455
|
color: var(--foreground);
|
|
1433
1456
|
}
|
|
1457
|
+
.text-gray-800 {
|
|
1458
|
+
color: var(--color-gray-800);
|
|
1459
|
+
}
|
|
1434
1460
|
.text-green-400 {
|
|
1435
1461
|
color: var(--color-green-400);
|
|
1436
1462
|
}
|
|
@@ -1461,6 +1487,9 @@
|
|
|
1461
1487
|
.lowercase {
|
|
1462
1488
|
text-transform: lowercase;
|
|
1463
1489
|
}
|
|
1490
|
+
.italic {
|
|
1491
|
+
font-style: italic;
|
|
1492
|
+
}
|
|
1464
1493
|
.underline {
|
|
1465
1494
|
text-decoration-line: underline;
|
|
1466
1495
|
}
|
|
@@ -1534,6 +1563,10 @@
|
|
|
1534
1563
|
outline-style: var(--tw-outline-style);
|
|
1535
1564
|
outline-width: 1px;
|
|
1536
1565
|
}
|
|
1566
|
+
.blur {
|
|
1567
|
+
--tw-blur: blur(8px);
|
|
1568
|
+
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
|
1569
|
+
}
|
|
1537
1570
|
.filter {
|
|
1538
1571
|
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
|
1539
1572
|
}
|
|
@@ -2644,6 +2677,192 @@
|
|
|
2644
2677
|
background-color: color-mix(in oklab, var(--input) 80%, transparent);
|
|
2645
2678
|
}
|
|
2646
2679
|
}
|
|
2680
|
+
.\[\&_\.tiptap\]\:outline-none .tiptap {
|
|
2681
|
+
--tw-outline-style: none;
|
|
2682
|
+
outline-style: none;
|
|
2683
|
+
}
|
|
2684
|
+
.\[\&_\.tiptap_a\]\:text-blue-600 .tiptap a {
|
|
2685
|
+
color: var(--color-blue-600);
|
|
2686
|
+
}
|
|
2687
|
+
.\[\&_\.tiptap_a\]\:underline .tiptap a {
|
|
2688
|
+
text-decoration-line: underline;
|
|
2689
|
+
}
|
|
2690
|
+
.\[\&_\.tiptap_a\]\:underline-offset-2 .tiptap a {
|
|
2691
|
+
text-underline-offset: 2px;
|
|
2692
|
+
}
|
|
2693
|
+
.\[\&_\.tiptap_blockquote\]\:my-2 .tiptap blockquote {
|
|
2694
|
+
margin-block: calc(var(--spacing) * 2);
|
|
2695
|
+
}
|
|
2696
|
+
.\[\&_\.tiptap_blockquote\]\:border-l-2 .tiptap blockquote {
|
|
2697
|
+
border-left-style: var(--tw-border-style);
|
|
2698
|
+
border-left-width: 2px;
|
|
2699
|
+
}
|
|
2700
|
+
.\[\&_\.tiptap_blockquote\]\:border-gray-300 .tiptap blockquote {
|
|
2701
|
+
border-color: var(--color-gray-300);
|
|
2702
|
+
}
|
|
2703
|
+
.\[\&_\.tiptap_blockquote\]\:pl-3 .tiptap blockquote {
|
|
2704
|
+
padding-left: calc(var(--spacing) * 3);
|
|
2705
|
+
}
|
|
2706
|
+
.\[\&_\.tiptap_blockquote\]\:text-gray-600 .tiptap blockquote {
|
|
2707
|
+
color: var(--color-gray-600);
|
|
2708
|
+
}
|
|
2709
|
+
.\[\&_\.tiptap_blockquote\]\:italic .tiptap blockquote {
|
|
2710
|
+
font-style: italic;
|
|
2711
|
+
}
|
|
2712
|
+
.\[\&_\.tiptap_code\]\:rounded .tiptap code {
|
|
2713
|
+
border-radius: .25rem;
|
|
2714
|
+
}
|
|
2715
|
+
.\[\&_\.tiptap_code\]\:bg-gray-100 .tiptap code {
|
|
2716
|
+
background-color: var(--color-gray-100);
|
|
2717
|
+
}
|
|
2718
|
+
.\[\&_\.tiptap_code\]\:px-1 .tiptap code {
|
|
2719
|
+
padding-inline: var(--spacing);
|
|
2720
|
+
}
|
|
2721
|
+
.\[\&_\.tiptap_code\]\:py-0\.5 .tiptap code {
|
|
2722
|
+
padding-block: calc(var(--spacing) * 0.5);
|
|
2723
|
+
}
|
|
2724
|
+
.\[\&_\.tiptap_code\]\:font-mono .tiptap code {
|
|
2725
|
+
font-family: var(--font-geist-mono);
|
|
2726
|
+
}
|
|
2727
|
+
.\[\&_\.tiptap_code\]\:text-\[0\.85em\] .tiptap code {
|
|
2728
|
+
font-size: 0.85em;
|
|
2729
|
+
}
|
|
2730
|
+
.\[\&_\.tiptap_h1\]\:mt-6 .tiptap h1 {
|
|
2731
|
+
margin-top: calc(var(--spacing) * 6);
|
|
2732
|
+
}
|
|
2733
|
+
.\[\&_\.tiptap_h1\]\:mb-2 .tiptap h1 {
|
|
2734
|
+
margin-bottom: calc(var(--spacing) * 2);
|
|
2735
|
+
}
|
|
2736
|
+
.\[\&_\.tiptap_h1\]\:text-2xl .tiptap h1 {
|
|
2737
|
+
font-size: var(--text-2xl);
|
|
2738
|
+
line-height: var(--tw-leading, var(--text-2xl--line-height));
|
|
2739
|
+
}
|
|
2740
|
+
.\[\&_\.tiptap_h1\]\:font-bold .tiptap h1 {
|
|
2741
|
+
--tw-font-weight: var(--font-weight-bold);
|
|
2742
|
+
font-weight: var(--font-weight-bold);
|
|
2743
|
+
}
|
|
2744
|
+
.\[\&_\.tiptap_h2\]\:mt-5 .tiptap h2 {
|
|
2745
|
+
margin-top: calc(var(--spacing) * 5);
|
|
2746
|
+
}
|
|
2747
|
+
.\[\&_\.tiptap_h2\]\:mb-2 .tiptap h2 {
|
|
2748
|
+
margin-bottom: calc(var(--spacing) * 2);
|
|
2749
|
+
}
|
|
2750
|
+
.\[\&_\.tiptap_h2\]\:text-xl .tiptap h2 {
|
|
2751
|
+
font-size: var(--text-xl);
|
|
2752
|
+
line-height: var(--tw-leading, var(--text-xl--line-height));
|
|
2753
|
+
}
|
|
2754
|
+
.\[\&_\.tiptap_h2\]\:font-bold .tiptap h2 {
|
|
2755
|
+
--tw-font-weight: var(--font-weight-bold);
|
|
2756
|
+
font-weight: var(--font-weight-bold);
|
|
2757
|
+
}
|
|
2758
|
+
.\[\&_\.tiptap_h3\]\:mt-4 .tiptap h3 {
|
|
2759
|
+
margin-top: calc(var(--spacing) * 4);
|
|
2760
|
+
}
|
|
2761
|
+
.\[\&_\.tiptap_h3\]\:mb-2 .tiptap h3 {
|
|
2762
|
+
margin-bottom: calc(var(--spacing) * 2);
|
|
2763
|
+
}
|
|
2764
|
+
.\[\&_\.tiptap_h3\]\:text-lg .tiptap h3 {
|
|
2765
|
+
font-size: var(--text-lg);
|
|
2766
|
+
line-height: var(--tw-leading, var(--text-lg--line-height));
|
|
2767
|
+
}
|
|
2768
|
+
.\[\&_\.tiptap_h3\]\:font-semibold .tiptap h3 {
|
|
2769
|
+
--tw-font-weight: var(--font-weight-semibold);
|
|
2770
|
+
font-weight: var(--font-weight-semibold);
|
|
2771
|
+
}
|
|
2772
|
+
.\[\&_\.tiptap_h4\]\:mt-3 .tiptap h4 {
|
|
2773
|
+
margin-top: calc(var(--spacing) * 3);
|
|
2774
|
+
}
|
|
2775
|
+
.\[\&_\.tiptap_h4\]\:mb-1 .tiptap h4 {
|
|
2776
|
+
margin-bottom: var(--spacing);
|
|
2777
|
+
}
|
|
2778
|
+
.\[\&_\.tiptap_h4\]\:text-base .tiptap h4 {
|
|
2779
|
+
font-size: var(--text-base);
|
|
2780
|
+
line-height: var(--tw-leading, var(--text-base--line-height));
|
|
2781
|
+
}
|
|
2782
|
+
.\[\&_\.tiptap_h4\]\:font-semibold .tiptap h4 {
|
|
2783
|
+
--tw-font-weight: var(--font-weight-semibold);
|
|
2784
|
+
font-weight: var(--font-weight-semibold);
|
|
2785
|
+
}
|
|
2786
|
+
.\[\&_\.tiptap_hr\]\:my-4 .tiptap hr {
|
|
2787
|
+
margin-block: calc(var(--spacing) * 4);
|
|
2788
|
+
}
|
|
2789
|
+
.\[\&_\.tiptap_hr\]\:border-gray-200 .tiptap hr {
|
|
2790
|
+
border-color: var(--color-gray-200);
|
|
2791
|
+
}
|
|
2792
|
+
.\[\&_\.tiptap_li\]\:my-1 .tiptap li {
|
|
2793
|
+
margin-block: var(--spacing);
|
|
2794
|
+
}
|
|
2795
|
+
.\[\&_\.tiptap_ol\]\:my-2 .tiptap ol {
|
|
2796
|
+
margin-block: calc(var(--spacing) * 2);
|
|
2797
|
+
}
|
|
2798
|
+
.\[\&_\.tiptap_ol\]\:list-decimal .tiptap ol {
|
|
2799
|
+
list-style-type: decimal;
|
|
2800
|
+
}
|
|
2801
|
+
.\[\&_\.tiptap_ol\]\:pl-5 .tiptap ol {
|
|
2802
|
+
padding-left: calc(var(--spacing) * 5);
|
|
2803
|
+
}
|
|
2804
|
+
.\[\&_\.tiptap_p\.is-editor-empty\:first-child\:\:before\]\:pointer-events-none .tiptap p.is-editor-empty:first-child::before {
|
|
2805
|
+
pointer-events: none;
|
|
2806
|
+
}
|
|
2807
|
+
.\[\&_\.tiptap_p\.is-editor-empty\:first-child\:\:before\]\:float-left .tiptap p.is-editor-empty:first-child::before {
|
|
2808
|
+
float: left;
|
|
2809
|
+
}
|
|
2810
|
+
.\[\&_\.tiptap_p\.is-editor-empty\:first-child\:\:before\]\:h-0 .tiptap p.is-editor-empty:first-child::before {
|
|
2811
|
+
height: 0px;
|
|
2812
|
+
}
|
|
2813
|
+
.\[\&_\.tiptap_p\.is-editor-empty\:first-child\:\:before\]\:text-gray-400 .tiptap p.is-editor-empty:first-child::before {
|
|
2814
|
+
color: var(--color-gray-400);
|
|
2815
|
+
}
|
|
2816
|
+
.\[\&_\.tiptap_p\.is-editor-empty\:first-child\:\:before\]\:content-\[attr\(data-placeholder\)\] .tiptap p.is-editor-empty:first-child::before {
|
|
2817
|
+
--tw-content: attr(data-placeholder);
|
|
2818
|
+
content: var(--tw-content);
|
|
2819
|
+
}
|
|
2820
|
+
.\[\&_\.tiptap_pre\]\:my-2 .tiptap pre {
|
|
2821
|
+
margin-block: calc(var(--spacing) * 2);
|
|
2822
|
+
}
|
|
2823
|
+
.\[\&_\.tiptap_pre\]\:overflow-x-auto .tiptap pre {
|
|
2824
|
+
overflow-x: auto;
|
|
2825
|
+
}
|
|
2826
|
+
.\[\&_\.tiptap_pre\]\:rounded .tiptap pre {
|
|
2827
|
+
border-radius: .25rem;
|
|
2828
|
+
}
|
|
2829
|
+
.\[\&_\.tiptap_pre\]\:bg-gray-900 .tiptap pre {
|
|
2830
|
+
background-color: var(--color-gray-900);
|
|
2831
|
+
}
|
|
2832
|
+
.\[\&_\.tiptap_pre\]\:p-3 .tiptap pre {
|
|
2833
|
+
padding: calc(var(--spacing) * 3);
|
|
2834
|
+
}
|
|
2835
|
+
.\[\&_\.tiptap_pre\]\:font-mono .tiptap pre {
|
|
2836
|
+
font-family: var(--font-geist-mono);
|
|
2837
|
+
}
|
|
2838
|
+
.\[\&_\.tiptap_pre\]\:text-sm .tiptap pre {
|
|
2839
|
+
font-size: var(--text-sm);
|
|
2840
|
+
line-height: var(--tw-leading, var(--text-sm--line-height));
|
|
2841
|
+
}
|
|
2842
|
+
.\[\&_\.tiptap_pre\]\:text-gray-100 .tiptap pre {
|
|
2843
|
+
color: var(--color-gray-100);
|
|
2844
|
+
}
|
|
2845
|
+
.\[\&_\.tiptap_pre_code\]\:bg-transparent .tiptap pre code {
|
|
2846
|
+
background-color: transparent;
|
|
2847
|
+
}
|
|
2848
|
+
.\[\&_\.tiptap_pre_code\]\:p-0 .tiptap pre code {
|
|
2849
|
+
padding: 0px;
|
|
2850
|
+
}
|
|
2851
|
+
.\[\&_\.tiptap_pre_code\]\:text-inherit .tiptap pre code {
|
|
2852
|
+
color: inherit;
|
|
2853
|
+
}
|
|
2854
|
+
.\[\&_\.tiptap_ul\]\:my-2 .tiptap ul {
|
|
2855
|
+
margin-block: calc(var(--spacing) * 2);
|
|
2856
|
+
}
|
|
2857
|
+
.\[\&_\.tiptap_ul\]\:list-disc .tiptap ul {
|
|
2858
|
+
list-style-type: disc;
|
|
2859
|
+
}
|
|
2860
|
+
.\[\&_\.tiptap_ul\]\:pl-5 .tiptap ul {
|
|
2861
|
+
padding-left: calc(var(--spacing) * 5);
|
|
2862
|
+
}
|
|
2863
|
+
.\[\&_\.tiptap\>\*\:first-child\]\:mt-0 .tiptap > :first-child {
|
|
2864
|
+
margin-top: 0px;
|
|
2865
|
+
}
|
|
2647
2866
|
.\[\&_svg\]\:pointer-events-none svg {
|
|
2648
2867
|
pointer-events: none;
|
|
2649
2868
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbpark/ui-kit",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.1.0",
|
|
4
4
|
"description": "Modern React UI component library built with TypeScript, Tailwind CSS, and Radix UI. Featuring atoms, molecules, organisms and layout templates for building beautiful interfaces.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -143,6 +143,11 @@
|
|
|
143
143
|
"@radix-ui/react-slider": "^1.4.7",
|
|
144
144
|
"@radix-ui/react-slot": "^1.3.3",
|
|
145
145
|
"@radix-ui/react-switch": "^1.3.7",
|
|
146
|
+
"@tiptap/core": "^3.30.1",
|
|
147
|
+
"@tiptap/extension-placeholder": "^3.30.1",
|
|
148
|
+
"@tiptap/extension-text-style": "^3.30.1",
|
|
149
|
+
"@tiptap/react": "^3.30.1",
|
|
150
|
+
"@tiptap/starter-kit": "^3.30.1",
|
|
146
151
|
"class-variance-authority": "^0.7.1",
|
|
147
152
|
"clsx": "^2.1.1",
|
|
148
153
|
"date-fns": "^4.4.0",
|