@pylerai/design-system 1.2.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -316
- package/dist/components/ui/badge.d.ts +2 -1
- package/dist/components/ui/badge.js +49 -0
- package/dist/components/ui/body.js +52 -0
- package/dist/components/ui/button.d.ts +2 -1
- package/dist/components/ui/button.js +172 -0
- package/dist/components/ui/calendar.js +275 -0
- package/dist/components/ui/checkbox.d.ts +7 -0
- package/dist/components/ui/checkbox.js +45 -0
- package/dist/components/ui/chip.d.ts +4 -3
- package/dist/components/ui/chip.js +66 -0
- package/dist/components/ui/dropdown.d.ts +8 -2
- package/dist/components/ui/dropdown.js +256 -0
- package/dist/components/ui/headline.js +50 -0
- package/dist/components/ui/input.d.ts +3 -2
- package/dist/components/ui/input.js +129 -0
- package/dist/components/ui/label.js +43 -0
- package/dist/components/ui/loading-bar.d.ts +2 -1
- package/dist/components/ui/loading-bar.js +64 -0
- package/dist/components/ui/modal.d.ts +3 -2
- package/dist/components/ui/modal.js +170 -0
- package/dist/components/ui/pagination.d.ts +2 -0
- package/dist/components/ui/pagination.js +106 -0
- package/dist/components/ui/radio.d.ts +7 -0
- package/dist/components/ui/radio.js +42 -0
- package/dist/components/ui/search-field.d.ts +3 -2
- package/dist/components/ui/search-field.js +98 -0
- package/dist/components/ui/table.js +206 -0
- package/dist/components/ui/tabs.js +149 -0
- package/dist/components/ui/tag.d.ts +2 -1
- package/dist/components/ui/tag.js +31 -0
- package/dist/components/ui/tips.d.ts +2 -1
- package/dist/components/ui/tips.js +25 -0
- package/dist/components/ui/toast.js +70 -0
- package/dist/components/ui/toggle.d.ts +1 -2
- package/dist/components/ui/toggle.js +41 -0
- package/dist/components/ui/use-modal.js +94 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +75 -5769
- package/dist/lib/icons.js +225 -0
- package/dist/lib/size.d.ts +8 -0
- package/dist/lib/use-dialog-a11y.d.ts +2 -0
- package/dist/lib/use-dialog-a11y.js +50 -0
- package/dist/lib/utils.js +16 -0
- package/dist/style.css +1 -1
- package/dist/tokens/pyler-light.js +134 -0
- package/dist/tokens/typography.js +84 -0
- package/package.json +14 -1
- package/pyler-tailwind-colors.cjs +4 -0
- package/dist/index.css.d.ts +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as y } from "react/jsx-runtime";
|
|
3
|
+
import { cn as b } from "../../lib/utils.js";
|
|
4
|
+
import { Slot as n } from "@radix-ui/react-slot";
|
|
5
|
+
import { cva as s } from "class-variance-authority";
|
|
6
|
+
import * as i from "react";
|
|
7
|
+
const p = s(
|
|
8
|
+
"text-foreground leading-normal",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
"body-1-m": "text-body-1-m",
|
|
13
|
+
"body-1-r": "text-body-1-r",
|
|
14
|
+
"body-2-sb": "text-body-2-sb",
|
|
15
|
+
"body-2-m": "text-body-2-m",
|
|
16
|
+
"body-2-r": "text-body-2-r",
|
|
17
|
+
"body-3-m": "text-body-3-m",
|
|
18
|
+
"body-3-r": "text-body-3-r",
|
|
19
|
+
"body-4-m": "text-body-4-m",
|
|
20
|
+
"body-4-r": "text-body-4-r"
|
|
21
|
+
},
|
|
22
|
+
as: {
|
|
23
|
+
p: "",
|
|
24
|
+
div: "",
|
|
25
|
+
span: "",
|
|
26
|
+
article: "",
|
|
27
|
+
section: ""
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
variant: "body-1-m",
|
|
32
|
+
as: "p"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
), x = i.forwardRef(
|
|
36
|
+
({ className: t, variant: r, as: d, asChild: a, ...e }, m) => {
|
|
37
|
+
const o = d || "p";
|
|
38
|
+
return /* @__PURE__ */ y(
|
|
39
|
+
a ? n : o,
|
|
40
|
+
{
|
|
41
|
+
className: b(p({ variant: r, as: o, className: t })),
|
|
42
|
+
ref: m,
|
|
43
|
+
...e
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
x.displayName = "Body";
|
|
49
|
+
export {
|
|
50
|
+
x as Body,
|
|
51
|
+
p as bodyVariants
|
|
52
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DsSize } from '../../lib/size';
|
|
1
2
|
import { VariantProps } from 'class-variance-authority';
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
declare const buttonVariants: (props?: ({
|
|
@@ -19,7 +20,7 @@ export interface ButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonE
|
|
|
19
20
|
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
20
21
|
export interface ButtonIndicatorProps {
|
|
21
22
|
color?: "blue" | "red" | "green";
|
|
22
|
-
size?: "sm" | "md" | "lg" | "xl"
|
|
23
|
+
size?: Extract<DsSize, "sm" | "md" | "lg" | "xl">;
|
|
23
24
|
className?: string;
|
|
24
25
|
}
|
|
25
26
|
declare const ButtonIndicator: React.ForwardRefExoticComponent<ButtonIndicatorProps & React.RefAttributes<HTMLSpanElement>>;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as a, jsxs as O, Fragment as k } from "react/jsx-runtime";
|
|
3
|
+
import { cn as m } from "../../lib/utils.js";
|
|
4
|
+
import { Slot as B } from "@radix-ui/react-slot";
|
|
5
|
+
import { cva as R } from "class-variance-authority";
|
|
6
|
+
import * as g from "react";
|
|
7
|
+
const v = R(
|
|
8
|
+
"inline-flex items-center justify-center whitespace-nowrap font-sans transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none select-none",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
filled: "rounded-lg",
|
|
13
|
+
outlined: "rounded-lg border border-ds-line-normal bg-ds-background-default text-ds-text-strong hover:bg-ds-surface-normal active:bg-ds-surface-strong disabled:bg-ds-surface-normal disabled:text-ds-text-disabled",
|
|
14
|
+
text: "rounded-lg bg-transparent text-ds-text-strong disabled:text-ds-text-disabled",
|
|
15
|
+
icon: "rounded-lg",
|
|
16
|
+
indicator: "rounded-full inline-block"
|
|
17
|
+
},
|
|
18
|
+
color: {
|
|
19
|
+
blue: "",
|
|
20
|
+
red: "",
|
|
21
|
+
green: ""
|
|
22
|
+
},
|
|
23
|
+
size: {
|
|
24
|
+
sm: "h-7 gap-1",
|
|
25
|
+
md: "h-8 gap-1.5",
|
|
26
|
+
lg: "h-9 gap-1.5",
|
|
27
|
+
xl: "h-11 gap-2"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
compoundVariants: [
|
|
31
|
+
// ── filled × color ──────────────────────────────────────────────────
|
|
32
|
+
{
|
|
33
|
+
variant: "filled",
|
|
34
|
+
color: "blue",
|
|
35
|
+
className: "bg-ds-primary-blue-normal text-white hover:bg-ds-primary-blue-hovered active:bg-ds-primary-blue-hovered disabled:bg-ds-primary-blue-disabled disabled:text-white focus-visible:ring-ds-primary-blue-normal"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
variant: "filled",
|
|
39
|
+
color: "red",
|
|
40
|
+
className: "bg-ds-primary-red-normal text-white hover:bg-ds-primary-red-hovered active:bg-ds-primary-red-hovered disabled:bg-ds-primary-red-disabled disabled:text-white focus-visible:ring-ds-primary-red-normal"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
variant: "filled",
|
|
44
|
+
color: "green",
|
|
45
|
+
className: "bg-ds-primary-green-normal text-white hover:bg-ds-primary-green-hovered active:bg-ds-primary-green-hovered disabled:bg-ds-primary-green-disabled disabled:text-white focus-visible:ring-ds-primary-green-normal"
|
|
46
|
+
},
|
|
47
|
+
// ── icon filled × color ───────────────────────────────────────────────
|
|
48
|
+
{
|
|
49
|
+
variant: "icon",
|
|
50
|
+
color: "blue",
|
|
51
|
+
className: "bg-ds-primary-blue-normal text-white hover:bg-ds-primary-blue-hovered active:bg-ds-primary-blue-hovered disabled:bg-ds-primary-blue-disabled disabled:text-white focus-visible:ring-ds-primary-blue-normal"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
variant: "icon",
|
|
55
|
+
color: "red",
|
|
56
|
+
className: "bg-ds-primary-red-normal text-white hover:bg-ds-primary-red-hovered active:bg-ds-primary-red-hovered disabled:bg-ds-primary-red-disabled disabled:text-white focus-visible:ring-ds-primary-red-normal"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
variant: "icon",
|
|
60
|
+
color: "green",
|
|
61
|
+
className: "bg-ds-primary-green-normal text-white hover:bg-ds-primary-green-hovered active:bg-ds-primary-green-hovered disabled:bg-ds-primary-green-disabled disabled:text-white focus-visible:ring-ds-primary-green-normal"
|
|
62
|
+
},
|
|
63
|
+
// ── icon × size (fixed square dimensions + SVG sizing) ──────────────
|
|
64
|
+
{ variant: "icon", size: "sm", className: "h-7 w-7 p-0 rounded [&_svg]:size-3" },
|
|
65
|
+
{ variant: "icon", size: "md", className: "h-8 w-8 p-0 [&_svg]:size-5" },
|
|
66
|
+
{ variant: "icon", size: "lg", className: "h-9 w-9 p-0 [&_svg]:size-5" },
|
|
67
|
+
{ variant: "icon", size: "xl", className: "h-11 w-11 p-0 [&_svg]:size-7" },
|
|
68
|
+
// ── filled/outlined/text size → padding + typography ─────────────────
|
|
69
|
+
{ variant: "filled", size: "sm", className: "px-2 text-body-4-m rounded" },
|
|
70
|
+
{ variant: "filled", size: "md", className: "px-3 text-body-3-m" },
|
|
71
|
+
{ variant: "filled", size: "lg", className: "px-3.5 text-body-2-m" },
|
|
72
|
+
{ variant: "filled", size: "xl", className: "px-[18px] text-body-2-m" },
|
|
73
|
+
{ variant: "outlined", size: "sm", className: "px-2 text-body-4-m rounded" },
|
|
74
|
+
{ variant: "outlined", size: "md", className: "px-3 text-body-3-m" },
|
|
75
|
+
{ variant: "outlined", size: "lg", className: "px-3.5 text-body-2-m" },
|
|
76
|
+
{ variant: "outlined", size: "xl", className: "px-[18px] text-body-2-m" },
|
|
77
|
+
{ variant: "text", size: "sm", className: "text-body-4-m" },
|
|
78
|
+
{ variant: "text", size: "md", className: "text-body-3-m" },
|
|
79
|
+
{ variant: "text", size: "lg", className: "text-body-2-m" },
|
|
80
|
+
// text xl → lg 사이즈 폴백 (Figma에 xl 없음)
|
|
81
|
+
{ variant: "text", size: "xl", className: "text-body-2-m h-9" },
|
|
82
|
+
// ── indicator × size (dot dimensions) ────────────────────────────────
|
|
83
|
+
{ variant: "indicator", size: "sm", className: "h-2 w-2" },
|
|
84
|
+
{ variant: "indicator", size: "md", className: "h-2.5 w-2.5" },
|
|
85
|
+
{ variant: "indicator", size: "lg", className: "h-3 w-3" },
|
|
86
|
+
{ variant: "indicator", size: "xl", className: "h-3.5 w-3.5" },
|
|
87
|
+
// ── indicator × color ─────────────────────────────────────────────────
|
|
88
|
+
{
|
|
89
|
+
variant: "indicator",
|
|
90
|
+
color: "blue",
|
|
91
|
+
className: "bg-ds-primary-blue-normal"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
variant: "indicator",
|
|
95
|
+
color: "red",
|
|
96
|
+
className: "bg-ds-primary-red-normal"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
variant: "indicator",
|
|
100
|
+
color: "green",
|
|
101
|
+
className: "bg-ds-primary-green-normal"
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
defaultVariants: {
|
|
105
|
+
variant: "filled",
|
|
106
|
+
color: "blue",
|
|
107
|
+
size: "md"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
), _ = g.forwardRef(
|
|
111
|
+
({
|
|
112
|
+
className: s,
|
|
113
|
+
variant: e,
|
|
114
|
+
color: i,
|
|
115
|
+
size: r,
|
|
116
|
+
asChild: c = !1,
|
|
117
|
+
shape: u = "square",
|
|
118
|
+
iconStyle: x = "filled",
|
|
119
|
+
leftIcon: t,
|
|
120
|
+
rightIcon: d,
|
|
121
|
+
children: b,
|
|
122
|
+
...h
|
|
123
|
+
}, y) => {
|
|
124
|
+
const f = c ? B : "button", N = e === "icon" && x === "outlined" ? "bg-ds-background-default border border-ds-line-normal text-ds-text-strong hover:bg-ds-surface-normal active:bg-ds-surface-strong disabled:text-ds-text-disabled" : void 0, l = !!t, p = !!d, z = e !== "icon" && e !== "indicator" && (l || p) ? (() => {
|
|
125
|
+
const n = r ?? "md", o = {
|
|
126
|
+
sm: { leftOnly: "pl-1 pr-2", rightOnly: "pl-2 pr-1", both: "px-1" },
|
|
127
|
+
md: { leftOnly: "pl-2 pr-3", rightOnly: "pl-3 pr-2", both: "px-2" },
|
|
128
|
+
lg: { leftOnly: "pl-2.5 pr-3.5", rightOnly: "pl-3.5 pr-2.5", both: "px-2.5" },
|
|
129
|
+
xl: { leftOnly: "pl-3.5 pr-[18px]", rightOnly: "pl-[18px] pr-3.5", both: "px-3.5" }
|
|
130
|
+
}, w = l && p ? o[n].both : l ? o[n].leftOnly : o[n].rightOnly;
|
|
131
|
+
return m(w, "gap-1");
|
|
132
|
+
})() : void 0;
|
|
133
|
+
return /* @__PURE__ */ a(
|
|
134
|
+
f,
|
|
135
|
+
{
|
|
136
|
+
className: m(
|
|
137
|
+
v({ variant: e, color: i, size: r }),
|
|
138
|
+
e === "icon" && u === "round" && "rounded-full",
|
|
139
|
+
N,
|
|
140
|
+
z,
|
|
141
|
+
s
|
|
142
|
+
),
|
|
143
|
+
ref: y,
|
|
144
|
+
...h,
|
|
145
|
+
children: c ? b : /* @__PURE__ */ O(k, { children: [
|
|
146
|
+
t && /* @__PURE__ */ a("span", { className: "shrink-0", children: t }),
|
|
147
|
+
b,
|
|
148
|
+
d && /* @__PURE__ */ a("span", { className: "shrink-0", children: d })
|
|
149
|
+
] })
|
|
150
|
+
}
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
);
|
|
154
|
+
_.displayName = "Button";
|
|
155
|
+
const j = g.forwardRef(
|
|
156
|
+
({ color: s = "blue", size: e = "md", className: i }, r) => /* @__PURE__ */ a(
|
|
157
|
+
"span",
|
|
158
|
+
{
|
|
159
|
+
className: m(
|
|
160
|
+
v({ variant: "indicator", color: s, size: e }),
|
|
161
|
+
i
|
|
162
|
+
),
|
|
163
|
+
ref: r
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
);
|
|
167
|
+
j.displayName = "ButtonIndicator";
|
|
168
|
+
export {
|
|
169
|
+
_ as Button,
|
|
170
|
+
j as ButtonIndicator,
|
|
171
|
+
v as buttonVariants
|
|
172
|
+
};
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as N, jsx as l } from "react/jsx-runtime";
|
|
3
|
+
import { useState as k, useCallback as S } from "react";
|
|
4
|
+
import i from "dayjs";
|
|
5
|
+
import { cn as z } from "../../lib/utils.js";
|
|
6
|
+
import { CloseIcon as Q, ArrowLeftIcon as $, ArrowRightIcon as C } from "../../lib/icons.js";
|
|
7
|
+
import { Radio as H } from "./radio.js";
|
|
8
|
+
import { Button as B } from "./button.js";
|
|
9
|
+
const F = ["일", "월", "화", "수", "목", "금", "토"], K = [
|
|
10
|
+
{ label: "오늘", getDays: () => ({ from: i(), to: i() }) },
|
|
11
|
+
{ label: "어제", getDays: () => ({ from: i().subtract(1, "day"), to: i().subtract(1, "day") }) },
|
|
12
|
+
{ label: "최근 7일", getDays: () => ({ from: i().subtract(6, "day"), to: i() }) },
|
|
13
|
+
{ label: "최근 14일", getDays: () => ({ from: i().subtract(13, "day"), to: i() }) },
|
|
14
|
+
{ label: "최근 31일", getDays: () => ({ from: i().subtract(30, "day"), to: i() }) }
|
|
15
|
+
];
|
|
16
|
+
function P(u, e) {
|
|
17
|
+
const d = i(new Date(u, e, 1)), m = d.daysInMonth(), b = d.day(), o = Array(b).fill(null);
|
|
18
|
+
for (let t = 1; t <= m; t++)
|
|
19
|
+
o.push(i(new Date(u, e, t)));
|
|
20
|
+
for (; o.length % 7 !== 0; ) o.push(null);
|
|
21
|
+
const c = [];
|
|
22
|
+
for (let t = 0; t < o.length; t += 7)
|
|
23
|
+
c.push(o.slice(t, t + 7));
|
|
24
|
+
return c;
|
|
25
|
+
}
|
|
26
|
+
function q(u, e, d, m, b, o) {
|
|
27
|
+
var a, h;
|
|
28
|
+
const c = i().startOf("day"), t = u.startOf("day");
|
|
29
|
+
if (m && t.isBefore(m.startOf("day")) || b && t.isAfter(b.startOf("day"))) return "disabled";
|
|
30
|
+
const s = ((a = e.from) == null ? void 0 : a.startOf("day")) ?? null;
|
|
31
|
+
let n = ((h = e.to) == null ? void 0 : h.startOf("day")) ?? (d == null ? void 0 : d.startOf("day")) ?? null;
|
|
32
|
+
if (s && n && o) {
|
|
33
|
+
const f = n.diff(s, "day");
|
|
34
|
+
f > 0 && f >= o ? n = s.add(o - 1, "day") : f < 0 && Math.abs(f) >= o && (n = s.subtract(o - 1, "day"));
|
|
35
|
+
}
|
|
36
|
+
const y = s && n ? s.isBefore(n) ? s : n : s, x = s && n ? s.isBefore(n) ? n : s : null;
|
|
37
|
+
return y && t.isSame(y) ? x && !t.isSame(x) ? "range-start" : "selected" : x && t.isSame(x) ? y && !t.isSame(y) ? "range-end" : "selected" : y && x && t.isAfter(y) && t.isBefore(x) ? "range-middle" : t.isSame(c) ? "today" : "default";
|
|
38
|
+
}
|
|
39
|
+
function G({ day: u, state: e, dayOfWeek: d, onClick: m, onMouseEnter: b }) {
|
|
40
|
+
const o = e === "disabled", c = e === "selected" || e === "range-start" || e === "range-end", t = e === "range-middle", s = e === "range-start", w = e === "range-end", n = e === "today", y = o ? "text-ds-text-disabled" : c ? "text-white" : d === 0 ? "text-ds-primary-red-normal" : d === 6 ? "text-ds-primary-blue-normal" : "text-ds-text-strong";
|
|
41
|
+
return /* @__PURE__ */ l(
|
|
42
|
+
"div",
|
|
43
|
+
{
|
|
44
|
+
className: z(
|
|
45
|
+
"relative flex size-7 shrink-0 flex-col items-center justify-center p-0.5",
|
|
46
|
+
t && "border-y-2 border-ds-primary-blue-normal",
|
|
47
|
+
s && "border-y-2 border-l-2 border-ds-primary-blue-normal rounded-l-full",
|
|
48
|
+
w && "border-y-2 border-r-2 border-ds-primary-blue-normal rounded-r-full"
|
|
49
|
+
),
|
|
50
|
+
onMouseEnter: b,
|
|
51
|
+
children: /* @__PURE__ */ l(
|
|
52
|
+
"button",
|
|
53
|
+
{
|
|
54
|
+
type: "button",
|
|
55
|
+
"aria-label": u.format("YYYY년 M월 D일"),
|
|
56
|
+
disabled: o,
|
|
57
|
+
onClick: m,
|
|
58
|
+
className: z(
|
|
59
|
+
"relative flex size-6 items-center justify-center rounded-full text-body-4-m transition-colors",
|
|
60
|
+
!o && "cursor-pointer",
|
|
61
|
+
c && "bg-ds-primary-blue-normal",
|
|
62
|
+
n && !c && "bg-ds-surface-strong",
|
|
63
|
+
!o && !c && !n && "hover:bg-ds-surface-strong",
|
|
64
|
+
y
|
|
65
|
+
),
|
|
66
|
+
children: u.date()
|
|
67
|
+
}
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
function O({
|
|
73
|
+
year: u,
|
|
74
|
+
month: e,
|
|
75
|
+
range: d,
|
|
76
|
+
hovered: m,
|
|
77
|
+
onDayClick: b,
|
|
78
|
+
onDayHover: o,
|
|
79
|
+
disabledBefore: c,
|
|
80
|
+
disabledAfter: t,
|
|
81
|
+
maxDays: s,
|
|
82
|
+
showPrevArrow: w,
|
|
83
|
+
showNextArrow: n,
|
|
84
|
+
onPrev: y,
|
|
85
|
+
onNext: x
|
|
86
|
+
}) {
|
|
87
|
+
const a = P(u, e);
|
|
88
|
+
return /* @__PURE__ */ N("div", { className: "flex flex-col gap-3", children: [
|
|
89
|
+
/* @__PURE__ */ N("div", { className: "flex items-center gap-1", children: [
|
|
90
|
+
w ? /* @__PURE__ */ l(
|
|
91
|
+
"button",
|
|
92
|
+
{
|
|
93
|
+
type: "button",
|
|
94
|
+
"aria-label": "이전 달",
|
|
95
|
+
onClick: y,
|
|
96
|
+
className: "flex size-5 items-center justify-center text-ds-text-strong hover:text-ds-primary-blue-normal",
|
|
97
|
+
children: /* @__PURE__ */ l($, { className: "size-5" })
|
|
98
|
+
}
|
|
99
|
+
) : /* @__PURE__ */ l("div", { className: "size-5" }),
|
|
100
|
+
/* @__PURE__ */ N("p", { className: "flex-1 text-center text-body-3-r text-ds-text-strong", children: [
|
|
101
|
+
u,
|
|
102
|
+
"년 ",
|
|
103
|
+
e + 1,
|
|
104
|
+
"월"
|
|
105
|
+
] }),
|
|
106
|
+
n ? /* @__PURE__ */ l(
|
|
107
|
+
"button",
|
|
108
|
+
{
|
|
109
|
+
type: "button",
|
|
110
|
+
"aria-label": "다음 달",
|
|
111
|
+
onClick: x,
|
|
112
|
+
className: "flex size-5 items-center justify-center text-ds-text-strong hover:text-ds-primary-blue-normal",
|
|
113
|
+
children: /* @__PURE__ */ l(C, { className: "size-5" })
|
|
114
|
+
}
|
|
115
|
+
) : /* @__PURE__ */ l("div", { className: "size-5" })
|
|
116
|
+
] }),
|
|
117
|
+
/* @__PURE__ */ N("div", { className: "grid grid-cols-7", children: [
|
|
118
|
+
F.map((h, f) => /* @__PURE__ */ l("div", { className: "flex size-7 items-center justify-center", children: /* @__PURE__ */ l(
|
|
119
|
+
"span",
|
|
120
|
+
{
|
|
121
|
+
className: z(
|
|
122
|
+
"text-body-4-r",
|
|
123
|
+
f === 0 ? "text-ds-primary-red-normal" : f === 6 ? "text-ds-primary-blue-normal" : "text-ds-text-strong"
|
|
124
|
+
),
|
|
125
|
+
children: h
|
|
126
|
+
}
|
|
127
|
+
) }, h)),
|
|
128
|
+
a.map(
|
|
129
|
+
(h, f) => h.map(
|
|
130
|
+
(g, v) => g ? /* @__PURE__ */ l(
|
|
131
|
+
G,
|
|
132
|
+
{
|
|
133
|
+
day: g,
|
|
134
|
+
dayOfWeek: v,
|
|
135
|
+
state: q(g, d, m, c, t, s),
|
|
136
|
+
onClick: () => b(g),
|
|
137
|
+
onMouseEnter: () => o(g)
|
|
138
|
+
},
|
|
139
|
+
`${f}-${v}`
|
|
140
|
+
) : /* @__PURE__ */ l("div", { className: "size-7" }, `${f}-${v}`)
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
] })
|
|
144
|
+
] });
|
|
145
|
+
}
|
|
146
|
+
function ee({
|
|
147
|
+
value: u,
|
|
148
|
+
onChange: e,
|
|
149
|
+
onClose: d,
|
|
150
|
+
onConfirm: m,
|
|
151
|
+
maxDays: b = 31,
|
|
152
|
+
disabledBefore: o,
|
|
153
|
+
disabledAfter: c = i(),
|
|
154
|
+
className: t
|
|
155
|
+
}) {
|
|
156
|
+
const s = i(), [w, n] = k({ year: s.year(), month: s.month() - 1 < 0 ? 11 : s.month() - 1 }), [y, x] = k({ year: s.year(), month: s.month() }), [a, h] = k(u ?? { from: null, to: null }), [f, g] = k(null), [v, D] = k(!1), [E, j] = k(null), R = S(
|
|
157
|
+
(r) => {
|
|
158
|
+
if (!v || a.from === null)
|
|
159
|
+
h({ from: r, to: null }), D(!0), j(null);
|
|
160
|
+
else {
|
|
161
|
+
const p = a.from, M = p.isBefore(r) ? { from: p, to: r } : { from: r, to: p };
|
|
162
|
+
h(M), D(!1), g(null), e == null || e(M);
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
[v, a.from, e]
|
|
166
|
+
), I = S(
|
|
167
|
+
(r, p) => {
|
|
168
|
+
const M = p();
|
|
169
|
+
h(M), D(!1), g(null), j(r), e == null || e(M);
|
|
170
|
+
},
|
|
171
|
+
[e]
|
|
172
|
+
), T = S(() => {
|
|
173
|
+
n((r) => {
|
|
174
|
+
const p = r.month === 0 ? { year: r.year - 1, month: 11 } : { year: r.year, month: r.month - 1 };
|
|
175
|
+
return x(r), p;
|
|
176
|
+
});
|
|
177
|
+
}, []), Y = S(() => {
|
|
178
|
+
x((r) => {
|
|
179
|
+
const p = r.month === 11 ? { year: r.year + 1, month: 0 } : { year: r.year, month: r.month + 1 };
|
|
180
|
+
return n(r), p;
|
|
181
|
+
});
|
|
182
|
+
}, []), L = S(() => {
|
|
183
|
+
a.from && a.to && (m == null || m({ from: a.from, to: a.to }));
|
|
184
|
+
}, [a, m]), A = o ?? s.subtract(1, "year");
|
|
185
|
+
return /* @__PURE__ */ N(
|
|
186
|
+
"div",
|
|
187
|
+
{
|
|
188
|
+
className: z(
|
|
189
|
+
"flex w-[612px] flex-col overflow-hidden rounded-ds-lg bg-ds-background-default shadow-ds-modal",
|
|
190
|
+
t
|
|
191
|
+
),
|
|
192
|
+
onMouseLeave: () => g(null),
|
|
193
|
+
children: [
|
|
194
|
+
/* @__PURE__ */ N("div", { className: "flex items-center justify-between px-5 pt-5 pb-3", children: [
|
|
195
|
+
/* @__PURE__ */ l("span", { className: "text-body-2-m text-ds-text-strong", children: "기간 설정" }),
|
|
196
|
+
/* @__PURE__ */ l(
|
|
197
|
+
"button",
|
|
198
|
+
{
|
|
199
|
+
type: "button",
|
|
200
|
+
"aria-label": "닫기",
|
|
201
|
+
onClick: d,
|
|
202
|
+
className: "text-ds-text-normal hover:text-ds-text-strong",
|
|
203
|
+
children: /* @__PURE__ */ l(Q, { className: "size-5" })
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
] }),
|
|
207
|
+
/* @__PURE__ */ l("div", { className: "mx-5 h-px bg-ds-line-normal" }),
|
|
208
|
+
/* @__PURE__ */ N("div", { className: "flex min-h-0 flex-1", children: [
|
|
209
|
+
/* @__PURE__ */ l("div", { className: "flex w-40 shrink-0 flex-col border-r border-b border-ds-line-normal px-5 pt-5 pb-5 gap-0.5", children: K.map(({ label: r, getDays: p }) => (
|
|
210
|
+
// Radio가 자체적으로 <label>을 렌더하므로 밖에서 또 감싸면 label이
|
|
211
|
+
// 중첩되어 연결이 깨진다. 텍스트는 children으로 넘긴다.
|
|
212
|
+
/* @__PURE__ */ l(
|
|
213
|
+
H,
|
|
214
|
+
{
|
|
215
|
+
name: "quick-select",
|
|
216
|
+
value: r,
|
|
217
|
+
checked: E === r,
|
|
218
|
+
onChange: () => I(r, p),
|
|
219
|
+
className: "h-8 w-full rounded-ds-ss px-1 text-body-3-r text-ds-text-strong hover:bg-ds-surface-normal",
|
|
220
|
+
children: r
|
|
221
|
+
},
|
|
222
|
+
r
|
|
223
|
+
)
|
|
224
|
+
)) }),
|
|
225
|
+
/* @__PURE__ */ N("div", { className: "flex flex-col flex-1 border-b border-ds-line-normal p-5 gap-3", children: [
|
|
226
|
+
/* @__PURE__ */ N("div", { className: "flex gap-5 justify-between", children: [
|
|
227
|
+
/* @__PURE__ */ l(
|
|
228
|
+
O,
|
|
229
|
+
{
|
|
230
|
+
...w,
|
|
231
|
+
range: a,
|
|
232
|
+
hovered: v ? f : null,
|
|
233
|
+
onDayClick: R,
|
|
234
|
+
onDayHover: g,
|
|
235
|
+
disabledBefore: A,
|
|
236
|
+
disabledAfter: c,
|
|
237
|
+
maxDays: b,
|
|
238
|
+
showPrevArrow: !0,
|
|
239
|
+
onPrev: T
|
|
240
|
+
}
|
|
241
|
+
),
|
|
242
|
+
/* @__PURE__ */ l(
|
|
243
|
+
O,
|
|
244
|
+
{
|
|
245
|
+
...y,
|
|
246
|
+
range: a,
|
|
247
|
+
hovered: v ? f : null,
|
|
248
|
+
onDayClick: R,
|
|
249
|
+
onDayHover: g,
|
|
250
|
+
disabledBefore: A,
|
|
251
|
+
disabledAfter: c,
|
|
252
|
+
maxDays: b,
|
|
253
|
+
showNextArrow: !0,
|
|
254
|
+
onNext: Y
|
|
255
|
+
}
|
|
256
|
+
)
|
|
257
|
+
] }),
|
|
258
|
+
/* @__PURE__ */ N("p", { className: "text-body-4-r text-ds-text-normal", children: [
|
|
259
|
+
"설정 가능한 최대 기간은 ",
|
|
260
|
+
b,
|
|
261
|
+
"일이고, 최대 1년 전까지만 설정 가능합니다."
|
|
262
|
+
] })
|
|
263
|
+
] })
|
|
264
|
+
] }),
|
|
265
|
+
/* @__PURE__ */ N("div", { className: "flex items-center justify-end gap-2 px-5 py-3", children: [
|
|
266
|
+
/* @__PURE__ */ l(B, { variant: "outlined", size: "lg", onClick: d, children: "취소" }),
|
|
267
|
+
/* @__PURE__ */ l(B, { variant: "filled", color: "blue", size: "lg", disabled: !a.from || !a.to, onClick: L, children: "적용" })
|
|
268
|
+
] })
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
export {
|
|
274
|
+
ee as Calendar
|
|
275
|
+
};
|
|
@@ -4,6 +4,13 @@ export interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputE
|
|
|
4
4
|
indeterminate?: boolean;
|
|
5
5
|
/** 체크 상태 변경 핸들러 */
|
|
6
6
|
onChange?: (checked: boolean) => void;
|
|
7
|
+
/**
|
|
8
|
+
* 체크박스 옆에 표시할 라벨 텍스트.
|
|
9
|
+
* 이 컴포넌트는 자체적으로 `<label>`을 렌더하므로, 밖에서 `<label>`로 감싸면
|
|
10
|
+
* label이 중첩되어 연결이 깨진다. 텍스트는 반드시 여기로 넘긴다.
|
|
11
|
+
* (텍스트 없이 쓸 때는 `aria-label`을 지정할 것)
|
|
12
|
+
*/
|
|
13
|
+
children?: React.ReactNode;
|
|
7
14
|
}
|
|
8
15
|
declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLInputElement>>;
|
|
9
16
|
export { Checkbox };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as x, jsx as e } from "react/jsx-runtime";
|
|
3
|
+
import { CheckboxIndeterminateDisabledIcon as h, CheckboxCheckedDisabledIcon as p, CheckboxUncheckedDisabledIcon as u, CheckboxIndeterminateIcon as b, CheckboxCheckedIcon as I, CheckboxUncheckedIcon as d } from "../../lib/icons.js";
|
|
4
|
+
import { cn as C } from "../../lib/utils.js";
|
|
5
|
+
import * as o from "react";
|
|
6
|
+
const N = o.forwardRef(
|
|
7
|
+
({ className: l, checked: n, indeterminate: c, disabled: s, onChange: t, children: i, ...a }, f) => {
|
|
8
|
+
const r = o.useRef(null);
|
|
9
|
+
o.useImperativeHandle(f, () => r.current, []), o.useEffect(() => {
|
|
10
|
+
r.current && (r.current.indeterminate = !!c);
|
|
11
|
+
}, [c]);
|
|
12
|
+
const k = s ? c ? /* @__PURE__ */ e(h, {}) : n ? /* @__PURE__ */ e(p, {}) : /* @__PURE__ */ e(u, {}) : c ? /* @__PURE__ */ e(b, {}) : n ? /* @__PURE__ */ e(I, {}) : /* @__PURE__ */ e(d, {});
|
|
13
|
+
return /* @__PURE__ */ x(
|
|
14
|
+
"label",
|
|
15
|
+
{
|
|
16
|
+
className: C(
|
|
17
|
+
"relative inline-flex items-center gap-1",
|
|
18
|
+
i ? "" : "shrink-0",
|
|
19
|
+
s ? "cursor-not-allowed" : "cursor-pointer",
|
|
20
|
+
l
|
|
21
|
+
),
|
|
22
|
+
children: [
|
|
23
|
+
/* @__PURE__ */ e(
|
|
24
|
+
"input",
|
|
25
|
+
{
|
|
26
|
+
type: "checkbox",
|
|
27
|
+
ref: r,
|
|
28
|
+
checked: n,
|
|
29
|
+
disabled: s,
|
|
30
|
+
onChange: (m) => t == null ? void 0 : t(m.target.checked),
|
|
31
|
+
className: "sr-only",
|
|
32
|
+
...a
|
|
33
|
+
}
|
|
34
|
+
),
|
|
35
|
+
/* @__PURE__ */ e("span", { className: "shrink-0 inline-flex", children: k }),
|
|
36
|
+
i
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
N.displayName = "Checkbox";
|
|
43
|
+
export {
|
|
44
|
+
N as Checkbox
|
|
45
|
+
};
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import { DsSize } from '../../lib/size';
|
|
1
2
|
import * as React from "react";
|
|
2
|
-
export type ChipSize = "
|
|
3
|
+
export type ChipSize = Extract<DsSize, "md" | "sm">;
|
|
3
4
|
export interface ChipProps {
|
|
4
|
-
/** 크기. 기본값: "
|
|
5
|
+
/** 크기. 기본값: "md" */
|
|
5
6
|
size?: ChipSize;
|
|
6
7
|
/** 선택 상태 */
|
|
7
8
|
selected?: boolean;
|
|
8
9
|
disabled?: boolean;
|
|
9
10
|
/** 제거 버튼 클릭 핸들러. 정의 시 제거 버튼 표시 */
|
|
10
11
|
onRemove?: () => void;
|
|
11
|
-
onClick?: React.MouseEventHandler<
|
|
12
|
+
onClick?: React.MouseEventHandler<HTMLElement>;
|
|
12
13
|
children?: React.ReactNode;
|
|
13
14
|
className?: string;
|
|
14
15
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as x, jsx as o } from "react/jsx-runtime";
|
|
3
|
+
import { XIcon as b } from "../../lib/icons.js";
|
|
4
|
+
import { cn as n } from "../../lib/utils.js";
|
|
5
|
+
import * as f from "react";
|
|
6
|
+
const h = f.forwardRef(
|
|
7
|
+
({ size: l = "md", selected: i = !1, disabled: e = !1, onRemove: a, onClick: r, children: p, className: d }, c) => {
|
|
8
|
+
const s = l === "md", t = !!a, u = r ? "button" : "span";
|
|
9
|
+
return /* @__PURE__ */ x(
|
|
10
|
+
"div",
|
|
11
|
+
{
|
|
12
|
+
ref: c,
|
|
13
|
+
className: n(
|
|
14
|
+
"inline-flex items-center border rounded-[4px] bg-ds-background-default select-none transition-colors",
|
|
15
|
+
// 좌우 여백은 컨테이너가 아니라 본문(클릭 대상)이 갖는다.
|
|
16
|
+
// 컨테이너에 두면 여백 영역이 클릭되지 않는 죽은 공간이 된다.
|
|
17
|
+
s ? t ? "h-8 pr-1" : "h-8" : t ? "h-[26px] pr-0.5" : "h-[26px]",
|
|
18
|
+
s ? "text-body-3-r" : "text-body-4-r",
|
|
19
|
+
e ? "border-ds-line-normal text-ds-text-disabled cursor-not-allowed" : i ? "border-ds-primary-blue-normal text-ds-text-strong cursor-pointer" : "border-ds-line-normal text-ds-text-strong cursor-pointer hover:border-ds-line-strong",
|
|
20
|
+
d
|
|
21
|
+
),
|
|
22
|
+
children: [
|
|
23
|
+
/* @__PURE__ */ o(
|
|
24
|
+
u,
|
|
25
|
+
{
|
|
26
|
+
...r ? {
|
|
27
|
+
type: "button",
|
|
28
|
+
disabled: e,
|
|
29
|
+
"aria-pressed": i,
|
|
30
|
+
onClick: r
|
|
31
|
+
} : {},
|
|
32
|
+
className: n(
|
|
33
|
+
"inline-flex h-full items-center whitespace-nowrap bg-transparent",
|
|
34
|
+
// 컨테이너에서 옮겨온 여백 — 칩 전체가 클릭 대상이 되도록 한다
|
|
35
|
+
s ? t ? "pl-2" : "px-2" : t ? "pl-1.5" : "px-1.5",
|
|
36
|
+
r && !e && "cursor-pointer",
|
|
37
|
+
r && "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ds-primary-blue-normal rounded-[3px]"
|
|
38
|
+
),
|
|
39
|
+
children: p
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
t && /* @__PURE__ */ o(
|
|
43
|
+
"button",
|
|
44
|
+
{
|
|
45
|
+
type: "button",
|
|
46
|
+
"aria-label": "제거",
|
|
47
|
+
disabled: e,
|
|
48
|
+
onClick: (m) => {
|
|
49
|
+
m.stopPropagation(), a();
|
|
50
|
+
},
|
|
51
|
+
className: n(
|
|
52
|
+
"inline-flex items-center justify-center shrink-0",
|
|
53
|
+
e ? "text-ds-text-disabled cursor-not-allowed" : "text-ds-text-strong"
|
|
54
|
+
),
|
|
55
|
+
children: /* @__PURE__ */ o(b, { className: "size-5" })
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
h.displayName = "Chip";
|
|
64
|
+
export {
|
|
65
|
+
h as Chip
|
|
66
|
+
};
|