@jbpark/ui-kit 9.1.1 → 10.0.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/README.ko.md +18 -17
- package/README.md +18 -17
- package/dist/Button.d.mts +1 -1
- package/dist/Button.d.mts.map +1 -1
- package/dist/Button.mjs +4 -5
- package/dist/Button.mjs.map +1 -1
- package/dist/Tag.d.mts.map +1 -1
- package/dist/Tag.mjs.map +1 -1
- package/dist/components/atoms/checkbox/checkbox.mjs.map +1 -1
- package/dist/components/atoms/option-group.mjs.map +1 -1
- package/dist/components/atoms/popover.d.mts +3 -1
- package/dist/components/atoms/popover.d.mts.map +1 -1
- package/dist/components/atoms/popover.mjs +10 -111
- package/dist/components/atoms/popover.mjs.map +1 -1
- package/dist/components/atoms/progress.mjs +3 -4
- package/dist/components/atoms/progress.mjs.map +1 -1
- package/dist/components/atoms/radio/context.mjs +2 -2
- package/dist/components/atoms/radio/context.mjs.map +1 -1
- package/dist/components/atoms/radio/group.mjs +6 -6
- package/dist/components/atoms/radio/group.mjs.map +1 -1
- package/dist/components/atoms/radio/radio.d.mts +2 -5
- package/dist/components/atoms/radio/radio.d.mts.map +1 -1
- package/dist/components/atoms/radio/radio.mjs +0 -1
- package/dist/components/atoms/radio/radio.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/content-classes.mjs +1 -1
- package/dist/components/atoms/rich-text-editor/content-classes.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/rich-text-editor.mjs +1 -1
- package/dist/components/atoms/rich-text-editor/rich-text-editor.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/toolbar-button.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/toolbar-presets.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/toolbar.mjs +1 -1
- package/dist/components/atoms/rich-text-editor/toolbar.mjs.map +1 -1
- package/dist/components/atoms/select.mjs +5 -1
- package/dist/components/atoms/select.mjs.map +1 -1
- package/dist/components/atoms/slider/slider.mjs.map +1 -1
- package/dist/components/atoms/switch.d.mts +1 -1
- package/dist/components/atoms/switch.d.mts.map +1 -1
- package/dist/components/atoms/switch.mjs +3 -3
- package/dist/components/atoms/switch.mjs.map +1 -1
- package/dist/components/molecules/collapse.mjs +3 -10
- package/dist/components/molecules/collapse.mjs.map +1 -1
- package/dist/components/organisms/drawer.d.mts +1 -2
- package/dist/components/organisms/drawer.d.mts.map +1 -1
- package/dist/components/organisms/drawer.mjs +5 -7
- package/dist/components/organisms/drawer.mjs.map +1 -1
- package/dist/components/organisms/modal.d.mts.map +1 -1
- package/dist/components/organisms/modal.mjs +1 -3
- package/dist/components/organisms/modal.mjs.map +1 -1
- package/dist/components/templates/container.d.mts +4 -3
- package/dist/components/templates/container.d.mts.map +1 -1
- package/dist/components/templates/container.mjs +10 -6
- package/dist/components/templates/container.mjs.map +1 -1
- package/dist/components/templates/index.d.mts +13 -0
- package/dist/components/templates/layout/content.d.mts +4 -3
- package/dist/components/templates/layout/content.d.mts.map +1 -1
- package/dist/components/templates/layout/content.mjs +14 -9
- package/dist/components/templates/layout/content.mjs.map +1 -1
- package/dist/core/accordion.d.mts +1 -1
- package/dist/core/accordion.mjs +12 -12
- package/dist/core/accordion.mjs.map +1 -1
- package/dist/core/badge.d.mts +5 -17
- package/dist/core/badge.d.mts.map +1 -1
- package/dist/core/badge.mjs +12 -21
- package/dist/core/badge.mjs.map +1 -1
- package/dist/core/button.d.mts +7 -6
- package/dist/core/button.d.mts.map +1 -1
- package/dist/core/button.mjs +4 -4
- package/dist/core/button.mjs.map +1 -1
- package/dist/core/calendar.mjs +2 -1
- package/dist/core/calendar.mjs.map +1 -1
- package/dist/core/checkbox.d.mts +1 -1
- package/dist/core/checkbox.mjs +14 -14
- package/dist/core/checkbox.mjs.map +1 -1
- package/dist/core/dialog.d.mts +1 -1
- package/dist/core/dialog.mjs +25 -33
- package/dist/core/dialog.mjs.map +1 -1
- package/dist/core/drawer.d.mts +1 -1
- package/dist/core/drawer.mjs +45 -46
- package/dist/core/drawer.mjs.map +1 -1
- package/dist/core/label.d.mts +1 -2
- package/dist/core/label.mjs +1 -3
- package/dist/core/label.mjs.map +1 -1
- package/dist/core/popover.d.mts +1 -1
- package/dist/core/popover.mjs +42 -37
- package/dist/core/popover.mjs.map +1 -1
- package/dist/core/progress.d.mts +1 -1
- package/dist/core/progress.mjs +7 -10
- package/dist/core/progress.mjs.map +1 -1
- package/dist/core/radio-group.d.mts +3 -7
- package/dist/core/radio-group.mjs +14 -13
- package/dist/core/radio-group.mjs.map +1 -1
- package/dist/core/select.d.mts +7 -3
- package/dist/core/select.d.mts.map +1 -1
- package/dist/core/select.mjs +60 -56
- package/dist/core/select.mjs.map +1 -1
- package/dist/core/separator.d.mts +1 -1
- package/dist/core/separator.mjs +6 -5
- package/dist/core/separator.mjs.map +1 -1
- package/dist/core/slider.d.mts +1 -1
- package/dist/core/slider.mjs +38 -27
- package/dist/core/slider.mjs.map +1 -1
- package/dist/core/switch.d.mts +1 -1
- package/dist/core/switch.mjs +15 -15
- package/dist/core/switch.mjs.map +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/lib/z-layers.mjs +4 -6
- package/dist/lib/z-layers.mjs.map +1 -1
- package/dist/providers/config/config.mjs +2 -2
- package/dist/providers/config/config.mjs.map +1 -1
- package/dist/style.css +327 -462
- package/package.json +7 -20
- package/dist/core/radio-group.d.mts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.mjs","names":["progress"],"sources":["../../../src/components/atoms/progress.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nimport { progress } from '../../core';\n\nconst { Progress: Core } = progress;\n\nexport interface Props extends React.ComponentPropsWithoutRef<'div'> {\n value: number;\n direction?: 'horizontal' | 'vertical';\n classNames?: {\n background?: string;\n bar?: string;\n };\n}\n\nconst Progress = ({\n value,\n className,\n direction = 'horizontal',\n classNames,\n ...props\n}: Props) => {\n const isHorizontal = direction === 'horizontal';\n const
|
|
1
|
+
{"version":3,"file":"progress.mjs","names":["progress"],"sources":["../../../src/components/atoms/progress.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nimport { progress } from '../../core';\n\nconst { Progress: Core } = progress;\n\nexport interface Props extends React.ComponentPropsWithoutRef<'div'> {\n value: number;\n direction?: 'horizontal' | 'vertical';\n classNames?: {\n background?: string;\n bar?: string;\n };\n}\n\nconst Progress = ({\n value,\n className,\n direction = 'horizontal',\n classNames,\n ...props\n}: Props) => {\n const isHorizontal = direction === 'horizontal';\n const normalizedValue = Number.isFinite(value)\n ? Math.min(100, Math.max(0, value))\n : 0;\n\n return (\n <Core\n {...props}\n value={normalizedValue}\n className={cn(\n isHorizontal ? 'h-4 w-full' : 'flex h-full w-4 flex-col justify-end',\n className,\n classNames?.background,\n //\n )}\n barClassName={cn('flex-none', classNames?.bar)}\n barStyle={\n isHorizontal\n ? { width: `${normalizedValue}%` }\n : { width: '100%', height: `${normalizedValue}%` }\n }\n />\n );\n};\n\nexport default Progress;\n"],"mappings":";;;;AAIA,MAAM,EAAE,UAAU,SAASA;AAW3B,MAAM,YAAY,EAChB,OACA,WACA,YAAY,cACZ,YACA,GAAG,YACQ;CACX,MAAM,eAAe,cAAc;CACnC,MAAM,kBAAkB,OAAO,SAAS,KAAK,IACzC,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,CAAC,IAChC;CAEJ,OACE,oBAAC,MAAD;EACE,GAAI;EACJ,OAAO;EACP,WAAW,GACT,eAAe,eAAe,wCAC9B,WACA,YAAY,UAEd;EACA,cAAc,GAAG,aAAa,YAAY,GAAG;EAC7C,UACE,eACI,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAC/B;GAAE,OAAO;GAAQ,QAAQ,GAAG,gBAAgB;EAAG;CAEtD,CAAA;AAEL"}
|
|
@@ -5,8 +5,8 @@ import { createContext } from "react";
|
|
|
5
5
|
* Internal only — not exported from the package entry points.
|
|
6
6
|
*
|
|
7
7
|
* `true` when a `Radio` is rendered inside a `RadioGroup` that already owns a
|
|
8
|
-
* single shared `
|
|
9
|
-
* only its `RadioGroupItem` so that
|
|
8
|
+
* single shared Base UI `RadioGroup` root. In that case each `Radio` renders
|
|
9
|
+
* only its `RadioGroupItem` so that Base UI can manage roving focus (arrow-key
|
|
10
10
|
* navigation) across every option of the group.
|
|
11
11
|
*
|
|
12
12
|
* `false` (default) means the `Radio` is standalone and has to wrap itself in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.mjs","names":[],"sources":["../../../../src/components/atoms/radio/context.tsx"],"sourcesContent":["'use client';\n\nimport { createContext } from 'react';\n\n/**\n * Internal only — not exported from the package entry points.\n *\n * `true` when a `Radio` is rendered inside a `RadioGroup` that already owns a\n * single shared `
|
|
1
|
+
{"version":3,"file":"context.mjs","names":[],"sources":["../../../../src/components/atoms/radio/context.tsx"],"sourcesContent":["'use client';\n\nimport { createContext } from 'react';\n\n/**\n * Internal only — not exported from the package entry points.\n *\n * `true` when a `Radio` is rendered inside a `RadioGroup` that already owns a\n * single shared Base UI `RadioGroup` root. In that case each `Radio` renders\n * only its `RadioGroupItem` so that Base UI can manage roving focus (arrow-key\n * navigation) across every option of the group.\n *\n * `false` (default) means the `Radio` is standalone and has to wrap itself in\n * its own `Root` to stay functional.\n */\nexport const RadioGroupContext = createContext(false);\n"],"mappings":";;;;;;;;;;;;;;AAeA,MAAa,oBAAoB,cAAc,KAAK"}
|
|
@@ -4,10 +4,10 @@ import { radio_group_exports } from "../../../core/radio-group.mjs";
|
|
|
4
4
|
import Button from "../../../Button.mjs";
|
|
5
5
|
import { normalizeOptions, warnOnDuplicateOptionValues } from "../option-group.mjs";
|
|
6
6
|
import { RadioGroupContext } from "./context.mjs";
|
|
7
|
-
import Radio from "./radio.mjs";
|
|
7
|
+
import Radio$1 from "./radio.mjs";
|
|
8
8
|
import { useId } from "react";
|
|
9
9
|
import { jsx } from "react/jsx-runtime";
|
|
10
|
-
import
|
|
10
|
+
import { Radio } from "@base-ui/react/radio";
|
|
11
11
|
import { useControllableState } from "@jbpark/use-hooks";
|
|
12
12
|
//#region src/components/atoms/radio/group.tsx
|
|
13
13
|
const { RadioGroup: Core } = radio_group_exports;
|
|
@@ -39,19 +39,19 @@ const RadioGroup = ({ orientation = "horizontal", placement = "left", className,
|
|
|
39
39
|
const checked = value === item.value;
|
|
40
40
|
return /* @__PURE__ */ jsx("li", {
|
|
41
41
|
className: cn("m-0 flex", classNames?.wrapper),
|
|
42
|
-
children: isButton ? /* @__PURE__ */ jsx(
|
|
43
|
-
asChild: true,
|
|
42
|
+
children: isButton ? /* @__PURE__ */ jsx(Radio.Root, {
|
|
44
43
|
"data-slot": "radio-group-item",
|
|
45
44
|
value: String(item.value),
|
|
46
45
|
disabled: disabled || item.disabled,
|
|
47
|
-
|
|
46
|
+
nativeButton: true,
|
|
47
|
+
render: /* @__PURE__ */ jsx(Button, {
|
|
48
48
|
variant: checked ? buttonStyle : "outlined",
|
|
49
49
|
size,
|
|
50
50
|
disabled: disabled || item.disabled,
|
|
51
51
|
className: cn("rounded-none border", checked && (buttonStyle === "outlined" ? "border-primary" : "border-transparent"), index === 0 && (orientation === "vertical" ? "rounded-t-lg" : "rounded-l-lg"), index === options.length - 1 && (orientation === "vertical" ? "rounded-b-lg" : "rounded-r-lg")),
|
|
52
52
|
children: item.label
|
|
53
53
|
})
|
|
54
|
-
}) : /* @__PURE__ */ jsx(Radio, {
|
|
54
|
+
}) : /* @__PURE__ */ jsx(Radio$1, {
|
|
55
55
|
id: getOptionId(index),
|
|
56
56
|
placement,
|
|
57
57
|
className: cn(classNames?.item),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.mjs","names":["radio"],"sources":["../../../../src/components/atoms/radio/group.tsx"],"sourcesContent":["'use client';\n\nimport { useId } from 'react';\n\nimport {
|
|
1
|
+
{"version":3,"file":"group.mjs","names":["radio","RadioPrimitive","Radio"],"sources":["../../../../src/components/atoms/radio/group.tsx"],"sourcesContent":["'use client';\n\nimport { useId } from 'react';\n\nimport { Radio as RadioPrimitive } from '@base-ui/react/radio';\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { radio } from '../../../core';\nimport Button from '../button';\nimport {\n type Option,\n type OptionGroupClassNames,\n type OptionValue,\n type Options,\n normalizeOptions,\n warnOnDuplicateOptionValues,\n} from '../option-group';\nimport { RadioGroupContext } from './context';\nimport Radio from './radio';\n\nconst { RadioGroup: Core } = radio;\n\nexport type { OptionValue };\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'ul'>,\n 'onChange' | 'defaultValue' | 'value'\n> {\n options?: Options;\n orientation?: 'vertical' | 'horizontal';\n placement?: 'left' | 'right';\n classNames?: OptionGroupClassNames;\n defaultValue?: OptionValue;\n value?: OptionValue;\n /** Native form field name — participates in `FormData` when set. */\n name?: string;\n optionType?: 'default' | 'button';\n buttonStyle?: 'solid' | 'outlined';\n size?: 'small' | 'middle' | 'large';\n disabled?: boolean;\n onChange?: (value: OptionValue) => void;\n}\n\nconst RadioGroup = ({\n orientation = 'horizontal',\n placement = 'left',\n className,\n classNames = {},\n options: _options = [],\n name,\n optionType = 'default',\n buttonStyle = 'solid',\n size,\n disabled,\n defaultValue,\n value: _value,\n onChange: _onChange = () => {},\n ...props\n}: Props) => {\n const [value, setValue] = useControllableState<OptionValue>({\n value: _value,\n defaultValue,\n onChange: _onChange,\n });\n\n const options: Option[] = normalizeOptions(_options);\n warnOnDuplicateOptionValues(options, 'Radio.Group');\n\n const isButton = optionType === 'button';\n\n const onChange = (checked: boolean, optionValue: OptionValue) => {\n if (!checked) {\n return;\n }\n setValue(optionValue);\n };\n\n // A single Base UI RadioGroup root owns every option so that arrow keys\n // move focus across the whole group. `id` stays index-derived (for DOM\n // id/label pairing), but Base UI itself addresses/submits items by their\n // real (stringified) `value` — see radio.tsx.\n const baseId = useId();\n const getOptionId = (index: number) => `${baseId}-${index}`;\n const checkedItemValue = value === undefined ? '' : String(value);\n\n const onValueChange = (itemValue: string) => {\n const item = options.find(option => String(option.value) === itemValue);\n\n if (!item) {\n return;\n }\n\n onChange(true, item.value);\n };\n\n const list = (\n <ul\n {...props}\n className={cn(\n 'm-0 flex list-none gap-4 p-0',\n className,\n orientation === 'vertical' && 'flex-col',\n isButton && 'gap-0',\n )}\n >\n {options.map((item: Option, index) => {\n const checked = value === item.value;\n\n return (\n <li\n key={`${index}-${String(item.value)}`}\n // `m-0` completes the list reset the `ul` above starts (#253):\n // without preflight, hosts that style prose lists still reach the\n // items — Docusaurus/Infima's `.markdown li + li` gives every item\n // but the first a `margin-top`, which in horizontal orientation\n // drops options 2..n by that much and stretches the first one,\n // making it look misaligned.\n className={cn('m-0 flex', classNames?.wrapper)}\n >\n {isButton ? (\n // `render` gives the Button real radio semantics (role,\n // aria-checked, roving tabindex, arrow-key nav, click/keyboard\n // selection via the shared Core's onValueChange below) instead\n // of a plain list of buttons with none of that. Base UI has no\n // `asChild`; its `render` prop merges the primitive's props onto\n // the Button element. Uses the Radio primitive directly (not\n // `core/RadioGroupItem`) so the core stays a plain default item;\n // the `data-slot` matches what that item emits.\n <RadioPrimitive.Root\n data-slot=\"radio-group-item\"\n value={String(item.value)}\n disabled={disabled || item.disabled}\n // The Button below renders a real `<button>`, so tell Base UI\n // it's a native button — otherwise `useButton` synthesises\n // Enter/Space activation for a non-native element and would\n // double-handle keyboard selection.\n nativeButton\n render={\n <Button\n variant={checked ? buttonStyle : 'outlined'}\n size={size}\n disabled={disabled || item.disabled}\n className={cn(\n // The `solid` variant (the checked item, by default)\n // renders no border at all while `outlined` (every\n // unchecked item) renders a 1px one — reserving the\n // border unconditionally keeps every option's box the\n // same size regardless of which variant it's in.\n 'rounded-none border',\n checked &&\n (buttonStyle === 'outlined'\n ? 'border-primary'\n : 'border-transparent'),\n index === 0 &&\n (orientation === 'vertical'\n ? 'rounded-t-lg'\n : 'rounded-l-lg'),\n index === options.length - 1 &&\n (orientation === 'vertical'\n ? 'rounded-b-lg'\n : 'rounded-r-lg'),\n )}\n >\n {item.label}\n </Button>\n }\n />\n ) : (\n <Radio\n id={getOptionId(index)}\n placement={placement}\n className={cn(classNames?.item)}\n value={item.value}\n checked={checked}\n disabled={disabled || item.disabled}\n onChange={checked => onChange(checked, item.value)}\n >\n {item.label}\n </Radio>\n )}\n </li>\n );\n })}\n </ul>\n );\n\n return (\n <RadioGroupContext.Provider value={true}>\n <Core\n className=\"block\"\n name={name}\n value={checkedItemValue}\n onValueChange={onValueChange}\n >\n {list}\n </Core>\n </RadioGroupContext.Provider>\n );\n};\n\nexport default RadioGroup;\n"],"mappings":";;;;;;;;;;;;AAsBA,MAAM,EAAE,YAAY,SAASA;AAuB7B,MAAM,cAAc,EAClB,cAAc,cACd,YAAY,QACZ,WACA,aAAa,CAAC,GACd,SAAS,WAAW,CAAC,GACrB,MACA,aAAa,WACb,cAAc,SACd,MACA,UACA,cACA,OAAO,QACP,UAAU,kBAAkB,CAAC,GAC7B,GAAG,YACQ;CACX,MAAM,CAAC,OAAO,YAAY,qBAAkC;EAC1D,OAAO;EACP;EACA,UAAU;CACZ,CAAC;CAED,MAAM,UAAoB,iBAAiB,QAAQ;CACnD,4BAA4B,SAAS,aAAa;CAElD,MAAM,WAAW,eAAe;CAEhC,MAAM,YAAY,SAAkB,gBAA6B;EAC/D,IAAI,CAAC,SACH;EAEF,SAAS,WAAW;CACtB;CAMA,MAAM,SAAS,MAAM;CACrB,MAAM,eAAe,UAAkB,GAAG,OAAO,GAAG;CACpD,MAAM,mBAAmB,UAAU,KAAA,IAAY,KAAK,OAAO,KAAK;CAEhE,MAAM,iBAAiB,cAAsB;EAC3C,MAAM,OAAO,QAAQ,MAAK,WAAU,OAAO,OAAO,KAAK,MAAM,SAAS;EAEtE,IAAI,CAAC,MACH;EAGF,SAAS,MAAM,KAAK,KAAK;CAC3B;CAEA,MAAM,OACJ,oBAAC,MAAD;EACE,GAAI;EACJ,WAAW,GACT,gCACA,WACA,gBAAgB,cAAc,YAC9B,YAAY,OACd;EAEC,UAAA,QAAQ,KAAK,MAAc,UAAU;GACpC,MAAM,UAAU,UAAU,KAAK;GAE/B,OACE,oBAAC,MAAD;IAQE,WAAW,GAAG,YAAY,YAAY,OAAO;IAE5C,UAAA,WASC,oBAACC,MAAe,MAAhB;KACE,aAAU;KACV,OAAO,OAAO,KAAK,KAAK;KACxB,UAAU,YAAY,KAAK;KAK3B,cAAA;KACA,QACE,oBAAC,QAAD;MACE,SAAS,UAAU,cAAc;MAC3B;MACN,UAAU,YAAY,KAAK;MAC3B,WAAW,GAMT,uBACA,YACG,gBAAgB,aACb,mBACA,uBACN,UAAU,MACP,gBAAgB,aACb,iBACA,iBACN,UAAU,QAAQ,SAAS,MACxB,gBAAgB,aACb,iBACA,eACR;MAEC,UAAA,KAAK;KACA,CAAA;IAEX,CAAA,IAED,oBAACC,SAAD;KACE,IAAI,YAAY,KAAK;KACV;KACX,WAAW,GAAG,YAAY,IAAI;KAC9B,OAAO,KAAK;KACH;KACT,UAAU,YAAY,KAAK;KAC3B,WAAU,YAAW,SAAS,SAAS,KAAK,KAAK;KAEhD,UAAA,KAAK;IACD,CAAA;GAEP,GAtEG,GAAG,MAAM,GAAG,OAAO,KAAK,KAAK,GAsEhC;EAER,CAAC;CACC,CAAA;CAGN,OACE,oBAAC,kBAAkB,UAAnB;EAA4B,OAAO;EACjC,UAAA,oBAAC,MAAD;GACE,WAAU;GACJ;GACN,OAAO;GACQ;GAEd,UAAA;EACG,CAAA;CACoB,CAAA;AAEhC"}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import { RadioGroup } from "../../../core/radio-group.mjs";
|
|
2
|
-
import "../../../core/index.mjs";
|
|
3
1
|
import { OptionValue } from "../option-group.mjs";
|
|
4
2
|
//#region src/components/atoms/radio/radio.d.ts
|
|
5
|
-
|
|
6
|
-
interface Props extends Omit<React.ComponentPropsWithoutRef<typeof Core>, 'onChange' | 'value'> {
|
|
3
|
+
interface Props extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange'> {
|
|
7
4
|
placement?: 'left' | 'right';
|
|
8
5
|
defaultChecked?: boolean;
|
|
9
6
|
checked?: boolean;
|
|
@@ -14,7 +11,7 @@ interface Props extends Omit<React.ComponentPropsWithoutRef<typeof Core>, 'onCha
|
|
|
14
11
|
/**
|
|
15
12
|
* Id shared by the underlying control and its label. Generated internally
|
|
16
13
|
* when omitted. `RadioGroup` passes a deterministic id so that the group's
|
|
17
|
-
* single
|
|
14
|
+
* single Base UI root can address each option.
|
|
18
15
|
*/
|
|
19
16
|
id?: string;
|
|
20
17
|
icons?: Partial<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio.d.mts","names":[],"sources":["../../../../src/components/atoms/radio/radio.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"radio.d.mts","names":[],"sources":["../../../../src/components/atoms/radio/radio.tsx"],"mappings":";;UAoBiB,cAAc,KAC7B,MAAM;EAGN;EACA;EACA;EACA,QAAQ;;EAER;EACA;;;;;;EAMA;EACA,QAAQ;IAAU,SAAS,MAAM;IAAW,WAAW,MAAM;;EAC7D,YAAY;;cAGR,UAAS,WAAA,OAAA,QAAA,UAAA,WAAA,OAAA,UAAA,gBAAA,SAAA,UAAA,IAAA,KAAA,MAAA,UAAA,cAAA,SAaZ,0BAAK,IAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio.mjs","names":["radio","field"],"sources":["../../../../src/components/atoms/radio/radio.tsx"],"sourcesContent":["'use client';\n\nimport { useContext, useId, useRef } from 'react';\n\nimport { useControllableState, useKeyPress } from '@jbpark/use-hooks';\nimport { Circle, CircleCheck } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { field, radio } from '../../../core';\nimport { RadioGroupContext } from './context';\nimport { type OptionValue } from './group';\n\nconst { RadioGroup: Core, RadioGroupItem: Item } = radio;\nconst { Field, FieldLabel } = field;\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<
|
|
1
|
+
{"version":3,"file":"radio.mjs","names":["radio","field"],"sources":["../../../../src/components/atoms/radio/radio.tsx"],"sourcesContent":["'use client';\n\nimport { useContext, useId, useRef } from 'react';\n\nimport { useControllableState, useKeyPress } from '@jbpark/use-hooks';\nimport { Circle, CircleCheck } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { field, radio } from '../../../core';\nimport { RadioGroupContext } from './context';\nimport { type OptionValue } from './group';\n\nconst { RadioGroup: Core, RadioGroupItem: Item } = radio;\nconst { Field, FieldLabel } = field;\n\n// Spreads onto the wrapper `<div>`, so the host props are div-based. (Base UI's\n// `RadioGroup` — `Core` here — types `style`/`className` as state callbacks,\n// which a native `<div>` can't take; the meaningful control props below are\n// re-declared explicitly anyway.)\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'onChange'\n> {\n placement?: 'left' | 'right';\n defaultChecked?: boolean;\n checked?: boolean;\n value?: OptionValue;\n /** Native form field name — participates in `FormData` when set. */\n name?: string;\n disabled?: boolean;\n /**\n * Id shared by the underlying control and its label. Generated internally\n * when omitted. `RadioGroup` passes a deterministic id so that the group's\n * single Base UI root can address each option.\n */\n id?: string;\n icons?: Partial<{ checked: React.ReactNode; unchecked: React.ReactNode }>;\n onChange?: (checked: boolean) => void;\n}\n\nconst Radio = ({\n placement = 'left',\n value: _value = '',\n children,\n className,\n icons,\n disabled,\n defaultChecked,\n checked: _checked,\n id: _id,\n name,\n onChange: _onChange = () => {},\n ...props\n}: Props) => {\n const [checked, setChecked] = useControllableState<boolean>({\n value: _checked,\n defaultValue: defaultChecked ?? false,\n onChange: _onChange,\n });\n\n const generatedId = useId();\n const id = _id ?? generatedId;\n // Base UI identifies/submits an item by its `value`, which is separate\n // from `id` (used only for the DOM id/label pairing) — stringified since\n // the group value is a string, while `OptionValue` also allows\n // number/boolean.\n const itemValue = String(_value);\n const grouped = useContext(RadioGroupContext);\n\n const cursorClassName = disabled ? 'cursor-not-allowed' : 'cursor-pointer';\n\n const onChange = (next: boolean) => {\n if (disabled) {\n return;\n }\n\n setChecked(next);\n };\n\n const iconTriggerRef = useRef<HTMLSpanElement>(null);\n\n useKeyPress(\n ['Enter', 'space'],\n event => {\n event.preventDefault();\n onChange(true);\n },\n { target: iconTriggerRef, enabled: !!icons && !disabled },\n );\n\n // When rendered inside a `RadioGroup`, the group owns the single shared\n // `Core` (Base UI RadioGroup root) so that arrow keys move focus across\n // every option. A standalone `Radio` still has to provide its own root.\n const renderField = (\n <Field\n orientation=\"horizontal\"\n className={cn('flex gap-2', placement === 'right' && 'flex-row-reverse')}\n data-disabled={disabled}\n >\n <Item value={itemValue} id={id} disabled={disabled} />\n <FieldLabel htmlFor={id} className={cursorClassName}>\n {children}\n </FieldLabel>\n </Field>\n );\n\n const renderContent = icons ? (\n <>\n <input\n id={id}\n hidden\n type=\"radio\"\n name={name}\n value={itemValue}\n checked={checked}\n disabled={disabled}\n onChange={e => {\n onChange(e.target.checked);\n }}\n />\n <span\n ref={iconTriggerRef}\n role=\"radio\"\n aria-checked={checked}\n aria-disabled={disabled}\n tabIndex={disabled ? -1 : 0}\n className={cn(cursorClassName, disabled && 'opacity-50')}\n onClick={() => {\n onChange(true);\n }}\n >\n {checked\n ? (icons.checked ?? <CircleCheck />)\n : (icons.unchecked ?? <Circle />)}\n </span>\n {children && (\n <label\n className={cn(cursorClassName, disabled && 'opacity-50')}\n htmlFor={id}\n >\n {children}\n </label>\n )}\n </>\n ) : grouped ? (\n renderField\n ) : (\n <Core\n name={name}\n value={checked ? itemValue : ''}\n onValueChange={() => onChange(true)}\n >\n {renderField}\n </Core>\n );\n\n return (\n <div\n className={cn(\n 'flex items-center',\n icons && placement === 'right' && 'flex-row-reverse',\n cursorClassName,\n className,\n //\n )}\n {...props}\n >\n {renderContent}\n </div>\n );\n};\n\nexport default Radio;\n"],"mappings":";;;;;;;;;;AAaA,MAAM,EAAE,YAAY,MAAM,gBAAgB,SAASA;AACnD,MAAM,EAAE,OAAO,eAAeC;AA2B9B,MAAM,SAAS,EACb,YAAY,QACZ,OAAO,SAAS,IAChB,UACA,WACA,OACA,UACA,gBACA,SAAS,UACT,IAAI,KACJ,MACA,UAAU,kBAAkB,CAAC,GAC7B,GAAG,YACQ;CACX,MAAM,CAAC,SAAS,cAAc,qBAA8B;EAC1D,OAAO;EACP,cAAc,kBAAkB;EAChC,UAAU;CACZ,CAAC;CAED,MAAM,cAAc,MAAM;CAC1B,MAAM,KAAK,OAAO;CAKlB,MAAM,YAAY,OAAO,MAAM;CAC/B,MAAM,UAAU,WAAW,iBAAiB;CAE5C,MAAM,kBAAkB,WAAW,uBAAuB;CAE1D,MAAM,YAAY,SAAkB;EAClC,IAAI,UACF;EAGF,WAAW,IAAI;CACjB;CAEA,MAAM,iBAAiB,OAAwB,IAAI;CAEnD,YACE,CAAC,SAAS,OAAO,IACjB,UAAS;EACP,MAAM,eAAe;EACrB,SAAS,IAAI;CACf,GACA;EAAE,QAAQ;EAAgB,SAAS,CAAC,CAAC,SAAS,CAAC;CAAS,CAC1D;CAKA,MAAM,cACJ,qBAAC,OAAD;EACE,aAAY;EACZ,WAAW,GAAG,cAAc,cAAc,WAAW,kBAAkB;EACvE,iBAAe;EAHjB,UAAA,CAKE,oBAAC,MAAD;GAAM,OAAO;GAAe;GAAc;EAAW,CAAA,GACrD,oBAAC,YAAD;GAAY,SAAS;GAAI,WAAW;GACjC;EACS,CAAA,CACP;;CAGT,MAAM,gBAAgB,QACpB,qBAAA,YAAA,EAAA,UAAA;EACE,oBAAC,SAAD;GACM;GACJ,QAAA;GACA,MAAK;GACC;GACN,OAAO;GACE;GACC;GACV,WAAU,MAAK;IACb,SAAS,EAAE,OAAO,OAAO;GAC3B;EACD,CAAA;EACD,oBAAC,QAAD;GACE,KAAK;GACL,MAAK;GACL,gBAAc;GACd,iBAAe;GACf,UAAU,WAAW,KAAK;GAC1B,WAAW,GAAG,iBAAiB,YAAY,YAAY;GACvD,eAAe;IACb,SAAS,IAAI;GACf;GAEC,UAAA,UACI,MAAM,WAAW,oBAAC,aAAD,CAAc,CAAA,IAC/B,MAAM,aAAa,oBAAC,QAAD,CAAS,CAAA;EAC7B,CAAA;EACL,YACC,oBAAC,SAAD;GACE,WAAW,GAAG,iBAAiB,YAAY,YAAY;GACvD,SAAS;GAER;EACI,CAAA;CAET,EAAA,CAAA,IACA,UACF,cAEA,oBAAC,MAAD;EACQ;EACN,OAAO,UAAU,YAAY;EAC7B,qBAAqB,SAAS,IAAI;EAEjC,UAAA;CACG,CAAA;CAGR,OACE,oBAAC,OAAD;EACE,WAAW,GACT,qBACA,SAAS,cAAc,WAAW,oBAClC,iBACA,SAEF;EACA,GAAI;EAEH,UAAA;CACE,CAAA;AAET"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cn } from "../../../utils.mjs";
|
|
2
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-
|
|
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-border", "[&_.tiptap_blockquote]:pl-3", "[&_.tiptap_blockquote]:text-muted-foreground", "[&_.tiptap_blockquote]:italic", "[&_.tiptap_pre]:overflow-x-auto", "[&_.tiptap_pre]:my-2", "[&_.tiptap_pre]:rounded", "[&_.tiptap_pre]:bg-foreground", "[&_.tiptap_pre]:p-3", "[&_.tiptap_pre]:font-mono", "[&_.tiptap_pre]:text-sm", "[&_.tiptap_pre]:text-background", "[&_.tiptap_pre_code]:bg-transparent", "[&_.tiptap_pre_code]:p-0", "[&_.tiptap_pre_code]:text-inherit", "[&_.tiptap_code]:rounded", "[&_.tiptap_code]:bg-muted", "[&_.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-border", "[&_.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-muted-foreground", "[&_.tiptap_p.is-editor-empty:first-child::before]:content-[attr(data-placeholder)]");
|
|
4
4
|
//#endregion
|
|
5
5
|
export { RICH_TEXT_CONTENT_CLASSES };
|
|
6
6
|
|
|
@@ -1 +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-
|
|
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).\n//\n// Colours resolve from the theme tokens in globals.css, never from a fixed\n// palette step: a literal `bg-gray-100` renders the same in both schemes, so\n// the editor stayed a white card on a dark page. `bg-foreground`/\n// `text-background` on `pre` is deliberate — it is the one block that wants to\n// invert against the surface, and inverting the tokens keeps it legible in\n// either scheme without a `dark:` override.\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-border',\n '[&_.tiptap_blockquote]:pl-3',\n '[&_.tiptap_blockquote]:text-muted-foreground',\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-foreground',\n '[&_.tiptap_pre]:p-3',\n '[&_.tiptap_pre]:font-mono',\n '[&_.tiptap_pre]:text-sm',\n '[&_.tiptap_pre]:text-background',\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-muted',\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-border',\n\n // No colour: this theme's `--primary` is achromatic (near-black in light,\n // near-white in dark), so `text-primary` would render the link at almost the\n // body colour and buy nothing. `Typography.Link` reaches the same conclusion\n // and styles links with the underline alone — match it.\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-muted-foreground',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:content-[attr(data-placeholder)]',\n);\n"],"mappings":";;AAgBA,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,wCACA,+BACA,gDACA,iCAGA,mCACA,wBACA,2BACA,iCACA,uBACA,6BACA,2BACA,mCAGA,uCACA,4BACA,qCACA,4BACA,6BACA,yBACA,2BACA,8BACA,kCAEA,uBACA,gCAMA,2BACA,oCAEA,yEACA,gEACA,yDACA,2EACA,oFACF"}
|
|
@@ -36,7 +36,7 @@ const RichTextEditor = ({ value = "", placeholder = "Enter text...", className,
|
|
|
36
36
|
}, [value, editor]);
|
|
37
37
|
return /* @__PURE__ */ jsxs("div", {
|
|
38
38
|
"data-slot": "rich-text-editor",
|
|
39
|
-
className: cn("
|
|
39
|
+
className: cn("border-input bg-background text-foreground rounded border text-sm", className),
|
|
40
40
|
children: [showToolbar && editor && /* @__PURE__ */ jsx(Toolbar, {
|
|
41
41
|
editor,
|
|
42
42
|
presets,
|
|
@@ -1 +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 '
|
|
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 'border-input bg-background text-foreground rounded border text-sm',\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,qEACA,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"}
|
|
@@ -1 +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
|
|
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 so composition props cannot override Button's antd-style\n // color/variant switch below.\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;CAGE,GAAI;CACJ,MAAK;CACL,MAAK;CACL,OAAM;CACN,gBAAc;CACd,WAAW,GAAG,UAAU,aAAa,SAAS;AAC/C,CAAA"}
|
|
@@ -1 +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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"}
|
|
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 Base UI 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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"}
|
|
@@ -6,7 +6,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
const Toolbar = ({ editor, presets, items, className }) => {
|
|
7
7
|
return /* @__PURE__ */ jsxs("div", {
|
|
8
8
|
"data-slot": "rich-text-editor-toolbar",
|
|
9
|
-
className: cn("flex flex-wrap items-center gap-1 border-b
|
|
9
|
+
className: cn("border-input flex flex-wrap items-center gap-1 border-b px-2 py-1", className),
|
|
10
10
|
children: [presets.map((preset) => TOOLBAR_PRESET_RENDERERS[preset](editor)), items?.map((item) => /* @__PURE__ */ jsx(ToolbarButton, {
|
|
11
11
|
icon: item.icon,
|
|
12
12
|
"aria-label": item.label,
|
|
@@ -1 +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
|
|
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 'border-input flex flex-wrap items-center gap-1 border-b 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,qEACA,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"}
|
|
@@ -8,8 +8,12 @@ const isGroup = (option) => {
|
|
|
8
8
|
return "options" in option && Array.isArray(option.options);
|
|
9
9
|
};
|
|
10
10
|
const Select = ({ className, placeholder, options, onChange, ...props }) => {
|
|
11
|
+
const items = options?.flatMap((option) => isGroup(option) ? option.options : option);
|
|
11
12
|
return /* @__PURE__ */ jsxs(Core, {
|
|
12
|
-
|
|
13
|
+
items,
|
|
14
|
+
onValueChange: (value) => {
|
|
15
|
+
if (value !== null) onChange?.(value);
|
|
16
|
+
},
|
|
13
17
|
...props,
|
|
14
18
|
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
15
19
|
className: cn("w-full max-w-48", className),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.mjs","names":["select"],"sources":["../../../src/components/atoms/select.tsx"],"sourcesContent":["import React from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { select } from '../../core';\n\nconst {\n Select: Core,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} = select;\n\ninterface Option {\n label: React.ReactNode;\n value: string;\n}\n\ninterface OptionGroup {\n label: React.ReactNode;\n options: Option[];\n}\n\nconst isGroup = (option: Option | OptionGroup): option is OptionGroup => {\n return 'options' in option && Array.isArray(option.options);\n};\n\nexport interface Props extends Omit<\n React.ComponentProps<typeof Core>,\n 'onValueChange'\n> {\n placeholder?: string;\n className?: string;\n options?: (Option | OptionGroup)[];\n onChange?: (value: string) => void;\n}\n\nconst Select = ({\n className,\n placeholder,\n options,\n onChange,\n ...props\n}: Props) => {\n return (\n <Core
|
|
1
|
+
{"version":3,"file":"select.mjs","names":["select"],"sources":["../../../src/components/atoms/select.tsx"],"sourcesContent":["import React from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { select } from '../../core';\n\nconst {\n Select: Core,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} = select;\n\ninterface Option {\n label: React.ReactNode;\n value: string;\n}\n\ninterface OptionGroup {\n label: React.ReactNode;\n options: Option[];\n}\n\nconst isGroup = (option: Option | OptionGroup): option is OptionGroup => {\n return 'options' in option && Array.isArray(option.options);\n};\n\nexport interface Props extends Omit<\n React.ComponentProps<typeof Core>,\n 'onValueChange'\n> {\n placeholder?: string;\n className?: string;\n options?: (Option | OptionGroup)[];\n onChange?: (value: string) => void;\n}\n\nconst Select = ({\n className,\n placeholder,\n options,\n onChange,\n ...props\n}: Props) => {\n const items = options?.flatMap(option =>\n isGroup(option) ? option.options : option,\n );\n\n return (\n <Core\n items={items}\n onValueChange={value => {\n if (value !== null) {\n onChange?.(value);\n }\n }}\n {...props}\n >\n <SelectTrigger className={cn('w-full max-w-48', className)}>\n <SelectValue placeholder={placeholder} />\n </SelectTrigger>\n <SelectContent>\n {options?.map((option, index) =>\n isGroup(option) ? (\n <SelectGroup key={index}>\n <SelectLabel>{option.label}</SelectLabel>\n {option.options.map(item => (\n <SelectItem key={item.value} value={item.value}>\n {item.label}\n </SelectItem>\n ))}\n </SelectGroup>\n ) : (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ),\n )}\n </SelectContent>\n </Core>\n );\n};\n\nexport default Select;\n"],"mappings":";;;;;AAMA,MAAM,EACJ,QAAQ,MACR,eACA,aACA,YACA,aACA,eACA,gBACEA;AAYJ,MAAM,WAAW,WAAwD;CACvE,OAAO,aAAa,UAAU,MAAM,QAAQ,OAAO,OAAO;AAC5D;AAYA,MAAM,UAAU,EACd,WACA,aACA,SACA,UACA,GAAG,YACQ;CACX,MAAM,QAAQ,SAAS,SAAQ,WAC7B,QAAQ,MAAM,IAAI,OAAO,UAAU,MACrC;CAEA,OACE,qBAAC,MAAD;EACS;EACP,gBAAe,UAAS;GACtB,IAAI,UAAU,MACZ,WAAW,KAAK;EAEpB;EACA,GAAI;EAPN,UAAA,CASE,oBAAC,eAAD;GAAe,WAAW,GAAG,mBAAmB,SAAS;GACvD,UAAA,oBAAC,aAAD,EAA0B,YAAc,CAAA;EAC3B,CAAA,GACf,oBAAC,eAAD,EAAA,UACG,SAAS,KAAK,QAAQ,UACrB,QAAQ,MAAM,IACZ,qBAAC,aAAD,EAAA,UAAA,CACE,oBAAC,aAAD,EAAA,UAAc,OAAO,MAAmB,CAAA,GACvC,OAAO,QAAQ,KAAI,SAClB,oBAAC,YAAD;GAA6B,OAAO,KAAK;GACtC,UAAA,KAAK;EACI,GAFK,KAAK,KAEV,CACb,CACU,EAAA,GAPK,KAOL,IAEb,oBAAC,YAAD;GAA+B,OAAO,OAAO;GAC1C,UAAA,OAAO;EACE,GAFK,OAAO,KAEZ,CAEhB,EACa,CAAA,CACX;;AAEV"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slider.mjs","names":["slider"],"sources":["../../../../src/components/atoms/slider/slider.tsx"],"sourcesContent":["'use client';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { slider } from '../../../core';\n\nconst { Slider: Core } = slider;\n\n/** A single thumb (`number`) or a two-thumb range (`[min, max]`). */\nexport type SliderValue = number | number[];\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'span'>,\n 'onChange' | 'defaultValue' | 'dir'\n> {\n value?: SliderValue;\n defaultValue?: SliderValue;\n min?: number;\n max?: number;\n step?: number;\n disabled?: boolean;\n orientation?: 'horizontal' | 'vertical';\n onChange?: (value: SliderValue) => void;\n}\n\nconst toArray = (value: SliderValue | undefined): number[] | undefined => {\n if (value === undefined) {\n return undefined;\n }\n\n return Array.isArray(value) ? value : [value];\n};\n\nconst Slider = ({\n value: _value,\n defaultValue,\n min = 0,\n max = 100,\n step = 1,\n disabled,\n orientation = 'horizontal',\n onChange: _onChange = () => {},\n className,\n ...props\n}: Props) => {\n // A `number[]` value/defaultValue means the consumer wants a range; a bare\n // `number` means a single thumb.
|
|
1
|
+
{"version":3,"file":"slider.mjs","names":["slider"],"sources":["../../../../src/components/atoms/slider/slider.tsx"],"sourcesContent":["'use client';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { slider } from '../../../core';\n\nconst { Slider: Core } = slider;\n\n/** A single thumb (`number`) or a two-thumb range (`[min, max]`). */\nexport type SliderValue = number | number[];\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'span'>,\n 'onChange' | 'defaultValue' | 'dir'\n> {\n value?: SliderValue;\n defaultValue?: SliderValue;\n min?: number;\n max?: number;\n step?: number;\n disabled?: boolean;\n orientation?: 'horizontal' | 'vertical';\n onChange?: (value: SliderValue) => void;\n}\n\nconst toArray = (value: SliderValue | undefined): number[] | undefined => {\n if (value === undefined) {\n return undefined;\n }\n\n return Array.isArray(value) ? value : [value];\n};\n\nconst Slider = ({\n value: _value,\n defaultValue,\n min = 0,\n max = 100,\n step = 1,\n disabled,\n orientation = 'horizontal',\n onChange: _onChange = () => {},\n className,\n ...props\n}: Props) => {\n // A `number[]` value/defaultValue means the consumer wants a range; a bare\n // `number` means a single thumb. Normalize internally and hand the original\n // shape back through `onChange`.\n const isRange = Array.isArray(_value ?? defaultValue);\n\n const [value, onChange] = useControllableState<number[]>({\n value: toArray(_value),\n defaultValue: toArray(defaultValue) ?? [min],\n onChange: next => {\n _onChange(isRange ? next : (next[0] ?? min));\n },\n });\n\n return (\n <Core\n value={value}\n min={min}\n max={max}\n step={step}\n disabled={disabled}\n orientation={orientation}\n className={cn(className)}\n onValueChange={onChange}\n {...props}\n />\n );\n};\n\nexport default Slider;\n"],"mappings":";;;;;;AAQA,MAAM,EAAE,QAAQ,SAASA;AAmBzB,MAAM,WAAW,UAAyD;CACxE,IAAI,UAAU,KAAA,GACZ;CAGF,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC9C;AAEA,MAAM,UAAU,EACd,OAAO,QACP,cACA,MAAM,GACN,MAAM,KACN,OAAO,GACP,UACA,cAAc,cACd,UAAU,kBAAkB,CAAC,GAC7B,WACA,GAAG,YACQ;CAIX,MAAM,UAAU,MAAM,QAAQ,UAAU,YAAY;CAEpD,MAAM,CAAC,OAAO,YAAY,qBAA+B;EACvD,OAAO,QAAQ,MAAM;EACrB,cAAc,QAAQ,YAAY,KAAK,CAAC,GAAG;EAC3C,WAAU,SAAQ;GAChB,UAAU,UAAU,OAAQ,KAAK,MAAM,GAAI;EAC7C;CACF,CAAC;CAED,OACE,oBAAC,MAAD;EACS;EACF;EACA;EACC;EACI;EACG;EACb,WAAW,GAAG,SAAS;EACvB,eAAe;EACf,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ComponentSize } from "../../providers/config/types.mjs";
|
|
2
2
|
//#region src/components/atoms/switch.d.ts
|
|
3
|
-
interface Props extends Omit<React.ComponentPropsWithoutRef<'
|
|
3
|
+
interface Props extends Omit<React.ComponentPropsWithoutRef<'span'>, 'onChange'> {
|
|
4
4
|
classNames?: {
|
|
5
5
|
track?: string;
|
|
6
6
|
handle?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.d.mts","names":[],"sources":["../../../src/components/atoms/switch.tsx"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"switch.d.mts","names":[],"sources":["../../../src/components/atoms/switch.tsx"],"mappings":";;UAiDiB,cAAc,KAC7B,MAAM;EAGN;IACE;IACA;;;;;;;;;EASF,OAAO;EACP;EACA;EACA;EACA,YAAY;EACZ,kBAAkB,MAAM;EACxB,oBAAoB,MAAM;;cAGtB,WAAU,WAAA,YAAA,MAAA,gBAAA,SAAA,UAAA,UAAA,WAAA,iBAAA,sBAAA,SAUb,0BAAK,IAAA"}
|
|
@@ -11,7 +11,7 @@ const sizeConfig = {
|
|
|
11
11
|
core: "sm",
|
|
12
12
|
track: "h-6! w-10!",
|
|
13
13
|
handle: "size-5!",
|
|
14
|
-
handleChecked: "data-
|
|
14
|
+
handleChecked: "data-unchecked:left-0.5 data-checked:left-[calc(100%-22px)]",
|
|
15
15
|
fontSize: "text-[10px]",
|
|
16
16
|
marginChecked: "mr-6 ml-1.5",
|
|
17
17
|
marginUnchecked: "mr-1.5 ml-6"
|
|
@@ -20,7 +20,7 @@ const sizeConfig = {
|
|
|
20
20
|
core: "default",
|
|
21
21
|
track: "h-8! w-12!",
|
|
22
22
|
handle: "size-6!",
|
|
23
|
-
handleChecked: "data-
|
|
23
|
+
handleChecked: "data-unchecked:left-0.5 data-checked:left-[calc(100%-26px)]",
|
|
24
24
|
fontSize: "text-xs",
|
|
25
25
|
marginChecked: "mr-7 ml-2",
|
|
26
26
|
marginUnchecked: "mr-2 ml-7"
|
|
@@ -29,7 +29,7 @@ const sizeConfig = {
|
|
|
29
29
|
core: "default",
|
|
30
30
|
track: "h-10! w-16!",
|
|
31
31
|
handle: "size-8!",
|
|
32
|
-
handleChecked: "data-
|
|
32
|
+
handleChecked: "data-unchecked:left-0.5 data-checked:left-[calc(100%-34px)]",
|
|
33
33
|
fontSize: "text-sm",
|
|
34
34
|
marginChecked: "mr-9 ml-2.5",
|
|
35
35
|
marginUnchecked: "mr-2.5 ml-9"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.mjs","names":["switchComponent"],"sources":["../../../src/components/atoms/switch.tsx"],"sourcesContent":["'use client';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { type ComponentSize, useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { switchComponent } from '../../core';\n\nconst { Switch: Core } = switchComponent;\n\n// Keyed by the shared `ComponentSize` vocabulary (#350). The `calc` offset on\n// each `handleChecked` is `handle width + 2px` (the `left-0.5` inset), so the\n// handle lands flush at both ends — it must be recomputed per row, not copied.\nconst sizeConfig = {\n small: {\n core: 'sm' as const,\n track: 'h-6! w-10!',\n handle: 'size-5!',\n handleChecked:\n 'data-
|
|
1
|
+
{"version":3,"file":"switch.mjs","names":["switchComponent"],"sources":["../../../src/components/atoms/switch.tsx"],"sourcesContent":["'use client';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { type ComponentSize, useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { switchComponent } from '../../core';\n\nconst { Switch: Core } = switchComponent;\n\n// Keyed by the shared `ComponentSize` vocabulary (#350). The `calc` offset on\n// each `handleChecked` is `handle width + 2px` (the `left-0.5` inset), so the\n// handle lands flush at both ends — it must be recomputed per row, not copied.\nconst sizeConfig = {\n small: {\n core: 'sm' as const,\n track: 'h-6! w-10!',\n handle: 'size-5!',\n handleChecked:\n 'data-unchecked:left-0.5 data-checked:left-[calc(100%-22px)]',\n fontSize: 'text-[10px]',\n marginChecked: 'mr-6 ml-1.5',\n marginUnchecked: 'mr-1.5 ml-6',\n },\n middle: {\n core: 'default' as const,\n track: 'h-8! w-12!',\n handle: 'size-6!',\n handleChecked:\n 'data-unchecked:left-0.5 data-checked:left-[calc(100%-26px)]',\n fontSize: 'text-xs',\n marginChecked: 'mr-7 ml-2',\n marginUnchecked: 'mr-2 ml-7',\n },\n large: {\n core: 'default' as const,\n track: 'h-10! w-16!',\n handle: 'size-8!',\n handleChecked:\n 'data-unchecked:left-0.5 data-checked:left-[calc(100%-34px)]',\n fontSize: 'text-sm',\n marginChecked: 'mr-9 ml-2.5',\n marginUnchecked: 'mr-2.5 ml-9',\n },\n} satisfies Record<ComponentSize, unknown>;\n\n// Base UI's Switch renders a `<span>` (plus a hidden `<input>`), not the\n// `<button>` Radix used — so the forwarded host props are span-based now.\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'span'>,\n 'onChange'\n> {\n classNames?: {\n track?: string;\n handle?: string;\n };\n /**\n * Density on the shared `ComponentSize` scale (`small` | `middle` | `large`),\n * falling back to the nearest `Config`'s `componentSize`, then `middle`.\n *\n * `medium` is accepted as a deprecated alias of `middle` — kept so existing\n * `size=\"medium\"` calls keep working; removed in the next major.\n */\n size?: ComponentSize | 'medium';\n defaultChecked?: boolean;\n checked?: boolean;\n disabled?: boolean;\n onChange?: (checked: boolean) => void;\n checkedChildren?: React.ReactNode;\n unCheckedChildren?: React.ReactNode;\n}\n\nconst Switch = ({\n className,\n classNames,\n size,\n defaultChecked,\n checked: _checked,\n onChange: _onChange = () => {},\n checkedChildren,\n unCheckedChildren,\n ...props\n}: Props) => {\n const [checked, onChange] = useControllableState<boolean>({\n value: _checked,\n defaultValue: defaultChecked ?? false,\n onChange: _onChange,\n });\n\n const { componentSize } = useConfig();\n // `medium` is the deprecated spelling of `middle`; an explicit `size` wins,\n // then the Config default, then `middle`.\n const resolvedSize =\n (size === 'medium' ? 'middle' : size) ?? componentSize ?? 'middle';\n\n const hasChildren = !!(checkedChildren || unCheckedChildren);\n const config = sizeConfig[resolvedSize];\n\n return (\n <Core\n checked={checked}\n size={config.core}\n className={cn(\n 'relative',\n config.track,\n hasChildren && 'w-auto! overflow-hidden',\n className,\n classNames?.track,\n //\n )}\n handleClassName={cn(\n config.handle,\n '!absolute top-1/2 !-translate-y-1/2 !translate-x-0',\n 'transition-[left] duration-200 will-change-[left]',\n config.handleChecked,\n classNames?.handle,\n //\n )}\n onCheckedChange={checked => {\n onChange(checked);\n }}\n {...props}\n >\n {hasChildren && (\n <span\n className={cn(\n `grid leading-none transition-[margin] duration-200\n will-change-[margin]`,\n config.fontSize,\n checked\n ? [config.marginChecked, 'text-primary-foreground']\n : [config.marginUnchecked, 'text-foreground'],\n //\n )}\n >\n <span\n className={cn(\n 'col-start-1 row-start-1 transition-opacity duration-200',\n checked ? 'opacity-100' : 'opacity-0',\n )}\n >\n {checkedChildren}\n </span>\n <span\n className={cn(\n 'col-start-1 row-start-1 transition-opacity duration-200',\n checked ? 'opacity-0' : 'opacity-100',\n )}\n >\n {unCheckedChildren}\n </span>\n </span>\n )}\n </Core>\n );\n};\n\nexport default Switch;\n"],"mappings":";;;;;;;AASA,MAAM,EAAE,QAAQ,SAASA;AAKzB,MAAM,aAAa;CACjB,OAAO;EACL,MAAM;EACN,OAAO;EACP,QAAQ;EACR,eACE;EACF,UAAU;EACV,eAAe;EACf,iBAAiB;CACnB;CACA,QAAQ;EACN,MAAM;EACN,OAAO;EACP,QAAQ;EACR,eACE;EACF,UAAU;EACV,eAAe;EACf,iBAAiB;CACnB;CACA,OAAO;EACL,MAAM;EACN,OAAO;EACP,QAAQ;EACR,eACE;EACF,UAAU;EACV,eAAe;EACf,iBAAiB;CACnB;AACF;AA4BA,MAAM,UAAU,EACd,WACA,YACA,MACA,gBACA,SAAS,UACT,UAAU,kBAAkB,CAAC,GAC7B,iBACA,mBACA,GAAG,YACQ;CACX,MAAM,CAAC,SAAS,YAAY,qBAA8B;EACxD,OAAO;EACP,cAAc,kBAAkB;EAChC,UAAU;CACZ,CAAC;CAED,MAAM,EAAE,kBAAkB,UAAU;CAGpC,MAAM,gBACH,SAAS,WAAW,WAAW,SAAS,iBAAiB;CAE5D,MAAM,cAAc,CAAC,EAAE,mBAAmB;CAC1C,MAAM,SAAS,WAAW;CAE1B,OACE,oBAAC,MAAD;EACW;EACT,MAAM,OAAO;EACb,WAAW,GACT,YACA,OAAO,OACP,eAAe,2BACf,WACA,YAAY,KAEd;EACA,iBAAiB,GACf,OAAO,QACP,sDACA,qDACA,OAAO,eACP,YAAY,MAEd;EACA,kBAAiB,YAAW;GAC1B,SAAS,OAAO;EAClB;EACA,GAAI;EAEH,UAAA,eACC,qBAAC,QAAD;GACE,WAAW,GACT;mCAEA,OAAO,UACP,UACI,CAAC,OAAO,eAAe,yBAAyB,IAChD,CAAC,OAAO,iBAAiB,iBAAiB,CAEhD;GATF,UAAA,CAWE,oBAAC,QAAD;IACE,WAAW,GACT,2DACA,UAAU,gBAAgB,WAC5B;IAEC,UAAA;GACG,CAAA,GACN,oBAAC,QAAD;IACE,WAAW,GACT,2DACA,UAAU,cAAc,aAC1B;IAEC,UAAA;GACG,CAAA,CACF;;CAEJ,CAAA;AAEV"}
|
|
@@ -6,19 +6,12 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
//#region src/components/molecules/collapse.tsx
|
|
7
7
|
const { Accordion, AccordionItem, AccordionTrigger, AccordionContent } = accordion_exports;
|
|
8
8
|
const Collapse = ({ expandIcon, accordion = false, items = [], className, classNames, defaultActiveKey, activeKey: _activeKey, onChange: _onChange, ...props }) => {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
type: "single",
|
|
12
|
-
onValueChange: (value) => {
|
|
13
|
-
_onChange?.(value ? [value] : []);
|
|
14
|
-
},
|
|
15
|
-
...controlled ? { value: `${_activeKey?.[0] ?? ""}` } : { defaultValue: `${defaultActiveKey?.[0] ?? ""}` }
|
|
16
|
-
} : {
|
|
17
|
-
type: "multiple",
|
|
9
|
+
const accordionProps = {
|
|
10
|
+
multiple: !accordion,
|
|
18
11
|
onValueChange: (values) => {
|
|
19
12
|
_onChange?.(values);
|
|
20
13
|
},
|
|
21
|
-
...
|
|
14
|
+
..._activeKey !== void 0 ? { value: (_activeKey ?? []).map((key) => `${key}`) } : { defaultValue: (defaultActiveKey ?? []).map((key) => `${key}`) }
|
|
22
15
|
};
|
|
23
16
|
return /* @__PURE__ */ jsx(Accordion, {
|
|
24
17
|
...props,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collapse.mjs","names":["accordion"],"sources":["../../../src/components/molecules/collapse.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { accordion } from '../../core';\n\nconst { Accordion, AccordionItem, AccordionTrigger, AccordionContent } =\n accordion;\n\ninterface Item {\n key: React.Key;\n label: React.ReactNode;\n disabled?: boolean;\n children: React.ReactNode;\n}\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'onChange' | 'defaultValue' | 'value' | 'dir'\n> {\n items?: Item[];\n accordion?: boolean;\n expandIcon?: React.ReactNode;\n classNames?: {\n item?: string;\n header?: string;\n body?: string;\n };\n defaultActiveKey?: string[] | number[];\n activeKey?: string[] | number[];\n onChange?: (keys: string[]) => void;\n}\n\nconst Collapse = ({\n expandIcon,\n accordion = false,\n items = [],\n className,\n classNames,\n defaultActiveKey,\n activeKey: _activeKey,\n onChange: _onChange,\n ...props\n}: Props) => {\n const controlled = _activeKey !== undefined;\n\n
|
|
1
|
+
{"version":3,"file":"collapse.mjs","names":["accordion"],"sources":["../../../src/components/molecules/collapse.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { accordion } from '../../core';\n\nconst { Accordion, AccordionItem, AccordionTrigger, AccordionContent } =\n accordion;\n\ninterface Item {\n key: React.Key;\n label: React.ReactNode;\n disabled?: boolean;\n children: React.ReactNode;\n}\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'onChange' | 'defaultValue' | 'value' | 'dir'\n> {\n items?: Item[];\n accordion?: boolean;\n expandIcon?: React.ReactNode;\n classNames?: {\n item?: string;\n header?: string;\n body?: string;\n };\n defaultActiveKey?: string[] | number[];\n activeKey?: string[] | number[];\n onChange?: (keys: string[]) => void;\n}\n\nconst Collapse = ({\n expandIcon,\n accordion = false,\n items = [],\n className,\n classNames,\n defaultActiveKey,\n activeKey: _activeKey,\n onChange: _onChange,\n ...props\n}: Props) => {\n const controlled = _activeKey !== undefined;\n\n // Base UI's accordion has no `type` and always models the open set as an\n // array; `multiple` (default false) is the only single-vs-multiple switch.\n // `accordion` here means \"one panel open at a time\", so `multiple = !accordion`.\n const accordionProps = {\n multiple: !accordion,\n onValueChange: (values: string[]) => {\n _onChange?.(values);\n },\n ...(controlled\n ? { value: (_activeKey ?? []).map(key => `${key}`) }\n : { defaultValue: (defaultActiveKey ?? []).map(key => `${key}`) }),\n };\n\n return (\n <Accordion {...props} className={className} {...accordionProps}>\n {items.map(({ key, label, children, disabled }) => (\n <AccordionItem\n key={key}\n value={String(key)}\n className={cn(\n 'border-none',\n classNames?.item,\n //\n )}\n disabled={disabled}\n >\n <AccordionTrigger\n className={cn(\n 'hover:no-underline',\n classNames?.header,\n disabled && 'cursor-no-drop opacity-50',\n //\n )}\n expandIcon={expandIcon}\n disabled={disabled}\n >\n {label}\n </AccordionTrigger>\n <AccordionContent\n className={cn(\n classNames?.body,\n //\n )}\n >\n {children}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n );\n};\n\nexport default Collapse;\n"],"mappings":";;;;;;AAQA,MAAM,EAAE,WAAW,eAAe,kBAAkB,qBAClDA;AA0BF,MAAM,YAAY,EAChB,YACA,YAAY,OACZ,QAAQ,CAAC,GACT,WACA,YACA,kBACA,WAAW,YACX,UAAU,WACV,GAAG,YACQ;CAMX,MAAM,iBAAiB;EACrB,UAAU,CAAC;EACX,gBAAgB,WAAqB;GACnC,YAAY,MAAM;EACpB;EACA,GAViB,eAAe,KAAA,IAW5B,EAAE,QAAQ,cAAc,CAAC,EAAA,CAAG,KAAI,QAAO,GAAG,KAAK,EAAE,IACjD,EAAE,eAAe,oBAAoB,CAAC,EAAA,CAAG,KAAI,QAAO,GAAG,KAAK,EAAE;CACpE;CAEA,OACE,oBAAC,WAAD;EAAW,GAAI;EAAkB;EAAW,GAAI;EAC7C,UAAA,MAAM,KAAK,EAAE,KAAK,OAAO,UAAU,eAClC,qBAAC,eAAD;GAEE,OAAO,OAAO,GAAG;GACjB,WAAW,GACT,eACA,YAAY,IAEd;GACU;GARZ,UAAA,CAUE,oBAAC,kBAAD;IACE,WAAW,GACT,sBACA,YAAY,QACZ,YAAY,2BAEd;IACY;IACF;IAET,UAAA;GACe,CAAA,GAClB,oBAAC,kBAAD;IACE,WAAW,GACT,YAAY,IAEd;IAEC;GACe,CAAA,CACL;EA7BR,GAAA,GA6BQ,CAChB;CACQ,CAAA;AAEf"}
|
|
@@ -11,7 +11,6 @@ interface Props {
|
|
|
11
11
|
size?: 'small' | 'medium' | 'large' | 'full' | string;
|
|
12
12
|
maskClosable?: boolean;
|
|
13
13
|
handlebar?: boolean;
|
|
14
|
-
draggable?: boolean;
|
|
15
14
|
rounded?: boolean;
|
|
16
15
|
mask?: boolean;
|
|
17
16
|
className?: string;
|
|
@@ -30,7 +29,7 @@ interface Props {
|
|
|
30
29
|
container?: HTMLElement;
|
|
31
30
|
onClose: () => void;
|
|
32
31
|
}
|
|
33
|
-
declare const Drawer: ({ open, title, extra, footer, closable, closeIcon, direction, size, maskClosable, handlebar,
|
|
32
|
+
declare const Drawer: ({ open, title, extra, footer, closable, closeIcon, direction, size, maskClosable, handlebar, rounded, mask, className, classNames, style, children, container, onClose, ...props }: Props) => import("react").JSX.Element;
|
|
34
33
|
//#endregion
|
|
35
34
|
export { Props, Drawer as default };
|
|
36
35
|
//# sourceMappingURL=drawer.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawer.d.mts","names":[],"sources":["../../../src/components/organisms/drawer.tsx"],"mappings":";UA2CiB;EACf;EACA,WAAW,MAAM;EACjB,QAAQ,MAAM;EACd,QAAQ,MAAM;EACd,SAAS,MAAM;EACf;EACA,YAAY,MAAM;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA
|
|
1
|
+
{"version":3,"file":"drawer.d.mts","names":[],"sources":["../../../src/components/organisms/drawer.tsx"],"mappings":";UA2CiB;EACf;EACA,WAAW,MAAM;EACjB,QAAQ,MAAM;EACd,QAAQ,MAAM;EACd,SAAS,MAAM;EACf;EACA,YAAY,MAAM;EAClB;EACA;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ,MAAM;EACd;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEF,YAAY;EACZ;;cA8BI,WAAU,MAAA,OAAA,OAAA,QAAA,UAAA,WAAA,WAAA,MAAA,cAAA,WAAA,SAAA,MAAA,WAAA,YAAA,OAAA,UAAA,WAAA,YAAA,SAoBb,0BAAK,IAAA"}
|