@jbpark/ui-kit 3.6.0 → 3.8.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/Card.d.mts +1 -1
- package/dist/Card.d.mts.map +1 -1
- package/dist/Card.mjs.map +1 -1
- package/dist/Space.d.mts +1 -1
- package/dist/Space.d.mts.map +1 -1
- package/dist/Space.mjs +3 -1
- package/dist/Space.mjs.map +1 -1
- package/dist/components/atoms/checkbox/group.d.mts.map +1 -1
- package/dist/components/atoms/checkbox/group.mjs +4 -3
- package/dist/components/atoms/checkbox/group.mjs.map +1 -1
- package/dist/components/atoms/color-picker.d.mts +7 -1
- package/dist/components/atoms/color-picker.d.mts.map +1 -1
- package/dist/components/atoms/color-picker.mjs +8 -1
- package/dist/components/atoms/color-picker.mjs.map +1 -1
- package/dist/components/atoms/option-group.mjs +11 -1
- package/dist/components/atoms/option-group.mjs.map +1 -1
- package/dist/components/atoms/radio/group.d.mts.map +1 -1
- package/dist/components/atoms/radio/group.mjs +3 -2
- package/dist/components/atoms/radio/group.mjs.map +1 -1
- package/dist/components/atoms/spin.d.mts +2 -1
- package/dist/components/atoms/spin.d.mts.map +1 -1
- package/dist/components/atoms/spin.mjs +3 -2
- package/dist/components/atoms/spin.mjs.map +1 -1
- package/dist/components/molecules/collapse.d.mts +1 -1
- package/dist/components/molecules/collapse.d.mts.map +1 -1
- package/dist/components/molecules/collapse.mjs +1 -1
- package/dist/components/molecules/collapse.mjs.map +1 -1
- package/dist/components/molecules/dropdown.d.mts +2 -2
- package/dist/components/molecules/dropdown.d.mts.map +1 -1
- package/dist/components/molecules/dropdown.mjs +25 -12
- package/dist/components/molecules/dropdown.mjs.map +1 -1
- package/dist/components/molecules/index.d.mts +9 -6
- package/dist/components/molecules/marquees/item.d.mts.map +1 -1
- package/dist/components/molecules/marquees/item.mjs +3 -8
- package/dist/components/molecules/marquees/item.mjs.map +1 -1
- package/dist/components/molecules/menu/item/item.mjs +27 -11
- package/dist/components/molecules/menu/item/item.mjs.map +1 -1
- package/dist/components/molecules/menu/menu.d.mts.map +1 -1
- package/dist/components/molecules/menu/menu.mjs +9 -7
- package/dist/components/molecules/menu/menu.mjs.map +1 -1
- package/dist/components/molecules/reveals/reveals.d.mts +5 -0
- package/dist/components/molecules/reveals/reveals.d.mts.map +1 -1
- package/dist/components/molecules/reveals/reveals.mjs +6 -1
- package/dist/components/molecules/reveals/reveals.mjs.map +1 -1
- package/dist/components/molecules/splitter/splitter.mjs +2 -2
- package/dist/components/molecules/splitter/splitter.mjs.map +1 -1
- package/dist/components/molecules/upload.d.mts +11 -2
- package/dist/components/molecules/upload.d.mts.map +1 -1
- package/dist/components/molecules/upload.mjs +23 -6
- package/dist/components/molecules/upload.mjs.map +1 -1
- package/dist/components/organisms/modal.mjs +1 -1
- package/dist/components/organisms/toast.mjs +1 -1
- package/dist/components/templates/layout/header.mjs +1 -1
- package/dist/components/templates/layout/header.mjs.map +1 -1
- package/dist/components/templates/layout/layout.d.mts.map +1 -1
- package/dist/components/templates/layout/layout.mjs +23 -7
- package/dist/components/templates/layout/layout.mjs.map +1 -1
- package/dist/components/templates/layout/sider-context.mjs +20 -0
- package/dist/components/templates/layout/sider-context.mjs.map +1 -0
- package/dist/components/templates/layout/sider.d.mts.map +1 -1
- package/dist/components/templates/layout/sider.mjs +4 -2
- package/dist/components/templates/layout/sider.mjs.map +1 -1
- package/dist/index.d.mts +12 -9
- package/dist/providers/Config/index.mjs +6 -2
- package/dist/providers/Config/index.mjs.map +1 -1
- package/dist/style.css +72 -9
- package/package.json +2 -1
package/dist/Card.d.mts
CHANGED
package/dist/Card.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.d.mts","names":[],"sources":["../src/components/molecules/card.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"Card.d.mts","names":[],"sources":["../src/components/molecules/card.tsx"],"mappings":";;;UAEiB,KAAA,SAAc,IAAA,CAC7B,KAAA,CAAM,qBAAA;EAGN,KAAA,GAAQ,KAAA,CAAM,SAAA;EACd,OAAA;EACA,UAAA;IACE,KAAA;IACA,IAAA;EAAA;AAAA;AAAA,cAIE,IAAA;EAAQ,KAAA;EAAA,QAAA;EAAA,SAAA;EAAA,UAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAOX,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/Card.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.mjs","names":[],"sources":["../src/components/molecules/card.tsx"],"sourcesContent":["import { cn, renderConditional } from '@repo/ui/utils';\n\
|
|
1
|
+
{"version":3,"file":"Card.mjs","names":[],"sources":["../src/components/molecules/card.tsx"],"sourcesContent":["import { cn, renderConditional } from '@repo/ui/utils';\n\nexport interface Props extends Omit<\n React.ComponentPropsWithRef<'div'>,\n 'title'\n> {\n title?: React.ReactNode;\n variant?: 'outlined' | 'borderless';\n classNames?: {\n title?: string;\n body?: string;\n };\n}\n\nconst Card = ({\n title,\n children,\n className,\n classNames,\n variant = 'outlined',\n ...props\n}: Props) => {\n return (\n <div\n className={cn(\n 'w-full',\n 'rounded-lg p-4',\n 'bg-card text-card-foreground shadow-sm transition-all',\n variant === 'outlined' && 'border-border border',\n className,\n //\n )}\n {...props}\n >\n {renderConditional(title, v => (\n <div\n className={cn(\n 'mb-4 font-bold',\n classNames?.title,\n //\n )}\n >\n {v}\n </div>\n ))}\n <div\n className={cn(\n classNames?.body,\n //\n )}\n >\n {children}\n </div>\n </div>\n );\n};\n\nexport default Card;\n"],"mappings":";;;;AAcA,MAAM,QAAQ,EACZ,OACA,UACA,WACA,YACA,UAAU,YACV,GAAG,YACQ;AACX,QACE,qBAAC;EACC,WAAW,GACT,UACA,kBACA,yDACA,YAAY,cAAc,wBAC1B,UAED;EACD,GAAI;aAEH,kBAAkB,QAAO,MACxB,oBAAC;GACC,WAAW,GACT,kBACA,YAAY,MAEb;aAEA;IACG,CACN,EACF,oBAAC;GACC,WAAW,GACT,YAAY,KAEb;GAEA;IACG;GACF"}
|
package/dist/Space.d.mts
CHANGED
package/dist/Space.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Space.d.mts","names":[],"sources":["../src/components/molecules/space.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"Space.d.mts","names":[],"sources":["../src/components/molecules/space.tsx"],"mappings":";;;UAMiB,KAAA,SAAc,KAAA,CAAM,qBAAA;EACnC,OAAA;EACA,MAAA,GAAS,KAAA,CAAM,SAAA;EACf,WAAA;EACA,IAAA;EACA,KAAA;EACA,IAAA;EACA,KAAA,GAAQ,KAAA,CAAM,SAAA;EACd,IAAA;IACE,IAAA;IACA,IAAA;EAAA;AAAA;AAAA,cAiBE,KAAA;EAAS,OAAA;EAAA,MAAA;EAAA,QAAA;EAAA,IAAA;EAAA,WAAA;EAAA,KAAA;EAAA,IAAA;EAAA,KAAA;EAAA,SAAA;EAAA,IAAA;EAAA,MAAA;EAAA,KAAA;EAAA,GAAA;AAAA,GAcZ,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/Space.mjs
CHANGED
|
@@ -19,7 +19,9 @@ const Space = ({ loading, loader, children, size = "middle", orientation = "hori
|
|
|
19
19
|
const [x, y] = typeof size === "string" ? sizes[size] || [0, 0] : Array.isArray(size) ? size : [size, size];
|
|
20
20
|
const count = Children.count(children);
|
|
21
21
|
if (loading) return /* @__PURE__ */ jsx("div", {
|
|
22
|
-
className: cn(className),
|
|
22
|
+
className: cn(hidden && "hidden", className),
|
|
23
|
+
style,
|
|
24
|
+
...props,
|
|
23
25
|
children: loader || /* @__PURE__ */ jsx(Skeleton, {})
|
|
24
26
|
});
|
|
25
27
|
return /* @__PURE__ */ jsx("div", {
|
package/dist/Space.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Space.mjs","names":[],"sources":["../src/components/molecules/space.tsx"],"sourcesContent":["import { Children } from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Skeleton from '../atoms/skeleton';\n\
|
|
1
|
+
{"version":3,"file":"Space.mjs","names":[],"sources":["../src/components/molecules/space.tsx"],"sourcesContent":["import { Children } from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Skeleton from '../atoms/skeleton';\n\nexport interface Props extends React.ComponentPropsWithRef<'div'> {\n loading?: boolean;\n loader?: React.ReactNode;\n orientation?: 'horizontal' | 'vertical';\n size?: 'small' | 'middle' | 'large' | number | number[];\n align?: 'start' | 'end' | 'center' | 'baseline';\n wrap?: boolean;\n split?: React.ReactNode;\n grid?: {\n rows?: number;\n cols?: number;\n };\n}\n\nconst sizes: Record<string, number[]> = {\n small: [4, 4],\n middle: [8, 8],\n large: [16, 16],\n};\n\nconst aligns: Record<string, string> = {\n start: 'items-start text-start',\n end: 'items-end text-end',\n center: 'items-center text-center',\n baseline: 'items-baseline text-baseline',\n};\n\nconst Space = ({\n loading,\n loader,\n children,\n size = 'middle',\n orientation = 'horizontal',\n align = 'center',\n wrap = false,\n split,\n className,\n grid,\n hidden,\n style,\n ...props\n}: Props) => {\n const [x, y] =\n typeof size === 'string'\n ? sizes[size] || [0, 0]\n : Array.isArray(size)\n ? size\n : [size, size];\n const count = Children.count(children);\n\n if (loading) {\n return (\n <div\n className={cn(hidden && 'hidden', className)}\n style={style}\n {...props}\n >\n {loader || <Skeleton />}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n 'flex flex-nowrap',\n orientation === 'horizontal' ? 'flex-row' : 'flex-col',\n wrap && 'flex-wrap',\n aligns[align],\n grid && 'grid',\n hidden && 'hidden',\n className,\n )}\n style={{\n columnGap: x,\n rowGap: y,\n gridTemplateRows: grid?.rows\n ? `repeat(${grid.rows}, minmax(0, 1fr))`\n : undefined,\n gridTemplateColumns: grid?.cols\n ? `repeat(${grid.cols}, minmax(0, 1fr))`\n : undefined,\n ...style,\n }}\n {...props}\n >\n {Children.map(children, (child, i) => (\n <>\n {child}\n {split && i < count - 1 && split}\n </>\n ))}\n </div>\n );\n};\n\nexport default Space;\n"],"mappings":";;;;;;AAoBA,MAAM,QAAkC;CACtC,OAAO,CAAC,GAAG,EAAE;CACb,QAAQ,CAAC,GAAG,EAAE;CACd,OAAO,CAAC,IAAI,GAAG;CAChB;AAED,MAAM,SAAiC;CACrC,OAAO;CACP,KAAK;CACL,QAAQ;CACR,UAAU;CACX;AAED,MAAM,SAAS,EACb,SACA,QACA,UACA,OAAO,UACP,cAAc,cACd,QAAQ,UACR,OAAO,OACP,OACA,WACA,MACA,QACA,OACA,GAAG,YACQ;CACX,MAAM,CAAC,GAAG,KACR,OAAO,SAAS,WACZ,MAAM,SAAS,CAAC,GAAG,EAAE,GACrB,MAAM,QAAQ,KAAK,GACjB,OACA,CAAC,MAAM,KAAK;CACpB,MAAM,QAAQ,SAAS,MAAM,SAAS;AAEtC,KAAI,QACF,QACE,oBAAC;EACC,WAAW,GAAG,UAAU,UAAU,UAAU;EACrC;EACP,GAAI;YAEH,UAAU,oBAAC,aAAW;GACnB;AAIV,QACE,oBAAC;EACC,WAAW,GACT,oBACA,gBAAgB,eAAe,aAAa,YAC5C,QAAQ,aACR,OAAO,QACP,QAAQ,QACR,UAAU,UACV,UACD;EACD,OAAO;GACL,WAAW;GACX,QAAQ;GACR,kBAAkB,MAAM,OACpB,UAAU,KAAK,KAAK,qBACpB;GACJ,qBAAqB,MAAM,OACvB,UAAU,KAAK,KAAK,qBACpB;GACJ,GAAG;GACJ;EACD,GAAI;YAEH,SAAS,IAAI,WAAW,OAAO,MAC9B,8CACG,OACA,SAAS,IAAI,QAAQ,KAAK,SAC1B,CACH;GACE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.d.mts","names":[],"sources":["../../../../src/components/atoms/checkbox/group.tsx"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"group.d.mts","names":[],"sources":["../../../../src/components/atoms/checkbox/group.tsx"],"mappings":";;;;UAkBiB,KAAA,SAAc,IAAA,CAC7B,KAAA,CAAM,wBAAA;EAGN,OAAA,GAAU,OAAA;EACV,WAAA;EACA,SAAA;EACA,UAAA,GAAa,qBAAA;EACb,YAAA,GAAe,WAAA;EACf,KAAA,GAAQ,WAAA;EAFK;EAIb,IAAA;EACA,QAAA;EACA,QAAA,IAAY,MAAA,EAAQ,WAAA;AAAA;AAAA,cAGhB,KAAA;EAAS,WAAA;EAAA,SAAA;EAAA,SAAA;EAAA,UAAA;EAAA,OAAA,EAAA,QAAA;EAAA,IAAA;EAAA,QAAA;EAAA,YAAA;EAAA,KAAA,EAAA,MAAA;EAAA,QAAA,EAAA,SAAA;EAAA,GAAA;AAAA,GAYZ,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { cn } from "../../../utils.mjs";
|
|
4
4
|
import Checkbox from "./checkbox.mjs";
|
|
5
|
-
import { normalizeOptions } from "../option-group.mjs";
|
|
5
|
+
import { normalizeOptions, warnOnDuplicateOptionValues } from "../option-group.mjs";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import { useControllableState } from "@jbpark/use-hooks";
|
|
8
8
|
|
|
@@ -14,13 +14,14 @@ const Group = ({ orientation = "vertical", placement = "left", className, classN
|
|
|
14
14
|
onChange: _onChange
|
|
15
15
|
});
|
|
16
16
|
const options = normalizeOptions(_options);
|
|
17
|
+
warnOnDuplicateOptionValues(options, "Checkbox.Group");
|
|
17
18
|
const onChange = (checked, optionValue) => {
|
|
18
19
|
setValue(checked ? [...value, optionValue] : value.filter((v) => v !== optionValue));
|
|
19
20
|
};
|
|
20
21
|
return /* @__PURE__ */ jsx("ul", {
|
|
21
22
|
...props,
|
|
22
23
|
className: cn(orientation === "vertical" ? "space-y-2" : "flex gap-2", className),
|
|
23
|
-
children: options.map((item) => {
|
|
24
|
+
children: options.map((item, index) => {
|
|
24
25
|
const checked = value.includes(item.value);
|
|
25
26
|
return /* @__PURE__ */ jsx("li", {
|
|
26
27
|
className: cn("flex", classNames?.wrapper),
|
|
@@ -34,7 +35,7 @@ const Group = ({ orientation = "vertical", placement = "left", className, classN
|
|
|
34
35
|
onChange: (checked) => onChange(checked, item.value),
|
|
35
36
|
children: item.label
|
|
36
37
|
})
|
|
37
|
-
}, String(item.value));
|
|
38
|
+
}, `${index}-${String(item.value)}`);
|
|
38
39
|
})
|
|
39
40
|
});
|
|
40
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.mjs","names":[],"sources":["../../../../src/components/atoms/checkbox/group.tsx"],"sourcesContent":["'use client';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport {\n type Option,\n type OptionGroupClassNames,\n type OptionValue,\n type Options,\n normalizeOptions,\n} from '../option-group';\nimport Checkbox from './checkbox';\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, shared across every option's checkbox. */\n name?: string;\n disabled?: boolean;\n onChange?: (values: OptionValue[]) => void;\n}\n\nconst Group = ({\n orientation = 'vertical',\n placement = 'left',\n className,\n classNames = {},\n options: _options = [],\n name,\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: defaultValue ?? [],\n onChange: _onChange,\n });\n\n const options: Option[] = normalizeOptions(_options);\n\n const onChange = (checked: boolean, optionValue: OptionValue) => {\n const nextValue = checked\n ? [...value, optionValue]\n : value.filter(v => v !== optionValue);\n\n setValue(nextValue);\n };\n\n return (\n <ul\n {...props}\n className={cn(\n orientation === 'vertical' ? 'space-y-2' : 'flex gap-2',\n className,\n )}\n >\n {options.map((item: Option) => {\n const checked = value.includes(item.value);\n\n return (\n <li\n key={String(item.value)}\n className={cn('flex', classNames?.wrapper)}\n >\n <Checkbox\n placement={placement}\n className={cn(classNames?.item)}\n name={name}\n value={item.value}\n checked={checked}\n disabled={disabled || item.disabled}\n onChange={checked => onChange(checked, item.value)}\n >\n {item.label}\n </Checkbox>\n </li>\n );\n })}\n </ul>\n );\n};\n\nexport default Group;\n"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"group.mjs","names":[],"sources":["../../../../src/components/atoms/checkbox/group.tsx"],"sourcesContent":["'use client';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport {\n type Option,\n type OptionGroupClassNames,\n type OptionValue,\n type Options,\n normalizeOptions,\n warnOnDuplicateOptionValues,\n} from '../option-group';\nimport Checkbox from './checkbox';\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, shared across every option's checkbox. */\n name?: string;\n disabled?: boolean;\n onChange?: (values: OptionValue[]) => void;\n}\n\nconst Group = ({\n orientation = 'vertical',\n placement = 'left',\n className,\n classNames = {},\n options: _options = [],\n name,\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: defaultValue ?? [],\n onChange: _onChange,\n });\n\n const options: Option[] = normalizeOptions(_options);\n warnOnDuplicateOptionValues(options, 'Checkbox.Group');\n\n const onChange = (checked: boolean, optionValue: OptionValue) => {\n const nextValue = checked\n ? [...value, optionValue]\n : value.filter(v => v !== optionValue);\n\n setValue(nextValue);\n };\n\n return (\n <ul\n {...props}\n className={cn(\n orientation === 'vertical' ? 'space-y-2' : 'flex gap-2',\n className,\n )}\n >\n {options.map((item: Option, index) => {\n const checked = value.includes(item.value);\n\n return (\n <li\n key={`${index}-${String(item.value)}`}\n className={cn('flex', classNames?.wrapper)}\n >\n <Checkbox\n placement={placement}\n className={cn(classNames?.item)}\n name={name}\n value={item.value}\n checked={checked}\n disabled={disabled || item.disabled}\n onChange={checked => onChange(checked, item.value)}\n >\n {item.label}\n </Checkbox>\n </li>\n );\n })}\n </ul>\n );\n};\n\nexport default Group;\n"],"mappings":";;;;;;;;;AAkCA,MAAM,SAAS,EACb,cAAc,YACd,YAAY,QACZ,WACA,aAAa,EAAE,EACf,SAAS,WAAW,EAAE,EACtB,MACA,UACA,cACA,OAAO,QACP,UAAU,kBAAkB,IAC5B,GAAG,YACQ;CACX,MAAM,CAAC,OAAO,YAAY,qBAAoC;EAC5D,OAAO;EACP,cAAc,gBAAgB,EAAE;EAChC,UAAU;EACX,CAAC;CAEF,MAAM,UAAoB,iBAAiB,SAAS;AACpD,6BAA4B,SAAS,iBAAiB;CAEtD,MAAM,YAAY,SAAkB,gBAA6B;AAK/D,WAJkB,UACd,CAAC,GAAG,OAAO,YAAY,GACvB,MAAM,QAAO,MAAK,MAAM,YAAY,CAErB;;AAGrB,QACE,oBAAC;EACC,GAAI;EACJ,WAAW,GACT,gBAAgB,aAAa,cAAc,cAC3C,UACD;YAEA,QAAQ,KAAK,MAAc,UAAU;GACpC,MAAM,UAAU,MAAM,SAAS,KAAK,MAAM;AAE1C,UACE,oBAAC;IAEC,WAAW,GAAG,QAAQ,YAAY,QAAQ;cAE1C,oBAAC;KACY;KACX,WAAW,GAAG,YAAY,KAAK;KACzB;KACN,OAAO,KAAK;KACH;KACT,UAAU,YAAY,KAAK;KAC3B,WAAU,YAAW,SAAS,SAAS,KAAK,MAAM;eAEjD,KAAK;MACG;MAbN,GAAG,MAAM,GAAG,OAAO,KAAK,MAAM,GAchC;IAEP;GACC"}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/components/atoms/color-picker.d.ts
|
|
4
|
-
interface Props extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue' | 'value' | 'onClick' | 'onKeyDown'> {
|
|
4
|
+
interface Props extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue' | 'value' | 'onClick' | 'onKeyDown' | 'open'> {
|
|
5
5
|
defaultValue?: string;
|
|
6
6
|
value?: string;
|
|
7
7
|
showText?: boolean;
|
|
8
8
|
disabled?: boolean;
|
|
9
9
|
onChange?: (color: string) => void;
|
|
10
|
+
open?: boolean;
|
|
11
|
+
defaultOpen?: boolean;
|
|
12
|
+
onOpenChange?: (open: boolean) => void;
|
|
10
13
|
}
|
|
11
14
|
declare const ColorPicker: ({
|
|
12
15
|
defaultValue,
|
|
@@ -15,6 +18,9 @@ declare const ColorPicker: ({
|
|
|
15
18
|
disabled,
|
|
16
19
|
className,
|
|
17
20
|
onChange: _onChange,
|
|
21
|
+
open: _open,
|
|
22
|
+
defaultOpen,
|
|
23
|
+
onOpenChange,
|
|
18
24
|
...props
|
|
19
25
|
}: Props) => react_jsx_runtime0.JSX.Element;
|
|
20
26
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color-picker.d.mts","names":[],"sources":["../../../src/components/atoms/color-picker.tsx"],"mappings":";;;UAUiB,KAAA,SAAc,IAAA,CAC7B,KAAA,CAAM,wBAAA;EAGN,YAAA;EACA,KAAA;EACA,QAAA;EACA,QAAA;EACA,QAAA,IAAY,KAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"color-picker.d.mts","names":[],"sources":["../../../src/components/atoms/color-picker.tsx"],"mappings":";;;UAUiB,KAAA,SAAc,IAAA,CAC7B,KAAA,CAAM,wBAAA;EAGN,YAAA;EACA,KAAA;EACA,QAAA;EACA,QAAA;EACA,QAAA,IAAY,KAAA;EACZ,IAAA;EACA,WAAA;EACA,YAAA,IAAgB,IAAA;AAAA;AAAA,cAGZ,WAAA;EAAe,YAAA;EAAA,KAAA,EAAA,MAAA;EAAA,QAAA;EAAA,QAAA;EAAA,SAAA;EAAA,QAAA,EAAA,SAAA;EAAA,IAAA,EAAA,KAAA;EAAA,WAAA;EAAA,YAAA;EAAA,GAAA;AAAA,GAWlB,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -7,18 +7,25 @@ import { useControllableState } from "@jbpark/use-hooks";
|
|
|
7
7
|
import { HexColorPicker } from "react-colorful";
|
|
8
8
|
|
|
9
9
|
//#region src/components/atoms/color-picker.tsx
|
|
10
|
-
const ColorPicker = ({ defaultValue, value: _value, showText, disabled, className, onChange: _onChange = () => {}, ...props }) => {
|
|
10
|
+
const ColorPicker = ({ defaultValue, value: _value, showText, disabled, className, onChange: _onChange = () => {}, open: _open, defaultOpen, onOpenChange, ...props }) => {
|
|
11
11
|
const [value, setValue] = useControllableState({
|
|
12
12
|
value: _value,
|
|
13
13
|
defaultValue: defaultValue ?? "#fff",
|
|
14
14
|
onChange: _onChange
|
|
15
15
|
});
|
|
16
|
+
const [open, setOpen] = useControllableState({
|
|
17
|
+
value: _open,
|
|
18
|
+
defaultValue: defaultOpen ?? false,
|
|
19
|
+
onChange: onOpenChange
|
|
20
|
+
});
|
|
16
21
|
const onChange = (color) => {
|
|
17
22
|
if (disabled) return;
|
|
18
23
|
setValue(color);
|
|
19
24
|
};
|
|
20
25
|
return /* @__PURE__ */ jsx(Popover, {
|
|
21
26
|
placement: "bottomLeft",
|
|
27
|
+
open,
|
|
28
|
+
onOpenChange: setOpen,
|
|
22
29
|
content: /* @__PURE__ */ jsx(HexColorPicker, {
|
|
23
30
|
color: value,
|
|
24
31
|
onChange
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color-picker.mjs","names":[],"sources":["../../../src/components/atoms/color-picker.tsx"],"sourcesContent":["'use client';\n\nimport { HexColorPicker } from 'react-colorful';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Popover from './popover';\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'onChange' | 'defaultValue' | 'value' | 'onClick' | 'onKeyDown'\n> {\n defaultValue?: string;\n value?: string;\n showText?: boolean;\n disabled?: boolean;\n onChange?: (color: string) => void;\n}\n\nconst ColorPicker = ({\n defaultValue,\n value: _value,\n showText,\n disabled,\n className,\n onChange: _onChange = () => {},\n ...props\n}: Props) => {\n const [value, setValue] = useControllableState<string>({\n value: _value,\n defaultValue: defaultValue ?? '#fff',\n onChange: _onChange,\n });\n\n const onChange = (color: string) => {\n if (disabled) {\n return;\n }\n setValue(color);\n };\n\n return (\n <Popover\n placement=\"bottomLeft\"\n content={<HexColorPicker color={value} onChange={onChange} />}\n >\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n className={cn(\n 'inline-flex items-center',\n 'rounded border p-0.5',\n disabled && 'cursor-not-allowed opacity-50',\n className,\n )}\n {...props}\n onClick={e => {\n if (disabled) {\n e.preventDefault();\n }\n }}\n onKeyDown={e => {\n if (disabled) {\n return;\n }\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.currentTarget.click();\n }\n }}\n >\n <div\n className={cn(\n 'size-6 rounded border',\n 'shadow-sm',\n disabled ? 'cursor-not-allowed' : 'cursor-pointer',\n )}\n style={{ backgroundColor: value }}\n />\n {showText && (\n <span className=\"px-1 font-mono text-sm font-medium\">\n {value.toUpperCase()}\n </span>\n )}\n </div>\n </Popover>\n );\n};\n\nexport default ColorPicker;\n"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"color-picker.mjs","names":[],"sources":["../../../src/components/atoms/color-picker.tsx"],"sourcesContent":["'use client';\n\nimport { HexColorPicker } from 'react-colorful';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Popover from './popover';\n\nexport interface Props extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'onChange' | 'defaultValue' | 'value' | 'onClick' | 'onKeyDown' | 'open'\n> {\n defaultValue?: string;\n value?: string;\n showText?: boolean;\n disabled?: boolean;\n onChange?: (color: string) => void;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nconst ColorPicker = ({\n defaultValue,\n value: _value,\n showText,\n disabled,\n className,\n onChange: _onChange = () => {},\n open: _open,\n defaultOpen,\n onOpenChange,\n ...props\n}: Props) => {\n const [value, setValue] = useControllableState<string>({\n value: _value,\n defaultValue: defaultValue ?? '#fff',\n onChange: _onChange,\n });\n const [open, setOpen] = useControllableState<boolean>({\n value: _open,\n defaultValue: defaultOpen ?? false,\n onChange: onOpenChange,\n });\n\n const onChange = (color: string) => {\n if (disabled) {\n return;\n }\n setValue(color);\n };\n\n return (\n <Popover\n placement=\"bottomLeft\"\n open={open}\n onOpenChange={setOpen}\n content={<HexColorPicker color={value} onChange={onChange} />}\n >\n <div\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n className={cn(\n 'inline-flex items-center',\n 'rounded border p-0.5',\n disabled && 'cursor-not-allowed opacity-50',\n className,\n )}\n {...props}\n onClick={e => {\n if (disabled) {\n e.preventDefault();\n }\n }}\n onKeyDown={e => {\n if (disabled) {\n return;\n }\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n e.currentTarget.click();\n }\n }}\n >\n <div\n className={cn(\n 'size-6 rounded border',\n 'shadow-sm',\n disabled ? 'cursor-not-allowed' : 'cursor-pointer',\n )}\n style={{ backgroundColor: value }}\n />\n {showText && (\n <span className=\"px-1 font-mono text-sm font-medium\">\n {value.toUpperCase()}\n </span>\n )}\n </div>\n </Popover>\n );\n};\n\nexport default ColorPicker;\n"],"mappings":";;;;;;;;;AAwBA,MAAM,eAAe,EACnB,cACA,OAAO,QACP,UACA,UACA,WACA,UAAU,kBAAkB,IAC5B,MAAM,OACN,aACA,cACA,GAAG,YACQ;CACX,MAAM,CAAC,OAAO,YAAY,qBAA6B;EACrD,OAAO;EACP,cAAc,gBAAgB;EAC9B,UAAU;EACX,CAAC;CACF,MAAM,CAAC,MAAM,WAAW,qBAA8B;EACpD,OAAO;EACP,cAAc,eAAe;EAC7B,UAAU;EACX,CAAC;CAEF,MAAM,YAAY,UAAkB;AAClC,MAAI,SACF;AAEF,WAAS,MAAM;;AAGjB,QACE,oBAAC;EACC,WAAU;EACJ;EACN,cAAc;EACd,SAAS,oBAAC;GAAe,OAAO;GAAiB;IAAY;YAE7D,qBAAC;GACC,MAAK;GACL,UAAU,WAAW,KAAK;GAC1B,iBAAe;GACf,WAAW,GACT,4BACA,wBACA,YAAY,iCACZ,UACD;GACD,GAAI;GACJ,UAAS,MAAK;AACZ,QAAI,SACF,GAAE,gBAAgB;;GAGtB,YAAW,MAAK;AACd,QAAI,SACF;AAEF,QAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,OAAE,gBAAgB;AAClB,OAAE,cAAc,OAAO;;;cAI3B,oBAAC;IACC,WAAW,GACT,yBACA,aACA,WAAW,uBAAuB,iBACnC;IACD,OAAO,EAAE,iBAAiB,OAAO;KACjC,EACD,YACC,oBAAC;IAAK,WAAU;cACb,MAAM,aAAa;KACf;IAEL;GACE"}
|
|
@@ -3,7 +3,17 @@ const normalizeOptions = (options) => options.map((item) => typeof item === "obj
|
|
|
3
3
|
label: `${item}`,
|
|
4
4
|
value: item
|
|
5
5
|
});
|
|
6
|
+
const warnOnDuplicateOptionValues = (options, componentName) => {
|
|
7
|
+
if (globalThis.process?.env?.NODE_ENV === "production") return;
|
|
8
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9
|
+
const duplicates = /* @__PURE__ */ new Set();
|
|
10
|
+
for (const option of options) {
|
|
11
|
+
if (seen.has(option.value)) duplicates.add(option.value);
|
|
12
|
+
seen.add(option.value);
|
|
13
|
+
}
|
|
14
|
+
if (duplicates.size > 0) console.warn(`${componentName}: duplicate option value(s) [${[...duplicates].map((v) => JSON.stringify(v)).join(", ")}] — options sharing a value render as if selecting one selects all of them, since selection is matched by value.`);
|
|
15
|
+
};
|
|
6
16
|
|
|
7
17
|
//#endregion
|
|
8
|
-
export { normalizeOptions };
|
|
18
|
+
export { normalizeOptions, warnOnDuplicateOptionValues };
|
|
9
19
|
//# sourceMappingURL=option-group.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-group.mjs","names":[],"sources":["../../../src/components/atoms/option-group.ts"],"sourcesContent":["export type OptionValue = string | number | boolean;\n\nexport interface Option {\n label: string;\n value: OptionValue;\n disabled?: boolean;\n}\n\nexport type Options = string[] | number[] | boolean[] | Option[];\n\nexport interface OptionGroupClassNames {\n wrapper?: string;\n item?: string;\n}\n\nexport const normalizeOptions = (options: Options): Option[] =>\n options.map(item =>\n typeof item === 'object'\n ? item\n : {\n label: `${item}`,\n value: item,\n },\n );\n"],"mappings":";AAeA,MAAa,oBAAoB,YAC/B,QAAQ,KAAI,SACV,OAAO,SAAS,WACZ,OACA;CACE,OAAO,GAAG;CACV,OAAO;CACR,CACN"}
|
|
1
|
+
{"version":3,"file":"option-group.mjs","names":[],"sources":["../../../src/components/atoms/option-group.ts"],"sourcesContent":["export type OptionValue = string | number | boolean;\n\nexport interface Option {\n label: string;\n value: OptionValue;\n disabled?: boolean;\n}\n\nexport type Options = string[] | number[] | boolean[] | Option[];\n\nexport interface OptionGroupClassNames {\n wrapper?: string;\n item?: string;\n}\n\nexport const normalizeOptions = (options: Options): Option[] =>\n options.map(item =>\n typeof item === 'object'\n ? item\n : {\n label: `${item}`,\n value: item,\n },\n );\n\n// Radio.Group/Checkbox.Group both key selection off `value` (Radix's\n// RadioGroup matches items by it, and Checkbox.Group tests membership via\n// `value.includes(...)`), so two options sharing a value aren't just a\n// React list-key collision — they become indistinguishable to the\n// component's own selection logic, e.g. both rendering aria-checked=true\n// together. A duplicate is virtually always a caller mistake (two radios\n// for the \"same\" value can't be meaningfully different choices), so warn\n// instead of silently accepting it.\nexport const warnOnDuplicateOptionValues = (\n options: Option[],\n componentName: string,\n) => {\n const nodeEnv = (globalThis as { process?: { env?: { NODE_ENV?: string } } })\n .process?.env?.NODE_ENV;\n\n if (nodeEnv === 'production') {\n return;\n }\n\n const seen = new Set<OptionValue>();\n const duplicates = new Set<OptionValue>();\n\n for (const option of options) {\n if (seen.has(option.value)) {\n duplicates.add(option.value);\n }\n seen.add(option.value);\n }\n\n if (duplicates.size > 0) {\n console.warn(\n `${componentName}: duplicate option value(s) [${[...duplicates].map(v => JSON.stringify(v)).join(', ')}] — options sharing a value render as if selecting one selects all of them, since selection is matched by value.`,\n );\n }\n};\n"],"mappings":";AAeA,MAAa,oBAAoB,YAC/B,QAAQ,KAAI,SACV,OAAO,SAAS,WACZ,OACA;CACE,OAAO,GAAG;CACV,OAAO;CACR,CACN;AAUH,MAAa,+BACX,SACA,kBACG;AAIH,KAHiB,WACd,SAAS,KAAK,aAED,aACd;CAGF,MAAM,uBAAO,IAAI,KAAkB;CACnC,MAAM,6BAAa,IAAI,KAAkB;AAEzC,MAAK,MAAM,UAAU,SAAS;AAC5B,MAAI,KAAK,IAAI,OAAO,MAAM,CACxB,YAAW,IAAI,OAAO,MAAM;AAE9B,OAAK,IAAI,OAAO,MAAM;;AAGxB,KAAI,WAAW,OAAO,EACpB,SAAQ,KACN,GAAG,cAAc,+BAA+B,CAAC,GAAG,WAAW,CAAC,KAAI,MAAK,KAAK,UAAU,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,kHACxG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.d.mts","names":[],"sources":["../../../../src/components/atoms/radio/group.tsx"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"group.d.mts","names":[],"sources":["../../../../src/components/atoms/radio/group.tsx"],"mappings":";;;;UAyBiB,KAAA,SAAc,IAAA,CAC7B,KAAA,CAAM,wBAAA;EAGN,OAAA,GAAU,OAAA;EACV,WAAA;EACA,SAAA;EACA,UAAA,GAAa,qBAAA;EACb,YAAA,GAAe,WAAA;EACf,KAAA,GAAQ,WAAA;EAFK;EAIb,IAAA;EACA,UAAA;EACA,WAAA;EACA,IAAA;EACA,QAAA;EACA,QAAA,IAAY,KAAA,EAAO,WAAA;AAAA;AAAA,cAGf,UAAA;EAAc,WAAA;EAAA,SAAA;EAAA,SAAA;EAAA,UAAA;EAAA,OAAA,EAAA,QAAA;EAAA,IAAA;EAAA,UAAA;EAAA,WAAA;EAAA,IAAA;EAAA,QAAA;EAAA,YAAA;EAAA,KAAA,EAAA,MAAA;EAAA,QAAA,EAAA,SAAA;EAAA,GAAA;AAAA,GAejB,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { cn } from "../../../utils.mjs";
|
|
4
4
|
import { radio_group_exports } from "../../../core/radio-group.mjs";
|
|
5
5
|
import Button from "../../../Button.mjs";
|
|
6
|
-
import { normalizeOptions } from "../option-group.mjs";
|
|
6
|
+
import { normalizeOptions, warnOnDuplicateOptionValues } from "../option-group.mjs";
|
|
7
7
|
import { RadioGroupContext } from "./context.mjs";
|
|
8
8
|
import Radio from "./radio.mjs";
|
|
9
9
|
import { useId } from "react";
|
|
@@ -19,6 +19,7 @@ const RadioGroup = ({ orientation = "horizontal", placement = "left", className,
|
|
|
19
19
|
onChange: _onChange
|
|
20
20
|
});
|
|
21
21
|
const options = normalizeOptions(_options);
|
|
22
|
+
warnOnDuplicateOptionValues(options, "Radio.Group");
|
|
22
23
|
const isButton = optionType === "button";
|
|
23
24
|
const onChange = (checked, optionValue) => {
|
|
24
25
|
if (!checked) return;
|
|
@@ -60,7 +61,7 @@ const RadioGroup = ({ orientation = "horizontal", placement = "left", className,
|
|
|
60
61
|
onChange: (checked) => onChange(checked, item.value),
|
|
61
62
|
children: item.label
|
|
62
63
|
})
|
|
63
|
-
}, String(item.value));
|
|
64
|
+
}, `${index}-${String(item.value)}`);
|
|
64
65
|
})
|
|
65
66
|
});
|
|
66
67
|
return /* @__PURE__ */ jsx(RadioGroupContext.Provider, {
|
|
@@ -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 { useControllableState } from '@jbpark/use-hooks';\n\nimport { radio } from '@repo/ui/core';\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../button';\nimport {\n type Option,\n type OptionGroupClassNames,\n type OptionValue,\n type Options,\n normalizeOptions,\n} from '../option-group';\nimport { RadioGroupContext } from './context';\nimport Radio from './radio';\n\nconst { RadioGroup: Core, RadioGroupItem: Item } = 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\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 Radix radiogroup root owns every option so that arrow keys move\n // focus across the whole group. `id` stays index-derived (for DOM\n // id/label pairing), but Radix itself now addresses/submits items by\n // their 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 'flex gap-4',\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={String(item.value)}\n className={cn('flex', classNames?.wrapper)}\n >\n {isButton ? (\n // `asChild` 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.\n <Item\n asChild\n value={String(item.value)}\n disabled={disabled || item.disabled}\n >\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 </Item>\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":";;;;;;;;;;;;;
|
|
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 { useControllableState } from '@jbpark/use-hooks';\n\nimport { radio } from '@repo/ui/core';\nimport { cn } from '@repo/ui/utils';\n\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, RadioGroupItem: Item } = 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 Radix radiogroup root owns every option so that arrow keys move\n // focus across the whole group. `id` stays index-derived (for DOM\n // id/label pairing), but Radix itself now addresses/submits items by\n // their 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 'flex gap-4',\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 className={cn('flex', classNames?.wrapper)}\n >\n {isButton ? (\n // `asChild` 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.\n <Item\n asChild\n value={String(item.value)}\n disabled={disabled || item.disabled}\n >\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 </Item>\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":";;;;;;;;;;;;;AAqBA,MAAM,EAAE,YAAY,MAAM,gBAAgB,SAASA;AAuBnD,MAAM,cAAc,EAClB,cAAc,cACd,YAAY,QACZ,WACA,aAAa,EAAE,EACf,SAAS,WAAW,EAAE,EACtB,MACA,aAAa,WACb,cAAc,SACd,MACA,UACA,cACA,OAAO,QACP,UAAU,kBAAkB,IAC5B,GAAG,YACQ;CACX,MAAM,CAAC,OAAO,YAAY,qBAAkC;EAC1D,OAAO;EACP;EACA,UAAU;EACX,CAAC;CAEF,MAAM,UAAoB,iBAAiB,SAAS;AACpD,6BAA4B,SAAS,cAAc;CAEnD,MAAM,WAAW,eAAe;CAEhC,MAAM,YAAY,SAAkB,gBAA6B;AAC/D,MAAI,CAAC,QACH;AAEF,WAAS,YAAY;;CAOvB,MAAM,SAAS,OAAO;CACtB,MAAM,eAAe,UAAkB,GAAG,OAAO,GAAG;CACpD,MAAM,mBAAmB,UAAU,SAAY,KAAK,OAAO,MAAM;CAEjE,MAAM,iBAAiB,cAAsB;EAC3C,MAAM,OAAO,QAAQ,MAAK,WAAU,OAAO,OAAO,MAAM,KAAK,UAAU;AAEvE,MAAI,CAAC,KACH;AAGF,WAAS,MAAM,KAAK,MAAM;;CAG5B,MAAM,OACJ,oBAAC;EACC,GAAI;EACJ,WAAW,GACT,cACA,WACA,gBAAgB,cAAc,YAC9B,YAAY,QACb;YAEA,QAAQ,KAAK,MAAc,UAAU;GACpC,MAAM,UAAU,UAAU,KAAK;AAE/B,UACE,oBAAC;IAEC,WAAW,GAAG,QAAQ,YAAY,QAAQ;cAEzC,WAKC,oBAAC;KACC;KACA,OAAO,OAAO,KAAK,MAAM;KACzB,UAAU,YAAY,KAAK;eAE3B,oBAAC;MACC,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,gBACP;gBAEA,KAAK;OACC;MACJ,GAEP,oBAAC;KACC,IAAI,YAAY,MAAM;KACX;KACX,WAAW,GAAG,YAAY,KAAK;KAC/B,OAAO,KAAK;KACH;KACT,UAAU,YAAY,KAAK;KAC3B,WAAU,YAAW,SAAS,SAAS,KAAK,MAAM;eAEjD,KAAK;MACA;MApDL,GAAG,MAAM,GAAG,OAAO,KAAK,MAAM,GAsDhC;IAEP;GACC;AAGP,QACE,oBAAC,kBAAkB;EAAS,OAAO;YACjC,oBAAC;GACC,WAAU;GACJ;GACN,OAAO;GACQ;aAEd;IACI;GACoB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as react from "react";
|
|
1
2
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
3
|
|
|
3
4
|
//#region src/components/atoms/spin.d.ts
|
|
@@ -9,7 +10,7 @@ declare const Spin: ({
|
|
|
9
10
|
className,
|
|
10
11
|
children,
|
|
11
12
|
...props
|
|
12
|
-
}: Props) => react_jsx_runtime0.JSX.Element | null;
|
|
13
|
+
}: Props) => string | number | bigint | true | Iterable<react.ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<react.ReactNode> | null | undefined> | react_jsx_runtime0.JSX.Element | null;
|
|
13
14
|
//#endregion
|
|
14
15
|
export { Spin };
|
|
15
16
|
//# sourceMappingURL=spin.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spin.d.mts","names":[],"sources":["../../../src/components/atoms/spin.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"spin.d.mts","names":[],"sources":["../../../src/components/atoms/spin.tsx"],"mappings":";;;;UAIiB,KAAA,SAAc,KAAA,CAAM,wBAAA;EACnC,QAAA;AAAA;AAAA,cAGI,IAAA;EAAQ,QAAA;EAAA,SAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GAA6C,KAAA,uCAAK,QAAA,CAAA,KAAA,CAAA,SAAA,IAAA,OAAA,sCAAA,KAAA,CAAA,WAAA,GAAA,KAAA,CAAA,YAAA,mBAAA,KAAA,CAAA,qBAAA,SAAA,QAAA,CAAA,KAAA,CAAA,SAAA,wBAAA,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -14,13 +14,14 @@ const Spin = ({ spinning, className, children, ...props }) => {
|
|
|
14
14
|
children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" })
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
+
if (!spinning) return children;
|
|
17
18
|
return /* @__PURE__ */ jsxs("div", {
|
|
18
19
|
className: cn("relative", className),
|
|
19
20
|
...props,
|
|
20
21
|
children: [/* @__PURE__ */ jsx("div", {
|
|
21
|
-
className:
|
|
22
|
+
className: "pointer-events-none opacity-50",
|
|
22
23
|
children
|
|
23
|
-
}),
|
|
24
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
24
25
|
role: "status",
|
|
25
26
|
"aria-label": "로딩 중",
|
|
26
27
|
className: "absolute inset-0 flex items-center justify-center",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spin.mjs","names":[],"sources":["../../../src/components/atoms/spin.tsx"],"sourcesContent":["import { Loader2 } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentPropsWithoutRef<'div'> {\n spinning?: boolean;\n}\n\nconst Spin = ({ spinning, className, children, ...props }: Props) => {\n // With no children there's nothing to render at all while idle — unlike\n // the branch below, there's no wrapper for `className`/`props` to land\n // on regardless, so returning null here isn't the same bug.\n if (!children) {\n if (!spinning) {\n return null;\n }\n\n return (\n <div\n role=\"status\"\n aria-label=\"로딩 중\"\n className={cn('flex h-full items-center justify-center', className)}\n {...props}\n >\n <Loader2 className=\"animate-spin\" />\n </div>\n );\n }\n\n //
|
|
1
|
+
{"version":3,"file":"spin.mjs","names":[],"sources":["../../../src/components/atoms/spin.tsx"],"sourcesContent":["import { Loader2 } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentPropsWithoutRef<'div'> {\n spinning?: boolean;\n}\n\nconst Spin = ({ spinning, className, children, ...props }: Props) => {\n // With no children there's nothing to render at all while idle — unlike\n // the branch below, there's no wrapper for `className`/`props` to land\n // on regardless, so returning null here isn't the same bug.\n if (!children) {\n if (!spinning) {\n return null;\n }\n\n return (\n <div\n role=\"status\"\n aria-label=\"로딩 중\"\n className={cn('flex h-full items-center justify-center', className)}\n {...props}\n >\n <Loader2 className=\"animate-spin\" />\n </div>\n );\n }\n\n // Idle: return children as-is rather than inserting a wrapper div, same\n // policy Skeleton follows and for the same reason — a wrapper here could\n // produce invalid markup (e.g. inside a <tr>/<li>) or break flex/grid\n // child layout. className/props only ever describe the spinning overlay\n // below, so there's nothing for them to apply to while idle.\n if (!spinning) {\n return children;\n }\n\n return (\n <div className={cn('relative', className)} {...props}>\n <div className=\"pointer-events-none opacity-50\">{children}</div>\n <div\n role=\"status\"\n aria-label=\"로딩 중\"\n className=\"absolute inset-0 flex items-center justify-center\"\n >\n <Loader2 className=\"animate-spin\" />\n </div>\n </div>\n );\n};\n\nexport default Spin;\n"],"mappings":";;;;;AAQA,MAAM,QAAQ,EAAE,UAAU,WAAW,UAAU,GAAG,YAAmB;AAInE,KAAI,CAAC,UAAU;AACb,MAAI,CAAC,SACH,QAAO;AAGT,SACE,oBAAC;GACC,MAAK;GACL,cAAW;GACX,WAAW,GAAG,2CAA2C,UAAU;GACnE,GAAI;aAEJ,oBAAC,WAAQ,WAAU,iBAAiB;IAChC;;AASV,KAAI,CAAC,SACH,QAAO;AAGT,QACE,qBAAC;EAAI,WAAW,GAAG,YAAY,UAAU;EAAE,GAAI;aAC7C,oBAAC;GAAI,WAAU;GAAkC;IAAe,EAChE,oBAAC;GACC,MAAK;GACL,cAAW;GACX,WAAU;aAEV,oBAAC,WAAQ,WAAU,iBAAiB;IAChC;GACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collapse.d.mts","names":[],"sources":["../../../src/components/molecules/collapse.tsx"],"mappings":";;;;UAUU,IAAA;EACR,GAAA,EAAK,KAAA,CAAM,GAAA;EACX,KAAA,EAAO,KAAA,CAAM,SAAA;EACb,QAAA;EACA,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"collapse.d.mts","names":[],"sources":["../../../src/components/molecules/collapse.tsx"],"mappings":";;;;UAUU,IAAA;EACR,GAAA,EAAK,KAAA,CAAM,GAAA;EACX,KAAA,EAAO,KAAA,CAAM,SAAA;EACb,QAAA;EACA,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;AAAA,UAGD,KAAA,SAAc,IAAA,CAC7B,KAAA,CAAM,wBAAA;EAGN,KAAA,GAAQ,IAAA;EACR,SAAA;EACA,UAAA,GAAa,KAAA,CAAM,SAAA;EACnB,UAAA;IACE,IAAA;IACA,MAAA;IACA,IAAA;EAAA;EAEF,gBAAA;EACA,SAAA;EACA,QAAA,IAAY,IAAA;AAAA;AAAA,cAGR,QAAA;EAAY,UAAA;EAAA,SAAA;EAAA,KAAA;EAAA,SAAA;EAAA,UAAA;EAAA,gBAAA;EAAA,SAAA,EAAA,UAAA;EAAA,QAAA,EAAA,SAAA;EAAA,GAAA;AAAA,GAUf,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -26,7 +26,7 @@ const Collapse = ({ expandIcon, accordion = false, items = [], className, classN
|
|
|
26
26
|
...props,
|
|
27
27
|
className,
|
|
28
28
|
...accordionProps,
|
|
29
|
-
children: items.map(({ label, children, disabled }
|
|
29
|
+
children: items.map(({ key, label, children, disabled }) => /* @__PURE__ */ jsxs(AccordionItem, {
|
|
30
30
|
value: `${key}`,
|
|
31
31
|
className: cn("border-none", classNames?.item),
|
|
32
32
|
disabled,
|
|
@@ -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 { accordion } from '@repo/ui/core';\nimport { cn } from '@repo/ui/utils';\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\
|
|
1
|
+
{"version":3,"file":"collapse.mjs","names":["accordion"],"sources":["../../../src/components/molecules/collapse.tsx"],"sourcesContent":["'use client';\n\nimport React from 'react';\n\nimport { accordion } from '@repo/ui/core';\nimport { cn } from '@repo/ui/utils';\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 const accordionProps = accordion\n ? {\n type: 'single' as const,\n onValueChange: (value: string) => {\n _onChange?.(value ? [value] : []);\n },\n ...(controlled\n ? { value: `${_activeKey?.[0] ?? ''}` }\n : { defaultValue: `${defaultActiveKey?.[0] ?? ''}` }),\n }\n : {\n type: 'multiple' as const,\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={`${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":";;;;;;;;AAOA,MAAM,EAAE,WAAW,eAAe,kBAAkB,qBAClDA;AA0BF,MAAM,YAAY,EAChB,YACA,YAAY,OACZ,QAAQ,EAAE,EACV,WACA,YACA,kBACA,WAAW,YACX,UAAU,WACV,GAAG,YACQ;CACX,MAAM,aAAa,eAAe;CAElC,MAAM,iBAAiB,YACnB;EACE,MAAM;EACN,gBAAgB,UAAkB;AAChC,eAAY,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC;;EAEnC,GAAI,aACA,EAAE,OAAO,GAAG,aAAa,MAAM,MAAM,GACrC,EAAE,cAAc,GAAG,mBAAmB,MAAM,MAAM;EACvD,GACD;EACE,MAAM;EACN,gBAAgB,WAAqB;AACnC,eAAY,OAAO;;EAErB,GAAI,aACA,EAAE,OAAO,YAAY,KAAI,QAAO,GAAG,MAAM,EAAE,GAC3C,EAAE,cAAc,kBAAkB,KAAI,QAAO,GAAG,MAAM,EAAE;EAC7D;AAEL,QACE,oBAAC;EAAU,GAAI;EAAkB;EAAW,GAAI;YAC7C,MAAM,KAAK,EAAE,KAAK,OAAO,UAAU,eAClC,qBAAC;GAEC,OAAO,GAAG;GACV,WAAW,GACT,eACA,YAAY,KAEb;GACS;cAEV,oBAAC;IACC,WAAW,GACT,sBACA,YAAY,QACZ,YAAY,4BAEb;IACW;IACF;cAET;KACgB,EACnB,oBAAC;IACC,WAAW,GACT,YAAY,KAEb;IAEA;KACgB;KA5Bd,IA6BS,CAChB;GACQ"}
|
|
@@ -6,7 +6,7 @@ import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
|
6
6
|
type ChangeEventHandler = (open: boolean) => void;
|
|
7
7
|
interface Props extends React.ComponentPropsWithoutRef<'div'> {
|
|
8
8
|
open?: boolean;
|
|
9
|
-
trigger?:
|
|
9
|
+
trigger?: 'hover' | 'click';
|
|
10
10
|
menu?: MenuProps;
|
|
11
11
|
onOpenChange?: ChangeEventHandler;
|
|
12
12
|
}
|
|
@@ -22,5 +22,5 @@ declare const Dropdown: ({
|
|
|
22
22
|
...props
|
|
23
23
|
}: Props) => react_jsx_runtime0.JSX.Element;
|
|
24
24
|
//#endregion
|
|
25
|
-
export { Dropdown };
|
|
25
|
+
export { Dropdown, Props };
|
|
26
26
|
//# sourceMappingURL=dropdown.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.d.mts","names":[],"sources":["../../../src/components/molecules/dropdown.tsx"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"dropdown.d.mts","names":[],"sources":["../../../src/components/molecules/dropdown.tsx"],"mappings":";;;;;KAWK,kBAAA,IAAsB,IAAA;AAAA,UAEV,KAAA,SAAc,KAAA,CAAM,wBAAA;EACnC,IAAA;EACA,OAAA;EACA,IAAA,GAAO,SAAA;EACP,YAAA,GAAe,kBAAA;AAAA;AAAA,cAGX,QAAA;EAAY,QAAA;EAAA,IAAA;EAAA,OAAA;EAAA,IAAA,EAAA,KAAA;EAAA,YAAA,EAAA,aAAA;EAAA,SAAA;EAAA,YAAA;EAAA,YAAA;EAAA,GAAA;AAAA,GAUf,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -2,23 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
import { cn } from "../../utils.mjs";
|
|
4
4
|
import Menu from "./menu/menu.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { useId, useRef } from "react";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { useControllableState } from "@jbpark/use-hooks";
|
|
7
8
|
import { AnimatePresence, motion } from "motion/react";
|
|
8
9
|
|
|
9
10
|
//#region src/components/molecules/dropdown.tsx
|
|
10
11
|
const Dropdown = ({ children, menu, trigger = "hover", open: _open, onOpenChange: _onOpenChange = () => {}, className, onMouseEnter, onMouseLeave, ...props }) => {
|
|
11
|
-
const [
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const [open, onOpenChange] = useControllableState({
|
|
13
|
+
value: _open,
|
|
14
|
+
defaultValue: false,
|
|
15
|
+
onChange: _onOpenChange
|
|
16
|
+
});
|
|
14
17
|
const isClickTrigger = trigger === "click";
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
_onOpenChange(nextOpen);
|
|
18
|
-
};
|
|
18
|
+
const menuId = useId();
|
|
19
|
+
const containerRef = useRef(null);
|
|
19
20
|
return /* @__PURE__ */ jsxs("div", {
|
|
20
21
|
...props,
|
|
21
|
-
|
|
22
|
+
ref: containerRef,
|
|
23
|
+
className: cn("relative", "inline-block cursor-pointer", className),
|
|
22
24
|
onMouseEnter: (event) => {
|
|
23
25
|
onMouseEnter?.(event);
|
|
24
26
|
if (isClickTrigger) return;
|
|
@@ -30,8 +32,11 @@ const Dropdown = ({ children, menu, trigger = "hover", open: _open, onOpenChange
|
|
|
30
32
|
onOpenChange(false);
|
|
31
33
|
},
|
|
32
34
|
children: [/* @__PURE__ */ jsx("div", {
|
|
35
|
+
role: isClickTrigger ? "button" : void 0,
|
|
36
|
+
tabIndex: isClickTrigger ? 0 : void 0,
|
|
33
37
|
"aria-haspopup": "menu",
|
|
34
38
|
"aria-expanded": open,
|
|
39
|
+
"aria-controls": open ? menuId : void 0,
|
|
35
40
|
onClick: () => {
|
|
36
41
|
if (!isClickTrigger) return;
|
|
37
42
|
onOpenChange(!open);
|
|
@@ -40,11 +45,18 @@ const Dropdown = ({ children, menu, trigger = "hover", open: _open, onOpenChange
|
|
|
40
45
|
if (isClickTrigger) return;
|
|
41
46
|
onOpenChange(true);
|
|
42
47
|
},
|
|
43
|
-
onBlur: () => {
|
|
44
|
-
onOpenChange(false);
|
|
48
|
+
onBlur: (e) => {
|
|
49
|
+
if (!containerRef.current?.contains(e.relatedTarget)) onOpenChange(false);
|
|
45
50
|
},
|
|
46
51
|
onKeyDown: (e) => {
|
|
47
|
-
if (e.key === "Escape")
|
|
52
|
+
if (e.key === "Escape") {
|
|
53
|
+
onOpenChange(false);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (isClickTrigger && (e.key === "Enter" || e.key === " ")) {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
onOpenChange(!open);
|
|
59
|
+
}
|
|
48
60
|
},
|
|
49
61
|
children
|
|
50
62
|
}), /* @__PURE__ */ jsx(AnimatePresence, { children: open && /* @__PURE__ */ jsx(motion.div, {
|
|
@@ -64,6 +76,7 @@ const Dropdown = ({ children, menu, trigger = "hover", open: _open, onOpenChange
|
|
|
64
76
|
transition: { duration: .1 },
|
|
65
77
|
children: /* @__PURE__ */ jsx(Menu, {
|
|
66
78
|
...menu,
|
|
79
|
+
id: menuId,
|
|
67
80
|
onMouseDown: (e) => {
|
|
68
81
|
e.preventDefault();
|
|
69
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.mjs","names":[],"sources":["../../../src/components/molecules/dropdown.tsx"],"sourcesContent":["'use client';\n\nimport {
|
|
1
|
+
{"version":3,"file":"dropdown.mjs","names":[],"sources":["../../../src/components/molecules/dropdown.tsx"],"sourcesContent":["'use client';\n\nimport { useId, useRef } from 'react';\n\nimport { useControllableState } from '@jbpark/use-hooks';\nimport { AnimatePresence, motion } from 'motion/react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Menu, { MenuProps } from './menu';\n\ntype ChangeEventHandler = (open: boolean) => void;\n\nexport interface Props extends React.ComponentPropsWithoutRef<'div'> {\n open?: boolean;\n trigger?: 'hover' | 'click';\n menu?: MenuProps;\n onOpenChange?: ChangeEventHandler;\n}\n\nconst Dropdown = ({\n children,\n menu,\n trigger = 'hover',\n open: _open,\n onOpenChange: _onOpenChange = () => {},\n className,\n onMouseEnter,\n onMouseLeave,\n ...props\n}: Props) => {\n const [open, onOpenChange] = useControllableState<boolean>({\n value: _open,\n defaultValue: false,\n onChange: _onOpenChange,\n });\n\n const isClickTrigger = trigger === 'click';\n const menuId = useId();\n const containerRef = useRef<HTMLDivElement>(null);\n\n return (\n <div\n {...props}\n ref={containerRef}\n className={cn(\n 'relative',\n 'inline-block cursor-pointer',\n className,\n //\n )}\n onMouseEnter={event => {\n onMouseEnter?.(event);\n if (isClickTrigger) {\n return;\n }\n onOpenChange(true);\n }}\n onMouseLeave={event => {\n onMouseLeave?.(event);\n if (isClickTrigger) {\n return;\n }\n onOpenChange(false);\n }}\n >\n <div\n role={isClickTrigger ? 'button' : undefined}\n tabIndex={isClickTrigger ? 0 : undefined}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n onClick={() => {\n if (!isClickTrigger) {\n return;\n }\n onOpenChange(!open);\n }}\n onFocus={() => {\n if (isClickTrigger) {\n return;\n }\n onOpenChange(true);\n }}\n onBlur={e => {\n // Without this check, moving focus from the trigger into the\n // menu itself (e.g. via Tab) closed the dropdown before the\n // user could ever reach it — the mouse path avoided the same\n // bug only by way of onMouseDown's preventDefault below, which\n // does nothing for keyboard focus. Mirrors the containment\n // check menu/item/item.tsx already uses for the same reason.\n if (!containerRef.current?.contains(e.relatedTarget as Node)) {\n onOpenChange(false);\n }\n }}\n onKeyDown={e => {\n if (e.key === 'Escape') {\n onOpenChange(false);\n return;\n }\n if (isClickTrigger && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onOpenChange(!open);\n }\n }}\n >\n {children}\n </div>\n <AnimatePresence>\n {open && (\n <motion.div\n className={cn(\n 'absolute top-full pt-2',\n //\n )}\n initial={{ opacity: 0, y: -10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10 }}\n transition={{ duration: 0.1 }}\n >\n <Menu\n {...menu}\n id={menuId}\n onMouseDown={e => {\n e.preventDefault();\n }}\n />\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n );\n};\n\nexport default Dropdown;\n"],"mappings":";;;;;;;;;;AAoBA,MAAM,YAAY,EAChB,UACA,MACA,UAAU,SACV,MAAM,OACN,cAAc,sBAAsB,IACpC,WACA,cACA,cACA,GAAG,YACQ;CACX,MAAM,CAAC,MAAM,gBAAgB,qBAA8B;EACzD,OAAO;EACP,cAAc;EACd,UAAU;EACX,CAAC;CAEF,MAAM,iBAAiB,YAAY;CACnC,MAAM,SAAS,OAAO;CACtB,MAAM,eAAe,OAAuB,KAAK;AAEjD,QACE,qBAAC;EACC,GAAI;EACJ,KAAK;EACL,WAAW,GACT,YACA,+BACA,UAED;EACD,eAAc,UAAS;AACrB,kBAAe,MAAM;AACrB,OAAI,eACF;AAEF,gBAAa,KAAK;;EAEpB,eAAc,UAAS;AACrB,kBAAe,MAAM;AACrB,OAAI,eACF;AAEF,gBAAa,MAAM;;aAGrB,oBAAC;GACC,MAAM,iBAAiB,WAAW;GAClC,UAAU,iBAAiB,IAAI;GAC/B,iBAAc;GACd,iBAAe;GACf,iBAAe,OAAO,SAAS;GAC/B,eAAe;AACb,QAAI,CAAC,eACH;AAEF,iBAAa,CAAC,KAAK;;GAErB,eAAe;AACb,QAAI,eACF;AAEF,iBAAa,KAAK;;GAEpB,SAAQ,MAAK;AAOX,QAAI,CAAC,aAAa,SAAS,SAAS,EAAE,cAAsB,CAC1D,cAAa,MAAM;;GAGvB,YAAW,MAAK;AACd,QAAI,EAAE,QAAQ,UAAU;AACtB,kBAAa,MAAM;AACnB;;AAEF,QAAI,mBAAmB,EAAE,QAAQ,WAAW,EAAE,QAAQ,MAAM;AAC1D,OAAE,gBAAgB;AAClB,kBAAa,CAAC,KAAK;;;GAItB;IACG,EACN,oBAAC,6BACE,QACC,oBAAC,OAAO;GACN,WAAW,GACT,yBAED;GACD,SAAS;IAAE,SAAS;IAAG,GAAG;IAAK;GAC/B,SAAS;IAAE,SAAS;IAAG,GAAG;IAAG;GAC7B,MAAM;IAAE,SAAS;IAAG,GAAG;IAAK;GAC5B,YAAY,EAAE,UAAU,IAAK;aAE7B,oBAAC;IACC,GAAI;IACJ,IAAI;IACJ,cAAa,MAAK;AAChB,OAAE,gBAAgB;;KAEpB;IACS,GAEC;GACd"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import Card from "../../Card.mjs";
|
|
2
|
-
import { Menu } from "./menu/menu.mjs";
|
|
1
|
+
import Card, { Props } from "../../Card.mjs";
|
|
2
|
+
import { Menu, Props as Props$1 } from "./menu/menu.mjs";
|
|
3
3
|
import "../../Menu.mjs";
|
|
4
|
+
import { Props as Props$2 } from "./reveals/reveals.mjs";
|
|
4
5
|
import Reveals from "../../Reveals.mjs";
|
|
5
|
-
import Space from "../../Space.mjs";
|
|
6
|
-
import { Collapse } from "./collapse.mjs";
|
|
7
|
-
import { Dropdown } from "./dropdown.mjs";
|
|
6
|
+
import Space, { Props as Props$3 } from "../../Space.mjs";
|
|
7
|
+
import { Collapse, Props as Props$4 } from "./collapse.mjs";
|
|
8
|
+
import { Dropdown, Props as Props$5 } from "./dropdown.mjs";
|
|
9
|
+
import { Props as Props$6 } from "./marquees/marquees.mjs";
|
|
8
10
|
import { Marquees } from "./marquees/index.mjs";
|
|
11
|
+
import { Props as Props$7 } from "./splitter/splitter.mjs";
|
|
9
12
|
import { Splitter } from "./splitter/index.mjs";
|
|
10
|
-
import { Upload, UploadFile } from "./upload.mjs";
|
|
13
|
+
import { Props as Props$8, Upload, UploadFile } from "./upload.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item.d.mts","names":[],"sources":["../../../../src/components/molecules/marquees/item.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"item.d.mts","names":[],"sources":["../../../../src/components/molecules/marquees/item.tsx"],"mappings":";;;UAOiB,SAAA;EACf,GAAA,GAAM,KAAA,CAAM,GAAA;EACZ,KAAA;EACA,QAAA;EACA,KAAA;EACA,YAAA;EACA,QAAA,GAAW,KAAA,CAAM,SAAA;AAAA;AAAA,UAGF,KAAA,SACP,IAAA,CAAK,KAAA,CAAM,wBAAA,iBAAyC,SAAA;EAC5D,KAAA;AAAA;AAAA,cAYI,IAAA;EAAQ,KAAA,EAAA,MAAA;EAAA,KAAA;EAAA,QAAA;EAAA,KAAA,EAAA,MAAA;EAAA,YAAA;EAAA;AAAA,GAOX,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|