@jbpark/ui-kit 3.0.0 → 3.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.
@@ -0,0 +1,20 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+
3
+ //#region src/components/atoms/date-picker.d.ts
4
+ interface Props {
5
+ defaultValue?: Date;
6
+ value?: Date;
7
+ placeholder?: string;
8
+ className?: string;
9
+ onChange?: (date: Date | undefined) => void;
10
+ }
11
+ declare const DatePicker: ({
12
+ defaultValue,
13
+ value: _value,
14
+ placeholder,
15
+ className,
16
+ onChange: _onChange
17
+ }: Props) => react_jsx_runtime0.JSX.Element;
18
+ //#endregion
19
+ export { DatePicker };
20
+ //# sourceMappingURL=date-picker.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-picker.d.mts","names":[],"sources":["../../../src/components/atoms/date-picker.tsx"],"mappings":";;;UAeU,KAAA;EACR,YAAA,GAAe,IAAA;EACf,KAAA,GAAQ,IAAA;EACR,WAAA;EACA,SAAA;EACA,QAAA,IAAY,IAAA,EAAM,IAAA;AAAA;AAAA,cAGd,UAAA;EAAc,YAAA;EAAA,KAAA,EAAA,MAAA;EAAA,WAAA;EAAA,SAAA;EAAA,QAAA,EAAA;AAAA,GAMjB,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,41 @@
1
+ 'use client';
2
+
3
+ import { cn } from "../../utils.mjs";
4
+ import { calendar_exports } from "../../core/calendar.mjs";
5
+ import Button from "../../Button.mjs";
6
+ import Popover from "./popover.mjs";
7
+ import { CalendarIcon } from "lucide-react";
8
+ import { useState } from "react";
9
+ import { jsx } from "react/jsx-runtime";
10
+ import { format } from "date-fns";
11
+
12
+ //#region src/components/atoms/date-picker.tsx
13
+ const { Calendar } = calendar_exports;
14
+ const DatePicker = ({ defaultValue, value: _value, placeholder = "Pick a date", className, onChange: _onChange = () => {} }) => {
15
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
16
+ const controlled = _value !== void 0;
17
+ const value = controlled ? _value : uncontrolledValue;
18
+ const onChange = (date) => {
19
+ if (!controlled) setUncontrolledValue(date);
20
+ _onChange(date);
21
+ };
22
+ return /* @__PURE__ */ jsx(Popover, {
23
+ placement: "bottomLeft",
24
+ content: /* @__PURE__ */ jsx(Calendar, {
25
+ mode: "single",
26
+ selected: value,
27
+ onSelect: onChange
28
+ }),
29
+ children: /* @__PURE__ */ jsx(Button, {
30
+ type: "default",
31
+ icon: /* @__PURE__ */ jsx(CalendarIcon, {}),
32
+ "data-empty": !value,
33
+ className: cn("w-full justify-start text-left font-normal", "data-[empty=true]:text-muted-foreground", className),
34
+ children: value ? format(value, "PPP") : placeholder
35
+ })
36
+ });
37
+ };
38
+
39
+ //#endregion
40
+ export { DatePicker as default };
41
+ //# sourceMappingURL=date-picker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-picker.mjs","names":["calendar"],"sources":["../../../src/components/atoms/date-picker.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\n\nimport { format } from 'date-fns';\nimport { CalendarIcon } from 'lucide-react';\n\nimport { calendar } from '@repo/ui/core';\nimport { cn } from '@repo/ui/utils';\n\nimport Button from './button';\nimport Popover from './popover';\n\nconst { Calendar } = calendar;\n\ninterface Props {\n defaultValue?: Date;\n value?: Date;\n placeholder?: string;\n className?: string;\n onChange?: (date: Date | undefined) => void;\n}\n\nconst DatePicker = ({\n defaultValue,\n value: _value,\n placeholder = 'Pick a date',\n className,\n onChange: _onChange = () => {},\n}: Props) => {\n const [uncontrolledValue, setUncontrolledValue] = useState<Date | undefined>(\n defaultValue,\n );\n\n const controlled = _value !== undefined;\n const value = controlled ? _value : uncontrolledValue;\n\n const onChange = (date: Date | undefined) => {\n if (!controlled) {\n setUncontrolledValue(date);\n }\n _onChange(date);\n };\n\n return (\n <Popover\n placement=\"bottomLeft\"\n content={<Calendar mode=\"single\" selected={value} onSelect={onChange} />}\n >\n <Button\n type=\"default\"\n icon={<CalendarIcon />}\n data-empty={!value}\n className={cn(\n 'w-full justify-start text-left font-normal',\n 'data-[empty=true]:text-muted-foreground',\n className,\n //\n )}\n >\n {value ? format(value, 'PPP') : placeholder}\n </Button>\n </Popover>\n );\n};\n\nexport default DatePicker;\nexport type { Props };\n"],"mappings":";;;;;;;;;;;;AAaA,MAAM,EAAE,aAAaA;AAUrB,MAAM,cAAc,EAClB,cACA,OAAO,QACP,cAAc,eACd,WACA,UAAU,kBAAkB,SACjB;CACX,MAAM,CAAC,mBAAmB,wBAAwB,SAChD,aACD;CAED,MAAM,aAAa,WAAW;CAC9B,MAAM,QAAQ,aAAa,SAAS;CAEpC,MAAM,YAAY,SAA2B;AAC3C,MAAI,CAAC,WACH,sBAAqB,KAAK;AAE5B,YAAU,KAAK;;AAGjB,QACE,oBAAC;EACC,WAAU;EACV,SAAS,oBAAC;GAAS,MAAK;GAAS,UAAU;GAAO,UAAU;IAAY;YAExE,oBAAC;GACC,MAAK;GACL,MAAM,oBAAC,iBAAe;GACtB,cAAY,CAAC;GACb,WAAW,GACT,8CACA,2CACA,UAED;aAEA,QAAQ,OAAO,OAAO,MAAM,GAAG;IACzB;GACD"}
@@ -4,17 +4,17 @@ import { cn } from "../../../utils.mjs";
4
4
  import FloatButton from "./float-button.mjs";
5
5
  import { ArrowUp } from "lucide-react";
6
6
  import { jsx } from "react/jsx-runtime";
7
- import { useWindowScroll } from "@uidotdev/usehooks";
7
+ import { useWindowScroll } from "@jbpark/use-hooks";
8
8
 
9
9
  //#region src/components/atoms/float-button/back-top.tsx
10
10
  const BackTop = ({ visibilityHeight = 450, className, onClick, ...props }) => {
11
- const [{ y }, scrollTo] = useWindowScroll();
11
+ const { y } = useWindowScroll();
12
12
  return /* @__PURE__ */ jsx(FloatButton, {
13
13
  "aria-label": "맨 위로",
14
14
  icon: /* @__PURE__ */ jsx(ArrowUp, {}),
15
15
  className: cn(className, (!y || visibilityHeight > y) && "hidden"),
16
16
  onClick: (e) => {
17
- scrollTo({
17
+ window.scrollTo({
18
18
  left: 0,
19
19
  top: 0,
20
20
  behavior: "smooth"
@@ -1 +1 @@
1
- {"version":3,"file":"back-top.mjs","names":[],"sources":["../../../../src/components/atoms/float-button/back-top.tsx"],"sourcesContent":["'use client';\n\nimport { MouseEvent } from 'react';\n\nimport { useWindowScroll } from '@uidotdev/usehooks';\nimport { ArrowUp } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { type Props as ButtonProps } from '../button';\nimport FloatButton from './float-button';\n\nexport interface Props extends ButtonProps {\n visibilityHeight?: number;\n onClick?: (e: MouseEvent<HTMLElement>) => void;\n}\n\nconst BackTop = ({\n visibilityHeight = 450,\n className,\n onClick,\n ...props\n}: Props) => {\n const [{ y }, scrollTo] = useWindowScroll();\n\n return (\n <FloatButton\n aria-label=\"맨 위로\"\n icon={<ArrowUp />}\n className={cn(\n className,\n (!y || visibilityHeight > y) && 'hidden',\n //\n )}\n onClick={e => {\n scrollTo({ left: 0, top: 0, behavior: 'smooth' });\n onClick?.(e);\n }}\n {...props}\n />\n );\n};\n\nexport default BackTop;\n"],"mappings":";;;;;;;;;AAiBA,MAAM,WAAW,EACf,mBAAmB,KACnB,WACA,SACA,GAAG,YACQ;CACX,MAAM,CAAC,EAAE,KAAK,YAAY,iBAAiB;AAE3C,QACE,oBAAC;EACC,cAAW;EACX,MAAM,oBAAC,YAAU;EACjB,WAAW,GACT,YACC,CAAC,KAAK,mBAAmB,MAAM,SAEjC;EACD,UAAS,MAAK;AACZ,YAAS;IAAE,MAAM;IAAG,KAAK;IAAG,UAAU;IAAU,CAAC;AACjD,aAAU,EAAE;;EAEd,GAAI;GACJ"}
1
+ {"version":3,"file":"back-top.mjs","names":[],"sources":["../../../../src/components/atoms/float-button/back-top.tsx"],"sourcesContent":["'use client';\n\nimport { MouseEvent } from 'react';\n\nimport { useWindowScroll } from '@jbpark/use-hooks';\nimport { ArrowUp } from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { type Props as ButtonProps } from '../button';\nimport FloatButton from './float-button';\n\nexport interface Props extends ButtonProps {\n visibilityHeight?: number;\n onClick?: (e: MouseEvent<HTMLElement>) => void;\n}\n\nconst BackTop = ({\n visibilityHeight = 450,\n className,\n onClick,\n ...props\n}: Props) => {\n const { y } = useWindowScroll();\n\n return (\n <FloatButton\n aria-label=\"맨 위로\"\n icon={<ArrowUp />}\n className={cn(\n className,\n (!y || visibilityHeight > y) && 'hidden',\n //\n )}\n onClick={e => {\n window.scrollTo({ left: 0, top: 0, behavior: 'smooth' });\n onClick?.(e);\n }}\n {...props}\n />\n );\n};\n\nexport default BackTop;\n"],"mappings":";;;;;;;;;AAiBA,MAAM,WAAW,EACf,mBAAmB,KACnB,WACA,SACA,GAAG,YACQ;CACX,MAAM,EAAE,MAAM,iBAAiB;AAE/B,QACE,oBAAC;EACC,cAAW;EACX,MAAM,oBAAC,YAAU;EACjB,WAAW,GACT,YACC,CAAC,KAAK,mBAAmB,MAAM,SAEjC;EACD,UAAS,MAAK;AACZ,UAAO,SAAS;IAAE,MAAM;IAAG,KAAK;IAAG,UAAU;IAAU,CAAC;AACxD,aAAU,EAAE;;EAEd,GAAI;GACJ"}
@@ -3,6 +3,7 @@ import Tag from "../../Tag.mjs";
3
3
  import Typography from "../../Typography.mjs";
4
4
  import { Checkbox } from "./checkbox/index.mjs";
5
5
  import { ColorPicker } from "./color-picker.mjs";
6
+ import { DatePicker } from "./date-picker.mjs";
6
7
  import { FloatButton } from "./float-button/index.mjs";
7
8
  import { Input } from "./input/index.mjs";
8
9
  import { Popover } from "./popover.mjs";
@@ -6,4 +6,5 @@ import Space from "../../Space.mjs";
6
6
  import { Collapse } from "./collapse.mjs";
7
7
  import { Dropdown } from "./dropdown.mjs";
8
8
  import { Marquees } from "./marquees/index.mjs";
9
- import { Splitter } from "./splitter/index.mjs";
9
+ import { Splitter } from "./splitter/index.mjs";
10
+ import { Upload, UploadFile } from "./upload.mjs";
@@ -0,0 +1,37 @@
1
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+
3
+ //#region src/components/molecules/upload.d.ts
4
+ interface UploadFile {
5
+ uid: string;
6
+ name: string;
7
+ url: string;
8
+ }
9
+ interface Props {
10
+ defaultValue?: UploadFile[];
11
+ value?: UploadFile[];
12
+ multiple?: boolean;
13
+ accept?: string;
14
+ maxCount?: number;
15
+ disabled?: boolean;
16
+ className?: string;
17
+ classNames?: {
18
+ dropzone?: string;
19
+ list?: string;
20
+ item?: string;
21
+ };
22
+ onChange?: (files: UploadFile[]) => void;
23
+ }
24
+ declare const Upload: ({
25
+ defaultValue,
26
+ value: _value,
27
+ multiple,
28
+ accept,
29
+ maxCount,
30
+ disabled,
31
+ className,
32
+ classNames,
33
+ onChange: _onChange
34
+ }: Props) => react_jsx_runtime0.JSX.Element;
35
+ //#endregion
36
+ export { Upload, UploadFile };
37
+ //# sourceMappingURL=upload.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.mts","names":[],"sources":["../../../src/components/molecules/upload.tsx"],"mappings":";;;UAWiB,UAAA;EACf,GAAA;EACA,IAAA;EACA,GAAA;AAAA;AAAA,UAGe,KAAA;EACf,YAAA,GAAe,UAAA;EACf,KAAA,GAAQ,UAAA;EACR,QAAA;EACA,MAAA;EACA,QAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;IACE,QAAA;IACA,IAAA;IACA,IAAA;EAAA;EAEF,QAAA,IAAY,KAAA,EAAO,UAAA;AAAA;AAAA,cAOf,MAAA;EAAU,YAAA;EAAA,KAAA,EAAA,MAAA;EAAA,QAAA;EAAA,MAAA;EAAA,QAAA;EAAA,QAAA;EAAA,SAAA;EAAA,UAAA;EAAA,QAAA,EAAA;AAAA,GAUb,KAAA,KAAK,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,104 @@
1
+ 'use client';
2
+
3
+ import { cn } from "../../utils.mjs";
4
+ import Button from "../../Button.mjs";
5
+ import { Upload, X } from "lucide-react";
6
+ import { useId, useState } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { useFileToDataUrl } from "@jbpark/use-hooks";
9
+
10
+ //#region src/components/molecules/upload.tsx
11
+ const isImage = (file) => /^data:image\//.test(file.url) || /\.(png|jpe?g|gif|webp|svg)$/i.test(file.name);
12
+ const Upload$1 = ({ defaultValue = [], value: _value, multiple = true, accept = "image/*", maxCount, disabled, className, classNames, onChange: _onChange = () => {} }) => {
13
+ const inputId = useId();
14
+ const readAsDataUrl = useFileToDataUrl();
15
+ const [isDragOver, setIsDragOver] = useState(false);
16
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
17
+ const controlled = _value !== void 0;
18
+ const files = controlled ? _value : uncontrolledValue;
19
+ const onChange = (next) => {
20
+ if (!controlled) setUncontrolledValue(next);
21
+ _onChange(next);
22
+ };
23
+ const addFiles = async (fileList) => {
24
+ const incoming = Array.from(fileList);
25
+ const remaining = typeof maxCount === "number" ? Math.max(0, maxCount - files.length) : incoming.length;
26
+ const accepted = incoming.slice(0, remaining);
27
+ const uploaded = await Promise.all(accepted.map(async (file) => ({
28
+ uid: `${file.name}-${file.lastModified}-${file.size}`,
29
+ name: file.name,
30
+ url: await readAsDataUrl(file)
31
+ })));
32
+ onChange([...files, ...uploaded]);
33
+ };
34
+ const removeFile = (uid) => {
35
+ onChange(files.filter((file) => file.uid !== uid));
36
+ };
37
+ return /* @__PURE__ */ jsxs("div", {
38
+ className: cn("flex flex-col gap-3", className),
39
+ children: [/* @__PURE__ */ jsxs("label", {
40
+ htmlFor: inputId,
41
+ onDragOver: (e) => {
42
+ e.preventDefault();
43
+ if (!disabled) setIsDragOver(true);
44
+ },
45
+ onDragLeave: () => setIsDragOver(false),
46
+ onDrop: (e) => {
47
+ e.preventDefault();
48
+ setIsDragOver(false);
49
+ if (disabled) return;
50
+ if (e.dataTransfer.files.length) addFiles(e.dataTransfer.files);
51
+ },
52
+ className: cn("flex cursor-pointer flex-col items-center justify-center gap-2", "rounded-md border border-dashed p-6 text-center", "text-muted-foreground text-sm", "transition-colors", isDragOver && "border-primary bg-accent", disabled && "pointer-events-none cursor-not-allowed opacity-50", classNames?.dropzone),
53
+ children: [
54
+ /* @__PURE__ */ jsx(Upload, { className: "size-6" }),
55
+ /* @__PURE__ */ jsxs("span", { children: [
56
+ "Click or drag file",
57
+ multiple ? "s" : "",
58
+ " to upload"
59
+ ] }),
60
+ /* @__PURE__ */ jsx("input", {
61
+ id: inputId,
62
+ type: "file",
63
+ accept,
64
+ multiple,
65
+ disabled,
66
+ className: "hidden",
67
+ onChange: (e) => {
68
+ if (e.target.files?.length) addFiles(e.target.files);
69
+ e.target.value = "";
70
+ }
71
+ })
72
+ ]
73
+ }), files.length > 0 && /* @__PURE__ */ jsx("ul", {
74
+ className: cn("flex flex-col gap-2", classNames?.list),
75
+ children: files.map((file) => /* @__PURE__ */ jsxs("li", {
76
+ className: cn("flex items-center gap-2 rounded-md border p-2", classNames?.item),
77
+ children: [
78
+ isImage(file) && /* @__PURE__ */ jsx("img", {
79
+ src: file.url,
80
+ alt: "",
81
+ className: "size-10 shrink-0 rounded object-cover"
82
+ }),
83
+ /* @__PURE__ */ jsx("span", {
84
+ className: "flex-1 truncate text-sm",
85
+ children: file.name
86
+ }),
87
+ /* @__PURE__ */ jsx(Button, {
88
+ type: "text",
89
+ shape: "circle",
90
+ size: "small",
91
+ icon: /* @__PURE__ */ jsx(X, { className: "size-4" }),
92
+ onClick: () => removeFile(file.uid),
93
+ className: "text-muted-foreground hover:text-foreground shrink-0",
94
+ "aria-label": `Remove ${file.name}`
95
+ })
96
+ ]
97
+ }, file.uid))
98
+ })]
99
+ });
100
+ };
101
+
102
+ //#endregion
103
+ export { Upload$1 as default };
104
+ //# sourceMappingURL=upload.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.mjs","names":["Upload","UploadIcon"],"sources":["../../../src/components/molecules/upload.tsx"],"sourcesContent":["'use client';\n\nimport { useId, useState } from 'react';\n\nimport { useFileToDataUrl } 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\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\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}: Props) => {\n const inputId = useId();\n const readAsDataUrl = useFileToDataUrl();\n const [isDragOver, setIsDragOver] = useState(false);\n const [uncontrolledValue, setUncontrolledValue] =\n useState<UploadFile[]>(defaultValue);\n\n const controlled = _value !== undefined;\n const files = controlled ? _value : uncontrolledValue;\n\n const onChange = (next: UploadFile[]) => {\n if (!controlled) {\n setUncontrolledValue(next);\n }\n _onChange(next);\n };\n\n const addFiles = async (fileList: FileList) => {\n const incoming = Array.from(fileList);\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\n const uploaded = await Promise.all(\n accepted.map(async file => ({\n uid: `${file.name}-${file.lastModified}-${file.size}`,\n name: file.name,\n url: await readAsDataUrl(file),\n })),\n );\n\n onChange([...files, ...uploaded]);\n };\n\n const removeFile = (uid: string) => {\n onChange(files.filter(file => file.uid !== uid));\n };\n\n return (\n <div\n className={cn(\n 'flex flex-col gap-3',\n className,\n //\n )}\n >\n <label\n htmlFor={inputId}\n onDragOver={e => {\n e.preventDefault();\n if (!disabled) {\n setIsDragOver(true);\n }\n }}\n onDragLeave={() => setIsDragOver(false)}\n onDrop={e => {\n e.preventDefault();\n setIsDragOver(false);\n\n if (disabled) {\n return;\n }\n\n if (e.dataTransfer.files.length) {\n addFiles(e.dataTransfer.files);\n }\n }}\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 isDragOver && '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(e.target.files);\n }\n e.target.value = '';\n }}\n />\n </label>\n\n {files.length > 0 && (\n <ul\n className={cn(\n 'flex flex-col gap-2',\n classNames?.list,\n //\n )}\n >\n {files.map(file => (\n <li\n key={file.uid}\n className={cn(\n '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 type=\"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":";;;;;;;;;;AAiCA,MAAM,WAAW,SACf,gBAAgB,KAAK,KAAK,IAAI,IAC9B,+BAA+B,KAAK,KAAK,KAAK;AAEhD,MAAMA,YAAU,EACd,eAAe,EAAE,EACjB,OAAO,QACP,WAAW,MACX,SAAS,WACT,UACA,UACA,WACA,YACA,UAAU,kBAAkB,SACjB;CACX,MAAM,UAAU,OAAO;CACvB,MAAM,gBAAgB,kBAAkB;CACxC,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CACnD,MAAM,CAAC,mBAAmB,wBACxB,SAAuB,aAAa;CAEtC,MAAM,aAAa,WAAW;CAC9B,MAAM,QAAQ,aAAa,SAAS;CAEpC,MAAM,YAAY,SAAuB;AACvC,MAAI,CAAC,WACH,sBAAqB,KAAK;AAE5B,YAAU,KAAK;;CAGjB,MAAM,WAAW,OAAO,aAAuB;EAC7C,MAAM,WAAW,MAAM,KAAK,SAAS;EACrC,MAAM,YACJ,OAAO,aAAa,WAChB,KAAK,IAAI,GAAG,WAAW,MAAM,OAAO,GACpC,SAAS;EAEf,MAAM,WAAW,SAAS,MAAM,GAAG,UAAU;EAE7C,MAAM,WAAW,MAAM,QAAQ,IAC7B,SAAS,IAAI,OAAM,UAAS;GAC1B,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,aAAa,GAAG,KAAK;GAC/C,MAAM,KAAK;GACX,KAAK,MAAM,cAAc,KAAK;GAC/B,EAAE,CACJ;AAED,WAAS,CAAC,GAAG,OAAO,GAAG,SAAS,CAAC;;CAGnC,MAAM,cAAc,QAAgB;AAClC,WAAS,MAAM,QAAO,SAAQ,KAAK,QAAQ,IAAI,CAAC;;AAGlD,QACE,qBAAC;EACC,WAAW,GACT,uBACA,UAED;aAED,qBAAC;GACC,SAAS;GACT,aAAY,MAAK;AACf,MAAE,gBAAgB;AAClB,QAAI,CAAC,SACH,eAAc,KAAK;;GAGvB,mBAAmB,cAAc,MAAM;GACvC,SAAQ,MAAK;AACX,MAAE,gBAAgB;AAClB,kBAAc,MAAM;AAEpB,QAAI,SACF;AAGF,QAAI,EAAE,aAAa,MAAM,OACvB,UAAS,EAAE,aAAa,MAAM;;GAGlC,WAAW,GACT,kEACA,mDACA,iCACA,qBACA,cAAc,4BACd,YAAY,qDACZ,YAAY,SAEb;;IAED,oBAACC,UAAW,WAAU,WAAW;IACjC,qBAAC;KAAK;KAAmB,WAAW,MAAM;KAAG;QAAiB;IAC9D,oBAAC;KACC,IAAI;KACJ,MAAK;KACG;KACE;KACA;KACV,WAAU;KACV,WAAU,MAAK;AACb,UAAI,EAAE,OAAO,OAAO,OAClB,UAAS,EAAE,OAAO,MAAM;AAE1B,QAAE,OAAO,QAAQ;;MAEnB;;IACI,EAEP,MAAM,SAAS,KACd,oBAAC;GACC,WAAW,GACT,uBACA,YAAY,KAEb;aAEA,MAAM,KAAI,SACT,qBAAC;IAEC,WAAW,GACT,iDACA,YAAY,KAEb;;KAEA,QAAQ,KAAK,IACZ,oBAAC;MACC,KAAK,KAAK;MACV,KAAI;MACJ,WAAU;OACV;KAEJ,oBAAC;MAAK,WAAU;gBAA2B,KAAK;OAAY;KAC5D,oBAAC;MACC,MAAK;MACL,OAAM;MACN,MAAK;MACL,MAAM,oBAAC,KAAE,WAAU,WAAW;MAC9B,eAAe,WAAW,KAAK,IAAI;MACnC,WAAU;MACV,cAAY,UAAU,KAAK;OAC3B;;MAvBG,KAAK,IAwBP,CACL;IACC;GAEH"}
@@ -5,7 +5,7 @@ import Title from "../../atoms/typography/title.mjs";
5
5
  import Skeleton from "../../atoms/skeleton/index.mjs";
6
6
  import React, { useEffect, useRef } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
- import { useIntersectionObserver } from "@uidotdev/usehooks";
8
+ import { useIntersectionObserver } from "@jbpark/use-hooks";
9
9
 
10
10
  //#region src/components/organisms/list/list.tsx
11
11
  const List = ({ loading, loaderProps, loader, header, title, titleLevel = 2, empty, scroll, data, className, classNames, renderItem = () => null, itemKey, ...props }) => {
@@ -1 +1 @@
1
- {"version":3,"file":"list.mjs","names":[],"sources":["../../../../src/components/organisms/list/list.tsx"],"sourcesContent":["'use client';\n\nimport React, { useEffect, useRef } from 'react';\n\nimport { useIntersectionObserver } from '@uidotdev/usehooks';\n\nimport { cn, renderConditional } from '@repo/ui/utils';\n\nimport Skeleton from '../../atoms/skeleton';\nimport { Title } from '../../atoms/typography';\n\ninterface Props<T> extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'title'\n> {\n loading?: boolean;\n loaderProps?: React.ComponentProps<typeof Skeleton>;\n loader?: React.ReactNode;\n title?: React.ReactNode;\n titleLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n header?: React.ReactNode;\n empty?: React.ReactNode;\n classNames?: {\n title?: string;\n header?: string;\n body?: string;\n };\n scroll?: {\n hasMore: boolean;\n loading: boolean;\n loader?: React.ReactNode;\n options?: IntersectionObserverInit;\n /**\n * Called when more items should be fetched. `List` tracks in-flight\n * requests via `loading` — the caller MUST flip `loading` back to\n * `false` when the fetch settles, including on failure/rejection.\n * If `loading` never becomes `false` again after a failed fetch,\n * `List` will stop calling `next()` for subsequent intersections.\n */\n next: () => void;\n };\n data?: T[];\n renderItem?: (item: T, index: number) => React.ReactNode;\n itemKey?: (item: T, index: number) => React.Key;\n}\n\nconst List = <T,>({\n loading,\n loaderProps,\n loader,\n header,\n title,\n titleLevel = 2,\n empty,\n scroll,\n data,\n className,\n classNames,\n renderItem = () => null,\n itemKey,\n ...props\n}: Props<T>) => {\n const [loaderRef, entry] = useIntersectionObserver({\n threshold: 0,\n root: null,\n rootMargin: '0px',\n ...scroll?.options,\n });\n\n // `scroll` is typically a new object identity every render, so this\n // effect re-runs often. Guard with a ref (updated synchronously, unlike\n // the `loading` prop which only reflects the caller's next state update)\n // to avoid firing `next()` again for the same in-flight request before\n // the caller's `loading` has had a chance to become true.\n const fetchingRef = useRef(false);\n\n useEffect(() => {\n if (!scroll) {\n return;\n }\n\n if (scroll.loading) {\n fetchingRef.current = false;\n return;\n }\n\n if (entry?.isIntersecting && scroll.hasMore && !fetchingRef.current) {\n fetchingRef.current = true;\n scroll.next();\n }\n }, [entry, scroll]);\n\n if (loading) {\n return (\n loader || (\n <div className={cn(className)} {...props}>\n <div className={cn(classNames?.title)}>{title && <Skeleton />}</div>\n <div className={cn(classNames?.header)}>\n {header && <Skeleton size=\"small\" />}\n </div>\n <div className={cn('space-y-2', classNames?.body)}>\n <Skeleton.Node count={10} gap={10} {...loaderProps} />\n </div>\n </div>\n )\n );\n }\n\n if (!data?.length && empty) {\n return (\n <div className={cn(className)} {...props}>\n {empty}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n className,\n //\n )}\n {...props}\n >\n {renderConditional(title, v => (\n <Title\n level={titleLevel}\n className={cn(\n 'px-1.5 py-4',\n 'text-black-90 text-lg leading-5.75 font-bold',\n //\n )}\n >\n {v}\n </Title>\n ))}\n <div className={cn(classNames?.header)}>{header}</div>\n <div role=\"list\" className={cn('space-y-2', classNames?.body)}>\n {data?.map((item, i) =>\n itemKey ? (\n <React.Fragment key={itemKey(item, i)}>\n {renderItem(item, i)}\n </React.Fragment>\n ) : (\n renderItem(item, i)\n ),\n )}\n {scroll?.loading &&\n (scroll?.loader ?? (\n <Skeleton.Node count={10} gap={10} {...loaderProps} />\n ))}\n {scroll && <div ref={loaderRef} />}\n </div>\n </div>\n );\n};\n\nexport default List;\n"],"mappings":";;;;;;;;;;AA8CA,MAAM,QAAY,EAChB,SACA,aACA,QACA,QACA,OACA,aAAa,GACb,OACA,QACA,MACA,WACA,YACA,mBAAmB,MACnB,SACA,GAAG,YACW;CACd,MAAM,CAAC,WAAW,SAAS,wBAAwB;EACjD,WAAW;EACX,MAAM;EACN,YAAY;EACZ,GAAG,QAAQ;EACZ,CAAC;CAOF,MAAM,cAAc,OAAO,MAAM;AAEjC,iBAAgB;AACd,MAAI,CAAC,OACH;AAGF,MAAI,OAAO,SAAS;AAClB,eAAY,UAAU;AACtB;;AAGF,MAAI,OAAO,kBAAkB,OAAO,WAAW,CAAC,YAAY,SAAS;AACnE,eAAY,UAAU;AACtB,UAAO,MAAM;;IAEd,CAAC,OAAO,OAAO,CAAC;AAEnB,KAAI,QACF,QACE,UACE,qBAAC;EAAI,WAAW,GAAG,UAAU;EAAE,GAAI;;GACjC,oBAAC;IAAI,WAAW,GAAG,YAAY,MAAM;cAAG,SAAS,oBAAC,aAAW;KAAO;GACpE,oBAAC;IAAI,WAAW,GAAG,YAAY,OAAO;cACnC,UAAU,oBAAC,YAAS,MAAK,UAAU;KAChC;GACN,oBAAC;IAAI,WAAW,GAAG,aAAa,YAAY,KAAK;cAC/C,oBAAC,SAAS;KAAK,OAAO;KAAI,KAAK;KAAI,GAAI;MAAe;KAClD;;GACF;AAKZ,KAAI,CAAC,MAAM,UAAU,MACnB,QACE,oBAAC;EAAI,WAAW,GAAG,UAAU;EAAE,GAAI;YAChC;GACG;AAIV,QACE,qBAAC;EACC,WAAW,GACT,UAED;EACD,GAAI;;GAEH,kBAAkB,QAAO,MACxB,oBAAC;IACC,OAAO;IACP,WAAW,GACT,eACA,+CAED;cAEA;KACK,CACR;GACF,oBAAC;IAAI,WAAW,GAAG,YAAY,OAAO;cAAG;KAAa;GACtD,qBAAC;IAAI,MAAK;IAAO,WAAW,GAAG,aAAa,YAAY,KAAK;;KAC1D,MAAM,KAAK,MAAM,MAChB,UACE,oBAAC,MAAM,sBACJ,WAAW,MAAM,EAAE,IADD,QAAQ,MAAM,EAAE,CAEpB,GAEjB,WAAW,MAAM,EAAE,CAEtB;KACA,QAAQ,YACN,QAAQ,UACP,oBAAC,SAAS;MAAK,OAAO;MAAI,KAAK;MAAI,GAAI;OAAe;KAEzD,UAAU,oBAAC,SAAI,KAAK,YAAa;;KAC9B;;GACF"}
1
+ {"version":3,"file":"list.mjs","names":[],"sources":["../../../../src/components/organisms/list/list.tsx"],"sourcesContent":["'use client';\n\nimport React, { useEffect, useRef } from 'react';\n\nimport { useIntersectionObserver } from '@jbpark/use-hooks';\n\nimport { cn, renderConditional } from '@repo/ui/utils';\n\nimport Skeleton from '../../atoms/skeleton';\nimport { Title } from '../../atoms/typography';\n\ninterface Props<T> extends Omit<\n React.ComponentPropsWithoutRef<'div'>,\n 'title'\n> {\n loading?: boolean;\n loaderProps?: React.ComponentProps<typeof Skeleton>;\n loader?: React.ReactNode;\n title?: React.ReactNode;\n titleLevel?: 1 | 2 | 3 | 4 | 5 | 6;\n header?: React.ReactNode;\n empty?: React.ReactNode;\n classNames?: {\n title?: string;\n header?: string;\n body?: string;\n };\n scroll?: {\n hasMore: boolean;\n loading: boolean;\n loader?: React.ReactNode;\n options?: IntersectionObserverInit;\n /**\n * Called when more items should be fetched. `List` tracks in-flight\n * requests via `loading` — the caller MUST flip `loading` back to\n * `false` when the fetch settles, including on failure/rejection.\n * If `loading` never becomes `false` again after a failed fetch,\n * `List` will stop calling `next()` for subsequent intersections.\n */\n next: () => void;\n };\n data?: T[];\n renderItem?: (item: T, index: number) => React.ReactNode;\n itemKey?: (item: T, index: number) => React.Key;\n}\n\nconst List = <T,>({\n loading,\n loaderProps,\n loader,\n header,\n title,\n titleLevel = 2,\n empty,\n scroll,\n data,\n className,\n classNames,\n renderItem = () => null,\n itemKey,\n ...props\n}: Props<T>) => {\n const [loaderRef, entry] = useIntersectionObserver({\n threshold: 0,\n root: null,\n rootMargin: '0px',\n ...scroll?.options,\n });\n\n // `scroll` is typically a new object identity every render, so this\n // effect re-runs often. Guard with a ref (updated synchronously, unlike\n // the `loading` prop which only reflects the caller's next state update)\n // to avoid firing `next()` again for the same in-flight request before\n // the caller's `loading` has had a chance to become true.\n const fetchingRef = useRef(false);\n\n useEffect(() => {\n if (!scroll) {\n return;\n }\n\n if (scroll.loading) {\n fetchingRef.current = false;\n return;\n }\n\n if (entry?.isIntersecting && scroll.hasMore && !fetchingRef.current) {\n fetchingRef.current = true;\n scroll.next();\n }\n }, [entry, scroll]);\n\n if (loading) {\n return (\n loader || (\n <div className={cn(className)} {...props}>\n <div className={cn(classNames?.title)}>{title && <Skeleton />}</div>\n <div className={cn(classNames?.header)}>\n {header && <Skeleton size=\"small\" />}\n </div>\n <div className={cn('space-y-2', classNames?.body)}>\n <Skeleton.Node count={10} gap={10} {...loaderProps} />\n </div>\n </div>\n )\n );\n }\n\n if (!data?.length && empty) {\n return (\n <div className={cn(className)} {...props}>\n {empty}\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n className,\n //\n )}\n {...props}\n >\n {renderConditional(title, v => (\n <Title\n level={titleLevel}\n className={cn(\n 'px-1.5 py-4',\n 'text-black-90 text-lg leading-5.75 font-bold',\n //\n )}\n >\n {v}\n </Title>\n ))}\n <div className={cn(classNames?.header)}>{header}</div>\n <div role=\"list\" className={cn('space-y-2', classNames?.body)}>\n {data?.map((item, i) =>\n itemKey ? (\n <React.Fragment key={itemKey(item, i)}>\n {renderItem(item, i)}\n </React.Fragment>\n ) : (\n renderItem(item, i)\n ),\n )}\n {scroll?.loading &&\n (scroll?.loader ?? (\n <Skeleton.Node count={10} gap={10} {...loaderProps} />\n ))}\n {scroll && <div ref={loaderRef} />}\n </div>\n </div>\n );\n};\n\nexport default List;\n"],"mappings":";;;;;;;;;;AA8CA,MAAM,QAAY,EAChB,SACA,aACA,QACA,QACA,OACA,aAAa,GACb,OACA,QACA,MACA,WACA,YACA,mBAAmB,MACnB,SACA,GAAG,YACW;CACd,MAAM,CAAC,WAAW,SAAS,wBAAwB;EACjD,WAAW;EACX,MAAM;EACN,YAAY;EACZ,GAAG,QAAQ;EACZ,CAAC;CAOF,MAAM,cAAc,OAAO,MAAM;AAEjC,iBAAgB;AACd,MAAI,CAAC,OACH;AAGF,MAAI,OAAO,SAAS;AAClB,eAAY,UAAU;AACtB;;AAGF,MAAI,OAAO,kBAAkB,OAAO,WAAW,CAAC,YAAY,SAAS;AACnE,eAAY,UAAU;AACtB,UAAO,MAAM;;IAEd,CAAC,OAAO,OAAO,CAAC;AAEnB,KAAI,QACF,QACE,UACE,qBAAC;EAAI,WAAW,GAAG,UAAU;EAAE,GAAI;;GACjC,oBAAC;IAAI,WAAW,GAAG,YAAY,MAAM;cAAG,SAAS,oBAAC,aAAW;KAAO;GACpE,oBAAC;IAAI,WAAW,GAAG,YAAY,OAAO;cACnC,UAAU,oBAAC,YAAS,MAAK,UAAU;KAChC;GACN,oBAAC;IAAI,WAAW,GAAG,aAAa,YAAY,KAAK;cAC/C,oBAAC,SAAS;KAAK,OAAO;KAAI,KAAK;KAAI,GAAI;MAAe;KAClD;;GACF;AAKZ,KAAI,CAAC,MAAM,UAAU,MACnB,QACE,oBAAC;EAAI,WAAW,GAAG,UAAU;EAAE,GAAI;YAChC;GACG;AAIV,QACE,qBAAC;EACC,WAAW,GACT,UAED;EACD,GAAI;;GAEH,kBAAkB,QAAO,MACxB,oBAAC;IACC,OAAO;IACP,WAAW,GACT,eACA,+CAED;cAEA;KACK,CACR;GACF,oBAAC;IAAI,WAAW,GAAG,YAAY,OAAO;cAAG;KAAa;GACtD,qBAAC;IAAI,MAAK;IAAO,WAAW,GAAG,aAAa,YAAY,KAAK;;KAC1D,MAAM,KAAK,MAAM,MAChB,UACE,oBAAC,MAAM,sBACJ,WAAW,MAAM,EAAE,IADD,QAAQ,MAAM,EAAE,CAEpB,GAEjB,WAAW,MAAM,EAAE,CAEtB;KACA,QAAQ,YACN,QAAQ,UACP,oBAAC,SAAS;MAAK,OAAO;MAAI,KAAK;MAAI,GAAI;OAAe;KAEzD,UAAU,oBAAC,SAAI,KAAK,YAAa;;KAC9B;;GACF"}
@@ -9,7 +9,7 @@ declare namespace button_d_exports {
9
9
  }
10
10
  declare const buttonVariants: (props?: ({
11
11
  variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
12
- size?: "icon" | "default" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
12
+ size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
13
13
  } & class_variance_authority_types0.ClassProp) | undefined) => string;
14
14
  type Props = React$1.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
15
15
  asChild?: boolean;
@@ -22,5 +22,5 @@ declare function Button({
22
22
  ...props
23
23
  }: Props): react_jsx_runtime0.JSX.Element;
24
24
  //#endregion
25
- export { type Props, button_d_exports };
25
+ export { Button, type Props, button_d_exports };
26
26
  //# sourceMappingURL=button.d.mts.map
@@ -51,5 +51,5 @@ function Button({ className, variant = "default", size = "default", asChild = fa
51
51
  }
52
52
 
53
53
  //#endregion
54
- export { Button, button_exports };
54
+ export { Button, buttonVariants, button_exports };
55
55
  //# sourceMappingURL=button.mjs.map
@@ -0,0 +1,30 @@
1
+ import { Button } from "./button.mjs";
2
+ import * as React$1 from "react";
3
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
4
+ import { DayButton, DayPicker } from "react-day-picker";
5
+
6
+ //#region src/core/calendar.d.ts
7
+ declare namespace calendar_d_exports {
8
+ export { Calendar, CalendarDayButton };
9
+ }
10
+ declare function Calendar({
11
+ className,
12
+ classNames,
13
+ showOutsideDays,
14
+ captionLayout,
15
+ buttonVariant,
16
+ formatters,
17
+ components,
18
+ ...props
19
+ }: React$1.ComponentProps<typeof DayPicker> & {
20
+ buttonVariant?: React$1.ComponentProps<typeof Button>['variant'];
21
+ }): react_jsx_runtime0.JSX.Element;
22
+ declare function CalendarDayButton({
23
+ className,
24
+ day,
25
+ modifiers,
26
+ ...props
27
+ }: React$1.ComponentProps<typeof DayButton>): react_jsx_runtime0.JSX.Element;
28
+ //#endregion
29
+ export { calendar_d_exports };
30
+ //# sourceMappingURL=calendar.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.d.mts","names":[],"sources":["../../src/core/calendar.tsx"],"mappings":";;;;;;;;;iBAeS,QAAA,CAAA;EACP,SAAA;EACA,UAAA;EACA,eAAA;EACA,aAAA;EACA,aAAA;EACA,UAAA;EACA,UAAA;EAAA,GACG;AAAA,GACF,OAAA,CAAM,cAAA,QAAsB,SAAA;EAC7B,aAAA,GAAgB,OAAA,CAAM,cAAA,QAAsB,MAAA;AAAA,IAC7C,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAkKQ,iBAAA,CAAA;EACP,SAAA;EACA,GAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,OAAA,CAAM,cAAA,QAAsB,SAAA,IAAU,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -0,0 +1,136 @@
1
+ 'use client';
2
+
3
+ import { __exportAll } from "../_virtual/_rolldown/runtime.mjs";
4
+ import { cn } from "../utils.mjs";
5
+ import { Button, buttonVariants } from "./button.mjs";
6
+ import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
7
+ import * as React$1 from "react";
8
+ import { jsx } from "react/jsx-runtime";
9
+ import { DayPicker, getDefaultClassNames } from "react-day-picker";
10
+
11
+ //#region src/core/calendar.tsx
12
+ var calendar_exports = /* @__PURE__ */ __exportAll({
13
+ Calendar: () => Calendar,
14
+ CalendarDayButton: () => CalendarDayButton
15
+ });
16
+ function Calendar({ className, classNames, showOutsideDays = true, captionLayout = "label", buttonVariant = "ghost", formatters, components, ...props }) {
17
+ const defaultClassNames = getDefaultClassNames();
18
+ return /* @__PURE__ */ jsx(DayPicker, {
19
+ showOutsideDays,
20
+ className: cn(`bg-background group/calendar p-3 [--cell-size:2rem]
21
+ [[data-slot=card-content]_&]:bg-transparent
22
+ [[data-slot=popover-content]_&]:bg-transparent`, String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`, String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`, className),
23
+ captionLayout,
24
+ formatters: {
25
+ formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
26
+ ...formatters
27
+ },
28
+ classNames: {
29
+ root: cn("w-fit", defaultClassNames.root),
30
+ months: cn("relative flex flex-col gap-4 md:flex-row", defaultClassNames.months),
31
+ month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
32
+ nav: cn("absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1", defaultClassNames.nav),
33
+ button_previous: cn(buttonVariants({ variant: buttonVariant }), "h-(--cell-size) w-(--cell-size) select-none p-0 aria-disabled:opacity-50", defaultClassNames.button_previous),
34
+ button_next: cn(buttonVariants({ variant: buttonVariant }), "h-(--cell-size) w-(--cell-size) select-none p-0 aria-disabled:opacity-50", defaultClassNames.button_next),
35
+ month_caption: cn("flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)", defaultClassNames.month_caption),
36
+ dropdowns: cn("flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium", defaultClassNames.dropdowns),
37
+ dropdown_root: cn(`has-focus:border-ring border-input shadow-xs
38
+ has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md
39
+ border`, defaultClassNames.dropdown_root),
40
+ dropdown: cn("bg-popover absolute inset-0 opacity-0", defaultClassNames.dropdown),
41
+ caption_label: cn("select-none font-medium", captionLayout === "label" ? "text-sm" : `[&>svg]:text-muted-foreground flex h-8 items-center gap-1
42
+ rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5`, defaultClassNames.caption_label),
43
+ month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
44
+ weekdays: cn("flex", defaultClassNames.weekdays),
45
+ weekday: cn("text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal", defaultClassNames.weekday),
46
+ week: cn("mt-2 flex w-full", defaultClassNames.week),
47
+ week_number_header: cn("w-(--cell-size) select-none", defaultClassNames.week_number_header),
48
+ week_number: cn("text-muted-foreground select-none text-[0.8rem]", defaultClassNames.week_number),
49
+ day: cn(`group/day relative aspect-square h-full w-full select-none p-0
50
+ text-center [&:first-child[data-selected=true]_button]:rounded-l-md
51
+ [&:last-child[data-selected=true]_button]:rounded-r-md`, defaultClassNames.day),
52
+ range_start: cn("bg-accent rounded-l-md", defaultClassNames.range_start),
53
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
54
+ range_end: cn("bg-accent rounded-r-md", defaultClassNames.range_end),
55
+ today: cn("bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none", defaultClassNames.today),
56
+ outside: cn("text-muted-foreground aria-selected:text-muted-foreground", defaultClassNames.outside),
57
+ disabled: cn("text-muted-foreground opacity-50", defaultClassNames.disabled),
58
+ hidden: cn("invisible", defaultClassNames.hidden),
59
+ ...classNames
60
+ },
61
+ components: {
62
+ Root: ({ className, rootRef, ...props }) => {
63
+ return /* @__PURE__ */ jsx("div", {
64
+ "data-slot": "calendar",
65
+ ref: rootRef,
66
+ className: cn(className),
67
+ ...props
68
+ });
69
+ },
70
+ Chevron: ({ className, orientation, ...props }) => {
71
+ if (orientation === "left") return /* @__PURE__ */ jsx(ChevronLeftIcon, {
72
+ className: cn("size-4", className),
73
+ ...props
74
+ });
75
+ if (orientation === "right") return /* @__PURE__ */ jsx(ChevronRightIcon, {
76
+ className: cn("size-4", className),
77
+ ...props
78
+ });
79
+ return /* @__PURE__ */ jsx(ChevronDownIcon, {
80
+ className: cn("size-4", className),
81
+ ...props
82
+ });
83
+ },
84
+ DayButton: CalendarDayButton,
85
+ WeekNumber: ({ children, ...props }) => {
86
+ return /* @__PURE__ */ jsx("td", {
87
+ ...props,
88
+ children: /* @__PURE__ */ jsx("div", {
89
+ className: "flex size-(--cell-size) items-center justify-center\n text-center",
90
+ children
91
+ })
92
+ });
93
+ },
94
+ ...components
95
+ },
96
+ ...props
97
+ });
98
+ }
99
+ function CalendarDayButton({ className, day, modifiers, ...props }) {
100
+ const defaultClassNames = getDefaultClassNames();
101
+ const ref = React$1.useRef(null);
102
+ React$1.useEffect(() => {
103
+ if (modifiers.focused) ref.current?.focus();
104
+ }, [modifiers.focused]);
105
+ return /* @__PURE__ */ jsx(Button, {
106
+ ref,
107
+ variant: "ghost",
108
+ size: "icon",
109
+ "data-day": day.date.toLocaleDateString(),
110
+ "data-selected-single": modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle,
111
+ "data-range-start": modifiers.range_start,
112
+ "data-range-end": modifiers.range_end,
113
+ "data-range-middle": modifiers.range_middle,
114
+ className: cn(`data-[selected-single=true]:bg-primary
115
+ data-[selected-single=true]:text-primary-foreground
116
+ data-[range-middle=true]:bg-accent
117
+ data-[range-middle=true]:text-accent-foreground
118
+ data-[range-start=true]:bg-primary
119
+ data-[range-start=true]:text-primary-foreground
120
+ data-[range-end=true]:bg-primary
121
+ data-[range-end=true]:text-primary-foreground
122
+ group-data-[focused=true]/day:border-ring
123
+ group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto
124
+ w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal
125
+ group-data-[focused=true]/day:relative
126
+ group-data-[focused=true]/day:z-10
127
+ group-data-[focused=true]/day:ring-[3px]
128
+ data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none
129
+ data-[range-start=true]:rounded-md [&>span]:text-xs [&>span]:opacity-70`, defaultClassNames.day, className),
130
+ ...props
131
+ });
132
+ }
133
+
134
+ //#endregion
135
+ export { calendar_exports };
136
+ //# sourceMappingURL=calendar.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.mjs","names":["React"],"sources":["../../src/core/calendar.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker';\n\nimport {\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n} from 'lucide-react';\n\nimport { cn } from '@repo/ui/utils';\n\nimport { Button, buttonVariants } from './button';\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n captionLayout = 'label',\n buttonVariant = 'ghost',\n formatters,\n components,\n ...props\n}: React.ComponentProps<typeof DayPicker> & {\n buttonVariant?: React.ComponentProps<typeof Button>['variant'];\n}) {\n const defaultClassNames = getDefaultClassNames();\n\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\n `bg-background group/calendar p-3 [--cell-size:2rem]\n [[data-slot=card-content]_&]:bg-transparent\n [[data-slot=popover-content]_&]:bg-transparent`,\n String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n className,\n )}\n captionLayout={captionLayout}\n formatters={{\n formatMonthDropdown: date =>\n date.toLocaleString('default', { month: 'short' }),\n ...formatters,\n }}\n classNames={{\n root: cn('w-fit', defaultClassNames.root),\n months: cn(\n 'relative flex flex-col gap-4 md:flex-row',\n defaultClassNames.months,\n ),\n month: cn('flex w-full flex-col gap-4', defaultClassNames.month),\n nav: cn(\n 'absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1',\n defaultClassNames.nav,\n ),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n 'h-(--cell-size) w-(--cell-size) select-none p-0 aria-disabled:opacity-50',\n defaultClassNames.button_previous,\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n 'h-(--cell-size) w-(--cell-size) select-none p-0 aria-disabled:opacity-50',\n defaultClassNames.button_next,\n ),\n month_caption: cn(\n 'flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)',\n defaultClassNames.month_caption,\n ),\n dropdowns: cn(\n 'flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium',\n defaultClassNames.dropdowns,\n ),\n dropdown_root: cn(\n `has-focus:border-ring border-input shadow-xs\n has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md\n border`,\n defaultClassNames.dropdown_root,\n ),\n dropdown: cn(\n 'bg-popover absolute inset-0 opacity-0',\n defaultClassNames.dropdown,\n ),\n caption_label: cn(\n 'select-none font-medium',\n captionLayout === 'label'\n ? 'text-sm'\n : `[&>svg]:text-muted-foreground flex h-8 items-center gap-1\n rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5`,\n defaultClassNames.caption_label,\n ),\n month_grid: cn('w-full border-collapse', defaultClassNames.month_grid),\n weekdays: cn('flex', defaultClassNames.weekdays),\n weekday: cn(\n 'text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal',\n defaultClassNames.weekday,\n ),\n week: cn('mt-2 flex w-full', defaultClassNames.week),\n week_number_header: cn(\n 'w-(--cell-size) select-none',\n defaultClassNames.week_number_header,\n ),\n week_number: cn(\n 'text-muted-foreground select-none text-[0.8rem]',\n defaultClassNames.week_number,\n ),\n day: cn(\n `group/day relative aspect-square h-full w-full select-none p-0\n text-center [&:first-child[data-selected=true]_button]:rounded-l-md\n [&:last-child[data-selected=true]_button]:rounded-r-md`,\n defaultClassNames.day,\n ),\n range_start: cn(\n 'bg-accent rounded-l-md',\n defaultClassNames.range_start,\n ),\n range_middle: cn('rounded-none', defaultClassNames.range_middle),\n range_end: cn('bg-accent rounded-r-md', defaultClassNames.range_end),\n today: cn(\n 'bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none',\n defaultClassNames.today,\n ),\n outside: cn(\n 'text-muted-foreground aria-selected:text-muted-foreground',\n defaultClassNames.outside,\n ),\n disabled: cn(\n 'text-muted-foreground opacity-50',\n defaultClassNames.disabled,\n ),\n hidden: cn('invisible', defaultClassNames.hidden),\n ...classNames,\n }}\n components={{\n // eslint-disable-next-line react/prop-types -- typed via DayPicker's `components` prop, not local PropTypes\n Root: ({ className, rootRef, ...props }) => {\n return (\n <div\n data-slot=\"calendar\"\n ref={rootRef}\n className={cn(className)}\n {...props}\n />\n );\n },\n // eslint-disable-next-line react/prop-types -- typed via DayPicker's `components` prop, not local PropTypes\n Chevron: ({ className, orientation, ...props }) => {\n if (orientation === 'left') {\n return (\n <ChevronLeftIcon className={cn('size-4', className)} {...props} />\n );\n }\n\n if (orientation === 'right') {\n return (\n <ChevronRightIcon\n className={cn('size-4', className)}\n {...props}\n />\n );\n }\n\n return (\n <ChevronDownIcon className={cn('size-4', className)} {...props} />\n );\n },\n DayButton: CalendarDayButton,\n WeekNumber: ({ children, ...props }) => {\n return (\n <td {...props}>\n <div\n className=\"flex size-(--cell-size) items-center justify-center\n text-center\"\n >\n {children}\n </div>\n </td>\n );\n },\n ...components,\n }}\n {...props}\n />\n );\n}\n\nfunction CalendarDayButton({\n className,\n day,\n modifiers,\n ...props\n}: React.ComponentProps<typeof DayButton>) {\n const defaultClassNames = getDefaultClassNames();\n\n const ref = React.useRef<HTMLButtonElement>(null);\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus();\n }, [modifiers.focused]);\n\n return (\n <Button\n ref={ref}\n variant=\"ghost\"\n size=\"icon\"\n data-day={day.date.toLocaleDateString()}\n data-selected-single={\n modifiers.selected &&\n !modifiers.range_start &&\n !modifiers.range_end &&\n !modifiers.range_middle\n }\n data-range-start={modifiers.range_start}\n data-range-end={modifiers.range_end}\n data-range-middle={modifiers.range_middle}\n className={cn(\n `data-[selected-single=true]:bg-primary\n data-[selected-single=true]:text-primary-foreground\n data-[range-middle=true]:bg-accent\n data-[range-middle=true]:text-accent-foreground\n data-[range-start=true]:bg-primary\n data-[range-start=true]:text-primary-foreground\n data-[range-end=true]:bg-primary\n data-[range-end=true]:text-primary-foreground\n group-data-[focused=true]/day:border-ring\n group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto\n w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal\n group-data-[focused=true]/day:relative\n group-data-[focused=true]/day:z-10\n group-data-[focused=true]/day:ring-[3px]\n data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none\n data-[range-start=true]:rounded-md [&>span]:text-xs [&>span]:opacity-70`,\n defaultClassNames.day,\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Calendar, CalendarDayButton };\n"],"mappings":";;;;;;;;;;;;;;;AAeA,SAAS,SAAS,EAChB,WACA,YACA,kBAAkB,MAClB,gBAAgB,SAChB,gBAAgB,SAChB,YACA,YACA,GAAG,SAGF;CACD,MAAM,oBAAoB,sBAAsB;AAEhD,QACE,oBAAC;EACkB;EACjB,WAAW,GACT;;yDAGA,OAAO,GAAG,6CACV,OAAO,GAAG,iDACV,UACD;EACc;EACf,YAAY;GACV,sBAAqB,SACnB,KAAK,eAAe,WAAW,EAAE,OAAO,SAAS,CAAC;GACpD,GAAG;GACJ;EACD,YAAY;GACV,MAAM,GAAG,SAAS,kBAAkB,KAAK;GACzC,QAAQ,GACN,4CACA,kBAAkB,OACnB;GACD,OAAO,GAAG,8BAA8B,kBAAkB,MAAM;GAChE,KAAK,GACH,2EACA,kBAAkB,IACnB;GACD,iBAAiB,GACf,eAAe,EAAE,SAAS,eAAe,CAAC,EAC1C,4EACA,kBAAkB,gBACnB;GACD,aAAa,GACX,eAAe,EAAE,SAAS,eAAe,CAAC,EAC1C,4EACA,kBAAkB,YACnB;GACD,eAAe,GACb,4EACA,kBAAkB,cACnB;GACD,WAAW,GACT,uFACA,kBAAkB,UACnB;GACD,eAAe,GACb;;mBAGA,kBAAkB,cACnB;GACD,UAAU,GACR,yCACA,kBAAkB,SACnB;GACD,eAAe,GACb,2BACA,kBAAkB,UACd,YACA;8DAEJ,kBAAkB,cACnB;GACD,YAAY,GAAG,0BAA0B,kBAAkB,WAAW;GACtE,UAAU,GAAG,QAAQ,kBAAkB,SAAS;GAChD,SAAS,GACP,iFACA,kBAAkB,QACnB;GACD,MAAM,GAAG,oBAAoB,kBAAkB,KAAK;GACpD,oBAAoB,GAClB,+BACA,kBAAkB,mBACnB;GACD,aAAa,GACX,mDACA,kBAAkB,YACnB;GACD,KAAK,GACH;;mEAGA,kBAAkB,IACnB;GACD,aAAa,GACX,0BACA,kBAAkB,YACnB;GACD,cAAc,GAAG,gBAAgB,kBAAkB,aAAa;GAChE,WAAW,GAAG,0BAA0B,kBAAkB,UAAU;GACpE,OAAO,GACL,iFACA,kBAAkB,MACnB;GACD,SAAS,GACP,6DACA,kBAAkB,QACnB;GACD,UAAU,GACR,oCACA,kBAAkB,SACnB;GACD,QAAQ,GAAG,aAAa,kBAAkB,OAAO;GACjD,GAAG;GACJ;EACD,YAAY;GAEV,OAAO,EAAE,WAAW,SAAS,GAAG,YAAY;AAC1C,WACE,oBAAC;KACC,aAAU;KACV,KAAK;KACL,WAAW,GAAG,UAAU;KACxB,GAAI;MACJ;;GAIN,UAAU,EAAE,WAAW,aAAa,GAAG,YAAY;AACjD,QAAI,gBAAgB,OAClB,QACE,oBAAC;KAAgB,WAAW,GAAG,UAAU,UAAU;KAAE,GAAI;MAAS;AAItE,QAAI,gBAAgB,QAClB,QACE,oBAAC;KACC,WAAW,GAAG,UAAU,UAAU;KAClC,GAAI;MACJ;AAIN,WACE,oBAAC;KAAgB,WAAW,GAAG,UAAU,UAAU;KAAE,GAAI;MAAS;;GAGtE,WAAW;GACX,aAAa,EAAE,UAAU,GAAG,YAAY;AACtC,WACE,oBAAC;KAAG,GAAI;eACN,oBAAC;MACC,WAAU;MAGT;OACG;MACH;;GAGT,GAAG;GACJ;EACD,GAAI;GACJ;;AAIN,SAAS,kBAAkB,EACzB,WACA,KACA,WACA,GAAG,SACsC;CACzC,MAAM,oBAAoB,sBAAsB;CAEhD,MAAM,MAAMA,QAAM,OAA0B,KAAK;AACjD,SAAM,gBAAgB;AACpB,MAAI,UAAU,QAAS,KAAI,SAAS,OAAO;IAC1C,CAAC,UAAU,QAAQ,CAAC;AAEvB,QACE,oBAAC;EACM;EACL,SAAQ;EACR,MAAK;EACL,YAAU,IAAI,KAAK,oBAAoB;EACvC,wBACE,UAAU,YACV,CAAC,UAAU,eACX,CAAC,UAAU,aACX,CAAC,UAAU;EAEb,oBAAkB,UAAU;EAC5B,kBAAgB,UAAU;EAC1B,qBAAmB,UAAU;EAC7B,WAAW,GACT;;;;;;;;;;;;;;;kFAgBA,kBAAkB,KAClB,UACD;EACD,GAAI;GACJ"}
package/dist/core.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { accordion_d_exports } from "./core/accordion.mjs";
2
2
  import { badge_d_exports } from "./core/badge.mjs";
3
3
  import { button_d_exports } from "./core/button.mjs";
4
+ import { calendar_d_exports } from "./core/calendar.mjs";
4
5
  import { checkbox_d_exports } from "./core/checkbox.mjs";
5
6
  import { dialog_d_exports } from "./core/dialog.mjs";
6
7
  import { drawer_d_exports } from "./core/drawer.mjs";
@@ -16,4 +17,4 @@ import { separator_d_exports } from "./core/separator.mjs";
16
17
  import { skeleton_d_exports } from "./core/skeleton.mjs";
17
18
  import { switch_d_exports } from "./core/switch.mjs";
18
19
  import { textarea_d_exports } from "./core/textarea.mjs";
19
- export { accordion_d_exports as accordion, badge_d_exports as badge, button_d_exports as button, checkbox_d_exports as checkbox, dialog_d_exports as dialog, drawer_d_exports as drawer, field_d_exports as field, input_d_exports as input, label_d_exports as label, popover_d_exports as popover, progress_d_exports as progress, radio_group_d_exports as radio, resizable_d_exports as resizable, select_d_exports as select, separator_d_exports as separator, skeleton_d_exports as skeleton, switch_d_exports as switchComponent, textarea_d_exports as textarea };
20
+ export { accordion_d_exports as accordion, badge_d_exports as badge, button_d_exports as button, calendar_d_exports as calendar, checkbox_d_exports as checkbox, dialog_d_exports as dialog, drawer_d_exports as drawer, field_d_exports as field, input_d_exports as input, label_d_exports as label, popover_d_exports as popover, progress_d_exports as progress, radio_group_d_exports as radio, resizable_d_exports as resizable, select_d_exports as select, separator_d_exports as separator, skeleton_d_exports as skeleton, switch_d_exports as switchComponent, textarea_d_exports as textarea };
package/dist/core.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { accordion_exports } from "./core/accordion.mjs";
2
2
  import { badge_exports } from "./core/badge.mjs";
3
3
  import { button_exports } from "./core/button.mjs";
4
+ import { calendar_exports } from "./core/calendar.mjs";
4
5
  import { checkbox_exports } from "./core/checkbox.mjs";
5
6
  import { dialog_exports } from "./core/dialog.mjs";
6
7
  import { drawer_exports } from "./core/drawer.mjs";
@@ -17,4 +18,4 @@ import { skeleton_exports } from "./core/skeleton.mjs";
17
18
  import { switch_exports } from "./core/switch.mjs";
18
19
  import { textarea_exports } from "./core/textarea.mjs";
19
20
 
20
- export { accordion_exports as accordion, badge_exports as badge, button_exports as button, checkbox_exports as checkbox, dialog_exports as dialog, drawer_exports as drawer, field_exports as field, input_exports as input, label_exports as label, popover_exports as popover, progress_exports as progress, radio_group_exports as radio, resizable_exports as resizable, select_exports as select, separator_exports as separator, skeleton_exports as skeleton, switch_exports as switchComponent, textarea_exports as textarea };
21
+ export { accordion_exports as accordion, badge_exports as badge, button_exports as button, calendar_exports as calendar, checkbox_exports as checkbox, dialog_exports as dialog, drawer_exports as drawer, field_exports as field, input_exports as input, label_exports as label, popover_exports as popover, progress_exports as progress, radio_group_exports as radio, resizable_exports as resizable, select_exports as select, separator_exports as separator, skeleton_exports as skeleton, switch_exports as switchComponent, textarea_exports as textarea };
package/dist/index.d.mts CHANGED
@@ -8,6 +8,7 @@ import Space from "./Space.mjs";
8
8
  import Layout from "./Layout.mjs";
9
9
  import { Checkbox } from "./components/atoms/checkbox/index.mjs";
10
10
  import { ColorPicker } from "./components/atoms/color-picker.mjs";
11
+ import { DatePicker } from "./components/atoms/date-picker.mjs";
11
12
  import { FloatButton } from "./components/atoms/float-button/index.mjs";
12
13
  import { Input } from "./components/atoms/input/index.mjs";
13
14
  import { Popover } from "./components/atoms/popover.mjs";
@@ -22,6 +23,7 @@ import { Collapse } from "./components/molecules/collapse.mjs";
22
23
  import { Dropdown } from "./components/molecules/dropdown.mjs";
23
24
  import { Marquees } from "./components/molecules/marquees/index.mjs";
24
25
  import { Splitter } from "./components/molecules/splitter/index.mjs";
26
+ import { Upload, UploadFile } from "./components/molecules/upload.mjs";
25
27
  import "./components/molecules/index.mjs";
26
28
  import { Drawer, Props as Props$1 } from "./components/organisms/drawer.mjs";
27
29
  import { List } from "./components/organisms/list/index.mjs";
@@ -33,4 +35,4 @@ import { ThemeConfig, ThemeToken } from "./providers/Config/types.mjs";
33
35
  import { useConfig } from "./providers/Config/context.mjs";
34
36
  import { Config, Props } from "./providers/Config/index.mjs";
35
37
  import "./providers/index.mjs";
36
- export { Button, Card, Checkbox, Collapse, ColorPicker, Config, Props as ConfigProps, Drawer, Props$1 as DrawerProps, Dropdown, FloatButton, Input, Layout, List, Marquees, Menu, Modal, Popover, Progress, Radio, Reveals, Select, Skeleton, Space, Spin, Splitter, Swiper, Switch, Tag, ThemeConfig, ThemeToken, Typography, useConfig };
38
+ export { Button, Card, Checkbox, Collapse, ColorPicker, Config, Props as ConfigProps, DatePicker, Drawer, Props$1 as DrawerProps, Dropdown, FloatButton, Input, Layout, List, Marquees, Menu, Modal, Popover, Progress, Radio, Reveals, Select, Skeleton, Space, Spin, Splitter, Swiper, Switch, Tag, ThemeConfig, ThemeToken, Typography, Upload, UploadFile, useConfig };
package/dist/index.mjs CHANGED
@@ -4,6 +4,7 @@ import Checkbox from "./components/atoms/checkbox/index.mjs";
4
4
  import Typography from "./Typography.mjs";
5
5
  import Popover from "./components/atoms/popover.mjs";
6
6
  import ColorPicker from "./components/atoms/color-picker.mjs";
7
+ import DatePicker from "./components/atoms/date-picker.mjs";
7
8
  import FloatButton from "./components/atoms/float-button/index.mjs";
8
9
  import Input from "./components/atoms/input/index.mjs";
9
10
  import Progress from "./components/atoms/progress.mjs";
@@ -21,6 +22,7 @@ import Marquees from "./components/molecules/marquees/index.mjs";
21
22
  import Reveals from "./Reveals.mjs";
22
23
  import Splitter from "./components/molecules/splitter/index.mjs";
23
24
  import Space from "./Space.mjs";
25
+ import Upload from "./components/molecules/upload.mjs";
24
26
  import Drawer from "./components/organisms/drawer.mjs";
25
27
  import List from "./components/organisms/list/index.mjs";
26
28
  import Modal from "./components/organisms/modal.mjs";
@@ -29,4 +31,4 @@ import Layout from "./Layout.mjs";
29
31
  import { useConfig } from "./providers/Config/context.mjs";
30
32
  import Config from "./providers/Config/index.mjs";
31
33
 
32
- export { Button, Card, Checkbox, Collapse, ColorPicker, Config, Drawer, Dropdown, FloatButton, Input, Layout, List, Marquees, Menu, Modal, Popover, Progress, Radio, Reveals, Select, Skeleton, Space, Spin, Splitter, Swiper, Switch, Tag, Typography, useConfig };
34
+ export { Button, Card, Checkbox, Collapse, ColorPicker, Config, DatePicker, Drawer, Dropdown, FloatButton, Input, Layout, List, Marquees, Menu, Modal, Popover, Progress, Radio, Reveals, Select, Skeleton, Space, Spin, Splitter, Swiper, Switch, Tag, Typography, Upload, useConfig };
package/dist/style.css CHANGED
@@ -207,6 +207,9 @@
207
207
  .pointer-events-none {
208
208
  pointer-events: none;
209
209
  }
210
+ .invisible {
211
+ visibility: hidden;
212
+ }
210
213
  .sr-only {
211
214
  position: absolute;
212
215
  width: 1px;
@@ -239,6 +242,9 @@
239
242
  .inset-0 {
240
243
  inset: calc(var(--spacing) * 0);
241
244
  }
245
+ .inset-x-0 {
246
+ inset-inline: calc(var(--spacing) * 0);
247
+ }
242
248
  .top-0 {
243
249
  top: calc(var(--spacing) * 0);
244
250
  }
@@ -347,6 +353,9 @@
347
353
  .my-1 {
348
354
  margin-block: calc(var(--spacing) * 1);
349
355
  }
356
+ .mt-2 {
357
+ margin-top: calc(var(--spacing) * 2);
358
+ }
350
359
  .mt-3 {
351
360
  margin-top: calc(var(--spacing) * 3);
352
361
  }
@@ -422,6 +431,10 @@
422
431
  .aspect-square {
423
432
  aspect-ratio: 1 / 1;
424
433
  }
434
+ .size-\(--cell-size\) {
435
+ width: var(--cell-size);
436
+ height: var(--cell-size);
437
+ }
425
438
  .size-2 {
426
439
  width: calc(var(--spacing) * 2);
427
440
  height: calc(var(--spacing) * 2);
@@ -462,6 +475,9 @@
462
475
  width: calc(var(--spacing) * 10);
463
476
  height: calc(var(--spacing) * 10);
464
477
  }
478
+ .h-\(--cell-size\) {
479
+ height: var(--cell-size);
480
+ }
465
481
  .h-2 {
466
482
  height: calc(var(--spacing) * 2);
467
483
  }
@@ -501,6 +517,9 @@
501
517
  .h-50 {
502
518
  height: calc(var(--spacing) * 50);
503
519
  }
520
+ .h-\[--cell-size\] {
521
+ height: --cell-size;
522
+ }
504
523
  .h-\[var\(--radix-select-trigger-height\)\] {
505
524
  height: var(--radix-select-trigger-height);
506
525
  }
@@ -525,6 +544,9 @@
525
544
  .min-h-screen {
526
545
  min-height: 100vh;
527
546
  }
547
+ .w-\(--cell-size\) {
548
+ width: var(--cell-size);
549
+ }
528
550
  .w-3 {
529
551
  width: calc(var(--spacing) * 3);
530
552
  }
@@ -582,6 +604,9 @@
582
604
  .max-w-\[calc\(100\%-2rem\)\] {
583
605
  max-width: calc(100% - 2rem);
584
606
  }
607
+ .min-w-\(--cell-size\) {
608
+ min-width: var(--cell-size);
609
+ }
585
610
  .min-w-0 {
586
611
  min-width: calc(var(--spacing) * 0);
587
612
  }
@@ -618,6 +643,9 @@
618
643
  .basis-auto {
619
644
  flex-basis: auto;
620
645
  }
646
+ .border-collapse {
647
+ border-collapse: collapse;
648
+ }
621
649
  .origin-\(--radix-popover-content-transform-origin\) {
622
650
  transform-origin: var(--radix-popover-content-transform-origin);
623
651
  }
@@ -739,6 +767,9 @@
739
767
  .justify-end {
740
768
  justify-content: flex-end;
741
769
  }
770
+ .justify-start {
771
+ justify-content: flex-start;
772
+ }
742
773
  .gap-0 {
743
774
  gap: calc(var(--spacing) * 0);
744
775
  }
@@ -785,6 +816,11 @@
785
816
  .gap-y-5 {
786
817
  row-gap: calc(var(--spacing) * 5);
787
818
  }
819
+ .truncate {
820
+ overflow: hidden;
821
+ text-overflow: ellipsis;
822
+ white-space: nowrap;
823
+ }
788
824
  .overflow-auto {
789
825
  overflow: auto;
790
826
  }
@@ -838,6 +874,10 @@
838
874
  border-top-left-radius: var(--radius);
839
875
  border-bottom-left-radius: var(--radius);
840
876
  }
877
+ .rounded-l-md {
878
+ border-top-left-radius: calc(var(--radius) - 2px);
879
+ border-bottom-left-radius: calc(var(--radius) - 2px);
880
+ }
841
881
  .rounded-l-none {
842
882
  border-top-left-radius: 0;
843
883
  border-bottom-left-radius: 0;
@@ -846,6 +886,10 @@
846
886
  border-top-right-radius: var(--radius);
847
887
  border-bottom-right-radius: var(--radius);
848
888
  }
889
+ .rounded-r-md {
890
+ border-top-right-radius: calc(var(--radius) - 2px);
891
+ border-bottom-right-radius: calc(var(--radius) - 2px);
892
+ }
849
893
  .rounded-r-none {
850
894
  border-top-right-radius: 0;
851
895
  border-bottom-right-radius: 0;
@@ -1000,6 +1044,9 @@
1000
1044
  .fill-primary {
1001
1045
  fill: var(--primary);
1002
1046
  }
1047
+ .object-cover {
1048
+ object-fit: cover;
1049
+ }
1003
1050
  .p-0 {
1004
1051
  padding: calc(var(--spacing) * 0);
1005
1052
  }
@@ -1009,6 +1056,12 @@
1009
1056
  .p-1 {
1010
1057
  padding: calc(var(--spacing) * 1);
1011
1058
  }
1059
+ .p-2 {
1060
+ padding: calc(var(--spacing) * 2);
1061
+ }
1062
+ .p-3 {
1063
+ padding: calc(var(--spacing) * 3);
1064
+ }
1012
1065
  .p-4 {
1013
1066
  padding: calc(var(--spacing) * 4);
1014
1067
  }
@@ -1018,6 +1071,9 @@
1018
1071
  .p-6 {
1019
1072
  padding: calc(var(--spacing) * 6);
1020
1073
  }
1074
+ .px-\(--cell-size\) {
1075
+ padding-inline: var(--cell-size);
1076
+ }
1021
1077
  .px-1 {
1022
1078
  padding-inline: calc(var(--spacing) * 1);
1023
1079
  }
@@ -1066,6 +1122,9 @@
1066
1122
  .pt-2 {
1067
1123
  padding-top: calc(var(--spacing) * 2);
1068
1124
  }
1125
+ .pr-1 {
1126
+ padding-right: calc(var(--spacing) * 1);
1127
+ }
1069
1128
  .pr-8 {
1070
1129
  padding-right: calc(var(--spacing) * 8);
1071
1130
  }
@@ -1128,6 +1187,9 @@
1128
1187
  font-size: var(--text-xs);
1129
1188
  line-height: var(--tw-leading, var(--text-xs--line-height));
1130
1189
  }
1190
+ .text-\[0\.8rem\] {
1191
+ font-size: 0.8rem;
1192
+ }
1131
1193
  .text-\[10px\] {
1132
1194
  font-size: 10px;
1133
1195
  }
@@ -1178,6 +1240,9 @@
1178
1240
  .text-\(--btn-fg\) {
1179
1241
  color: var(--btn-fg);
1180
1242
  }
1243
+ .text-accent-foreground {
1244
+ color: var(--accent-foreground);
1245
+ }
1181
1246
  .text-blue-400 {
1182
1247
  color: var(--color-blue-400);
1183
1248
  }
@@ -1364,6 +1429,9 @@
1364
1429
  -webkit-user-select: none;
1365
1430
  user-select: none;
1366
1431
  }
1432
+ .\[--cell-size\:2rem\] {
1433
+ --cell-size: 2rem;
1434
+ }
1367
1435
  .group-hover\:border-current {
1368
1436
  &:is(:where(.group):hover *) {
1369
1437
  @media (hover: hover) {
@@ -1391,6 +1459,35 @@
1391
1459
  opacity: 50%;
1392
1460
  }
1393
1461
  }
1462
+ .group-data-\[focused\=true\]\/day\:relative {
1463
+ &:is(:where(.group\/day)[data-focused="true"] *) {
1464
+ position: relative;
1465
+ }
1466
+ }
1467
+ .group-data-\[focused\=true\]\/day\:z-10 {
1468
+ &:is(:where(.group\/day)[data-focused="true"] *) {
1469
+ z-index: 10;
1470
+ }
1471
+ }
1472
+ .group-data-\[focused\=true\]\/day\:border-ring {
1473
+ &:is(:where(.group\/day)[data-focused="true"] *) {
1474
+ border-color: var(--ring);
1475
+ }
1476
+ }
1477
+ .group-data-\[focused\=true\]\/day\:ring-\[3px\] {
1478
+ &:is(:where(.group\/day)[data-focused="true"] *) {
1479
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1480
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1481
+ }
1482
+ }
1483
+ .group-data-\[focused\=true\]\/day\:ring-ring\/50 {
1484
+ &:is(:where(.group\/day)[data-focused="true"] *) {
1485
+ --tw-ring-color: var(--ring);
1486
+ @supports (color: color-mix(in lab, red, red)) {
1487
+ --tw-ring-color: color-mix(in oklab, var(--ring) 50%, transparent);
1488
+ }
1489
+ }
1490
+ }
1394
1491
  .group-data-\[size\=default\]\/switch\:size-4 {
1395
1492
  &:is(:where(.group\/switch)[data-size="default"] *) {
1396
1493
  width: calc(var(--spacing) * 4);
@@ -1937,6 +2034,13 @@
1937
2034
  }
1938
2035
  }
1939
2036
  }
2037
+ .hover\:text-foreground {
2038
+ &:hover {
2039
+ @media (hover: hover) {
2040
+ color: var(--foreground);
2041
+ }
2042
+ }
2043
+ }
1940
2044
  .hover\:no-underline {
1941
2045
  &:hover {
1942
2046
  @media (hover: hover) {
@@ -2076,6 +2180,25 @@
2076
2180
  opacity: 50%;
2077
2181
  }
2078
2182
  }
2183
+ .has-focus\:border-ring {
2184
+ &:has(*:focus) {
2185
+ border-color: var(--ring);
2186
+ }
2187
+ }
2188
+ .has-focus\:ring-\[3px\] {
2189
+ &:has(*:focus) {
2190
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
2191
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2192
+ }
2193
+ }
2194
+ .has-focus\:ring-ring\/50 {
2195
+ &:has(*:focus) {
2196
+ --tw-ring-color: var(--ring);
2197
+ @supports (color: color-mix(in lab, red, red)) {
2198
+ --tw-ring-color: color-mix(in oklab, var(--ring) 50%, transparent);
2199
+ }
2200
+ }
2201
+ }
2079
2202
  .has-data-\[state\=checked\]\:border-primary {
2080
2203
  &:has(*[data-state="checked"]) {
2081
2204
  border-color: var(--primary);
@@ -2145,6 +2268,11 @@
2145
2268
  padding-inline: calc(var(--spacing) * 4);
2146
2269
  }
2147
2270
  }
2271
+ .aria-disabled\:opacity-50 {
2272
+ &[aria-disabled="true"] {
2273
+ opacity: 50%;
2274
+ }
2275
+ }
2148
2276
  .aria-invalid\:border-destructive {
2149
2277
  &[aria-invalid="true"] {
2150
2278
  border-color: var(--destructive);
@@ -2158,6 +2286,11 @@
2158
2286
  }
2159
2287
  }
2160
2288
  }
2289
+ .aria-selected\:text-muted-foreground {
2290
+ &[aria-selected="true"] {
2291
+ color: var(--muted-foreground);
2292
+ }
2293
+ }
2161
2294
  .aria-\[orientation\=horizontal\]\:h-px {
2162
2295
  &[aria-orientation="horizontal"] {
2163
2296
  height: 1px;
@@ -2230,6 +2363,11 @@
2230
2363
  opacity: 50%;
2231
2364
  }
2232
2365
  }
2366
+ .data-\[empty\=true\]\:text-muted-foreground {
2367
+ &[data-empty="true"] {
2368
+ color: var(--muted-foreground);
2369
+ }
2370
+ }
2233
2371
  .data-\[invalid\=true\]\:text-destructive {
2234
2372
  &[data-invalid="true"] {
2235
2373
  color: var(--destructive);
@@ -2260,6 +2398,66 @@
2260
2398
  color: var(--muted-foreground);
2261
2399
  }
2262
2400
  }
2401
+ .data-\[range-end\=true\]\:rounded-md {
2402
+ &[data-range-end="true"] {
2403
+ border-radius: calc(var(--radius) - 2px);
2404
+ }
2405
+ }
2406
+ .data-\[range-end\=true\]\:bg-primary {
2407
+ &[data-range-end="true"] {
2408
+ background-color: var(--primary);
2409
+ }
2410
+ }
2411
+ .data-\[range-end\=true\]\:text-primary-foreground {
2412
+ &[data-range-end="true"] {
2413
+ color: var(--primary-foreground);
2414
+ }
2415
+ }
2416
+ .data-\[range-middle\=true\]\:rounded-none {
2417
+ &[data-range-middle="true"] {
2418
+ border-radius: 0;
2419
+ }
2420
+ }
2421
+ .data-\[range-middle\=true\]\:bg-accent {
2422
+ &[data-range-middle="true"] {
2423
+ background-color: var(--accent);
2424
+ }
2425
+ }
2426
+ .data-\[range-middle\=true\]\:text-accent-foreground {
2427
+ &[data-range-middle="true"] {
2428
+ color: var(--accent-foreground);
2429
+ }
2430
+ }
2431
+ .data-\[range-start\=true\]\:rounded-md {
2432
+ &[data-range-start="true"] {
2433
+ border-radius: calc(var(--radius) - 2px);
2434
+ }
2435
+ }
2436
+ .data-\[range-start\=true\]\:bg-primary {
2437
+ &[data-range-start="true"] {
2438
+ background-color: var(--primary);
2439
+ }
2440
+ }
2441
+ .data-\[range-start\=true\]\:text-primary-foreground {
2442
+ &[data-range-start="true"] {
2443
+ color: var(--primary-foreground);
2444
+ }
2445
+ }
2446
+ .data-\[selected-single\=true\]\:bg-primary {
2447
+ &[data-selected-single="true"] {
2448
+ background-color: var(--primary);
2449
+ }
2450
+ }
2451
+ .data-\[selected-single\=true\]\:text-primary-foreground {
2452
+ &[data-selected-single="true"] {
2453
+ color: var(--primary-foreground);
2454
+ }
2455
+ }
2456
+ .data-\[selected\=true\]\:rounded-none {
2457
+ &[data-selected="true"] {
2458
+ border-radius: 0;
2459
+ }
2460
+ }
2263
2461
  .data-\[side\=bottom\]\:translate-y-1 {
2264
2462
  &[data-side="bottom"] {
2265
2463
  --tw-translate-y: calc(var(--spacing) * 1);
@@ -2605,6 +2803,11 @@
2605
2803
  }
2606
2804
  }
2607
2805
  }
2806
+ .md\:flex-row {
2807
+ @media (width >= 48rem) {
2808
+ flex-direction: row;
2809
+ }
2810
+ }
2608
2811
  .md\:gap-1\.5 {
2609
2812
  @media (width >= 48rem) {
2610
2813
  gap: calc(var(--spacing) * 1.5);
@@ -2833,6 +3036,30 @@
2833
3036
  display: none;
2834
3037
  }
2835
3038
  }
3039
+ .\[\&\:first-child\[data-selected\=true\]_button\]\:rounded-l-md {
3040
+ &:first-child[data-selected=true] button {
3041
+ border-top-left-radius: calc(var(--radius) - 2px);
3042
+ border-bottom-left-radius: calc(var(--radius) - 2px);
3043
+ }
3044
+ }
3045
+ .rtl\:\*\*\:\[\.rdp-button\\_next\>svg\]\:rotate-180 {
3046
+ &:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
3047
+ :is(& *) {
3048
+ &:is(.rdp-button_next>svg) {
3049
+ rotate: 180deg;
3050
+ }
3051
+ }
3052
+ }
3053
+ }
3054
+ .rtl\:\*\*\:\[\.rdp-button\\_previous\>svg\]\:rotate-180 {
3055
+ &:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
3056
+ :is(& *) {
3057
+ &:is(.rdp-button_previous>svg) {
3058
+ rotate: 180deg;
3059
+ }
3060
+ }
3061
+ }
3062
+ }
2836
3063
  .\*\:\[span\]\:last\:flex {
2837
3064
  :is(& > *) {
2838
3065
  &:is(span) {
@@ -2860,6 +3087,12 @@
2860
3087
  }
2861
3088
  }
2862
3089
  }
3090
+ .\[\&\:last-child\[data-selected\=true\]_button\]\:rounded-r-md {
3091
+ &:last-child[data-selected=true] button {
3092
+ border-top-right-radius: calc(var(--radius) - 2px);
3093
+ border-bottom-right-radius: calc(var(--radius) - 2px);
3094
+ }
3095
+ }
2863
3096
  .\[\&\>\*\]\:w-full {
2864
3097
  &>* {
2865
3098
  width: 100%;
@@ -2932,6 +3165,17 @@
2932
3165
  color: var(--primary);
2933
3166
  }
2934
3167
  }
3168
+ .\[\&\>span\]\:text-xs {
3169
+ &>span {
3170
+ font-size: var(--text-xs);
3171
+ line-height: var(--tw-leading, var(--text-xs--line-height));
3172
+ }
3173
+ }
3174
+ .\[\&\>span\]\:opacity-70 {
3175
+ &>span {
3176
+ opacity: 70%;
3177
+ }
3178
+ }
2935
3179
  .\[\&\>svg\]\:pointer-events-none {
2936
3180
  &>svg {
2937
3181
  pointer-events: none;
@@ -2943,6 +3187,17 @@
2943
3187
  height: calc(var(--spacing) * 3);
2944
3188
  }
2945
3189
  }
3190
+ .\[\&\>svg\]\:size-3\.5 {
3191
+ &>svg {
3192
+ width: calc(var(--spacing) * 3.5);
3193
+ height: calc(var(--spacing) * 3.5);
3194
+ }
3195
+ }
3196
+ .\[\&\>svg\]\:text-muted-foreground {
3197
+ &>svg {
3198
+ color: var(--muted-foreground);
3199
+ }
3200
+ }
2946
3201
  .\[\&\[aria-orientation\=horizontal\]\>div\]\:rotate-90 {
2947
3202
  &[aria-orientation=horizontal]>div {
2948
3203
  rotate: 90deg;
@@ -2953,6 +3208,16 @@
2953
3208
  rotate: 180deg;
2954
3209
  }
2955
3210
  }
3211
+ .\[\[data-slot\=card-content\]_\&\]\:bg-transparent {
3212
+ [data-slot=card-content] & {
3213
+ background-color: transparent;
3214
+ }
3215
+ }
3216
+ .\[\[data-slot\=popover-content\]_\&\]\:bg-transparent {
3217
+ [data-slot=popover-content] & {
3218
+ background-color: transparent;
3219
+ }
3220
+ }
2956
3221
  .\[\[data-variant\=legend\]\+\&\]\:-mt-1\.5 {
2957
3222
  [data-variant=legend]+& {
2958
3223
  margin-top: calc(var(--spacing) * -1.5);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbpark/ui-kit",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "description": "Modern React UI component library built with TypeScript, Tailwind CSS, and Radix UI. Featuring atoms, molecules, organisms and layout templates for building beautiful interfaces.",
5
5
  "keywords": [
6
6
  "react",
@@ -126,7 +126,7 @@
126
126
  },
127
127
  "dependencies": {
128
128
  "@gsap/react": "^2.1.2",
129
- "@jbpark/use-hooks": "^2.1.0",
129
+ "@jbpark/use-hooks": "^2.6.0",
130
130
  "@radix-ui/react-accordion": "^1.2.12",
131
131
  "@radix-ui/react-checkbox": "^1.3.3",
132
132
  "@radix-ui/react-dialog": "^1.1.15",
@@ -135,15 +135,16 @@
135
135
  "@radix-ui/react-progress": "^1.1.7",
136
136
  "@radix-ui/react-slot": "^1.2.3",
137
137
  "@radix-ui/react-switch": "^1.2.6",
138
- "@uidotdev/usehooks": "^2.4.1",
139
138
  "class-variance-authority": "^0.7.1",
140
139
  "clsx": "^2.1.1",
140
+ "date-fns": "^4.4.0",
141
141
  "gsap": "^3.15.0",
142
142
  "lucide-react": "^0.542.0",
143
143
  "motion": "^12.23.12",
144
144
  "postcss": "^8.4.31",
145
145
  "radix-ui": "^1.4.3",
146
146
  "react-colorful": "^5.6.1",
147
+ "react-day-picker": "^10.0.1",
147
148
  "react-resizable-panels": "^4.10.0",
148
149
  "react-use": "^17.6.0",
149
150
  "swiper": "^11.2.10",