@jbpark/ui-kit 6.2.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/Tag.d.mts +11 -10
- package/dist/Tag.d.mts.map +1 -1
- package/dist/Tag.mjs +5 -21
- package/dist/Tag.mjs.map +1 -1
- 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 +256 -54
- package/package.json +6 -1
- package/dist/lib/colors.mjs +0 -28
- package/dist/lib/colors.mjs.map +0 -1
package/dist/Tag.d.mts
CHANGED
|
@@ -6,18 +6,19 @@ type NativeSpanProps = React$1.ComponentProps<'span'> & {
|
|
|
6
6
|
};
|
|
7
7
|
interface Props extends Omit<NativeSpanProps, 'variant' | 'color'> {
|
|
8
8
|
/**
|
|
9
|
-
* Fill style, aligned with `Button`'s vocabulary.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @remarks `'default'` will be removed in a future major.
|
|
9
|
+
* Fill style, aligned with `Button`'s vocabulary (#320). The pre-7.0
|
|
10
|
+
* `'default'` spelling was removed — use `'filled'`, which renders
|
|
11
|
+
* identically.
|
|
14
12
|
*/
|
|
15
|
-
variant?: 'filled' | 'outlined'
|
|
13
|
+
variant?: 'filled' | 'outlined';
|
|
16
14
|
/**
|
|
17
|
-
* Colour
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
15
|
+
* Colour. Every value — the semantic states (`primary`/`success`/`warning`/
|
|
16
|
+
* `danger`) as well as the palette shared with `Button` (`blue`, `red`,
|
|
17
|
+
* `gold`, …) — resolves through the same `data-color` + `--tag-*` system
|
|
18
|
+
* (#320), so any of them can be re-themed the same way.
|
|
19
|
+
*
|
|
20
|
+
* `success`/`warning` have no `Button` counterpart on purpose: a Tag marks
|
|
21
|
+
* state, which is why antd's Tag also carries them while its Button does not.
|
|
21
22
|
*/
|
|
22
23
|
color?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | PresetColor;
|
|
23
24
|
}
|
package/dist/Tag.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tag.d.mts","names":[],"sources":["../src/components/atoms/tag.tsx"],"mappings":";;;KAYK,kBAAkB,QAAM;EAC3B;;UAGe,cAAc,KAAK
|
|
1
|
+
{"version":3,"file":"Tag.d.mts","names":[],"sources":["../src/components/atoms/tag.tsx"],"mappings":";;;KAYK,kBAAkB,QAAM;EAC3B;;UAGe,cAAc,KAAK;;;;;;EAMlC;;;;;;;;;;EAUA,mEAC6D;;cA+BzD,QAAO,WAAA,SAAA,OAAA,SAAA,aAAA,SAOV,UAAK,QAAA,IAAA"}
|
package/dist/Tag.mjs
CHANGED
|
@@ -2,39 +2,23 @@
|
|
|
2
2
|
import { cn } from "./utils.mjs";
|
|
3
3
|
import { useConfig } from "./providers/config/context.mjs";
|
|
4
4
|
import { INTERACTIVE_CHASSIS } from "./lib/chassis.mjs";
|
|
5
|
-
import { isPresetColor } from "./lib/colors.mjs";
|
|
6
5
|
import "react";
|
|
7
6
|
import { Slot } from "@radix-ui/react-slot";
|
|
8
7
|
import { jsx } from "react/jsx-runtime";
|
|
9
8
|
//#region src/components/atoms/tag.tsx
|
|
10
9
|
const TAG_BASE = cn(INTERACTIVE_CHASSIS, "border w-fit whitespace-nowrap overflow-hidden", "text-xs font-medium gap-1 transition-[color,box-shadow]", "[&>svg]:size-3 [&>svg]:pointer-events-none", "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground");
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
primary: "border-transparent bg-primary/10 text-primary",
|
|
14
|
-
success: "border-transparent bg-green-500/10 text-green-600 dark:text-green-400",
|
|
15
|
-
warning: "border-transparent bg-yellow-500/10 text-yellow-600 dark:text-yellow-400",
|
|
16
|
-
danger: "border-transparent bg-destructive/10 text-destructive"
|
|
17
|
-
};
|
|
18
|
-
const outlinedColorClasses = {
|
|
19
|
-
default: "border-border text-foreground",
|
|
20
|
-
primary: "border-primary text-primary",
|
|
21
|
-
success: "border-green-500 text-green-600 dark:text-green-400",
|
|
22
|
-
warning: "border-yellow-500 text-yellow-600 dark:text-yellow-400",
|
|
23
|
-
danger: "border-destructive text-destructive"
|
|
24
|
-
};
|
|
25
|
-
const presetFillClasses = cn("border-transparent", "bg-[color-mix(in_oklch,var(--tag-bg),transparent_90%)]", "text-(--tag-bg)");
|
|
26
|
-
const presetOutlinedClasses = cn("border-(--tag-bg) text-(--tag-bg)");
|
|
10
|
+
const fillClasses = cn("border-transparent bg-(--tag-tint) text-(--tag-fg)");
|
|
11
|
+
const outlinedClasses = cn("border-(--tag-bg) text-(--tag-fg)");
|
|
27
12
|
const Tag = ({ className, variant, color, asChild = false, children, ...props }) => {
|
|
28
13
|
const { defaultProps } = useConfig();
|
|
29
14
|
const tagDefaults = defaultProps?.tag;
|
|
30
15
|
const resolvedVariant = variant ?? tagDefaults?.variant ?? "filled";
|
|
31
16
|
const resolvedColor = color ?? tagDefaults?.color ?? "default";
|
|
32
|
-
const isOutlined = resolvedVariant === "outlined";
|
|
33
|
-
const preset = isPresetColor(resolvedColor);
|
|
34
17
|
return /* @__PURE__ */ jsx(asChild ? Slot : "span", {
|
|
35
18
|
"data-slot": "badge",
|
|
36
|
-
"data-color":
|
|
37
|
-
|
|
19
|
+
"data-color": resolvedColor,
|
|
20
|
+
"data-variant": resolvedVariant,
|
|
21
|
+
className: cn(TAG_BASE, "rounded-full px-2.5 py-1", "text-xs font-medium", resolvedVariant === "outlined" ? outlinedClasses : fillClasses, className),
|
|
38
22
|
...props,
|
|
39
23
|
children
|
|
40
24
|
});
|
package/dist/Tag.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tag.mjs","names":[],"sources":["../src/components/atoms/tag.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { INTERACTIVE_CHASSIS } from '../../lib/chassis';\nimport { type PresetColor
|
|
1
|
+
{"version":3,"file":"Tag.mjs","names":[],"sources":["../src/components/atoms/tag.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { INTERACTIVE_CHASSIS } from '../../lib/chassis';\nimport { type PresetColor } from '../../lib/colors';\n\ntype NativeSpanProps = React.ComponentProps<'span'> & {\n asChild?: boolean;\n};\n\nexport interface Props extends Omit<NativeSpanProps, 'variant' | 'color'> {\n /**\n * Fill style, aligned with `Button`'s vocabulary (#320). The pre-7.0\n * `'default'` spelling was removed — use `'filled'`, which renders\n * identically.\n */\n variant?: 'filled' | 'outlined';\n /**\n * Colour. Every value — the semantic states (`primary`/`success`/`warning`/\n * `danger`) as well as the palette shared with `Button` (`blue`, `red`,\n * `gold`, …) — resolves through the same `data-color` + `--tag-*` system\n * (#320), so any of them can be re-themed the same way.\n *\n * `success`/`warning` have no `Button` counterpart on purpose: a Tag marks\n * state, which is why antd's Tag also carries them while its Button does not.\n */\n color?:\n 'default' | 'primary' | 'success' | 'warning' | 'danger' | PresetColor;\n}\n\n// Base absorbed from core/badge's cva base + its `outline` variant, which Tag\n// always rendered as (#278 ③ / #294 Phase 4). The shared focus/aria/centering\n// set lives in INTERACTIVE_CHASSIS; a Tag adds badge geometry and its svg\n// sizing but — unlike Button — no `disabled:*` (a Tag is not disableable). The\n// rounded/padding leftovers are overridden by the atom classes below exactly as\n// before, so the rendered output is unchanged (verified against a pre-refactor\n// render matrix).\nconst TAG_BASE = cn(\n INTERACTIVE_CHASSIS,\n 'border w-fit whitespace-nowrap overflow-hidden',\n 'text-xs font-medium gap-1 transition-[color,box-shadow]',\n '[&>svg]:size-3 [&>svg]:pointer-events-none',\n 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',\n);\n\n// Every colour — semantic states and shared presets alike — resolves from the\n// `--tag-*` custom properties that `globals.css` sets per `data-color` (#320).\n// Before 7.0 only the presets took this path while the states carried bespoke\n// Tailwind classes, which meant `[data-color]` hooks and `--tag-*` overrides\n// worked on some colours but silently not on others.\n//\n// --tag-bg the hue; the border in `outlined`\n// --tag-fg text colour (defaults to --tag-bg)\n// --tag-tint the fill behind `filled` (defaults to a 10% --tag-bg wash)\nconst fillClasses = cn('border-transparent bg-(--tag-tint) text-(--tag-fg)');\n\nconst outlinedClasses = cn('border-(--tag-bg) text-(--tag-fg)');\n\nconst Tag = ({\n className,\n variant,\n color,\n asChild = false,\n children,\n ...props\n}: Props) => {\n const { defaultProps } = useConfig();\n const tagDefaults = defaultProps?.tag as\n Partial<Pick<Props, 'variant' | 'color'>> | undefined;\n // An explicit prop wins over a `Config` default, which wins over the built-in\n // — the same resolution order `Button` uses.\n const resolvedVariant = variant ?? tagDefaults?.variant ?? 'filled';\n const resolvedColor = color ?? tagDefaults?.color ?? 'default';\n const isOutlined = resolvedVariant === 'outlined';\n const Comp = asChild ? Slot : 'span';\n\n return (\n <Comp\n data-slot=\"badge\"\n // Emitted for every colour, not just the presets, so consumers can hook\n // `[data-color]` / `[data-variant]` uniformly. `data-variant` is what\n // lets `globals.css` give `default` a different text colour when\n // outlined without reintroducing a second class path here.\n data-color={resolvedColor}\n data-variant={resolvedVariant}\n className={cn(\n TAG_BASE,\n 'rounded-full px-2.5 py-1',\n 'text-xs font-medium',\n isOutlined ? outlinedClasses : fillClasses,\n className,\n //\n )}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n\nexport default Tag;\n"],"mappings":";;;;;;;;AA2CA,MAAM,WAAW,GACf,qBACA,kDACA,2DACA,8CACA,wEACF;AAWA,MAAM,cAAc,GAAG,oDAAoD;AAE3E,MAAM,kBAAkB,GAAG,mCAAmC;AAE9D,MAAM,OAAO,EACX,WACA,SACA,OACA,UAAU,OACV,UACA,GAAG,YACQ;CACX,MAAM,EAAE,iBAAiB,UAAU;CACnC,MAAM,cAAc,cAAc;CAIlC,MAAM,kBAAkB,WAAW,aAAa,WAAW;CAC3D,MAAM,gBAAgB,SAAS,aAAa,SAAS;CAIrD,OACE,oBAHW,UAAU,OAAO,QAG5B;EACE,aAAU;EAKV,cAAY;EACZ,gBAAc;EACd,WAAW,GACT,UACA,4BACA,uBAfa,oBAAoB,aAgBpB,kBAAkB,aAC/B,SAEF;EACA,GAAI;EAEH;CACG,CAAA;AAEV"}
|
|
@@ -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":";;;;;;;;;;;AA6BA,MAAM,oBAAoB;CACxB;EAAE,OAAO;EAAM,OAAO;CAAO;CAC7B;EAAE,OAAO;EAAM,OAAO;CAAO;CAC7B;EAAE,OAAO;EAAM,OAAO;CAAO;CAC7B;EAAE,OAAO;EAAM,OAAO;CAAO;CAC7B;EAAE,OAAO;EAAM,OAAO;CAAO;CAC7B;EAAE,OAAO;EAAM,OAAO;CAAO;AAC/B;AAEA,MAAM,iBAAiB;CAAC;CAAG;CAAG;CAAG;AAAC;AAElC,MAAM,kBAAkB,CACtB;CAAE,OAAO;CAAa,OAAO;AAAY,GACzC,GAAG,eAAe,KAAI,WAAU;CAC9B,OAAO,WAAW;CAClB,OAAO,OAAO,KAAK;AACrB,EAAE,CACJ;AAKA,MAAM,eAAe,EAAE,aAAiC;CACtD,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,MAAM,WAAW,SAAS,EAAE;CAEnC,MAAM,cAAc;EAClB,MAAM,OAAO,KAAK,KAAK;EAEvB,IAAI,MACF,OACG,MAAM,CAAC,CACP,MAAM,CAAC,CACP,gBAAgB,MAAM,CAAC,CACvB,QAAQ,EAAE,MAAM,KAAK,CAAC,CAAC,CACvB,IAAI;OAEP,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI;EAEzC,QAAQ,KAAK;CACf;CAEA,OACE,oBAAC,SAAD;EACE,WAAU;EACJ;EACN,eAAc,SAAQ;GACpB,IAAI,MACF,QAAQ,OAAO,cAAc,MAAM,CAAC,CAAC,QAAQ,EAAE;GAEjD,QAAQ,IAAI;EACd;EACA,SACE,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,OAAD;IACE,OAAO;IACP,aAAY;IACZ,WAAU;IACV,WAAU,MAAK,QAAQ,EAAE,OAAO,KAAK;IACrC,YAAW,MAAK;KACd,IAAI,EAAE,QAAQ,SAAS;MACrB,EAAE,eAAe;MACjB,MAAM;KACR;IACF;GACD,CAAA,GACD,oBAAC,QAAD;IAAQ,MAAK;IAAQ,SAAS;IAAO,UAAA;GAE7B,CAAA,CACL;;EAGP,UAAA,oBAAC,eAAD;GACE,MAAM,oBAACA,MAAD,CAAW,CAAA;GACjB,cAAW;GACX,QAAQ,OAAO,SAAS,MAAM;EAC/B,CAAA;CACM,CAAA;AAEb;AAEA,MAAa,2BAGT;CACF,OAAM,WACJ,oBAAC,eAAD;EAEE,MAAM,oBAAC,OAAD,CAAQ,CAAA;EACd,cAAW;EACX,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK;EAC7B,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI;CAClD,GALK,MAKL;CAEH,OAAM,WACJ,oBAAC,eAAD;EAEE,MAAM,oBAAC,OAAD,CAAQ,CAAA;EACd,cAAW;EACX,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK;EAC7B,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI;CAClD,GALK,MAKL;CAEH,UAAS,WAAU;EACjB,MAAM,cAAc,eAAe,MAAK,UACtC,OAAO,SAAS,WAAW,EAAE,MAAM,CAAC,CACtC;EAEA,OACE,oBAAC,QAAD;GAEE,WAAU;GACV,aAAY;GACZ,SAAS;GACT,OAAO,cAAc,OAAO,WAAW,IAAI;GAI3C,WAAU,UACR,UAAU,cACN,OAAO,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,IAClC,OACG,MAAM,CAAC,CACP,WAAW,EAAE,OAAO,OAAO,KAAK,EAAmB,CAAC,CAAC,CACrD,IAAI;EAEd,GAhBK,SAgBL;CAEL;CACA,OAAM,WACJ,oBAAC,eAAD;EAEE,MAAM,oBAAC,MAAD,CAAO,CAAA;EACb,cAAW;EACX,QAAQ,OAAO,SAAS,MAAM;EAC9B,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI;CACxD,GALK,MAKL;CAEH,SAAQ,WACN,oBAAC,eAAD;EAEE,MAAM,oBAAC,QAAD,CAAS,CAAA;EACf,cAAW;EACX,QAAQ,OAAO,SAAS,QAAQ;EAChC,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI;CAC1D,GALK,QAKL;CAEH,YAAW,WACT,oBAAC,eAAD;EAEE,MAAM,oBAAC,WAAD,CAAY,CAAA;EAClB,cAAW;EACX,QAAQ,OAAO,SAAS,WAAW;EACnC,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC,IAAI;CAC7D,GALK,WAKL;CAEH,SAAQ,WACN,oBAAC,eAAD;EAEE,MAAM,oBAAC,eAAD,CAAgB,CAAA;EACtB,cAAW;EACX,QAAQ,OAAO,SAAS,QAAQ;EAChC,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI;CAC1D,GALK,QAKL;CAEH,OAAM,WACJ,oBAAC,eAAD;EAEE,MAAM,oBAAC,MAAD,CAAO,CAAA;EACb,cAAW;EACX,QAAQ,OAAO,SAAS,MAAM;EAC9B,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI;CACxD,GALK,MAKL;CAEH,aAAY,WACV,oBAAC,eAAD;EAEE,MAAM,oBAAC,MAAD,CAAO,CAAA;EACb,cAAW;EACX,QAAQ,OAAO,SAAS,YAAY;EACpC,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI;CAC9D,GALK,YAKL;CAEH,cAAa,WACX,oBAAC,eAAD;EAEE,MAAM,oBAAC,aAAD,CAAc,CAAA;EACpB,cAAW;EACX,QAAQ,OAAO,SAAS,aAAa;EACrC,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI;CAC/D,GALK,aAKL;CAEH,aAAY,WACV,oBAAC,eAAD;EAEE,MAAM,oBAAC,OAAD,CAAQ,CAAA;EACd,cAAW;EACX,QAAQ,OAAO,SAAS,YAAY;EACpC,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI;CAC9D,GALK,YAKL;CAEH,YAAW,WACT,oBAAC,eAAD;EAEE,MAAM,oBAAC,OAAD,CAAQ,CAAA;EACd,cAAW;EACX,QAAQ,OAAO,SAAS,WAAW;EACnC,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC,IAAI;CAC7D,GALK,WAKL;CAEH,iBAAgB,WACd,oBAAC,eAAD;EAEE,MAAM,oBAAC,OAAD,CAAQ,CAAA;EACd,cAAW;EACX,eAAe,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI;CAC/D,GAJK,gBAIL;CAEH,OAAM,WAAU,oBAAC,aAAD,EAAgC,OAAS,GAAxB,MAAwB;CACzD,WAAU,WACR,oBAAC,QAAD;EAEE,WAAU;EACV,aAAY;EACZ,SAAS;EACT,OAAO,OAAO,cAAc,WAAW,CAAC,CAAC,YAAY,KAAA;EAErD,WAAU,UAAS,OAAO,MAAM,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,IAAI;CAC1D,GAPK,UAOL;CAEH,QAAO,WACL,oBAAC,aAAD;EAEE,OAAO,OAAO,cAAc,WAAW,CAAC,CAAC,SAAS;EAOlD,WAAU,UAAS,OAAO,MAAM,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,IAAI;CACvD,GATK,OASL;AAEL;AAEA,MAAa,0BAA2C;CACtD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF"}
|
|
@@ -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
|
@@ -6,12 +6,16 @@
|
|
|
6
6
|
--font-mono: var(--font-geist-mono);
|
|
7
7
|
--color-red-400: oklch(70.4% .191 22.216);
|
|
8
8
|
--color-yellow-400: oklch(85.2% .199 91.936);
|
|
9
|
-
--color-yellow-500: oklch(79.5% .184 86.047);
|
|
10
|
-
--color-yellow-600: oklch(68.1% .162 75.834);
|
|
11
9
|
--color-green-400: oklch(79.2% .209 151.711);
|
|
12
|
-
--color-green-500: oklch(72.3% .219 149.579);
|
|
13
|
-
--color-green-600: oklch(62.7% .194 149.214);
|
|
14
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);
|
|
15
19
|
--color-black: #000;
|
|
16
20
|
--color-white: #fff;
|
|
17
21
|
--spacing: .25rem;
|
|
@@ -149,6 +153,41 @@
|
|
|
149
153
|
[data-slot="button"][data-color="gold"] {
|
|
150
154
|
--btn-bg: #f59e0b;
|
|
151
155
|
}
|
|
156
|
+
[data-slot="badge"][data-color] {
|
|
157
|
+
--tag-fg: var(--tag-bg);
|
|
158
|
+
--tag-tint: var(--tag-bg);
|
|
159
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
160
|
+
--tag-tint: color-mix(in oklab, var(--tag-bg), transparent 90%);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
[data-slot="badge"][data-color="default"] {
|
|
164
|
+
--tag-bg: var(--border);
|
|
165
|
+
--tag-tint: var(--muted);
|
|
166
|
+
--tag-fg: var(--muted-foreground);
|
|
167
|
+
}
|
|
168
|
+
[data-slot="badge"][data-color="default"][data-variant="outlined"] {
|
|
169
|
+
--tag-fg: var(--foreground);
|
|
170
|
+
}
|
|
171
|
+
[data-slot="badge"][data-color="primary"] {
|
|
172
|
+
--tag-bg: var(--primary);
|
|
173
|
+
}
|
|
174
|
+
[data-slot="badge"][data-color="danger"] {
|
|
175
|
+
--tag-bg: var(--destructive);
|
|
176
|
+
}
|
|
177
|
+
[data-slot="badge"][data-color="success"] {
|
|
178
|
+
--tag-bg: oklch(72.3% .219 149.579);
|
|
179
|
+
--tag-fg: oklch(62.7% .194 149.214);
|
|
180
|
+
}
|
|
181
|
+
[data-slot="badge"][data-color="warning"] {
|
|
182
|
+
--tag-bg: oklch(79.5% .184 86.047);
|
|
183
|
+
--tag-fg: oklch(68.1% .162 75.834);
|
|
184
|
+
}
|
|
185
|
+
:is(.dark, [data-theme="dark"]) [data-slot="badge"][data-color="success"] {
|
|
186
|
+
--tag-fg: oklch(79.2% .209 151.711);
|
|
187
|
+
}
|
|
188
|
+
:is(.dark, [data-theme="dark"]) [data-slot="badge"][data-color="warning"] {
|
|
189
|
+
--tag-fg: oklch(85.2% .199 91.936);
|
|
190
|
+
}
|
|
152
191
|
[data-slot="badge"][data-color="blue"] {
|
|
153
192
|
--tag-bg: #3b82f6;
|
|
154
193
|
}
|
|
@@ -598,6 +637,9 @@
|
|
|
598
637
|
.min-h-16 {
|
|
599
638
|
min-height: calc(var(--spacing) * 16);
|
|
600
639
|
}
|
|
640
|
+
.min-h-20 {
|
|
641
|
+
min-height: calc(var(--spacing) * 20);
|
|
642
|
+
}
|
|
601
643
|
.min-h-screen {
|
|
602
644
|
min-height: 100vh;
|
|
603
645
|
}
|
|
@@ -622,9 +664,15 @@
|
|
|
622
664
|
.w-15 {
|
|
623
665
|
width: calc(var(--spacing) * 15);
|
|
624
666
|
}
|
|
667
|
+
.w-20 {
|
|
668
|
+
width: calc(var(--spacing) * 20);
|
|
669
|
+
}
|
|
625
670
|
.w-25 {
|
|
626
671
|
width: calc(var(--spacing) * 25);
|
|
627
672
|
}
|
|
673
|
+
.w-28 {
|
|
674
|
+
width: calc(var(--spacing) * 28);
|
|
675
|
+
}
|
|
628
676
|
.w-48 {
|
|
629
677
|
width: calc(var(--spacing) * 48);
|
|
630
678
|
}
|
|
@@ -1096,11 +1144,8 @@
|
|
|
1096
1144
|
.border-current {
|
|
1097
1145
|
border-color: currentcolor;
|
|
1098
1146
|
}
|
|
1099
|
-
.border-
|
|
1100
|
-
border-color: var(--
|
|
1101
|
-
}
|
|
1102
|
-
.border-green-500 {
|
|
1103
|
-
border-color: var(--color-green-500);
|
|
1147
|
+
.border-gray-200 {
|
|
1148
|
+
border-color: var(--color-gray-200);
|
|
1104
1149
|
}
|
|
1105
1150
|
.border-input {
|
|
1106
1151
|
border-color: var(--input);
|
|
@@ -1111,17 +1156,11 @@
|
|
|
1111
1156
|
.border-transparent {
|
|
1112
1157
|
border-color: transparent;
|
|
1113
1158
|
}
|
|
1114
|
-
.border-yellow-500 {
|
|
1115
|
-
border-color: var(--color-yellow-500);
|
|
1116
|
-
}
|
|
1117
1159
|
.bg-\(--btn-bg\) {
|
|
1118
1160
|
background-color: var(--btn-bg);
|
|
1119
1161
|
}
|
|
1120
|
-
.bg-\
|
|
1121
|
-
background-color: var(--tag-
|
|
1122
|
-
@supports (color: color-mix(in lab, red, red)) {
|
|
1123
|
-
background-color: color-mix(in oklch,var(--tag-bg),transparent 90%);
|
|
1124
|
-
}
|
|
1162
|
+
.bg-\(--tag-tint\) {
|
|
1163
|
+
background-color: var(--tag-tint);
|
|
1125
1164
|
}
|
|
1126
1165
|
.bg-accent {
|
|
1127
1166
|
background-color: var(--accent);
|
|
@@ -1156,18 +1195,6 @@
|
|
|
1156
1195
|
.bg-destructive {
|
|
1157
1196
|
background-color: var(--destructive);
|
|
1158
1197
|
}
|
|
1159
|
-
.bg-destructive\/10 {
|
|
1160
|
-
background-color: var(--destructive);
|
|
1161
|
-
@supports (color: color-mix(in lab, red, red)) {
|
|
1162
|
-
background-color: color-mix(in oklab, var(--destructive) 10%, transparent);
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
.bg-green-500\/10 {
|
|
1166
|
-
background-color: color-mix(in srgb, oklch(72.3% .219 149.579) 10%, transparent);
|
|
1167
|
-
@supports (color: color-mix(in lab, red, red)) {
|
|
1168
|
-
background-color: color-mix(in oklab, var(--color-green-500) 10%, transparent);
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
1198
|
.bg-inherit {
|
|
1172
1199
|
background-color: inherit;
|
|
1173
1200
|
}
|
|
@@ -1183,12 +1210,6 @@
|
|
|
1183
1210
|
.bg-primary {
|
|
1184
1211
|
background-color: var(--primary);
|
|
1185
1212
|
}
|
|
1186
|
-
.bg-primary\/10 {
|
|
1187
|
-
background-color: var(--primary);
|
|
1188
|
-
@supports (color: color-mix(in lab, red, red)) {
|
|
1189
|
-
background-color: color-mix(in oklab, var(--primary) 10%, transparent);
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
1213
|
.bg-primary\/20 {
|
|
1193
1214
|
background-color: var(--primary);
|
|
1194
1215
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -1201,11 +1222,8 @@
|
|
|
1201
1222
|
.bg-transparent {
|
|
1202
1223
|
background-color: transparent;
|
|
1203
1224
|
}
|
|
1204
|
-
.bg-
|
|
1205
|
-
background-color: color-
|
|
1206
|
-
@supports (color: color-mix(in lab, red, red)) {
|
|
1207
|
-
background-color: color-mix(in oklab, var(--color-yellow-500) 10%, transparent);
|
|
1208
|
-
}
|
|
1225
|
+
.bg-white {
|
|
1226
|
+
background-color: var(--color-white);
|
|
1209
1227
|
}
|
|
1210
1228
|
.fill-primary {
|
|
1211
1229
|
fill: var(--primary);
|
|
@@ -1415,8 +1433,8 @@
|
|
|
1415
1433
|
.text-\(--btn-fg\) {
|
|
1416
1434
|
color: var(--btn-fg);
|
|
1417
1435
|
}
|
|
1418
|
-
.text-\(--tag-
|
|
1419
|
-
color: var(--tag-
|
|
1436
|
+
.text-\(--tag-fg\) {
|
|
1437
|
+
color: var(--tag-fg);
|
|
1420
1438
|
}
|
|
1421
1439
|
.text-accent-foreground {
|
|
1422
1440
|
color: var(--accent-foreground);
|
|
@@ -1436,12 +1454,12 @@
|
|
|
1436
1454
|
.text-foreground {
|
|
1437
1455
|
color: var(--foreground);
|
|
1438
1456
|
}
|
|
1457
|
+
.text-gray-800 {
|
|
1458
|
+
color: var(--color-gray-800);
|
|
1459
|
+
}
|
|
1439
1460
|
.text-green-400 {
|
|
1440
1461
|
color: var(--color-green-400);
|
|
1441
1462
|
}
|
|
1442
|
-
.text-green-600 {
|
|
1443
|
-
color: var(--color-green-600);
|
|
1444
|
-
}
|
|
1445
1463
|
.text-muted-foreground {
|
|
1446
1464
|
color: var(--muted-foreground);
|
|
1447
1465
|
}
|
|
@@ -1466,12 +1484,12 @@
|
|
|
1466
1484
|
.text-yellow-400 {
|
|
1467
1485
|
color: var(--color-yellow-400);
|
|
1468
1486
|
}
|
|
1469
|
-
.text-yellow-600 {
|
|
1470
|
-
color: var(--color-yellow-600);
|
|
1471
|
-
}
|
|
1472
1487
|
.lowercase {
|
|
1473
1488
|
text-transform: lowercase;
|
|
1474
1489
|
}
|
|
1490
|
+
.italic {
|
|
1491
|
+
font-style: italic;
|
|
1492
|
+
}
|
|
1475
1493
|
.underline {
|
|
1476
1494
|
text-decoration-line: underline;
|
|
1477
1495
|
}
|
|
@@ -1545,6 +1563,10 @@
|
|
|
1545
1563
|
outline-style: var(--tw-outline-style);
|
|
1546
1564
|
outline-width: 1px;
|
|
1547
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
|
+
}
|
|
1548
1570
|
.filter {
|
|
1549
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,);
|
|
1550
1572
|
}
|
|
@@ -2604,12 +2626,6 @@
|
|
|
2604
2626
|
background-color: color-mix(in oklab, var(--input) 30%, transparent);
|
|
2605
2627
|
}
|
|
2606
2628
|
}
|
|
2607
|
-
.dark\:text-green-400:is(.dark *, [data-theme="dark"] *) {
|
|
2608
|
-
color: var(--color-green-400);
|
|
2609
|
-
}
|
|
2610
|
-
.dark\:text-yellow-400:is(.dark *, [data-theme="dark"] *) {
|
|
2611
|
-
color: var(--color-yellow-400);
|
|
2612
|
-
}
|
|
2613
2629
|
@media (hover: hover) {
|
|
2614
2630
|
.dark\:hover\:bg-accent\/50:is(.dark *, [data-theme="dark"] *):hover {
|
|
2615
2631
|
background-color: var(--accent);
|
|
@@ -2661,6 +2677,192 @@
|
|
|
2661
2677
|
background-color: color-mix(in oklab, var(--input) 80%, transparent);
|
|
2662
2678
|
}
|
|
2663
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
|
+
}
|
|
2664
2866
|
.\[\&_svg\]\:pointer-events-none svg {
|
|
2665
2867
|
pointer-events: none;
|
|
2666
2868
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbpark/ui-kit",
|
|
3
|
-
"version": "
|
|
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",
|
package/dist/lib/colors.mjs
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
//#region src/lib/colors.ts
|
|
2
|
-
/**
|
|
3
|
-
* The shared preset colour palette. `Button` and `Tag` both express these via
|
|
4
|
-
* the `--btn-*` / `--tag-*` custom-property systems in `globals.css` (keyed off
|
|
5
|
-
* `data-color`), so the same word means the same hue on either component
|
|
6
|
-
* (#320). Keep this list in sync with the `[data-color='…']` rules there.
|
|
7
|
-
*/
|
|
8
|
-
const PRESET_COLORS = [
|
|
9
|
-
"blue",
|
|
10
|
-
"purple",
|
|
11
|
-
"cyan",
|
|
12
|
-
"green",
|
|
13
|
-
"magenta",
|
|
14
|
-
"pink",
|
|
15
|
-
"red",
|
|
16
|
-
"orange",
|
|
17
|
-
"yellow",
|
|
18
|
-
"volcano",
|
|
19
|
-
"geekblue",
|
|
20
|
-
"lime",
|
|
21
|
-
"gold"
|
|
22
|
-
];
|
|
23
|
-
/** Runtime membership test — true when `color` is one of the shared presets. */
|
|
24
|
-
const isPresetColor = (color) => PRESET_COLORS.includes(color);
|
|
25
|
-
//#endregion
|
|
26
|
-
export { PRESET_COLORS, isPresetColor };
|
|
27
|
-
|
|
28
|
-
//# sourceMappingURL=colors.mjs.map
|
package/dist/lib/colors.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"colors.mjs","names":[],"sources":["../../src/lib/colors.ts"],"sourcesContent":["/**\n * The shared preset colour palette. `Button` and `Tag` both express these via\n * the `--btn-*` / `--tag-*` custom-property systems in `globals.css` (keyed off\n * `data-color`), so the same word means the same hue on either component\n * (#320). Keep this list in sync with the `[data-color='…']` rules there.\n */\nexport const PRESET_COLORS = [\n 'blue',\n 'purple',\n 'cyan',\n 'green',\n 'magenta',\n 'pink',\n 'red',\n 'orange',\n 'yellow',\n 'volcano',\n 'geekblue',\n 'lime',\n 'gold',\n] as const;\n\nexport type PresetColor = (typeof PRESET_COLORS)[number];\n\n/** Runtime membership test — true when `color` is one of the shared presets. */\nexport const isPresetColor = (color: string): color is PresetColor =>\n (PRESET_COLORS as readonly string[]).includes(color);\n"],"mappings":";;;;;;;AAMA,MAAa,gBAAgB;CAC3B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAKA,MAAa,iBAAiB,UAC3B,cAAoC,SAAS,KAAK"}
|