@pylerai/design-system 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ui/calendar.js +155 -156
- package/dist/components/ui/checkbox.js +18 -18
- package/dist/components/ui/dropdown.js +119 -116
- package/dist/components/ui/modal.d.ts +9 -3
- package/dist/components/ui/modal.js +88 -85
- package/dist/components/ui/radio.js +16 -16
- package/dist/components/ui/table.js +86 -86
- package/dist/components/ui/tabs.js +77 -77
- package/dist/components/ui/toast.js +3 -3
- package/dist/components/ui/toggle.js +16 -16
- package/dist/components/ui/use-modal.js +41 -49
- package/dist/lib/use-dialog-a11y.js +25 -26
- package/dist/style.css +1 -1
- package/dist/tokens/pyler-light.js +20 -20
- package/package.json +14 -14
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as u, jsx as
|
|
3
|
-
import { DropdownArrowIcon as
|
|
4
|
-
import { cn as
|
|
5
|
-
import * as
|
|
6
|
-
import { Button as
|
|
2
|
+
import { jsxs as u, jsx as t } from "react/jsx-runtime";
|
|
3
|
+
import { DropdownArrowIcon as V, SelectCheckIcon as ee, CheckboxCheckedIcon as re, CheckboxUncheckedIcon as te, RadioCheckedIcon as ne, RadioUncheckedIcon as se } from "../../lib/icons.js";
|
|
4
|
+
import { cn as f } from "../../lib/utils.js";
|
|
5
|
+
import * as s from "react";
|
|
6
|
+
import { Button as U } from "./button.js";
|
|
7
7
|
const k = {
|
|
8
8
|
lg: {
|
|
9
9
|
trigger: "h-11 pl-3 pr-2 gap-1.5",
|
|
@@ -20,150 +20,151 @@ const k = {
|
|
|
20
20
|
option: "h-8 pl-3 pr-2",
|
|
21
21
|
text: "text-body-3-r"
|
|
22
22
|
}
|
|
23
|
-
},
|
|
23
|
+
}, ae = s.forwardRef(
|
|
24
24
|
({
|
|
25
|
-
type:
|
|
26
|
-
options:
|
|
27
|
-
value:
|
|
28
|
-
onValueChange:
|
|
29
|
-
values:
|
|
30
|
-
onValuesChange:
|
|
31
|
-
placeholder:
|
|
25
|
+
type: c = "default",
|
|
26
|
+
options: i,
|
|
27
|
+
value: R,
|
|
28
|
+
onValueChange: K,
|
|
29
|
+
values: m,
|
|
30
|
+
onValuesChange: T,
|
|
31
|
+
placeholder: D = "선택해주세요",
|
|
32
32
|
label: h,
|
|
33
33
|
showLabel: v = !0,
|
|
34
|
-
require:
|
|
34
|
+
require: E,
|
|
35
35
|
size: g = "lg",
|
|
36
36
|
disabled: x,
|
|
37
|
-
readOnly:
|
|
37
|
+
readOnly: w,
|
|
38
38
|
error: b,
|
|
39
|
-
hint:
|
|
40
|
-
leftIcon:
|
|
41
|
-
showButtons:
|
|
42
|
-
cancelLabel:
|
|
43
|
-
confirmLabel:
|
|
44
|
-
onCancel:
|
|
45
|
-
onConfirm:
|
|
46
|
-
wrapperClassName:
|
|
47
|
-
className:
|
|
48
|
-
"aria-label":
|
|
49
|
-
},
|
|
50
|
-
const [
|
|
51
|
-
|
|
52
|
-
const e = (
|
|
53
|
-
|
|
39
|
+
hint: N,
|
|
40
|
+
leftIcon: j,
|
|
41
|
+
showButtons: q,
|
|
42
|
+
cancelLabel: z = "취소",
|
|
43
|
+
confirmLabel: B = "확인",
|
|
44
|
+
onCancel: H,
|
|
45
|
+
onConfirm: F,
|
|
46
|
+
wrapperClassName: G,
|
|
47
|
+
className: J,
|
|
48
|
+
"aria-label": P
|
|
49
|
+
}, Q) => {
|
|
50
|
+
const [n, l] = s.useState(!1), [a, p] = s.useState(-1), [$, A] = s.useState("keyboard"), y = s.useRef(null), L = s.useRef(null), M = s.useRef(null), d = s.useId(), I = (e) => `${d}-option-${e}`;
|
|
51
|
+
s.useEffect(() => {
|
|
52
|
+
const e = (r) => {
|
|
53
|
+
y.current && !y.current.contains(r.target) && l(!1);
|
|
54
54
|
};
|
|
55
55
|
return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
|
|
56
|
-
}, []),
|
|
57
|
-
|
|
58
|
-
}, [
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
N == null || N(a);
|
|
56
|
+
}, []), s.useEffect(() => {
|
|
57
|
+
n || p(-1);
|
|
58
|
+
}, [n]), s.useEffect(() => {
|
|
59
|
+
!n || a < 0 || L.current?.querySelector(`#${CSS.escape(I(a))}`)?.scrollIntoView({ block: "nearest" });
|
|
60
|
+
}, [n, a]);
|
|
61
|
+
const W = (e) => c === "checkbox" ? m?.includes(e) ?? !1 : e === R, C = i.find((e) => e.value === R), X = () => c === "checkbox" ? !m || m.length === 0 ? D : i.filter((r) => m.includes(r.value)).map((r) => r.label).join(", ") : C ? C.label : D, Y = () => {
|
|
62
|
+
x || w || l((e) => !e);
|
|
63
|
+
}, O = (e) => {
|
|
64
|
+
if (c === "checkbox") {
|
|
65
|
+
const r = m ?? [], o = r.includes(e) ? r.filter((S) => S !== e) : [...r, e];
|
|
66
|
+
T?.(o);
|
|
68
67
|
} else
|
|
69
|
-
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
e.preventDefault(), s || d(!0), D(p);
|
|
68
|
+
K?.(e), l(!1);
|
|
69
|
+
}, Z = c === "checkbox" ? (m?.length ?? 0) > 0 : !!C, _ = (e) => {
|
|
70
|
+
if (x || w) return;
|
|
71
|
+
const r = (o) => {
|
|
72
|
+
e.preventDefault(), n || l(!0), A("keyboard"), p(o);
|
|
75
73
|
};
|
|
76
74
|
switch (e.key) {
|
|
77
75
|
case "ArrowDown":
|
|
78
|
-
return
|
|
76
|
+
return r(n ? Math.min(a + 1, i.length - 1) : 0);
|
|
79
77
|
case "ArrowUp":
|
|
80
|
-
return
|
|
78
|
+
return r(n ? Math.max(a - 1, 0) : i.length - 1);
|
|
81
79
|
case "Home":
|
|
82
|
-
return
|
|
80
|
+
return n ? r(0) : void 0;
|
|
83
81
|
case "End":
|
|
84
|
-
return
|
|
82
|
+
return n ? r(i.length - 1) : void 0;
|
|
85
83
|
case "Enter":
|
|
86
84
|
case " ":
|
|
87
|
-
e.preventDefault(),
|
|
85
|
+
e.preventDefault(), n ? a >= 0 && O(i[a].value) : l(!0);
|
|
88
86
|
return;
|
|
89
87
|
case "Escape":
|
|
90
|
-
|
|
88
|
+
n && (e.preventDefault(), l(!1), M.current?.focus());
|
|
91
89
|
return;
|
|
92
90
|
case "Tab":
|
|
93
|
-
|
|
91
|
+
l(!1);
|
|
94
92
|
return;
|
|
95
93
|
default:
|
|
96
94
|
return;
|
|
97
95
|
}
|
|
98
96
|
};
|
|
99
|
-
return /* @__PURE__ */ u("div", { ref:
|
|
97
|
+
return /* @__PURE__ */ u("div", { ref: Q, className: f("flex flex-col gap-2", G), children: [
|
|
100
98
|
v && h && /* @__PURE__ */ u("div", { className: "flex items-start gap-0.5 whitespace-nowrap", children: [
|
|
101
|
-
/* @__PURE__ */
|
|
102
|
-
|
|
99
|
+
/* @__PURE__ */ t("span", { id: `${d}-label`, className: "text-body-2-r text-ds-text-strong", children: h }),
|
|
100
|
+
E && /* @__PURE__ */ t("span", { "aria-hidden": "true", className: "text-body-2-r text-ds-primary-red-normal", children: "*" })
|
|
103
101
|
] }),
|
|
104
|
-
/* @__PURE__ */ u("div", { ref:
|
|
102
|
+
/* @__PURE__ */ u("div", { ref: y, className: "relative", children: [
|
|
105
103
|
/* @__PURE__ */ u(
|
|
106
104
|
"button",
|
|
107
105
|
{
|
|
108
|
-
ref:
|
|
106
|
+
ref: M,
|
|
109
107
|
type: "button",
|
|
110
108
|
role: "combobox",
|
|
111
|
-
"aria-expanded":
|
|
109
|
+
"aria-expanded": n,
|
|
112
110
|
"aria-haspopup": "listbox",
|
|
113
|
-
"aria-controls":
|
|
114
|
-
"aria-activedescendant":
|
|
115
|
-
"aria-labelledby": v && h ? `${
|
|
116
|
-
"aria-label": v && h ? void 0 :
|
|
111
|
+
"aria-controls": n ? d : void 0,
|
|
112
|
+
"aria-activedescendant": n && a >= 0 ? I(a) : void 0,
|
|
113
|
+
"aria-labelledby": v && h ? `${d}-label` : void 0,
|
|
114
|
+
"aria-label": v && h ? void 0 : P,
|
|
117
115
|
"aria-invalid": b ? !0 : void 0,
|
|
118
|
-
"aria-describedby": b ||
|
|
119
|
-
"aria-required":
|
|
116
|
+
"aria-describedby": b || N ? `${d}-description` : void 0,
|
|
117
|
+
"aria-required": E || void 0,
|
|
120
118
|
disabled: x,
|
|
121
|
-
onClick:
|
|
122
|
-
onKeyDown:
|
|
123
|
-
className:
|
|
119
|
+
onClick: Y,
|
|
120
|
+
onKeyDown: _,
|
|
121
|
+
className: f(
|
|
124
122
|
"flex items-center w-full rounded-ds-md border transition-colors",
|
|
125
|
-
x ? "bg-ds-surface-strong border-ds-line-normal cursor-not-allowed" :
|
|
123
|
+
x ? "bg-ds-surface-strong border-ds-line-normal cursor-not-allowed" : w ? "bg-ds-surface-normal border-ds-line-normal cursor-default" : b ? "bg-ds-background-default border-ds-primary-red-normal hover:bg-ds-surface-normal" : n ? "bg-ds-background-default border-ds-primary-blue-normal" : "bg-ds-background-default border-ds-line-normal hover:bg-ds-surface-normal hover:border-ds-primary-blue-normal",
|
|
126
124
|
k[g].trigger,
|
|
127
|
-
|
|
125
|
+
J
|
|
128
126
|
),
|
|
129
127
|
children: [
|
|
130
|
-
|
|
131
|
-
/* @__PURE__ */
|
|
128
|
+
j && /* @__PURE__ */ t("span", { className: "shrink-0 flex items-center justify-center text-ds-icon-normal", children: j }),
|
|
129
|
+
/* @__PURE__ */ t(
|
|
132
130
|
"span",
|
|
133
131
|
{
|
|
134
|
-
className:
|
|
132
|
+
className: f(
|
|
135
133
|
"flex-1 min-w-0 text-left truncate font-sans",
|
|
136
134
|
k[g].text,
|
|
137
|
-
|
|
135
|
+
Z ? "text-ds-text-strong" : x ? "text-ds-text-disabled" : "text-ds-text-normal"
|
|
138
136
|
),
|
|
139
|
-
children:
|
|
137
|
+
children: X()
|
|
140
138
|
}
|
|
141
139
|
),
|
|
142
|
-
/* @__PURE__ */
|
|
140
|
+
/* @__PURE__ */ t(
|
|
143
141
|
"span",
|
|
144
142
|
{
|
|
145
|
-
className:
|
|
143
|
+
className: f(
|
|
146
144
|
"shrink-0 flex items-center justify-center transition-transform",
|
|
147
|
-
|
|
148
|
-
x ? "text-ds-text-disabled" : "text-ds-
|
|
145
|
+
n && "rotate-180",
|
|
146
|
+
x ? "text-ds-text-disabled" : "text-ds-icon-strong"
|
|
149
147
|
),
|
|
150
|
-
children: /* @__PURE__ */
|
|
148
|
+
children: /* @__PURE__ */ t(V, {})
|
|
151
149
|
}
|
|
152
150
|
)
|
|
153
151
|
]
|
|
154
152
|
}
|
|
155
153
|
),
|
|
156
|
-
|
|
154
|
+
n && /* @__PURE__ */ u(
|
|
157
155
|
"ul",
|
|
158
156
|
{
|
|
159
|
-
ref:
|
|
160
|
-
id:
|
|
157
|
+
ref: L,
|
|
158
|
+
id: d,
|
|
161
159
|
role: "listbox",
|
|
162
|
-
"aria-multiselectable":
|
|
160
|
+
"aria-multiselectable": c === "checkbox" ? !0 : void 0,
|
|
163
161
|
className: "absolute top-full left-0 z-50 mt-1 min-w-full w-max max-w-sm bg-ds-background-default border border-ds-line-normal rounded-ds-md p-1 shadow-ds-default",
|
|
162
|
+
onMouseLeave: () => {
|
|
163
|
+
$ === "mouse" && p(-1);
|
|
164
|
+
},
|
|
164
165
|
children: [
|
|
165
|
-
|
|
166
|
-
const
|
|
166
|
+
i.map((e, r) => {
|
|
167
|
+
const o = W(e.value), S = r === a;
|
|
167
168
|
return (
|
|
168
169
|
// 키보드 조작은 aria-activedescendant 패턴에 따라 combobox 트리거의
|
|
169
170
|
// onKeyDown이 전담한다(옵션은 포커스를 받지 않는 것이 WAI-ARIA 권고).
|
|
@@ -172,23 +173,25 @@ const k = {
|
|
|
172
173
|
/* @__PURE__ */ u(
|
|
173
174
|
"li",
|
|
174
175
|
{
|
|
175
|
-
id:
|
|
176
|
+
id: I(r),
|
|
176
177
|
role: "option",
|
|
177
|
-
"aria-selected":
|
|
178
|
-
onClick: () =>
|
|
179
|
-
onMouseEnter: () =>
|
|
180
|
-
|
|
178
|
+
"aria-selected": o,
|
|
179
|
+
onClick: () => O(e.value),
|
|
180
|
+
onMouseEnter: () => {
|
|
181
|
+
A("mouse"), p(r);
|
|
182
|
+
},
|
|
183
|
+
className: f(
|
|
181
184
|
"flex items-center rounded-ds-md cursor-pointer gap-1.5 transition-colors",
|
|
182
185
|
k[g].option,
|
|
183
|
-
|
|
184
|
-
// 키보드 이동 위치 표시 (마우스 hover와 구분되도록
|
|
185
|
-
|
|
186
|
+
o ? "bg-ds-surface-normal" : "bg-ds-background-default hover:bg-ds-surface-normal",
|
|
187
|
+
// 키보드 이동 위치 표시 (마우스 hover와 구분되도록 링으로, 키보드 이동에만)
|
|
188
|
+
S && $ === "keyboard" && "ring-1 ring-inset ring-ds-primary-blue-normal"
|
|
186
189
|
),
|
|
187
190
|
children: [
|
|
188
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ t(
|
|
189
192
|
"span",
|
|
190
193
|
{
|
|
191
|
-
className:
|
|
194
|
+
className: f(
|
|
192
195
|
"flex-1 min-w-0 truncate font-sans",
|
|
193
196
|
k[g].text,
|
|
194
197
|
"text-ds-text-strong"
|
|
@@ -196,39 +199,39 @@ const k = {
|
|
|
196
199
|
children: e.label
|
|
197
200
|
}
|
|
198
201
|
),
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
c === "default" && o && /* @__PURE__ */ t("span", { className: "shrink-0 flex items-center justify-center text-ds-text-strong", children: /* @__PURE__ */ t(ee, {}) }),
|
|
203
|
+
c === "checkbox" && /* @__PURE__ */ t("span", { className: "shrink-0 flex items-center justify-center", children: o ? /* @__PURE__ */ t(re, {}) : /* @__PURE__ */ t(te, {}) }),
|
|
204
|
+
c === "radio" && /* @__PURE__ */ t("span", { className: "shrink-0 flex items-center justify-center", children: o ? /* @__PURE__ */ t(ne, {}) : /* @__PURE__ */ t(se, {}) })
|
|
202
205
|
]
|
|
203
206
|
},
|
|
204
207
|
e.value
|
|
205
208
|
)
|
|
206
209
|
);
|
|
207
210
|
}),
|
|
208
|
-
|
|
209
|
-
/* @__PURE__ */
|
|
210
|
-
|
|
211
|
+
q && /* @__PURE__ */ u("li", { className: "flex gap-2 pt-1", children: [
|
|
212
|
+
/* @__PURE__ */ t(
|
|
213
|
+
U,
|
|
211
214
|
{
|
|
212
215
|
variant: "outlined",
|
|
213
216
|
size: "lg",
|
|
214
217
|
className: "flex-1",
|
|
215
218
|
onClick: () => {
|
|
216
|
-
|
|
219
|
+
H?.(), l(!1);
|
|
217
220
|
},
|
|
218
|
-
children:
|
|
221
|
+
children: z
|
|
219
222
|
}
|
|
220
223
|
),
|
|
221
|
-
/* @__PURE__ */
|
|
222
|
-
|
|
224
|
+
/* @__PURE__ */ t(
|
|
225
|
+
U,
|
|
223
226
|
{
|
|
224
227
|
variant: "filled",
|
|
225
228
|
color: "blue",
|
|
226
229
|
size: "lg",
|
|
227
230
|
className: "flex-1",
|
|
228
231
|
onClick: () => {
|
|
229
|
-
|
|
232
|
+
F?.(), l(!1);
|
|
230
233
|
},
|
|
231
|
-
children:
|
|
234
|
+
children: B
|
|
232
235
|
}
|
|
233
236
|
)
|
|
234
237
|
] })
|
|
@@ -236,21 +239,21 @@ const k = {
|
|
|
236
239
|
}
|
|
237
240
|
)
|
|
238
241
|
] }),
|
|
239
|
-
(b ||
|
|
242
|
+
(b || N) && /* @__PURE__ */ t(
|
|
240
243
|
"p",
|
|
241
244
|
{
|
|
242
|
-
id: `${
|
|
243
|
-
className:
|
|
245
|
+
id: `${d}-description`,
|
|
246
|
+
className: f(
|
|
244
247
|
"text-body-4-r",
|
|
245
248
|
b ? "text-ds-primary-red-normal" : "text-ds-text-normal"
|
|
246
249
|
),
|
|
247
|
-
children: b ??
|
|
250
|
+
children: b ?? N
|
|
248
251
|
}
|
|
249
252
|
)
|
|
250
253
|
] });
|
|
251
254
|
}
|
|
252
255
|
);
|
|
253
|
-
|
|
256
|
+
ae.displayName = "Dropdown";
|
|
254
257
|
export {
|
|
255
|
-
|
|
258
|
+
ae as Dropdown
|
|
256
259
|
};
|
|
@@ -8,9 +8,11 @@ export interface InformationModalProps {
|
|
|
8
8
|
confirmLabel?: string;
|
|
9
9
|
onConfirm?: () => void;
|
|
10
10
|
onClose: () => void;
|
|
11
|
+
/** 배경 딤 표시 여부. 기본값: true */
|
|
12
|
+
dim?: boolean;
|
|
11
13
|
className?: string;
|
|
12
14
|
}
|
|
13
|
-
declare function InformationModal({ open, title, description, confirmLabel, onConfirm, onClose, className, }: InformationModalProps): React.ReactPortal | null;
|
|
15
|
+
declare function InformationModal({ open, title, description, confirmLabel, onConfirm, onClose, dim, className, }: InformationModalProps): React.ReactPortal | null;
|
|
14
16
|
export interface ActionModalProps {
|
|
15
17
|
open: boolean;
|
|
16
18
|
title: React.ReactNode;
|
|
@@ -22,9 +24,11 @@ export interface ActionModalProps {
|
|
|
22
24
|
onCancel?: () => void;
|
|
23
25
|
onConfirm?: () => void;
|
|
24
26
|
onClose: () => void;
|
|
27
|
+
/** 배경 딤 표시 여부. 기본값: true */
|
|
28
|
+
dim?: boolean;
|
|
25
29
|
className?: string;
|
|
26
30
|
}
|
|
27
|
-
declare function ActionModal({ open, title, description, cancelLabel, confirmLabel, onCancel, onConfirm, onClose, className, }: ActionModalProps): React.ReactPortal | null;
|
|
31
|
+
declare function ActionModal({ open, title, description, cancelLabel, confirmLabel, onCancel, onConfirm, onClose, dim, className, }: ActionModalProps): React.ReactPortal | null;
|
|
28
32
|
export type ContentModalSize = Extract<DsSize, "lg" | "md" | "sm">;
|
|
29
33
|
export interface ContentModalProps {
|
|
30
34
|
open: boolean;
|
|
@@ -40,7 +44,9 @@ export interface ContentModalProps {
|
|
|
40
44
|
onConfirm?: () => void;
|
|
41
45
|
onClose: () => void;
|
|
42
46
|
children?: React.ReactNode;
|
|
47
|
+
/** 배경 딤 표시 여부. 기본값: true */
|
|
48
|
+
dim?: boolean;
|
|
43
49
|
className?: string;
|
|
44
50
|
}
|
|
45
|
-
declare function ContentModal({ open, title, description, size, cancelLabel, confirmLabel, onCancel, onConfirm, onClose, children, className, }: ContentModalProps): React.ReactPortal | null;
|
|
51
|
+
declare function ContentModal({ open, title, description, size, cancelLabel, confirmLabel, onCancel, onConfirm, onClose, children, dim, className, }: ContentModalProps): React.ReactPortal | null;
|
|
46
52
|
export { InformationModal, ActionModal, ContentModal };
|