@jbpark/ui-kit 10.0.2 → 10.2.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 +7 -0
- package/README.md +7 -0
- package/dist/Alert.d.mts +24 -0
- package/dist/Alert.d.mts.map +1 -0
- package/dist/Alert.mjs +68 -0
- package/dist/Alert.mjs.map +1 -0
- package/dist/Avatar.d.mts +19 -0
- package/dist/Avatar.d.mts.map +1 -0
- package/dist/Avatar.mjs +43 -0
- package/dist/Avatar.mjs.map +1 -0
- package/dist/Badge.d.mts +23 -0
- package/dist/Badge.d.mts.map +1 -0
- package/dist/Badge.mjs +41 -0
- package/dist/Badge.mjs.map +1 -0
- package/dist/Breadcrumb.d.mts +39 -0
- package/dist/Breadcrumb.d.mts.map +1 -0
- package/dist/Breadcrumb.mjs +103 -0
- package/dist/Breadcrumb.mjs.map +1 -0
- package/dist/Button.mjs +1 -1
- package/dist/Pagination.d.mts +53 -0
- package/dist/Pagination.d.mts.map +1 -0
- package/dist/Pagination.mjs +208 -0
- package/dist/Pagination.mjs.map +1 -0
- package/dist/Segmented.d.mts +26 -0
- package/dist/Segmented.d.mts.map +1 -0
- package/dist/Segmented.mjs +57 -0
- package/dist/Segmented.mjs.map +1 -0
- package/dist/Steps.d.mts +28 -0
- package/dist/Steps.d.mts.map +1 -0
- package/dist/Steps.mjs +70 -0
- package/dist/Steps.mjs.map +1 -0
- package/dist/Table.d.mts +48 -0
- package/dist/Table.d.mts.map +1 -0
- package/dist/Table.mjs +119 -0
- package/dist/Table.mjs.map +1 -0
- package/dist/components/atoms/checkbox/checkbox.mjs +3 -2
- package/dist/components/atoms/checkbox/checkbox.mjs.map +1 -1
- package/dist/components/atoms/checkbox/group.mjs +2 -1
- package/dist/components/atoms/checkbox/group.mjs.map +1 -1
- package/dist/components/atoms/color-picker.mjs +1 -1
- package/dist/components/atoms/date-picker.mjs +2 -2
- package/dist/components/atoms/float-button/back-top.mjs +2 -2
- package/dist/components/atoms/index.d.mts +6 -1
- package/dist/components/atoms/input/index.d.mts +3 -1
- package/dist/components/atoms/input/index.d.mts.map +1 -1
- package/dist/components/atoms/input/index.mjs +3 -1
- package/dist/components/atoms/input/index.mjs.map +1 -1
- package/dist/components/atoms/input/number.d.mts +23 -0
- package/dist/components/atoms/input/number.d.mts.map +1 -0
- package/dist/components/atoms/input/number.mjs +71 -0
- package/dist/components/atoms/input/number.mjs.map +1 -0
- package/dist/components/atoms/input/search.d.mts +0 -5
- package/dist/components/atoms/input/search.d.mts.map +1 -1
- package/dist/components/atoms/input/search.mjs +8 -8
- package/dist/components/atoms/input/search.mjs.map +1 -1
- package/dist/components/atoms/popover.mjs +1 -1
- package/dist/components/atoms/progress.d.mts +3 -1
- package/dist/components/atoms/progress.d.mts.map +1 -1
- package/dist/components/atoms/progress.mjs +2 -2
- package/dist/components/atoms/progress.mjs.map +1 -1
- package/dist/components/atoms/radio/group.mjs +1 -1
- package/dist/components/atoms/radio/radio.mjs +3 -2
- package/dist/components/atoms/radio/radio.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/rich-text-editor.d.mts +6 -1
- package/dist/components/atoms/rich-text-editor/rich-text-editor.d.mts.map +1 -1
- package/dist/components/atoms/rich-text-editor/rich-text-editor.mjs +7 -2
- package/dist/components/atoms/rich-text-editor/rich-text-editor.mjs.map +1 -1
- package/dist/components/atoms/rich-text-editor/toolbar-presets.mjs +1 -1
- package/dist/components/atoms/select-multiple.d.mts +29 -0
- package/dist/components/atoms/select-multiple.d.mts.map +1 -0
- package/dist/components/atoms/select-multiple.mjs +97 -0
- package/dist/components/atoms/select-multiple.mjs.map +1 -0
- package/dist/components/atoms/select-searchable-options.d.mts +21 -0
- package/dist/components/atoms/select-searchable-options.d.mts.map +1 -0
- package/dist/components/atoms/select-searchable-options.mjs +62 -0
- package/dist/components/atoms/select-searchable-options.mjs.map +1 -0
- package/dist/components/atoms/select-searchable.d.mts +22 -0
- package/dist/components/atoms/select-searchable.d.mts.map +1 -0
- package/dist/components/atoms/select-searchable.mjs +65 -0
- package/dist/components/atoms/select-searchable.mjs.map +1 -0
- package/dist/components/atoms/select.d.mts +8 -2
- package/dist/components/atoms/select.d.mts.map +1 -1
- package/dist/components/atoms/select.mjs +12 -2
- package/dist/components/atoms/select.mjs.map +1 -1
- package/dist/components/atoms/skeleton/skeleton.d.mts +3 -1
- package/dist/components/atoms/skeleton/skeleton.d.mts.map +1 -1
- package/dist/components/atoms/skeleton/skeleton.mjs +2 -2
- package/dist/components/atoms/skeleton/skeleton.mjs.map +1 -1
- package/dist/components/atoms/slider/slider.mjs +1 -1
- package/dist/components/atoms/switch.mjs +1 -1
- package/dist/components/atoms/tooltip.d.mts +21 -0
- package/dist/components/atoms/tooltip.d.mts.map +1 -0
- package/dist/components/atoms/tooltip.mjs +78 -0
- package/dist/components/atoms/tooltip.mjs.map +1 -0
- package/dist/components/atoms/typography/paragraph.mjs +1 -0
- package/dist/components/atoms/typography/paragraph.mjs.map +1 -1
- package/dist/components/atoms/typography/title.mjs +1 -0
- package/dist/components/atoms/typography/title.mjs.map +1 -1
- package/dist/components/molecules/collapse.d.mts +8 -8
- package/dist/components/molecules/collapse.d.mts.map +1 -1
- package/dist/components/molecules/collapse.mjs +11 -2
- package/dist/components/molecules/collapse.mjs.map +1 -1
- package/dist/components/molecules/dropdown.mjs +1 -1
- package/dist/components/molecules/index.d.mts +15 -10
- package/dist/components/molecules/marquees/marquees.mjs +1 -1
- package/dist/components/molecules/menu/item/item.mjs +1 -1
- package/dist/components/molecules/menu/menu.d.mts +1 -1
- package/dist/components/molecules/menu/menu.d.mts.map +1 -1
- package/dist/components/molecules/menu/menu.mjs +5 -2
- package/dist/components/molecules/menu/menu.mjs.map +1 -1
- package/dist/components/molecules/tabs.d.mts +41 -0
- package/dist/components/molecules/tabs.d.mts.map +1 -0
- package/dist/components/molecules/tabs.mjs +55 -0
- package/dist/components/molecules/tabs.mjs.map +1 -0
- package/dist/components/molecules/upload.mjs +3 -2
- package/dist/components/molecules/upload.mjs.map +1 -1
- package/dist/components/organisms/drawer.d.mts +1 -1
- package/dist/components/organisms/drawer.d.mts.map +1 -1
- package/dist/components/organisms/drawer.mjs +10 -4
- package/dist/components/organisms/drawer.mjs.map +1 -1
- package/dist/components/organisms/index.d.mts +6 -5
- package/dist/components/organisms/list/list.mjs +1 -1
- package/dist/components/organisms/modal.d.mts.map +1 -1
- package/dist/components/organisms/modal.mjs +8 -5
- package/dist/components/organisms/modal.mjs.map +1 -1
- package/dist/components/organisms/toast.d.mts.map +1 -1
- package/dist/components/organisms/toast.mjs +3 -2
- package/dist/components/organisms/toast.mjs.map +1 -1
- package/dist/components/templates/empty.mjs +1 -0
- package/dist/components/templates/empty.mjs.map +1 -1
- package/dist/components/templates/layout/content.mjs +1 -0
- package/dist/components/templates/layout/content.mjs.map +1 -1
- package/dist/components/templates/layout/footer.mjs +1 -0
- package/dist/components/templates/layout/footer.mjs.map +1 -1
- package/dist/components/templates/layout/header.mjs +1 -0
- package/dist/components/templates/layout/header.mjs.map +1 -1
- package/dist/components/templates/layout/layout.mjs +1 -0
- package/dist/components/templates/layout/layout.mjs.map +1 -1
- package/dist/components/templates/layout/sider.mjs +4 -2
- package/dist/components/templates/layout/sider.mjs.map +1 -1
- package/dist/components/templates/page-header.mjs +1 -0
- package/dist/components/templates/page-header.mjs.map +1 -1
- package/dist/components/templates/result.mjs +1 -0
- package/dist/components/templates/result.mjs.map +1 -1
- package/dist/core/accordion.mjs +1 -1
- package/dist/core/button.d.mts +1 -1
- package/dist/core/calendar.mjs +1 -1
- package/dist/core/checkbox.mjs +1 -1
- package/dist/core/combobox.d.mts +7 -0
- package/dist/core/combobox.d.mts.map +1 -0
- package/dist/core/combobox.mjs +99 -0
- package/dist/core/combobox.mjs.map +1 -0
- package/dist/core/dialog.mjs +1 -1
- package/dist/core/dialog.mjs.map +1 -1
- package/dist/core/drawer.mjs.map +1 -1
- package/dist/core/field.mjs +2 -4
- package/dist/core/field.mjs.map +1 -1
- package/dist/core/index.d.mts +4 -1
- package/dist/core/radio-group.mjs +1 -1
- package/dist/core/select.mjs +28 -23
- package/dist/core/select.mjs.map +1 -1
- package/dist/core/tabs.d.mts +9 -0
- package/dist/core/tabs.d.mts.map +1 -0
- package/dist/core/tabs.mjs +59 -0
- package/dist/core/tabs.mjs.map +1 -0
- package/dist/core/tooltip.d.mts +2 -0
- package/dist/core/tooltip.mjs +41 -0
- package/dist/core/tooltip.mjs.map +1 -0
- package/dist/index.d.mts +40 -29
- package/dist/index.mjs +12 -2
- package/dist/lib/z-layers.mjs +21 -0
- package/dist/lib/z-layers.mjs.map +1 -1
- package/dist/providers/config/dark-mode.mjs +2 -10
- package/dist/providers/config/dark-mode.mjs.map +1 -1
- package/dist/style.css +388 -16
- package/package.json +42 -2
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ReactElement, ReactNode } from "react";
|
|
2
|
+
//#region src/components/atoms/tooltip.d.ts
|
|
3
|
+
declare const Core: <Payload>(props: import("@base-ui/react").TooltipRoot.Props<Payload>) => React.JSX.Element;
|
|
4
|
+
type Placement = 'top' | 'left' | 'right' | 'bottom' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
|
|
5
|
+
interface Props extends Omit<React.ComponentProps<typeof Core>, 'children' | 'handle' | 'triggerId' | 'defaultTriggerId'> {
|
|
6
|
+
children: ReactElement;
|
|
7
|
+
/** Supplementary visual hint; keep essential information visible elsewhere. */
|
|
8
|
+
content: ReactNode;
|
|
9
|
+
/** Popup class; the child retains its own className. */
|
|
10
|
+
className?: string;
|
|
11
|
+
placement?: Placement;
|
|
12
|
+
/** Distance between the trigger and popup in pixels. */
|
|
13
|
+
offset?: number;
|
|
14
|
+
/** Hover delay in milliseconds. Keyboard focus opens without this delay. */
|
|
15
|
+
delay?: number;
|
|
16
|
+
closeDelay?: number;
|
|
17
|
+
}
|
|
18
|
+
declare const Tooltip: ({ children, content, className, placement, offset, delay, closeDelay, ...props }: Props) => import("react").JSX.Element;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { Props, Tooltip as default };
|
|
21
|
+
//# sourceMappingURL=tooltip.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.d.mts","names":[],"sources":["../../../src/components/atoms/tooltip.tsx"],"mappings":";;cAMiB,OAAI,SAAA,gCAAA,YAAA,MAAA,aAAA,MAAA,IAAA;KAEhB;UAgCY,cAAc,KAC7B,MAAM,sBAAsB;EAG5B,UAAU;;EAEV,SAAS;;EAET;EACA,YAAY;;EAEZ;;EAEA;EACA;;cAGI,YAAW,UAAA,SAAA,WAAA,WAAA,QAAA,OAAA,eAAA,SASd,0BAAK,IAAA"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { tooltip_exports } from "../../core/tooltip.mjs";
|
|
3
|
+
import { Children } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/atoms/tooltip.tsx
|
|
6
|
+
const { Tooltip: Core, TooltipContent, TooltipTrigger } = tooltip_exports;
|
|
7
|
+
const placementMap = {
|
|
8
|
+
top: {
|
|
9
|
+
side: "top",
|
|
10
|
+
align: "center"
|
|
11
|
+
},
|
|
12
|
+
left: {
|
|
13
|
+
side: "left",
|
|
14
|
+
align: "center"
|
|
15
|
+
},
|
|
16
|
+
right: {
|
|
17
|
+
side: "right",
|
|
18
|
+
align: "center"
|
|
19
|
+
},
|
|
20
|
+
bottom: {
|
|
21
|
+
side: "bottom",
|
|
22
|
+
align: "center"
|
|
23
|
+
},
|
|
24
|
+
topLeft: {
|
|
25
|
+
side: "top",
|
|
26
|
+
align: "start"
|
|
27
|
+
},
|
|
28
|
+
topRight: {
|
|
29
|
+
side: "top",
|
|
30
|
+
align: "end"
|
|
31
|
+
},
|
|
32
|
+
bottomLeft: {
|
|
33
|
+
side: "bottom",
|
|
34
|
+
align: "start"
|
|
35
|
+
},
|
|
36
|
+
bottomRight: {
|
|
37
|
+
side: "bottom",
|
|
38
|
+
align: "end"
|
|
39
|
+
},
|
|
40
|
+
leftTop: {
|
|
41
|
+
side: "left",
|
|
42
|
+
align: "start"
|
|
43
|
+
},
|
|
44
|
+
leftBottom: {
|
|
45
|
+
side: "left",
|
|
46
|
+
align: "end"
|
|
47
|
+
},
|
|
48
|
+
rightTop: {
|
|
49
|
+
side: "right",
|
|
50
|
+
align: "start"
|
|
51
|
+
},
|
|
52
|
+
rightBottom: {
|
|
53
|
+
side: "right",
|
|
54
|
+
align: "end"
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const Tooltip = ({ children, content, className, placement = "top", offset = 8, delay, closeDelay, ...props }) => {
|
|
58
|
+
const trigger = Children.only(children);
|
|
59
|
+
const { side, align } = placementMap[placement];
|
|
60
|
+
return /* @__PURE__ */ jsxs(Core, {
|
|
61
|
+
...props,
|
|
62
|
+
children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
63
|
+
render: trigger,
|
|
64
|
+
delay,
|
|
65
|
+
closeDelay
|
|
66
|
+
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
67
|
+
side,
|
|
68
|
+
align,
|
|
69
|
+
sideOffset: offset,
|
|
70
|
+
className,
|
|
71
|
+
children: content
|
|
72
|
+
})]
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
//#endregion
|
|
76
|
+
export { Tooltip as default };
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=tooltip.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.mjs","names":["tooltip"],"sources":["../../../src/components/atoms/tooltip.tsx"],"sourcesContent":["'use client';\n\nimport { Children, type ReactElement, type ReactNode } from 'react';\n\nimport { tooltip } from '../../core';\n\nconst { Tooltip: Core, TooltipContent, TooltipTrigger } = tooltip;\n\ntype Placement =\n | 'top'\n | 'left'\n | 'right'\n | 'bottom'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n\ntype Side = NonNullable<React.ComponentProps<typeof TooltipContent>['side']>;\ntype Align = NonNullable<React.ComponentProps<typeof TooltipContent>['align']>;\n\nconst placementMap: Record<Placement, { side: Side; align: Align }> = {\n top: { side: 'top', align: 'center' },\n left: { side: 'left', align: 'center' },\n right: { side: 'right', align: 'center' },\n bottom: { side: 'bottom', align: 'center' },\n topLeft: { side: 'top', align: 'start' },\n topRight: { side: 'top', align: 'end' },\n bottomLeft: { side: 'bottom', align: 'start' },\n bottomRight: { side: 'bottom', align: 'end' },\n leftTop: { side: 'left', align: 'start' },\n leftBottom: { side: 'left', align: 'end' },\n rightTop: { side: 'right', align: 'start' },\n rightBottom: { side: 'right', align: 'end' },\n};\n\nexport interface Props extends Omit<\n React.ComponentProps<typeof Core>,\n 'children' | 'handle' | 'triggerId' | 'defaultTriggerId'\n> {\n children: ReactElement;\n /** Supplementary visual hint; keep essential information visible elsewhere. */\n content: ReactNode;\n /** Popup class; the child retains its own className. */\n className?: string;\n placement?: Placement;\n /** Distance between the trigger and popup in pixels. */\n offset?: number;\n /** Hover delay in milliseconds. Keyboard focus opens without this delay. */\n delay?: number;\n closeDelay?: number;\n}\n\nconst Tooltip = ({\n children,\n content,\n className,\n placement = 'top',\n offset = 8,\n delay,\n closeDelay,\n ...props\n}: Props) => {\n const trigger = Children.only(children);\n const { side, align } = placementMap[placement];\n\n return (\n <Core {...props}>\n <TooltipTrigger render={trigger} delay={delay} closeDelay={closeDelay} />\n <TooltipContent\n side={side}\n align={align}\n sideOffset={offset}\n className={className}\n >\n {content}\n </TooltipContent>\n </Core>\n );\n};\n\nexport default Tooltip;\n"],"mappings":";;;;;AAMA,MAAM,EAAE,SAAS,MAAM,gBAAgB,mBAAmBA;AAmB1D,MAAM,eAAgE;CACpE,KAAK;EAAE,MAAM;EAAO,OAAO;CAAS;CACpC,MAAM;EAAE,MAAM;EAAQ,OAAO;CAAS;CACtC,OAAO;EAAE,MAAM;EAAS,OAAO;CAAS;CACxC,QAAQ;EAAE,MAAM;EAAU,OAAO;CAAS;CAC1C,SAAS;EAAE,MAAM;EAAO,OAAO;CAAQ;CACvC,UAAU;EAAE,MAAM;EAAO,OAAO;CAAM;CACtC,YAAY;EAAE,MAAM;EAAU,OAAO;CAAQ;CAC7C,aAAa;EAAE,MAAM;EAAU,OAAO;CAAM;CAC5C,SAAS;EAAE,MAAM;EAAQ,OAAO;CAAQ;CACxC,YAAY;EAAE,MAAM;EAAQ,OAAO;CAAM;CACzC,UAAU;EAAE,MAAM;EAAS,OAAO;CAAQ;CAC1C,aAAa;EAAE,MAAM;EAAS,OAAO;CAAM;AAC7C;AAmBA,MAAM,WAAW,EACf,UACA,SACA,WACA,YAAY,OACZ,SAAS,GACT,OACA,YACA,GAAG,YACQ;CACX,MAAM,UAAU,SAAS,KAAK,QAAQ;CACtC,MAAM,EAAE,MAAM,UAAU,aAAa;CAErC,OACE,qBAAC,MAAD;EAAM,GAAI;EAAV,UAAA,CACE,oBAAC,gBAAD;GAAgB,QAAQ;GAAgB;GAAmB;EAAa,CAAA,GACxE,oBAAC,gBAAD;GACQ;GACC;GACP,YAAY;GACD;GAEV,UAAA;EACa,CAAA,CACZ;;AAEV"}
|
|
@@ -3,6 +3,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
//#region src/components/atoms/typography/paragraph.tsx
|
|
4
4
|
const Paragraph = ({ children, className, ...props }) => {
|
|
5
5
|
return /* @__PURE__ */ jsx("p", {
|
|
6
|
+
"data-slot": "typography-paragraph",
|
|
6
7
|
...props,
|
|
7
8
|
className: cn("m-0", className),
|
|
8
9
|
children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paragraph.mjs","names":[],"sources":["../../../../src/components/atoms/typography/paragraph.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentPropsWithoutRef<'p'> {}\n\nconst Paragraph = ({ children, className, ...props }: Props) => {\n return (\n <p\n {...props}\n className={cn(\n 'm-0',\n className,\n //\n )}\n >\n {children}\n </p>\n );\n};\n\nexport default Paragraph;\n"],"mappings":";;;AAIA,MAAM,aAAa,EAAE,UAAU,WAAW,GAAG,YAAmB;CAC9D,OACE,oBAAC,KAAD;EACE,GAAI;EACJ,WAAW,GACT,OACA,SAEF;EAEC;CACA,CAAA;AAEP"}
|
|
1
|
+
{"version":3,"file":"paragraph.mjs","names":[],"sources":["../../../../src/components/atoms/typography/paragraph.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentPropsWithoutRef<'p'> {}\n\nconst Paragraph = ({ children, className, ...props }: Props) => {\n return (\n <p\n data-slot=\"typography-paragraph\"\n {...props}\n className={cn(\n 'm-0',\n className,\n //\n )}\n >\n {children}\n </p>\n );\n};\n\nexport default Paragraph;\n"],"mappings":";;;AAIA,MAAM,aAAa,EAAE,UAAU,WAAW,GAAG,YAAmB;CAC9D,OACE,oBAAC,KAAD;EACE,aAAU;EACV,GAAI;EACJ,WAAW,GACT,OACA,SAEF;EAEC;CACA,CAAA;AAEP"}
|
|
@@ -12,6 +12,7 @@ const styles = {
|
|
|
12
12
|
const Title = ({ children, level = 1, className, ...props }) => {
|
|
13
13
|
const Element = level < 1 || level > 6 ? "h1" : `h${level}`;
|
|
14
14
|
return /* @__PURE__ */ jsx(Element, {
|
|
15
|
+
"data-slot": "typography-title",
|
|
15
16
|
className: cn("m-0 leading-snug font-bold", styles[Element], className),
|
|
16
17
|
...props,
|
|
17
18
|
children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"title.mjs","names":[],"sources":["../../../../src/components/atoms/typography/title.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentPropsWithoutRef<\n 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'\n> {\n level?: 1 | 2 | 3 | 4 | 5 | 6;\n}\n\ntype ElementType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\n// Scale up at wider breakpoints instead of a single fixed size — the desktop\n// size stays the same as before, but narrow/mobile viewports now get a\n// smaller starting size instead of always rendering at the full desktop size.\nconst styles: Record<string, string> = {\n h1: 'text-4xl sm:text-5xl lg:text-6xl',\n h2: 'text-3xl sm:text-4xl lg:text-5xl',\n h3: 'text-2xl sm:text-3xl lg:text-4xl',\n h4: 'text-xl sm:text-2xl lg:text-3xl',\n h5: 'text-lg sm:text-xl lg:text-2xl',\n h6: 'text-base sm:text-lg lg:text-xl',\n};\n\nconst Title = ({ children, level = 1, className, ...props }: Props) => {\n const Element: ElementType = level < 1 || level > 6 ? 'h1' : `h${level}`;\n\n return (\n <Element\n className={cn('m-0 leading-snug font-bold', styles[Element], className)}\n {...props}\n >\n {children}\n </Element>\n );\n};\n\nexport default Title;\n"],"mappings":";;;AAaA,MAAM,SAAiC;CACrC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,MAAM,SAAS,EAAE,UAAU,QAAQ,GAAG,WAAW,GAAG,YAAmB;CACrE,MAAM,UAAuB,QAAQ,KAAK,QAAQ,IAAI,OAAO,IAAI;CAEjE,OACE,oBAAC,SAAD;EACE,WAAW,GAAG,8BAA8B,OAAO,UAAU,SAAS;EACtE,GAAI;EAEH;CACM,CAAA;AAEb"}
|
|
1
|
+
{"version":3,"file":"title.mjs","names":[],"sources":["../../../../src/components/atoms/typography/title.tsx"],"sourcesContent":["import { cn } from '@repo/ui/utils';\n\nexport interface Props extends React.ComponentPropsWithoutRef<\n 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'\n> {\n level?: 1 | 2 | 3 | 4 | 5 | 6;\n}\n\ntype ElementType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\n// Scale up at wider breakpoints instead of a single fixed size — the desktop\n// size stays the same as before, but narrow/mobile viewports now get a\n// smaller starting size instead of always rendering at the full desktop size.\nconst styles: Record<string, string> = {\n h1: 'text-4xl sm:text-5xl lg:text-6xl',\n h2: 'text-3xl sm:text-4xl lg:text-5xl',\n h3: 'text-2xl sm:text-3xl lg:text-4xl',\n h4: 'text-xl sm:text-2xl lg:text-3xl',\n h5: 'text-lg sm:text-xl lg:text-2xl',\n h6: 'text-base sm:text-lg lg:text-xl',\n};\n\nconst Title = ({ children, level = 1, className, ...props }: Props) => {\n const Element: ElementType = level < 1 || level > 6 ? 'h1' : `h${level}`;\n\n return (\n <Element\n data-slot=\"typography-title\"\n className={cn('m-0 leading-snug font-bold', styles[Element], className)}\n {...props}\n >\n {children}\n </Element>\n );\n};\n\nexport default Title;\n"],"mappings":";;;AAaA,MAAM,SAAiC;CACrC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;AAEA,MAAM,SAAS,EAAE,UAAU,QAAQ,GAAG,WAAW,GAAG,YAAmB;CACrE,MAAM,UAAuB,QAAQ,KAAK,QAAQ,IAAI,OAAO,IAAI;CAEjE,OACE,oBAAC,SAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,OAAO,UAAU,SAAS;EACtE,GAAI;EAEH;CACM,CAAA;AAEb"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
//#region src/components/molecules/collapse.d.ts
|
|
3
|
-
interface Item {
|
|
4
|
-
key:
|
|
3
|
+
interface Item<Key extends React.Key = string> {
|
|
4
|
+
key: Key;
|
|
5
5
|
label: React.ReactNode;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
children: React.ReactNode;
|
|
8
8
|
}
|
|
9
|
-
interface Props extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue' | 'value' | 'dir'> {
|
|
10
|
-
items?: Item[];
|
|
9
|
+
interface Props<Key extends React.Key = string> extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange' | 'defaultValue' | 'value' | 'dir'> {
|
|
10
|
+
items?: Item<Key>[];
|
|
11
11
|
accordion?: boolean;
|
|
12
12
|
expandIcon?: React.ReactNode;
|
|
13
13
|
classNames?: {
|
|
@@ -15,11 +15,11 @@ interface Props extends Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange' |
|
|
|
15
15
|
header?: string;
|
|
16
16
|
body?: string;
|
|
17
17
|
};
|
|
18
|
-
defaultActiveKey?:
|
|
19
|
-
activeKey?:
|
|
20
|
-
onChange?: (keys:
|
|
18
|
+
defaultActiveKey?: Key[];
|
|
19
|
+
activeKey?: Key[];
|
|
20
|
+
onChange?: (keys: Key[]) => void;
|
|
21
21
|
}
|
|
22
|
-
declare const Collapse: ({ expandIcon, accordion, items, className, classNames, defaultActiveKey, activeKey: _activeKey, onChange: _onChange, ...props }: Props) => React.JSX.Element;
|
|
22
|
+
declare const Collapse: <Key extends React.Key = string>({ expandIcon, accordion, items, className, classNames, defaultActiveKey, activeKey: _activeKey, onChange: _onChange, ...props }: Props<Key>) => React.JSX.Element;
|
|
23
23
|
//#endregion
|
|
24
24
|
export { Props, Collapse as default };
|
|
25
25
|
//# sourceMappingURL=collapse.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collapse.d.mts","names":[],"sources":["../../../src/components/molecules/collapse.tsx"],"mappings":";;UAWU
|
|
1
|
+
{"version":3,"file":"collapse.d.mts","names":[],"sources":["../../../src/components/molecules/collapse.tsx"],"mappings":";;UAWU,KAAK,YAAY,MAAM;EAC/B,KAAK;EACL,OAAO,MAAM;EACb;EACA,UAAU,MAAM;;UAGD,MAAM,YAAY,MAAM,sBAAsB,KAC7D,MAAM;EAGN,QAAQ,KAAK;EACb;EACA,aAAa,MAAM;EACnB;IACE;IACA;IACA;;EAEF,mBAAmB;EACnB,YAAY;EACZ,YAAY,MAAM;;cAGd,WAAY,YAAY,MAAM,gBAAc,YAAA,WAAA,OAAA,WAAA,YAAA,kBAAA,WAAA,YAAA,UAAA,cAAA,SAU/C,MAAM,SAAI,MAAA,IAAA"}
|
|
@@ -6,12 +6,21 @@ 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 controlled = _activeKey !== void 0;
|
|
10
|
+
const keysByValue = new Map([
|
|
11
|
+
...defaultActiveKey ?? [],
|
|
12
|
+
..._activeKey ?? [],
|
|
13
|
+
...items.map((item) => item.key)
|
|
14
|
+
].map((key) => [String(key), key]));
|
|
9
15
|
const accordionProps = {
|
|
10
16
|
multiple: !accordion,
|
|
11
17
|
onValueChange: (values) => {
|
|
12
|
-
_onChange?.(values)
|
|
18
|
+
_onChange?.(values.flatMap((value) => {
|
|
19
|
+
const key = keysByValue.get(value);
|
|
20
|
+
return key === void 0 ? [] : [key];
|
|
21
|
+
}));
|
|
13
22
|
},
|
|
14
|
-
...
|
|
23
|
+
...controlled ? { value: (_activeKey ?? []).map((key) => String(key)) } : { defaultValue: (defaultActiveKey ?? []).map((key) => String(key)) }
|
|
15
24
|
};
|
|
16
25
|
return /* @__PURE__ */ jsx(Accordion, {
|
|
17
26
|
...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:
|
|
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<Key extends React.Key = string> {\n key: Key;\n label: React.ReactNode;\n disabled?: boolean;\n children: React.ReactNode;\n}\n\nexport interface Props<Key extends React.Key = string> extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'onChange' | 'defaultValue' | 'value' | 'dir'\n> {\n items?: Item<Key>[];\n accordion?: boolean;\n expandIcon?: React.ReactNode;\n classNames?: {\n item?: string;\n header?: string;\n body?: string;\n };\n defaultActiveKey?: Key[];\n activeKey?: Key[];\n onChange?: (keys: Key[]) => void;\n}\n\nconst Collapse = <Key extends React.Key = string>({\n expandIcon,\n accordion = false,\n items = [],\n className,\n classNames,\n defaultActiveKey,\n activeKey: _activeKey,\n onChange: _onChange,\n ...props\n}: Props<Key>) => {\n const controlled = _activeKey !== undefined;\n const keysByValue = new Map<string, Key>(\n [\n ...(defaultActiveKey ?? []),\n ...(_activeKey ?? []),\n ...items.map(item => item.key),\n ].map(key => [String(key), key]),\n );\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?.(\n values.flatMap(value => {\n const key = keysByValue.get(value);\n\n return key === undefined ? [] : [key];\n }),\n );\n },\n ...(controlled\n ? { value: (_activeKey ?? []).map(key => String(key)) }\n : { defaultValue: (defaultActiveKey ?? []).map(key => String(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,YAA4C,EAChD,YACA,YAAY,OACZ,QAAQ,CAAC,GACT,WACA,YACA,kBACA,WAAW,YACX,UAAU,WACV,GAAG,YACa;CAChB,MAAM,aAAa,eAAe,KAAA;CAClC,MAAM,cAAc,IAAI,IACtB;EACE,GAAI,oBAAoB,CAAC;EACzB,GAAI,cAAc,CAAC;EACnB,GAAG,MAAM,KAAI,SAAQ,KAAK,GAAG;CAC/B,CAAC,CAAC,KAAI,QAAO,CAAC,OAAO,GAAG,GAAG,GAAG,CAAC,CACjC;CAKA,MAAM,iBAAiB;EACrB,UAAU,CAAC;EACX,gBAAgB,WAAqB;GACnC,YACE,OAAO,SAAQ,UAAS;IACtB,MAAM,MAAM,YAAY,IAAI,KAAK;IAEjC,OAAO,QAAQ,KAAA,IAAY,CAAC,IAAI,CAAC,GAAG;GACtC,CAAC,CACH;EACF;EACA,GAAI,aACA,EAAE,QAAQ,cAAc,CAAC,EAAA,CAAG,KAAI,QAAO,OAAO,GAAG,CAAC,EAAE,IACpD,EAAE,eAAe,oBAAoB,CAAC,EAAA,CAAG,KAAI,QAAO,OAAO,GAAG,CAAC,EAAE;CACvE;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"}
|
|
@@ -3,8 +3,8 @@ import { cn } from "../../utils.mjs";
|
|
|
3
3
|
import "../../lib/z-layers.mjs";
|
|
4
4
|
import Menu from "./menu/menu.mjs";
|
|
5
5
|
import { useId, useRef } from "react";
|
|
6
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
6
|
import { useControllableState, useKeyPress } from "@jbpark/use-hooks";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { AnimatePresence, motion } from "motion/react";
|
|
9
9
|
//#region src/components/molecules/dropdown.tsx
|
|
10
10
|
const Dropdown = ({ children, menu, trigger = "hover", open: _open, onOpenChange: _onOpenChange = () => {}, className, onMouseEnter, onMouseLeave, ...props }) => {
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { Props as Props$2 } from "
|
|
1
|
+
import Alert, { Props } from "../../Alert.mjs";
|
|
2
|
+
import Breadcrumb, { Props as Props$1 } from "../../Breadcrumb.mjs";
|
|
3
|
+
import Card, { Props as Props$2 } from "../../Card.mjs";
|
|
4
|
+
import Menu, { Props as Props$3 } from "./menu/menu.mjs";
|
|
5
|
+
import Pagination, { Props as Props$4 } from "../../Pagination.mjs";
|
|
6
|
+
import { Props as Props$5 } from "./reveals/reveals.mjs";
|
|
4
7
|
import Reveals from "../../Reveals.mjs";
|
|
5
|
-
import Space, { Props as Props$
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import { Props as Props$
|
|
8
|
+
import Space, { Props as Props$6 } from "../../Space.mjs";
|
|
9
|
+
import Steps, { Item, Props as Props$7 } from "../../Steps.mjs";
|
|
10
|
+
import Collapse, { Props as Props$8 } from "./collapse.mjs";
|
|
11
|
+
import Dropdown, { Props as Props$9 } from "./dropdown.mjs";
|
|
12
|
+
import { Props as Props$10 } from "./marquees/marquees.mjs";
|
|
9
13
|
import Marquees from "./marquees/index.mjs";
|
|
10
|
-
import { Props as Props$
|
|
14
|
+
import { Props as Props$11 } from "./splitter/splitter.mjs";
|
|
11
15
|
import Splitter from "./splitter/index.mjs";
|
|
12
|
-
import
|
|
13
|
-
|
|
16
|
+
import Tabs, { Props as Props$12 } from "./tabs.mjs";
|
|
17
|
+
import Upload, { Props as Props$13, UploadFile } from "./upload.mjs";
|
|
18
|
+
export { Alert, type Props as AlertProps, Breadcrumb, type Props$1 as BreadcrumbProps, Card, type Props$2 as CardProps, Collapse, type Props$8 as CollapseProps, Dropdown, type Props$9 as DropdownProps, Marquees, type Props$10 as MarqueesProps, Menu, type Props$3 as MenuProps, Pagination, type Props$4 as PaginationProps, Reveals, type Props$5 as RevealsProps, Space, type Props$6 as SpaceProps, Splitter, type Props$11 as SplitterProps, type Item as StepItem, Steps, type Props$7 as StepsProps, Tabs, type Props$12 as TabsProps, Upload, type UploadFile, type Props$13 as UploadProps };
|
|
@@ -3,8 +3,8 @@ import { cn } from "../../../utils.mjs";
|
|
|
3
3
|
import usePauseOnHover from "./use-pause-on-hover.mjs";
|
|
4
4
|
import Item from "./item.mjs";
|
|
5
5
|
import { useEffect, useRef, useState } from "react";
|
|
6
|
-
import { jsx } from "react/jsx-runtime";
|
|
7
6
|
import { useMergedRef, useResponsiveSize, useThrottledValue } from "@jbpark/use-hooks";
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
8
|
//#region src/components/molecules/marquees/marquees.tsx
|
|
9
9
|
const Marquees = ({ className, items, speed, pauseOnHover = true, autoFill = true, gap, ...props }) => {
|
|
10
10
|
const [width, setWidth] = useState("100%");
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { cn } from "../../../../utils.mjs";
|
|
3
3
|
import Label from "./label.mjs";
|
|
4
4
|
import { MENU_CLASSNAMES } from "../menu.mjs";
|
|
5
|
-
import { createElement, useRef, useState } from "react";
|
|
6
5
|
import { ChevronDown } from "lucide-react";
|
|
6
|
+
import { createElement, useRef, useState } from "react";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { AnimatePresence, motion } from "motion/react";
|
|
9
9
|
//#region src/components/molecules/menu/item/item.tsx
|
|
@@ -28,7 +28,7 @@ interface Props {
|
|
|
28
28
|
onClick?: ClickEventHandler;
|
|
29
29
|
onSelect?: ClickEventHandler;
|
|
30
30
|
}
|
|
31
|
-
interface MenuProps extends Props, Omit<React.ComponentPropsWithoutRef<'ul'>, 'onClick' | 'onSelect'> {
|
|
31
|
+
interface MenuProps extends Omit<Props, 'selectionMap'>, Omit<React.ComponentPropsWithoutRef<'ul'>, 'onClick' | 'onSelect'> {
|
|
32
32
|
items?: MenuItem[];
|
|
33
33
|
}
|
|
34
34
|
type ClickEventHandler = (params: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.d.mts","names":[],"sources":["../../../../src/components/molecules/menu/menu.tsx"],"mappings":";UAUiB;EACf,OAAO,MAAM;EACb,KAAK,MAAM;EACX;EACA;EACA,WAAW;;UAGI;EACf;EACA,eAAe,MAAM;EACrB,sBAAsB,MAAM;EAC5B,eAAe;EACf;EACA;EACA;IACE;IACA;IACA;IACA;;EAEF;IACE,WAAW,MAAM;IACjB,UAAU,MAAM;IAChB,OAAO,MAAM;IACb,QAAQ,MAAM;;EAEhB,UAAU;EACV,WAAW;;UAGI,kBAEb,
|
|
1
|
+
{"version":3,"file":"menu.d.mts","names":[],"sources":["../../../../src/components/molecules/menu/menu.tsx"],"mappings":";UAUiB;EACf,OAAO,MAAM;EACb,KAAK,MAAM;EACX;EACA;EACA,WAAW;;UAGI;EACf;EACA,eAAe,MAAM;EACrB,sBAAsB,MAAM;EAC5B,eAAe;EACf;EACA;EACA;IACE;IACA;IACA;IACA;;EAEF;IACE,WAAW,MAAM;IACjB,UAAU,MAAM;IAChB,OAAO,MAAM;IACb,QAAQ,MAAM;;EAEhB,UAAU;EACV,WAAW;;UAGI,kBAEb,KAAK,wBACL,KAAK,MAAM;EACb,QAAQ;;KAGE,qBAAqB;EAC/B,UAAU,MAAM;EAChB,KAAK,MAAM;EACX,SAAS,MAAM;EACf,MAAM;;cAGK;KAWD,eAAe,YAAY,MAAM;cAEhC,oBACX,OAAO,YACP,iBAAiB,YAAY,MAAM,SAClC;cAeU,UACX,MAAM,UACN,YAAY,YAAY,MAAM;cAiB1B,SAAQ,OAAA,MAAA,qBAAA,cAAA,eAAA,WAAA,YAAA,QAAA,QAAA,cAAA,SAAA,UAAA,cAAA,SAaX,8BAAS,IAAA"}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { cn } from "../../../utils.mjs";
|
|
3
3
|
import Item from "./item/item.mjs";
|
|
4
4
|
import { createElement, useMemo } from "react";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
6
5
|
import { useControllableState } from "@jbpark/use-hooks";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
//#region src/components/molecules/menu/menu.tsx
|
|
8
8
|
const MENU_CLASSNAMES = [
|
|
9
9
|
"m-0",
|
|
@@ -40,14 +40,17 @@ const Menu = ({ items, mode = "vertical", defaultSelectedKeys = [], selectedKeys
|
|
|
40
40
|
});
|
|
41
41
|
const selectedKeysSet = useMemo(() => new Set(selectedKeys ?? []), [selectedKeys]);
|
|
42
42
|
const selectionMap = useMemo(() => buildSelectionMap(items ?? [], selectedKeysSet), [items, selectedKeysSet]);
|
|
43
|
+
const rootProps = { ...props };
|
|
44
|
+
Reflect.deleteProperty(rootProps, "selectionMap");
|
|
43
45
|
const onSelect = (params) => {
|
|
44
46
|
setSelectedKeys([params.key]);
|
|
45
47
|
_onSelect?.(params);
|
|
46
48
|
};
|
|
47
49
|
return /* @__PURE__ */ jsx("ul", {
|
|
50
|
+
"data-slot": "menu",
|
|
48
51
|
role: "menu",
|
|
49
52
|
className: cn(MENU_CLASSNAMES, mode === "horizontal" ? "flex" : "inline-block", className),
|
|
50
|
-
...
|
|
53
|
+
...rootProps,
|
|
51
54
|
children: items?.map((item, index) => /* @__PURE__ */ createElement(Item, {
|
|
52
55
|
root: true,
|
|
53
56
|
...item,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.mjs","names":[],"sources":["../../../../src/components/molecules/menu/menu.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Item from './item';\n\nexport interface MenuItem {\n label: React.ReactNode;\n key: React.Key;\n type?: string;\n path?: string;\n children?: MenuItem[];\n}\n\nexport interface Props {\n mode?: 'horizontal' | 'vertical' | 'inline';\n selectedKeys?: React.Key[];\n defaultSelectedKeys?: React.Key[];\n selectionMap?: SelectionMap;\n offset?: [number, number];\n inlineOffset?: number;\n classNames?: {\n rootItem?: string;\n subMenu?: string;\n item?: string;\n label?: string;\n };\n styles?: {\n rootItem?: React.CSSProperties;\n subMenu?: React.CSSProperties;\n item?: React.CSSProperties;\n label?: React.CSSProperties;\n };\n onClick?: ClickEventHandler;\n onSelect?: ClickEventHandler;\n}\n\nexport interface MenuProps\n extends\n Props
|
|
1
|
+
{"version":3,"file":"menu.mjs","names":[],"sources":["../../../../src/components/molecules/menu/menu.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\n\nimport { useControllableState } from '@jbpark/use-hooks';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Item from './item';\n\nexport interface MenuItem {\n label: React.ReactNode;\n key: React.Key;\n type?: string;\n path?: string;\n children?: MenuItem[];\n}\n\nexport interface Props {\n mode?: 'horizontal' | 'vertical' | 'inline';\n selectedKeys?: React.Key[];\n defaultSelectedKeys?: React.Key[];\n selectionMap?: SelectionMap;\n offset?: [number, number];\n inlineOffset?: number;\n classNames?: {\n rootItem?: string;\n subMenu?: string;\n item?: string;\n label?: string;\n };\n styles?: {\n rootItem?: React.CSSProperties;\n subMenu?: React.CSSProperties;\n item?: React.CSSProperties;\n label?: React.CSSProperties;\n };\n onClick?: ClickEventHandler;\n onSelect?: ClickEventHandler;\n}\n\nexport interface MenuProps\n extends\n Omit<Props, 'selectionMap'>,\n Omit<React.ComponentPropsWithoutRef<'ul'>, 'onClick' | 'onSelect'> {\n items?: MenuItem[];\n}\n\nexport type ClickEventHandler = (params: {\n domEvent: React.SyntheticEvent;\n key: React.Key;\n keyPath: React.Key[];\n item: MenuItem;\n}) => void;\n\nexport const MENU_CLASSNAMES = [\n 'm-0',\n 'list-none',\n 'p-0',\n 'bg-popover',\n 'text-popover-foreground',\n 'shadow-md',\n 'rounded-md',\n //\n];\n\nexport type SelectionMap = ReadonlyMap<React.Key, boolean>;\n\nexport const buildSelectionMap = (\n items: MenuItem[],\n selectedKeysSet: ReadonlySet<React.Key>,\n): SelectionMap => {\n const map = new Map<React.Key, boolean>();\n\n const dfs = (node: MenuItem): boolean => {\n const self = selectedKeysSet.has(node.key);\n const hasSelectedChild = node.children?.some(child => dfs(child)) ?? false;\n const isSelected = self || hasSelectedChild;\n map.set(node.key, isSelected);\n return isSelected;\n };\n\n items.forEach(dfs);\n return map;\n};\n\nexport const findKey = (\n menu: MenuItem,\n targetKeys: ReadonlySet<React.Key>,\n): boolean => {\n if (targetKeys.has(menu.key)) {\n return true;\n }\n\n if (menu.children && Array.isArray(menu.children)) {\n for (const child of menu.children) {\n if (findKey(child, targetKeys)) {\n return true;\n }\n }\n }\n\n return false;\n};\n\nconst Menu = ({\n items,\n mode = 'vertical',\n defaultSelectedKeys = [],\n selectedKeys: _selectedKeys,\n className,\n classNames,\n styles,\n offset,\n inlineOffset,\n onClick,\n onSelect: _onSelect,\n ...props\n}: MenuProps) => {\n const [selectedKeys, setSelectedKeys] = useControllableState<React.Key[]>({\n value: _selectedKeys,\n defaultValue: defaultSelectedKeys ?? [],\n });\n\n const selectedKeysSet = useMemo(\n () => new Set<React.Key>(selectedKeys ?? []),\n [selectedKeys],\n );\n\n const selectionMap = useMemo(\n () => buildSelectionMap(items ?? [], selectedKeysSet),\n [items, selectedKeysSet],\n );\n const rootProps = { ...props };\n\n // Ignore stale JavaScript callers that still supply this internal prop.\n Reflect.deleteProperty(rootProps, 'selectionMap');\n\n const onSelect = (params: {\n domEvent: React.SyntheticEvent;\n key: React.Key;\n keyPath: React.Key[];\n item: MenuItem;\n }) => {\n setSelectedKeys([params.key]);\n _onSelect?.(params);\n };\n\n return (\n <ul\n data-slot=\"menu\"\n role=\"menu\"\n className={cn(\n MENU_CLASSNAMES,\n mode === 'horizontal' ? 'flex' : 'inline-block',\n className,\n )}\n {...rootProps}\n >\n {items?.map((item, index) => (\n <Item\n root\n {...item}\n key={item.key}\n itemKey={item.key}\n keyPath={[item.key]}\n index={index}\n selectionMap={selectionMap}\n mode={mode}\n classNames={classNames}\n styles={styles}\n offset={offset}\n inlineOffset={inlineOffset}\n onClick={onClick}\n onSelect={onSelect}\n />\n ))}\n </ul>\n );\n};\n\nexport default Menu;\n"],"mappings":";;;;;;;AAuDA,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;AAEF;AAIA,MAAa,qBACX,OACA,oBACiB;CACjB,MAAM,sBAAM,IAAI,IAAwB;CAExC,MAAM,OAAO,SAA4B;EACvC,MAAM,OAAO,gBAAgB,IAAI,KAAK,GAAG;EACzC,MAAM,mBAAmB,KAAK,UAAU,MAAK,UAAS,IAAI,KAAK,CAAC,KAAK;EACrE,MAAM,aAAa,QAAQ;EAC3B,IAAI,IAAI,KAAK,KAAK,UAAU;EAC5B,OAAO;CACT;CAEA,MAAM,QAAQ,GAAG;CACjB,OAAO;AACT;AAEA,MAAa,WACX,MACA,eACY;CACZ,IAAI,WAAW,IAAI,KAAK,GAAG,GACzB,OAAO;CAGT,IAAI,KAAK,YAAY,MAAM,QAAQ,KAAK,QAAQ,GACzC;OAAA,MAAM,SAAS,KAAK,UACvB,IAAI,QAAQ,OAAO,UAAU,GAC3B,OAAO;CAAA;CAKb,OAAO;AACT;AAEA,MAAM,QAAQ,EACZ,OACA,OAAO,YACP,sBAAsB,CAAC,GACvB,cAAc,eACd,WACA,YACA,QACA,QACA,cACA,SACA,UAAU,WACV,GAAG,YACY;CACf,MAAM,CAAC,cAAc,mBAAmB,qBAAkC;EACxE,OAAO;EACP,cAAc,uBAAuB,CAAC;CACxC,CAAC;CAED,MAAM,kBAAkB,cAChB,IAAI,IAAe,gBAAgB,CAAC,CAAC,GAC3C,CAAC,YAAY,CACf;CAEA,MAAM,eAAe,cACb,kBAAkB,SAAS,CAAC,GAAG,eAAe,GACpD,CAAC,OAAO,eAAe,CACzB;CACA,MAAM,YAAY,EAAE,GAAG,MAAM;CAG7B,QAAQ,eAAe,WAAW,cAAc;CAEhD,MAAM,YAAY,WAKZ;EACJ,gBAAgB,CAAC,OAAO,GAAG,CAAC;EAC5B,YAAY,MAAM;CACpB;CAEA,OACE,oBAAC,MAAD;EACE,aAAU;EACV,MAAK;EACL,WAAW,GACT,iBACA,SAAS,eAAe,SAAS,gBACjC,SACF;EACA,GAAI;EAEH,UAAA,OAAO,KAAK,MAAM,UACjB,8BAAC,MAAD;GACE,MAAA;GACA,GAAI;GACJ,KAAK,KAAK;GACV,SAAS,KAAK;GACd,SAAS,CAAC,KAAK,GAAG;GACX;GACO;GACR;GACM;GACJ;GACA;GACM;GACL;GACC;EACX,CAAA,CACF;CACC,CAAA;AAER"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Tabs as Tabs$1 } from "../../core/tabs.mjs";
|
|
2
|
+
import "../../core/index.mjs";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
//#region src/components/molecules/tabs.d.ts
|
|
5
|
+
declare const Core: typeof Tabs$1;
|
|
6
|
+
interface Item {
|
|
7
|
+
key: string;
|
|
8
|
+
label: ReactNode;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
/** Decorative icon rendered before the label with consistent spacing. */
|
|
12
|
+
icon?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
interface Props extends Omit<React.ComponentProps<typeof Core>, 'children' | 'onChange'> {
|
|
15
|
+
items: Item[];
|
|
16
|
+
/** Called when the selected tab changes. */
|
|
17
|
+
onChange?: (value: string | number | null) => void;
|
|
18
|
+
/** @deprecated Use `onChange` for the selected value. */
|
|
19
|
+
onValueChange?: React.ComponentProps<typeof Core>['onValueChange'];
|
|
20
|
+
listLabel?: string;
|
|
21
|
+
/** Preserve inactive panel DOM and local state. */
|
|
22
|
+
keepMounted?: boolean;
|
|
23
|
+
/** Select a tab when arrow-key focus moves to it. */
|
|
24
|
+
activateOnFocus?: boolean;
|
|
25
|
+
/** Scroll the tab list when its items exceed the available space. */
|
|
26
|
+
scrollable?: boolean;
|
|
27
|
+
/** Give tabs equal width in horizontal mode; ignored when scrollable. */
|
|
28
|
+
fitted?: boolean;
|
|
29
|
+
/** Content shown after the tab list, outside the tablist role. */
|
|
30
|
+
extra?: ReactNode;
|
|
31
|
+
classNames?: {
|
|
32
|
+
list?: string;
|
|
33
|
+
tab?: string;
|
|
34
|
+
panel?: string;
|
|
35
|
+
extra?: string;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
declare const Tabs: ({ items, listLabel, keepMounted, activateOnFocus, scrollable, fitted, extra, classNames, defaultValue, onChange, onValueChange, orientation, ...props }: Props) => import("react").JSX.Element;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { Item, Props, Tabs as default };
|
|
41
|
+
//# sourceMappingURL=tabs.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.d.mts","names":[],"sources":["../../../src/components/molecules/tabs.tsx"],"mappings":";;;;cAQc,aAAI;UAED;EACf;EACA,OAAO;EACP,UAAU;EACV;;EAEA,OAAO;;UAGQ,cAAc,KAC7B,MAAM,sBAAsB;EAG5B,OAAO;;EAEP,YAAY;;EAEZ,gBAAgB,MAAM,sBAAsB;EAC5C;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,QAAQ;EACR;IACE;IACA;IACA;IACA;;;cAIE,SAAQ,OAAA,WAAA,aAAA,iBAAA,YAAA,QAAA,OAAA,YAAA,cAAA,UAAA,eAAA,gBAAA,SAcX,0BAAK,IAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../utils.mjs";
|
|
3
|
+
import { tabs_exports } from "../../core/tabs.mjs";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/molecules/tabs.tsx
|
|
6
|
+
const { Tabs: Core, TabsList, TabsTab, TabsPanel } = tabs_exports;
|
|
7
|
+
const Tabs = ({ items, listLabel = "Tabs", keepMounted = false, activateOnFocus = false, scrollable = false, fitted = false, extra, classNames, defaultValue, onChange, onValueChange, orientation = "horizontal", ...props }) => {
|
|
8
|
+
const initialValue = defaultValue === void 0 ? items.find((item) => !item.disabled)?.key : defaultValue;
|
|
9
|
+
return /* @__PURE__ */ jsxs(Core, {
|
|
10
|
+
defaultValue: props.value === void 0 ? initialValue : void 0,
|
|
11
|
+
orientation,
|
|
12
|
+
onValueChange: (value, eventDetails) => {
|
|
13
|
+
onChange?.(value);
|
|
14
|
+
onValueChange?.(value, eventDetails);
|
|
15
|
+
},
|
|
16
|
+
...props,
|
|
17
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
18
|
+
"data-slot": "tabs-bar",
|
|
19
|
+
className: cn("flex min-w-0 items-stretch", orientation === "vertical" && "min-h-0 shrink-0 flex-col"),
|
|
20
|
+
children: [/* @__PURE__ */ jsx(TabsList, {
|
|
21
|
+
"aria-label": listLabel,
|
|
22
|
+
activateOnFocus,
|
|
23
|
+
className: cn("min-w-0 flex-1", scrollable && (orientation === "vertical" ? "min-h-0 overflow-y-auto" : `[scrollbar-width:none] overflow-x-auto overflow-y-hidden
|
|
24
|
+
[&::-webkit-scrollbar]:hidden`), classNames?.list),
|
|
25
|
+
children: items.map((item) => /* @__PURE__ */ jsxs(TabsTab, {
|
|
26
|
+
value: item.key,
|
|
27
|
+
disabled: item.disabled,
|
|
28
|
+
className: cn(fitted && !scrollable && orientation === "horizontal" && "flex-1", scrollable && "shrink-0", classNames?.tab),
|
|
29
|
+
children: [item.icon != null && /* @__PURE__ */ jsx("span", {
|
|
30
|
+
"data-slot": "tabs-icon",
|
|
31
|
+
"aria-hidden": "true",
|
|
32
|
+
className: "inline-flex shrink-0 items-center",
|
|
33
|
+
children: item.icon
|
|
34
|
+
}), item.label]
|
|
35
|
+
}, item.key))
|
|
36
|
+
}), extra != null && /* @__PURE__ */ jsx("div", {
|
|
37
|
+
"data-slot": "tabs-extra",
|
|
38
|
+
className: cn(`border-border flex shrink-0 items-center border-b px-3
|
|
39
|
+
data-[orientation=vertical]:border-r
|
|
40
|
+
data-[orientation=vertical]:border-b-0`, classNames?.extra),
|
|
41
|
+
"data-orientation": orientation,
|
|
42
|
+
children: extra
|
|
43
|
+
})]
|
|
44
|
+
}), items.map((item) => /* @__PURE__ */ jsx(TabsPanel, {
|
|
45
|
+
value: item.key,
|
|
46
|
+
keepMounted,
|
|
47
|
+
className: classNames?.panel,
|
|
48
|
+
children: item.children
|
|
49
|
+
}, item.key))]
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { Tabs as default };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=tabs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.mjs","names":["tabs"],"sources":["../../../src/components/molecules/tabs.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { tabs } from '../../core';\n\nconst { Tabs: Core, TabsList, TabsTab, TabsPanel } = tabs;\n\nexport interface Item {\n key: string;\n label: ReactNode;\n children: ReactNode;\n disabled?: boolean;\n /** Decorative icon rendered before the label with consistent spacing. */\n icon?: ReactNode;\n}\n\nexport interface Props extends Omit<\n React.ComponentProps<typeof Core>,\n 'children' | 'onChange'\n> {\n items: Item[];\n /** Called when the selected tab changes. */\n onChange?: (value: string | number | null) => void;\n /** @deprecated Use `onChange` for the selected value. */\n onValueChange?: React.ComponentProps<typeof Core>['onValueChange'];\n listLabel?: string;\n /** Preserve inactive panel DOM and local state. */\n keepMounted?: boolean;\n /** Select a tab when arrow-key focus moves to it. */\n activateOnFocus?: boolean;\n /** Scroll the tab list when its items exceed the available space. */\n scrollable?: boolean;\n /** Give tabs equal width in horizontal mode; ignored when scrollable. */\n fitted?: boolean;\n /** Content shown after the tab list, outside the tablist role. */\n extra?: ReactNode;\n classNames?: {\n list?: string;\n tab?: string;\n panel?: string;\n extra?: string;\n };\n}\n\nconst Tabs = ({\n items,\n listLabel = 'Tabs',\n keepMounted = false,\n activateOnFocus = false,\n scrollable = false,\n fitted = false,\n extra,\n classNames,\n defaultValue,\n onChange,\n onValueChange,\n orientation = 'horizontal',\n ...props\n}: Props) => {\n const initialValue =\n defaultValue === undefined\n ? items.find(item => !item.disabled)?.key\n : defaultValue;\n\n return (\n <Core\n defaultValue={props.value === undefined ? initialValue : undefined}\n orientation={orientation}\n onValueChange={(value, eventDetails) => {\n onChange?.(value);\n onValueChange?.(value, eventDetails);\n }}\n {...props}\n >\n <div\n data-slot=\"tabs-bar\"\n className={cn(\n 'flex min-w-0 items-stretch',\n orientation === 'vertical' && 'min-h-0 shrink-0 flex-col',\n //\n )}\n >\n <TabsList\n aria-label={listLabel}\n activateOnFocus={activateOnFocus}\n className={cn(\n 'min-w-0 flex-1',\n scrollable &&\n (orientation === 'vertical'\n ? 'min-h-0 overflow-y-auto'\n : `[scrollbar-width:none] overflow-x-auto overflow-y-hidden\n [&::-webkit-scrollbar]:hidden`),\n classNames?.list,\n //\n )}\n >\n {items.map(item => (\n <TabsTab\n key={item.key}\n value={item.key}\n disabled={item.disabled}\n className={cn(\n fitted &&\n !scrollable &&\n orientation === 'horizontal' &&\n 'flex-1',\n scrollable && 'shrink-0',\n classNames?.tab,\n //\n )}\n >\n {item.icon != null && (\n <span\n data-slot=\"tabs-icon\"\n aria-hidden=\"true\"\n className=\"inline-flex shrink-0 items-center\"\n >\n {item.icon}\n </span>\n )}\n {item.label}\n </TabsTab>\n ))}\n </TabsList>\n {extra != null && (\n <div\n data-slot=\"tabs-extra\"\n className={cn(\n `border-border flex shrink-0 items-center border-b px-3\n data-[orientation=vertical]:border-r\n data-[orientation=vertical]:border-b-0`,\n classNames?.extra,\n //\n )}\n data-orientation={orientation}\n >\n {extra}\n </div>\n )}\n </div>\n {items.map(item => (\n <TabsPanel\n key={item.key}\n value={item.key}\n keepMounted={keepMounted}\n className={classNames?.panel}\n >\n {item.children}\n </TabsPanel>\n ))}\n </Core>\n );\n};\n\nexport default Tabs;\n"],"mappings":";;;;;AAQA,MAAM,EAAE,MAAM,MAAM,UAAU,SAAS,cAAcA;AAuCrD,MAAM,QAAQ,EACZ,OACA,YAAY,QACZ,cAAc,OACd,kBAAkB,OAClB,aAAa,OACb,SAAS,OACT,OACA,YACA,cACA,UACA,eACA,cAAc,cACd,GAAG,YACQ;CACX,MAAM,eACJ,iBAAiB,KAAA,IACb,MAAM,MAAK,SAAQ,CAAC,KAAK,QAAQ,CAAC,EAAE,MACpC;CAEN,OACE,qBAAC,MAAD;EACE,cAAc,MAAM,UAAU,KAAA,IAAY,eAAe,KAAA;EAC5C;EACb,gBAAgB,OAAO,iBAAiB;GACtC,WAAW,KAAK;GAChB,gBAAgB,OAAO,YAAY;EACrC;EACA,GAAI;EAPN,UAAA,CASE,qBAAC,OAAD;GACE,aAAU;GACV,WAAW,GACT,8BACA,gBAAgB,cAAc,2BAEhC;GANF,UAAA,CAQE,oBAAC,UAAD;IACE,cAAY;IACK;IACjB,WAAW,GACT,kBACA,eACG,gBAAgB,aACb,4BACA;mDAEN,YAAY,IAEd;IAEC,UAAA,MAAM,KAAI,SACT,qBAAC,SAAD;KAEE,OAAO,KAAK;KACZ,UAAU,KAAK;KACf,WAAW,GACT,UACE,CAAC,cACD,gBAAgB,gBAChB,UACF,cAAc,YACd,YAAY,GAEd;KAZF,UAAA,CAcG,KAAK,QAAQ,QACZ,oBAAC,QAAD;MACE,aAAU;MACV,eAAY;MACZ,WAAU;MAET,UAAA,KAAK;KACF,CAAA,GAEP,KAAK,KACC;IAvBF,GAAA,KAAK,GAuBH,CACV;GACO,CAAA,GACT,SAAS,QACR,oBAAC,OAAD;IACE,aAAU;IACV,WAAW,GACT;;uDAGA,YAAY,KAEd;IACA,oBAAkB;IAEjB,UAAA;GACE,CAAA,CAEJ;EACJ,CAAA,GAAA,MAAM,KAAI,SACT,oBAAC,WAAD;GAEE,OAAO,KAAK;GACC;GACb,WAAW,YAAY;GAEtB,UAAA,KAAK;EACG,GANJ,KAAK,GAMD,CACZ,CACG;;AAEV"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../../utils.mjs";
|
|
3
3
|
import Button from "../../Button.mjs";
|
|
4
|
-
import { useId } from "react";
|
|
5
4
|
import { Upload, X } from "lucide-react";
|
|
6
|
-
import {
|
|
5
|
+
import { useId } from "react";
|
|
7
6
|
import { useControllableState, useFileDrop, useFileToDataUrl } from "@jbpark/use-hooks";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
//#region src/components/molecules/upload.tsx
|
|
9
9
|
let uidCounter = 0;
|
|
10
10
|
const nextUid = () => uidCounter += 1;
|
|
@@ -53,6 +53,7 @@ const Upload$1 = ({ defaultValue = [], value: _value, multiple = true, accept =
|
|
|
53
53
|
onDrop: addFiles
|
|
54
54
|
});
|
|
55
55
|
return /* @__PURE__ */ jsxs("div", {
|
|
56
|
+
"data-slot": "upload",
|
|
56
57
|
className: cn("flex flex-col gap-3", className),
|
|
57
58
|
children: [/* @__PURE__ */ jsxs("label", {
|
|
58
59
|
ref: dropRef,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.mjs","names":["Upload","UploadIcon"],"sources":["../../../src/components/molecules/upload.tsx"],"sourcesContent":["'use client';\n\nimport { useId } from 'react';\n\nimport {\n useControllableState,\n useFileDrop,\n useFileToDataUrl,\n} from '@jbpark/use-hooks';\nimport { Upload as UploadIcon, X } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\n\n// Monotonic per-session counter used as a uniqueness tiebreaker for file\n// uids. Guarantees a unique suffix even for the same file (identical\n// name/lastModified/size) added twice, which name+lastModified+size alone\n// can't. These uids are internal React keys, not cryptographic, so a plain\n// counter is enough — and it avoids a runtime `uuid` dependency.\nlet uidCounter = 0;\nconst nextUid = () => (uidCounter += 1);\n\nexport interface UploadFile {\n uid: string;\n name: string;\n url: string;\n}\n\nexport interface Props {\n defaultValue?: UploadFile[];\n value?: UploadFile[];\n multiple?: boolean;\n accept?: string;\n maxCount?: number;\n disabled?: boolean;\n className?: string;\n classNames?: {\n dropzone?: string;\n list?: string;\n item?: string;\n };\n onChange?: (files: UploadFile[]) => void;\n /**\n * Called once per file that didn't make it in — either bumped by\n * `maxCount` or failed to read.\n */\n onReject?: (info: { file: File; reason: 'max-count' | 'read-error' }) => void;\n}\n\nconst isImage = (file: UploadFile) =>\n /^data:image\\//.test(file.url) ||\n /\\.(png|jpe?g|gif|webp|svg)$/i.test(file.name);\n\nconst Upload = ({\n defaultValue = [],\n value: _value,\n multiple = true,\n accept = 'image/*',\n maxCount,\n disabled,\n className,\n classNames,\n onChange: _onChange = () => {},\n onReject,\n}: Props) => {\n const inputId = useId();\n const readAsDataUrl = useFileToDataUrl();\n const [files, setFiles] = useControllableState<UploadFile[]>({\n value: _value,\n defaultValue,\n onChange: _onChange,\n });\n\n const addFiles = async (incoming: File[]) => {\n const remaining =\n typeof maxCount === 'number'\n ? Math.max(0, maxCount - files.length)\n : incoming.length;\n\n const accepted = incoming.slice(0, remaining);\n const rejected = incoming.slice(remaining);\n\n rejected.forEach(file => onReject?.({ file, reason: 'max-count' }));\n\n if (accepted.length === 0) {\n return;\n }\n\n const uploaded = (\n await Promise.all(\n accepted.map(async file => {\n try {\n return {\n // `nextUid()` guarantees uniqueness even for the same file\n // added twice (identical name/lastModified/size), which\n // name+lastModified+size alone can't — a collision there\n // corrupted React's item keys and made removeFile's\n // uid-based filter delete both copies at once.\n uid: `${file.name}-${file.lastModified}-${file.size}-${nextUid()}`,\n name: file.name,\n url: await readAsDataUrl(file),\n };\n } catch {\n onReject?.({ file, reason: 'read-error' });\n return null;\n }\n }),\n )\n ).filter((file): file is UploadFile => file !== null);\n\n if (uploaded.length === 0) {\n return;\n }\n\n setFiles([...files, ...uploaded]);\n };\n\n const removeFile = (uid: string) => {\n setFiles(files.filter(file => file.uid !== uid));\n };\n\n const { dropRef, isDragging } = useFileDrop<HTMLLabelElement>({\n accept,\n multiple,\n disabled,\n onDrop: addFiles,\n });\n\n return (\n <div\n className={cn(\n 'flex flex-col gap-3',\n className,\n //\n )}\n >\n <label\n ref={dropRef}\n htmlFor={inputId}\n className={cn(\n 'flex cursor-pointer flex-col items-center justify-center gap-2',\n 'rounded-md border border-dashed p-6 text-center',\n 'text-muted-foreground text-sm',\n 'transition-colors',\n isDragging && 'border-primary bg-accent',\n disabled && 'pointer-events-none cursor-not-allowed opacity-50',\n classNames?.dropzone,\n //\n )}\n >\n <UploadIcon className=\"size-6\" />\n <span>Click or drag file{multiple ? 's' : ''} to upload</span>\n <input\n id={inputId}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n className=\"hidden\"\n onChange={e => {\n if (e.target.files?.length) {\n addFiles(Array.from(e.target.files));\n }\n e.target.value = '';\n }}\n />\n </label>\n\n {files.length > 0 && (\n <ul\n className={cn(\n 'm-0 flex list-none flex-col gap-2 p-0',\n classNames?.list,\n //\n )}\n >\n {files.map(file => (\n <li\n key={file.uid}\n className={cn(\n // `m-0` completes the list reset the `ul` above starts — see\n // Radio.Group for the host rule this guards against.\n 'm-0 flex items-center gap-2 rounded-md border p-2',\n classNames?.item,\n //\n )}\n >\n {isImage(file) && (\n <img\n src={file.url}\n alt=\"\"\n className=\"size-10 shrink-0 rounded object-cover\"\n />\n )}\n <span className=\"flex-1 truncate text-sm\">{file.name}</span>\n <Button\n variant=\"text\"\n shape=\"circle\"\n size=\"small\"\n icon={<X className=\"size-4\" />}\n onClick={() => removeFile(file.uid)}\n className=\"text-muted-foreground hover:text-foreground shrink-0\"\n aria-label={`Remove ${file.name}`}\n />\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n\nexport default Upload;\n"],"mappings":";;;;;;;;AAoBA,IAAI,aAAa;AACjB,MAAM,gBAAiB,cAAc;AA6BrC,MAAM,WAAW,SACf,gBAAgB,KAAK,KAAK,GAAG,KAC7B,+BAA+B,KAAK,KAAK,IAAI;AAE/C,MAAMA,YAAU,EACd,eAAe,CAAC,GAChB,OAAO,QACP,WAAW,MACX,SAAS,WACT,UACA,UACA,WACA,YACA,UAAU,kBAAkB,CAAC,GAC7B,eACW;CACX,MAAM,UAAU,MAAM;CACtB,MAAM,gBAAgB,iBAAiB;CACvC,MAAM,CAAC,OAAO,YAAY,qBAAmC;EAC3D,OAAO;EACP;EACA,UAAU;CACZ,CAAC;CAED,MAAM,WAAW,OAAO,aAAqB;EAC3C,MAAM,YACJ,OAAO,aAAa,WAChB,KAAK,IAAI,GAAG,WAAW,MAAM,MAAM,IACnC,SAAS;EAEf,MAAM,WAAW,SAAS,MAAM,GAAG,SAAS;EAG5C,SAF0B,MAAM,SAEzB,CAAC,CAAC,SAAQ,SAAQ,WAAW;GAAE;GAAM,QAAQ;EAAY,CAAC,CAAC;EAElE,IAAI,SAAS,WAAW,GACtB;EAGF,MAAM,YACJ,MAAM,QAAQ,IACZ,SAAS,IAAI,OAAM,SAAQ;GACzB,IAAI;IACF,OAAO;KAML,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,aAAa,GAAG,KAAK,KAAK,GAAG,QAAQ;KAC/D,MAAM,KAAK;KACX,KAAK,MAAM,cAAc,IAAI;IAC/B;GACF,QAAQ;IACN,WAAW;KAAE;KAAM,QAAQ;IAAa,CAAC;IACzC,OAAO;GACT;EACF,CAAC,CACH,EAAA,CACA,QAAQ,SAA6B,SAAS,IAAI;EAEpD,IAAI,SAAS,WAAW,GACtB;EAGF,SAAS,CAAC,GAAG,OAAO,GAAG,QAAQ,CAAC;CAClC;CAEA,MAAM,cAAc,QAAgB;EAClC,SAAS,MAAM,QAAO,SAAQ,KAAK,QAAQ,GAAG,CAAC;CACjD;CAEA,MAAM,EAAE,SAAS,eAAe,YAA8B;EAC5D;EACA;EACA;EACA,QAAQ;CACV,CAAC;CAED,OACE,qBAAC,OAAD;EACE,WAAW,GACT,uBACA,SAEF;
|
|
1
|
+
{"version":3,"file":"upload.mjs","names":["Upload","UploadIcon"],"sources":["../../../src/components/molecules/upload.tsx"],"sourcesContent":["'use client';\n\nimport { useId } from 'react';\n\nimport {\n useControllableState,\n useFileDrop,\n useFileToDataUrl,\n} from '@jbpark/use-hooks';\nimport { Upload as UploadIcon, X } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\n\n// Monotonic per-session counter used as a uniqueness tiebreaker for file\n// uids. Guarantees a unique suffix even for the same file (identical\n// name/lastModified/size) added twice, which name+lastModified+size alone\n// can't. These uids are internal React keys, not cryptographic, so a plain\n// counter is enough — and it avoids a runtime `uuid` dependency.\nlet uidCounter = 0;\nconst nextUid = () => (uidCounter += 1);\n\nexport interface UploadFile {\n uid: string;\n name: string;\n url: string;\n}\n\nexport interface Props {\n defaultValue?: UploadFile[];\n value?: UploadFile[];\n multiple?: boolean;\n accept?: string;\n maxCount?: number;\n disabled?: boolean;\n className?: string;\n classNames?: {\n dropzone?: string;\n list?: string;\n item?: string;\n };\n onChange?: (files: UploadFile[]) => void;\n /**\n * Called once per file that didn't make it in — either bumped by\n * `maxCount` or failed to read.\n */\n onReject?: (info: { file: File; reason: 'max-count' | 'read-error' }) => void;\n}\n\nconst isImage = (file: UploadFile) =>\n /^data:image\\//.test(file.url) ||\n /\\.(png|jpe?g|gif|webp|svg)$/i.test(file.name);\n\nconst Upload = ({\n defaultValue = [],\n value: _value,\n multiple = true,\n accept = 'image/*',\n maxCount,\n disabled,\n className,\n classNames,\n onChange: _onChange = () => {},\n onReject,\n}: Props) => {\n const inputId = useId();\n const readAsDataUrl = useFileToDataUrl();\n const [files, setFiles] = useControllableState<UploadFile[]>({\n value: _value,\n defaultValue,\n onChange: _onChange,\n });\n\n const addFiles = async (incoming: File[]) => {\n const remaining =\n typeof maxCount === 'number'\n ? Math.max(0, maxCount - files.length)\n : incoming.length;\n\n const accepted = incoming.slice(0, remaining);\n const rejected = incoming.slice(remaining);\n\n rejected.forEach(file => onReject?.({ file, reason: 'max-count' }));\n\n if (accepted.length === 0) {\n return;\n }\n\n const uploaded = (\n await Promise.all(\n accepted.map(async file => {\n try {\n return {\n // `nextUid()` guarantees uniqueness even for the same file\n // added twice (identical name/lastModified/size), which\n // name+lastModified+size alone can't — a collision there\n // corrupted React's item keys and made removeFile's\n // uid-based filter delete both copies at once.\n uid: `${file.name}-${file.lastModified}-${file.size}-${nextUid()}`,\n name: file.name,\n url: await readAsDataUrl(file),\n };\n } catch {\n onReject?.({ file, reason: 'read-error' });\n return null;\n }\n }),\n )\n ).filter((file): file is UploadFile => file !== null);\n\n if (uploaded.length === 0) {\n return;\n }\n\n setFiles([...files, ...uploaded]);\n };\n\n const removeFile = (uid: string) => {\n setFiles(files.filter(file => file.uid !== uid));\n };\n\n const { dropRef, isDragging } = useFileDrop<HTMLLabelElement>({\n accept,\n multiple,\n disabled,\n onDrop: addFiles,\n });\n\n return (\n <div\n data-slot=\"upload\"\n className={cn(\n 'flex flex-col gap-3',\n className,\n //\n )}\n >\n <label\n ref={dropRef}\n htmlFor={inputId}\n className={cn(\n 'flex cursor-pointer flex-col items-center justify-center gap-2',\n 'rounded-md border border-dashed p-6 text-center',\n 'text-muted-foreground text-sm',\n 'transition-colors',\n isDragging && 'border-primary bg-accent',\n disabled && 'pointer-events-none cursor-not-allowed opacity-50',\n classNames?.dropzone,\n //\n )}\n >\n <UploadIcon className=\"size-6\" />\n <span>Click or drag file{multiple ? 's' : ''} to upload</span>\n <input\n id={inputId}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n disabled={disabled}\n className=\"hidden\"\n onChange={e => {\n if (e.target.files?.length) {\n addFiles(Array.from(e.target.files));\n }\n e.target.value = '';\n }}\n />\n </label>\n\n {files.length > 0 && (\n <ul\n className={cn(\n 'm-0 flex list-none flex-col gap-2 p-0',\n classNames?.list,\n //\n )}\n >\n {files.map(file => (\n <li\n key={file.uid}\n className={cn(\n // `m-0` completes the list reset the `ul` above starts — see\n // Radio.Group for the host rule this guards against.\n 'm-0 flex items-center gap-2 rounded-md border p-2',\n classNames?.item,\n //\n )}\n >\n {isImage(file) && (\n <img\n src={file.url}\n alt=\"\"\n className=\"size-10 shrink-0 rounded object-cover\"\n />\n )}\n <span className=\"flex-1 truncate text-sm\">{file.name}</span>\n <Button\n variant=\"text\"\n shape=\"circle\"\n size=\"small\"\n icon={<X className=\"size-4\" />}\n onClick={() => removeFile(file.uid)}\n className=\"text-muted-foreground hover:text-foreground shrink-0\"\n aria-label={`Remove ${file.name}`}\n />\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n\nexport default Upload;\n"],"mappings":";;;;;;;;AAoBA,IAAI,aAAa;AACjB,MAAM,gBAAiB,cAAc;AA6BrC,MAAM,WAAW,SACf,gBAAgB,KAAK,KAAK,GAAG,KAC7B,+BAA+B,KAAK,KAAK,IAAI;AAE/C,MAAMA,YAAU,EACd,eAAe,CAAC,GAChB,OAAO,QACP,WAAW,MACX,SAAS,WACT,UACA,UACA,WACA,YACA,UAAU,kBAAkB,CAAC,GAC7B,eACW;CACX,MAAM,UAAU,MAAM;CACtB,MAAM,gBAAgB,iBAAiB;CACvC,MAAM,CAAC,OAAO,YAAY,qBAAmC;EAC3D,OAAO;EACP;EACA,UAAU;CACZ,CAAC;CAED,MAAM,WAAW,OAAO,aAAqB;EAC3C,MAAM,YACJ,OAAO,aAAa,WAChB,KAAK,IAAI,GAAG,WAAW,MAAM,MAAM,IACnC,SAAS;EAEf,MAAM,WAAW,SAAS,MAAM,GAAG,SAAS;EAG5C,SAF0B,MAAM,SAEzB,CAAC,CAAC,SAAQ,SAAQ,WAAW;GAAE;GAAM,QAAQ;EAAY,CAAC,CAAC;EAElE,IAAI,SAAS,WAAW,GACtB;EAGF,MAAM,YACJ,MAAM,QAAQ,IACZ,SAAS,IAAI,OAAM,SAAQ;GACzB,IAAI;IACF,OAAO;KAML,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,aAAa,GAAG,KAAK,KAAK,GAAG,QAAQ;KAC/D,MAAM,KAAK;KACX,KAAK,MAAM,cAAc,IAAI;IAC/B;GACF,QAAQ;IACN,WAAW;KAAE;KAAM,QAAQ;IAAa,CAAC;IACzC,OAAO;GACT;EACF,CAAC,CACH,EAAA,CACA,QAAQ,SAA6B,SAAS,IAAI;EAEpD,IAAI,SAAS,WAAW,GACtB;EAGF,SAAS,CAAC,GAAG,OAAO,GAAG,QAAQ,CAAC;CAClC;CAEA,MAAM,cAAc,QAAgB;EAClC,SAAS,MAAM,QAAO,SAAQ,KAAK,QAAQ,GAAG,CAAC;CACjD;CAEA,MAAM,EAAE,SAAS,eAAe,YAA8B;EAC5D;EACA;EACA;EACA,QAAQ;CACV,CAAC;CAED,OACE,qBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,uBACA,SAEF;EANF,UAAA,CAQE,qBAAC,SAAD;GACE,KAAK;GACL,SAAS;GACT,WAAW,GACT,kEACA,mDACA,iCACA,qBACA,cAAc,4BACd,YAAY,qDACZ,YAAY,QAEd;GAZF,UAAA;IAcE,oBAACC,QAAD,EAAY,WAAU,SAAU,CAAA;IAChC,qBAAC,QAAD,EAAA,UAAA;KAAM;KAAmB,WAAW,MAAM;KAAG;IAAgB,EAAA,CAAA;IAC7D,oBAAC,SAAD;KACE,IAAI;KACJ,MAAK;KACG;KACE;KACA;KACV,WAAU;KACV,WAAU,MAAK;MACb,IAAI,EAAE,OAAO,OAAO,QAClB,SAAS,MAAM,KAAK,EAAE,OAAO,KAAK,CAAC;MAErC,EAAE,OAAO,QAAQ;KACnB;IACD,CAAA;GACI;EAEN,CAAA,GAAA,MAAM,SAAS,KACd,oBAAC,MAAD;GACE,WAAW,GACT,yCACA,YAAY,IAEd;GAEC,UAAA,MAAM,KAAI,SACT,qBAAC,MAAD;IAEE,WAAW,GAGT,qDACA,YAAY,IAEd;IARF,UAAA;KAUG,QAAQ,IAAI,KACX,oBAAC,OAAD;MACE,KAAK,KAAK;MACV,KAAI;MACJ,WAAU;KACX,CAAA;KAEH,oBAAC,QAAD;MAAM,WAAU;MAA2B,UAAA,KAAK;KAAW,CAAA;KAC3D,oBAAC,QAAD;MACE,SAAQ;MACR,OAAM;MACN,MAAK;MACL,MAAM,oBAAC,GAAD,EAAG,WAAU,SAAU,CAAA;MAC7B,eAAe,WAAW,KAAK,GAAG;MAClC,WAAU;MACV,cAAY,UAAU,KAAK;KAC5B,CAAA;IACC;GA1BG,GAAA,KAAK,GA0BR,CACL;EACC,CAAA,CAEH;;AAET"}
|
|
@@ -8,7 +8,7 @@ interface Props {
|
|
|
8
8
|
closable?: boolean;
|
|
9
9
|
closeIcon?: React.ReactNode;
|
|
10
10
|
direction?: 'top' | 'bottom' | 'left' | 'right';
|
|
11
|
-
size?: 'small' | 'medium' | 'large' | 'full' | string;
|
|
11
|
+
size?: 'small' | 'middle' | 'medium' | 'large' | 'full' | string;
|
|
12
12
|
maskClosable?: boolean;
|
|
13
13
|
handlebar?: boolean;
|
|
14
14
|
rounded?: boolean;
|
|
@@ -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,QAAQ,MAAM;EACd;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEF,YAAY;EACZ;;
|
|
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;;cA+CI,WAAU,MAAA,OAAA,OAAA,QAAA,UAAA,WAAA,WAAA,MAAA,cAAA,WAAA,SAAA,MAAA,WAAA,YAAA,OAAA,UAAA,WAAA,YAAA,SAoBb,0BAAK,IAAA"}
|