@bigtablet/design-system 3.4.1 → 3.5.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/index.css +24 -1
- package/dist/index.d.ts +47 -7
- package/dist/index.js +470 -278
- package/dist/vanilla/bigtablet.min.css +1 -1
- package/dist/vanilla/bigtablet.min.js +16 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import './index.css';
|
|
3
|
-
import * as
|
|
3
|
+
import * as React15 from 'react';
|
|
4
4
|
import { createContext, useRef, useState, useId, useEffect, useContext, useCallback, useMemo, Fragment, useLayoutEffect } from 'react';
|
|
5
5
|
import { useSpring, animated } from '@react-spring/web';
|
|
6
6
|
import { ChevronDown, ChevronRight, Globe, ChevronLeft, XCircle, AlertTriangle, CheckCircle2, Info, Search, Check, X, Image, ArrowUp, ArrowDown, ArrowUpDown, Bell, TriangleAlert } from 'lucide-react';
|
|
@@ -29,6 +29,44 @@ var cn = (...classes) => {
|
|
|
29
29
|
}
|
|
30
30
|
return classNames.join(" ");
|
|
31
31
|
};
|
|
32
|
+
var stack = [];
|
|
33
|
+
var handleKeyDown = (e) => {
|
|
34
|
+
if (e.key !== "Escape") return;
|
|
35
|
+
const top = stack[stack.length - 1];
|
|
36
|
+
if (!top) return;
|
|
37
|
+
e.stopImmediatePropagation();
|
|
38
|
+
top();
|
|
39
|
+
};
|
|
40
|
+
function registerOverlay(onEscape) {
|
|
41
|
+
if (typeof document === "undefined") {
|
|
42
|
+
return () => {
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if (stack.length === 0) {
|
|
46
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
47
|
+
}
|
|
48
|
+
stack.push(onEscape);
|
|
49
|
+
let done = false;
|
|
50
|
+
return () => {
|
|
51
|
+
if (done) return;
|
|
52
|
+
done = true;
|
|
53
|
+
const index = stack.lastIndexOf(onEscape);
|
|
54
|
+
if (index !== -1) stack.splice(index, 1);
|
|
55
|
+
if (stack.length === 0) {
|
|
56
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function useOverlayEscape(active, onEscape) {
|
|
61
|
+
const handlerRef = React15.useRef(onEscape);
|
|
62
|
+
React15.useEffect(() => {
|
|
63
|
+
handlerRef.current = onEscape;
|
|
64
|
+
});
|
|
65
|
+
React15.useEffect(() => {
|
|
66
|
+
if (!active) return;
|
|
67
|
+
return registerOverlay(() => handlerRef.current());
|
|
68
|
+
}, [active]);
|
|
69
|
+
}
|
|
32
70
|
var FOCUSABLE_SELECTORS = [
|
|
33
71
|
"a[href]",
|
|
34
72
|
"button:not([disabled])",
|
|
@@ -38,8 +76,8 @@ var FOCUSABLE_SELECTORS = [
|
|
|
38
76
|
'[tabindex]:not([tabindex="-1"])'
|
|
39
77
|
].join(", ");
|
|
40
78
|
function useFocusTrap(containerRef, isActive) {
|
|
41
|
-
const previousActiveElement =
|
|
42
|
-
|
|
79
|
+
const previousActiveElement = React15.useRef(null);
|
|
80
|
+
React15.useEffect(() => {
|
|
43
81
|
if (!isActive) return;
|
|
44
82
|
const container = containerRef.current;
|
|
45
83
|
if (!container) return;
|
|
@@ -56,7 +94,7 @@ function useFocusTrap(containerRef, isActive) {
|
|
|
56
94
|
wasTabIndexAdded = true;
|
|
57
95
|
container.focus();
|
|
58
96
|
}
|
|
59
|
-
const
|
|
97
|
+
const handleKeyDown2 = (e) => {
|
|
60
98
|
if (e.key !== "Tab") return;
|
|
61
99
|
const focusableElements2 = getFocusableElements();
|
|
62
100
|
if (focusableElements2.length === 0) {
|
|
@@ -77,9 +115,9 @@ function useFocusTrap(containerRef, isActive) {
|
|
|
77
115
|
}
|
|
78
116
|
}
|
|
79
117
|
};
|
|
80
|
-
document.addEventListener("keydown",
|
|
118
|
+
document.addEventListener("keydown", handleKeyDown2);
|
|
81
119
|
return () => {
|
|
82
|
-
document.removeEventListener("keydown",
|
|
120
|
+
document.removeEventListener("keydown", handleKeyDown2);
|
|
83
121
|
if (wasTabIndexAdded) {
|
|
84
122
|
container.removeAttribute("tabindex");
|
|
85
123
|
}
|
|
@@ -87,6 +125,13 @@ function useFocusTrap(containerRef, isActive) {
|
|
|
87
125
|
};
|
|
88
126
|
}, [isActive, containerRef]);
|
|
89
127
|
}
|
|
128
|
+
function useIsMounted() {
|
|
129
|
+
const [mounted, setMounted] = React15.useState(false);
|
|
130
|
+
React15.useEffect(() => {
|
|
131
|
+
setMounted(true);
|
|
132
|
+
}, []);
|
|
133
|
+
return mounted;
|
|
134
|
+
}
|
|
90
135
|
var QUERY = "(prefers-reduced-motion: reduce)";
|
|
91
136
|
var mqCache = null;
|
|
92
137
|
var cachedFor = null;
|
|
@@ -116,14 +161,14 @@ function getServerSnapshot() {
|
|
|
116
161
|
return false;
|
|
117
162
|
}
|
|
118
163
|
function useReducedMotion() {
|
|
119
|
-
return
|
|
164
|
+
return React15.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
120
165
|
}
|
|
121
166
|
var useSafeLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
122
167
|
function useSpringHover({
|
|
123
168
|
scale = 1.02,
|
|
124
169
|
lift = -2
|
|
125
170
|
} = {}) {
|
|
126
|
-
const [hovered, setHovered] =
|
|
171
|
+
const [hovered, setHovered] = React15.useState(false);
|
|
127
172
|
const reduced = useReducedMotion();
|
|
128
173
|
const style = useSpring({
|
|
129
174
|
transform: hovered ? `translateY(${lift}px) scale(${scale})` : "translateY(0px) scale(1)",
|
|
@@ -187,8 +232,9 @@ var Accordion = ({
|
|
|
187
232
|
...props
|
|
188
233
|
}) => {
|
|
189
234
|
const isControlled = controlledKeys !== void 0;
|
|
190
|
-
const [internalKeys, setInternalKeys] =
|
|
235
|
+
const [internalKeys, setInternalKeys] = React15.useState(defaultOpenKeys);
|
|
191
236
|
const open = isControlled ? controlledKeys ?? [] : internalKeys;
|
|
237
|
+
const idPrefix = React15.useId();
|
|
192
238
|
const toggle = (key) => {
|
|
193
239
|
const isOpen = open.includes(key);
|
|
194
240
|
const next = isOpen ? open.filter((k) => k !== key) : multiple ? [...open, key] : [key];
|
|
@@ -197,8 +243,8 @@ var Accordion = ({
|
|
|
197
243
|
};
|
|
198
244
|
return /* @__PURE__ */ jsx("div", { className: cn("accordion", className), ...props, children: items.map((item) => {
|
|
199
245
|
const isOpen = open.includes(item.key);
|
|
200
|
-
const headerId = `${item.key}-header`;
|
|
201
|
-
const panelId = `${item.key}-panel`;
|
|
246
|
+
const headerId = `${idPrefix}-${item.key}-header`;
|
|
247
|
+
const panelId = `${idPrefix}-${item.key}-panel`;
|
|
202
248
|
return /* @__PURE__ */ jsxs("div", { className: cn("accordion_item", isOpen && "accordion_item_open"), children: [
|
|
203
249
|
/* @__PURE__ */ jsx("h3", { className: "accordion_header", children: /* @__PURE__ */ jsxs(
|
|
204
250
|
"button",
|
|
@@ -254,7 +300,7 @@ var Avatar = ({
|
|
|
254
300
|
style,
|
|
255
301
|
...props
|
|
256
302
|
}) => {
|
|
257
|
-
const [imgFailed, setImgFailed] =
|
|
303
|
+
const [imgFailed, setImgFailed] = React15.useState(false);
|
|
258
304
|
const showImage = src && !imgFailed;
|
|
259
305
|
const initials = getInitials(name);
|
|
260
306
|
return /* @__PURE__ */ jsx(
|
|
@@ -262,8 +308,9 @@ var Avatar = ({
|
|
|
262
308
|
{
|
|
263
309
|
className: cn("avatar", `avatar_size_${size}`, `avatar_shape_${shape}`, className),
|
|
264
310
|
style: { background: !showImage ? bgColor : void 0, ...style },
|
|
265
|
-
role: showImage ? void 0 : "img",
|
|
311
|
+
role: showImage || !name ? void 0 : "img",
|
|
266
312
|
"aria-label": showImage ? void 0 : name || void 0,
|
|
313
|
+
"aria-hidden": !showImage && !name ? true : void 0,
|
|
267
314
|
...props,
|
|
268
315
|
children: showImage ? (
|
|
269
316
|
// biome-ignore lint/performance/noImgElement: DS is framework-agnostic - consumers wrap with next/image
|
|
@@ -472,12 +519,12 @@ var ErrorState = ({
|
|
|
472
519
|
);
|
|
473
520
|
};
|
|
474
521
|
var Menu = ({ items, trigger, align = "start" }) => {
|
|
475
|
-
const [open, setOpen] =
|
|
476
|
-
const wrapperRef =
|
|
477
|
-
const itemRefs =
|
|
478
|
-
const menuId =
|
|
522
|
+
const [open, setOpen] = React15.useState(false);
|
|
523
|
+
const wrapperRef = React15.useRef(null);
|
|
524
|
+
const itemRefs = React15.useRef([]);
|
|
525
|
+
const menuId = React15.useId();
|
|
479
526
|
const style = useSpringPresence({ visible: open, from: "translateY(-4px)" });
|
|
480
|
-
|
|
527
|
+
React15.useEffect(() => {
|
|
481
528
|
if (!open) return;
|
|
482
529
|
const handleClick = (e) => {
|
|
483
530
|
if (!wrapperRef.current?.contains(e.target)) setOpen(false);
|
|
@@ -492,7 +539,7 @@ var Menu = ({ items, trigger, align = "start" }) => {
|
|
|
492
539
|
document.removeEventListener("keydown", handleEsc);
|
|
493
540
|
};
|
|
494
541
|
}, [open]);
|
|
495
|
-
|
|
542
|
+
React15.useEffect(() => {
|
|
496
543
|
const active = document.activeElement;
|
|
497
544
|
if (!open || active && itemRefs.current.includes(active)) return;
|
|
498
545
|
const first = items.findIndex((it) => !it.disabled);
|
|
@@ -538,7 +585,7 @@ var Menu = ({ items, trigger, align = "start" }) => {
|
|
|
538
585
|
break;
|
|
539
586
|
}
|
|
540
587
|
};
|
|
541
|
-
const triggerWithProps =
|
|
588
|
+
const triggerWithProps = React15.cloneElement(
|
|
542
589
|
trigger,
|
|
543
590
|
{
|
|
544
591
|
onClick: () => setOpen((o) => !o),
|
|
@@ -782,7 +829,8 @@ var LocaleSwitcher = ({ locale }) => {
|
|
|
782
829
|
itemRefs.current[index] = el;
|
|
783
830
|
},
|
|
784
831
|
type: "button",
|
|
785
|
-
role: "
|
|
832
|
+
role: "menuitemradio",
|
|
833
|
+
"aria-checked": opt.value === locale.current,
|
|
786
834
|
tabIndex: -1,
|
|
787
835
|
className: cn(
|
|
788
836
|
"nav_bar_locale_item",
|
|
@@ -828,9 +876,9 @@ var Sidebar = ({
|
|
|
828
876
|
...props
|
|
829
877
|
}) => {
|
|
830
878
|
const isControlled = collapsedProp !== void 0;
|
|
831
|
-
const [internalCollapsed, setInternalCollapsed] =
|
|
879
|
+
const [internalCollapsed, setInternalCollapsed] = React15.useState(defaultCollapsed);
|
|
832
880
|
const collapsed = isControlled ? collapsedProp : internalCollapsed;
|
|
833
|
-
const toggle =
|
|
881
|
+
const toggle = React15.useCallback(() => {
|
|
834
882
|
const next = !collapsed;
|
|
835
883
|
if (!isControlled) setInternalCollapsed(next);
|
|
836
884
|
onCollapsedChange?.(next);
|
|
@@ -903,9 +951,9 @@ var SidebarSection = ({ label, className, children, ...props }) => {
|
|
|
903
951
|
children
|
|
904
952
|
] });
|
|
905
953
|
};
|
|
906
|
-
var TabsContext =
|
|
954
|
+
var TabsContext = React15.createContext(null);
|
|
907
955
|
function useTabsContext() {
|
|
908
|
-
const ctx =
|
|
956
|
+
const ctx = React15.useContext(TabsContext);
|
|
909
957
|
if (!ctx) {
|
|
910
958
|
throw new Error(
|
|
911
959
|
'[Bigtablet DS] <Tab>, <TabList>, <TabPanel>\uC740 \uBC18\uB4DC\uC2DC <Tabs> \uC548\uC5D0 \uC788\uC5B4\uC57C \uD569\uB2C8\uB2E4.\n\n\uC62C\uBC14\uB978 \uC0AC\uC6A9 \uC608:\n <Tabs defaultValue="a">\n <TabList>\n <Tab value="a">A</Tab>\n </TabList>\n <TabPanel value="a">...</TabPanel>\n </Tabs>'
|
|
@@ -924,27 +972,39 @@ var Tabs = ({
|
|
|
924
972
|
...props
|
|
925
973
|
}) => {
|
|
926
974
|
const isControlled = controlledValue !== void 0;
|
|
927
|
-
const [internalValue, setInternalValue] =
|
|
975
|
+
const [internalValue, setInternalValue] = React15.useState(defaultValue);
|
|
928
976
|
const value = isControlled ? controlledValue : internalValue;
|
|
929
|
-
const setValue =
|
|
977
|
+
const setValue = React15.useCallback(
|
|
930
978
|
(v) => {
|
|
931
979
|
if (!isControlled) setInternalValue(v);
|
|
932
980
|
onValueChange?.(v);
|
|
933
981
|
},
|
|
934
982
|
[isControlled, onValueChange]
|
|
935
983
|
);
|
|
936
|
-
const
|
|
937
|
-
const
|
|
938
|
-
|
|
939
|
-
|
|
984
|
+
const orderRef = React15.useRef([]);
|
|
985
|
+
const [firstTabValue, setFirstTabValue] = React15.useState();
|
|
986
|
+
const registerTab = React15.useCallback((v) => {
|
|
987
|
+
if (!orderRef.current.includes(v)) {
|
|
988
|
+
orderRef.current = [...orderRef.current, v];
|
|
989
|
+
setFirstTabValue(orderRef.current[0]);
|
|
990
|
+
}
|
|
991
|
+
return () => {
|
|
992
|
+
orderRef.current = orderRef.current.filter((x) => x !== v);
|
|
993
|
+
setFirstTabValue(orderRef.current[0]);
|
|
994
|
+
};
|
|
995
|
+
}, []);
|
|
996
|
+
const idPrefix = React15.useId();
|
|
997
|
+
const ctx = React15.useMemo(
|
|
998
|
+
() => ({ value, setValue, variant, size, idPrefix, registerTab, firstTabValue }),
|
|
999
|
+
[value, setValue, variant, size, idPrefix, registerTab, firstTabValue]
|
|
940
1000
|
);
|
|
941
1001
|
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx("div", { className: cn("tabs", `tabs_variant_${variant}`, `tabs_size_${size}`, className), ...props, children }) });
|
|
942
1002
|
};
|
|
943
1003
|
var TabList = ({ ariaLabel, className, children, ...props }) => {
|
|
944
1004
|
const { variant } = useTabsContext();
|
|
945
|
-
const listRef =
|
|
946
|
-
const [indicator, setIndicator] =
|
|
947
|
-
const [hasMounted, setHasMounted] =
|
|
1005
|
+
const listRef = React15.useRef(null);
|
|
1006
|
+
const [indicator, setIndicator] = React15.useState(null);
|
|
1007
|
+
const [hasMounted, setHasMounted] = React15.useState(false);
|
|
948
1008
|
useSafeLayoutEffect(() => {
|
|
949
1009
|
const list = listRef.current;
|
|
950
1010
|
if (!list) return;
|
|
@@ -1001,16 +1061,20 @@ var TabList = ({ ariaLabel, className, children, ...props }) => {
|
|
|
1001
1061
|
}
|
|
1002
1062
|
);
|
|
1003
1063
|
};
|
|
1004
|
-
var Tab = ({ value, className, children, onClick, ...props }) => {
|
|
1064
|
+
var Tab = ({ value, className, children, onClick, onKeyDown, ...props }) => {
|
|
1005
1065
|
const ctx = useTabsContext();
|
|
1006
1066
|
const isActive = ctx.value === value;
|
|
1007
1067
|
const panelId = `${ctx.idPrefix}-panel-${value}`;
|
|
1008
1068
|
const tabId = `${ctx.idPrefix}-tab-${value}`;
|
|
1069
|
+
const { registerTab } = ctx;
|
|
1070
|
+
React15.useEffect(() => registerTab(value), [registerTab, value]);
|
|
1009
1071
|
const handleClick = (e) => {
|
|
1010
1072
|
ctx.setValue(value);
|
|
1011
1073
|
onClick?.(e);
|
|
1012
1074
|
};
|
|
1013
|
-
const
|
|
1075
|
+
const handleKeyDown2 = (e) => {
|
|
1076
|
+
onKeyDown?.(e);
|
|
1077
|
+
if (e.defaultPrevented) return;
|
|
1014
1078
|
if (e.key !== "ArrowLeft" && e.key !== "ArrowRight" && e.key !== "Home" && e.key !== "End") return;
|
|
1015
1079
|
const list = e.currentTarget.closest('[role="tablist"]');
|
|
1016
1080
|
if (!list) return;
|
|
@@ -1032,17 +1096,17 @@ var Tab = ({ value, className, children, onClick, ...props }) => {
|
|
|
1032
1096
|
return /* @__PURE__ */ jsx(
|
|
1033
1097
|
"button",
|
|
1034
1098
|
{
|
|
1099
|
+
...props,
|
|
1035
1100
|
type: "button",
|
|
1036
1101
|
role: "tab",
|
|
1037
1102
|
id: tabId,
|
|
1038
1103
|
"data-value": value,
|
|
1039
1104
|
"aria-selected": isActive,
|
|
1040
1105
|
"aria-controls": panelId,
|
|
1041
|
-
tabIndex: isActive ? 0 : -1,
|
|
1106
|
+
tabIndex: isActive || !ctx.value && value === ctx.firstTabValue ? 0 : -1,
|
|
1042
1107
|
className: cn("tabs_tab", isActive && "tabs_tab_active", className),
|
|
1043
1108
|
onClick: handleClick,
|
|
1044
|
-
onKeyDown:
|
|
1045
|
-
...props,
|
|
1109
|
+
onKeyDown: handleKeyDown2,
|
|
1046
1110
|
children
|
|
1047
1111
|
}
|
|
1048
1112
|
);
|
|
@@ -1093,15 +1157,15 @@ var Popover = ({
|
|
|
1093
1157
|
className
|
|
1094
1158
|
}) => {
|
|
1095
1159
|
const isControlled = openProp !== void 0;
|
|
1096
|
-
const [internalOpen, setInternalOpen] =
|
|
1160
|
+
const [internalOpen, setInternalOpen] = React15.useState(defaultOpen);
|
|
1097
1161
|
const open = isControlled ? openProp : internalOpen;
|
|
1098
|
-
const [shouldRender, setShouldRender] =
|
|
1162
|
+
const [shouldRender, setShouldRender] = React15.useState(open ?? false);
|
|
1099
1163
|
if (open && !shouldRender) setShouldRender(true);
|
|
1100
|
-
const wrapperRef =
|
|
1101
|
-
const popoverRef =
|
|
1102
|
-
const previousFocusRef =
|
|
1103
|
-
const popoverId =
|
|
1104
|
-
const setOpen =
|
|
1164
|
+
const wrapperRef = React15.useRef(null);
|
|
1165
|
+
const popoverRef = React15.useRef(null);
|
|
1166
|
+
const previousFocusRef = React15.useRef(null);
|
|
1167
|
+
const popoverId = React15.useId();
|
|
1168
|
+
const setOpen = React15.useCallback(
|
|
1105
1169
|
(next) => {
|
|
1106
1170
|
if (!isControlled) setInternalOpen(next);
|
|
1107
1171
|
onOpenChange?.(next);
|
|
@@ -1121,7 +1185,7 @@ var Popover = ({
|
|
|
1121
1185
|
}
|
|
1122
1186
|
})();
|
|
1123
1187
|
const style = useSpringPresence({ visible: open, from: fromTransform, onExitComplete: () => setShouldRender(false) });
|
|
1124
|
-
|
|
1188
|
+
React15.useEffect(() => {
|
|
1125
1189
|
if (!open) return;
|
|
1126
1190
|
previousFocusRef.current = document.activeElement;
|
|
1127
1191
|
const node = popoverRef.current;
|
|
@@ -1129,25 +1193,19 @@ var Popover = ({
|
|
|
1129
1193
|
const focusable = node.querySelector(FOCUSABLE_SELECTORS2);
|
|
1130
1194
|
(focusable ?? node).focus();
|
|
1131
1195
|
}, [open]);
|
|
1132
|
-
|
|
1196
|
+
React15.useEffect(() => {
|
|
1133
1197
|
if (!open) return;
|
|
1134
1198
|
const handleClick = (e) => {
|
|
1135
1199
|
if (!wrapperRef.current?.contains(e.target)) setOpen(false);
|
|
1136
1200
|
};
|
|
1137
|
-
const handleKeyDown = (e) => {
|
|
1138
|
-
if (e.key === "Escape") {
|
|
1139
|
-
setOpen(false);
|
|
1140
|
-
previousFocusRef.current?.focus();
|
|
1141
|
-
}
|
|
1142
|
-
};
|
|
1143
1201
|
document.addEventListener("mousedown", handleClick);
|
|
1144
|
-
document.
|
|
1145
|
-
return () => {
|
|
1146
|
-
document.removeEventListener("mousedown", handleClick);
|
|
1147
|
-
document.removeEventListener("keydown", handleKeyDown);
|
|
1148
|
-
};
|
|
1202
|
+
return () => document.removeEventListener("mousedown", handleClick);
|
|
1149
1203
|
}, [open, setOpen]);
|
|
1150
|
-
|
|
1204
|
+
useOverlayEscape(open, () => {
|
|
1205
|
+
setOpen(false);
|
|
1206
|
+
previousFocusRef.current?.focus();
|
|
1207
|
+
});
|
|
1208
|
+
const triggerWithProps = React15.cloneElement(
|
|
1151
1209
|
trigger,
|
|
1152
1210
|
{
|
|
1153
1211
|
onClick: (e) => {
|
|
@@ -1186,22 +1244,31 @@ var Tooltip = ({
|
|
|
1186
1244
|
disabled = false,
|
|
1187
1245
|
children
|
|
1188
1246
|
}) => {
|
|
1189
|
-
const [open, setOpen] =
|
|
1190
|
-
const timerRef =
|
|
1191
|
-
const tooltipId =
|
|
1192
|
-
const
|
|
1247
|
+
const [open, setOpen] = React15.useState(false);
|
|
1248
|
+
const timerRef = React15.useRef(null);
|
|
1249
|
+
const tooltipId = React15.useId();
|
|
1250
|
+
const HIDE_DELAY = 120;
|
|
1251
|
+
const show = React15.useCallback(() => {
|
|
1193
1252
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1194
1253
|
timerRef.current = setTimeout(() => setOpen(true), delay);
|
|
1195
1254
|
}, [delay]);
|
|
1196
|
-
const
|
|
1255
|
+
const hideNow = React15.useCallback(() => {
|
|
1197
1256
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1198
1257
|
setOpen(false);
|
|
1199
1258
|
}, []);
|
|
1200
|
-
|
|
1259
|
+
const hide = React15.useCallback(() => {
|
|
1260
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1261
|
+
timerRef.current = setTimeout(() => setOpen(false), HIDE_DELAY);
|
|
1262
|
+
}, []);
|
|
1263
|
+
const cancelHide = React15.useCallback(() => {
|
|
1264
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1265
|
+
}, []);
|
|
1266
|
+
React15.useEffect(() => {
|
|
1201
1267
|
return () => {
|
|
1202
1268
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1203
1269
|
};
|
|
1204
1270
|
}, []);
|
|
1271
|
+
useOverlayEscape(open, hideNow);
|
|
1205
1272
|
const fromTransform = (() => {
|
|
1206
1273
|
switch (placement) {
|
|
1207
1274
|
case "top":
|
|
@@ -1217,7 +1284,7 @@ var Tooltip = ({
|
|
|
1217
1284
|
const style = useSpringPresence({ visible: open, from: fromTransform });
|
|
1218
1285
|
const child = children;
|
|
1219
1286
|
const childProps = child.props;
|
|
1220
|
-
const trigger =
|
|
1287
|
+
const trigger = React15.cloneElement(child, {
|
|
1221
1288
|
onMouseEnter: (e) => {
|
|
1222
1289
|
childProps.onMouseEnter?.(e);
|
|
1223
1290
|
show();
|
|
@@ -1232,7 +1299,7 @@ var Tooltip = ({
|
|
|
1232
1299
|
},
|
|
1233
1300
|
onBlur: (e) => {
|
|
1234
1301
|
childProps.onBlur?.(e);
|
|
1235
|
-
|
|
1302
|
+
hideNow();
|
|
1236
1303
|
},
|
|
1237
1304
|
// 자식의 기존 aria-describedby 보존 + tooltip id 합성 (폼 설명/에러 연결 끊김 방지)
|
|
1238
1305
|
"aria-describedby": open ? [childProps["aria-describedby"], tooltipId].filter(Boolean).join(" ") : childProps["aria-describedby"]
|
|
@@ -1240,16 +1307,24 @@ var Tooltip = ({
|
|
|
1240
1307
|
if (disabled) return children;
|
|
1241
1308
|
return /* @__PURE__ */ jsxs("span", { className: "tooltip_wrapper", children: [
|
|
1242
1309
|
trigger,
|
|
1243
|
-
open && /* @__PURE__ */ jsx(
|
|
1244
|
-
|
|
1310
|
+
open && /* @__PURE__ */ jsx(
|
|
1311
|
+
"span",
|
|
1245
1312
|
{
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1313
|
+
className: cn("tooltip_position", `tooltip_placement_${placement}`),
|
|
1314
|
+
onMouseEnter: cancelHide,
|
|
1315
|
+
onMouseLeave: hide,
|
|
1316
|
+
children: /* @__PURE__ */ jsx(
|
|
1317
|
+
animated.span,
|
|
1318
|
+
{
|
|
1319
|
+
id: tooltipId,
|
|
1320
|
+
role: "tooltip",
|
|
1321
|
+
style,
|
|
1322
|
+
className: cn("tooltip", `tooltip_placement_${placement}`),
|
|
1323
|
+
children: content
|
|
1324
|
+
}
|
|
1325
|
+
)
|
|
1251
1326
|
}
|
|
1252
|
-
)
|
|
1327
|
+
)
|
|
1253
1328
|
] });
|
|
1254
1329
|
};
|
|
1255
1330
|
|
|
@@ -1731,20 +1806,22 @@ var zIndex = {
|
|
|
1731
1806
|
level4: 500,
|
|
1732
1807
|
level5: 1e3
|
|
1733
1808
|
};
|
|
1734
|
-
var Button = ({
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1809
|
+
var Button = (props) => {
|
|
1810
|
+
const {
|
|
1811
|
+
variant = "filled",
|
|
1812
|
+
size = "md",
|
|
1813
|
+
leadingIcon,
|
|
1814
|
+
trailingIcon,
|
|
1815
|
+
fullWidth = false,
|
|
1816
|
+
radius: radius2,
|
|
1817
|
+
danger = false,
|
|
1818
|
+
disabled = false,
|
|
1819
|
+
as,
|
|
1820
|
+
className,
|
|
1821
|
+
children,
|
|
1822
|
+
ref,
|
|
1823
|
+
...rest
|
|
1824
|
+
} = props;
|
|
1748
1825
|
const buttonClassName = cn(
|
|
1749
1826
|
"button",
|
|
1750
1827
|
`button_variant_${variant}`,
|
|
@@ -1752,13 +1829,44 @@ var Button = ({
|
|
|
1752
1829
|
fullWidth && "button_full_width",
|
|
1753
1830
|
radius2 && `button_radius_${radius2}`,
|
|
1754
1831
|
danger && "button_danger",
|
|
1832
|
+
// anchor 엔 native :disabled 가 안 먹으므로 클래스로 비활성 스타일 적용 (button 도 무해)
|
|
1833
|
+
disabled && "button_disabled",
|
|
1755
1834
|
className
|
|
1756
1835
|
);
|
|
1757
|
-
|
|
1836
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
1758
1837
|
leadingIcon && /* @__PURE__ */ jsx("span", { className: "button_icon", "aria-hidden": "true", children: leadingIcon }),
|
|
1759
1838
|
children && /* @__PURE__ */ jsx("span", { className: "button_label", children }),
|
|
1760
1839
|
trailingIcon && /* @__PURE__ */ jsx("span", { className: "button_icon", "aria-hidden": "true", children: trailingIcon })
|
|
1761
1840
|
] });
|
|
1841
|
+
const anchorRest = rest;
|
|
1842
|
+
const renderAnchor = as === "a" || as === void 0 && anchorRest.href != null;
|
|
1843
|
+
if (renderAnchor) {
|
|
1844
|
+
const { onClick, tabIndex, ...anchorProps } = anchorRest;
|
|
1845
|
+
return /* @__PURE__ */ jsx(
|
|
1846
|
+
"a",
|
|
1847
|
+
{
|
|
1848
|
+
...anchorProps,
|
|
1849
|
+
ref,
|
|
1850
|
+
className: buttonClassName,
|
|
1851
|
+
"aria-disabled": disabled || void 0,
|
|
1852
|
+
tabIndex: disabled ? -1 : tabIndex,
|
|
1853
|
+
onClick: disabled ? (e) => e.preventDefault() : onClick,
|
|
1854
|
+
children: content
|
|
1855
|
+
}
|
|
1856
|
+
);
|
|
1857
|
+
}
|
|
1858
|
+
const { type = "button", ...buttonRest } = rest;
|
|
1859
|
+
return /* @__PURE__ */ jsx(
|
|
1860
|
+
"button",
|
|
1861
|
+
{
|
|
1862
|
+
ref,
|
|
1863
|
+
type,
|
|
1864
|
+
disabled,
|
|
1865
|
+
className: buttonClassName,
|
|
1866
|
+
...buttonRest,
|
|
1867
|
+
children: content
|
|
1868
|
+
}
|
|
1869
|
+
);
|
|
1762
1870
|
};
|
|
1763
1871
|
var ICONS = {
|
|
1764
1872
|
info: /* @__PURE__ */ jsx(Info, { size: iconSize.lg, "aria-hidden": "true" }),
|
|
@@ -1816,20 +1924,23 @@ var AlertModal = ({
|
|
|
1816
1924
|
destructive = false,
|
|
1817
1925
|
actionsAlign = "right",
|
|
1818
1926
|
showIcon = false,
|
|
1927
|
+
closeOnOverlay = true,
|
|
1819
1928
|
onConfirm,
|
|
1820
1929
|
onCancel,
|
|
1821
1930
|
onClose
|
|
1822
1931
|
}) => {
|
|
1823
|
-
const
|
|
1824
|
-
const
|
|
1825
|
-
const
|
|
1932
|
+
const dismiss = onCancel ?? onClose;
|
|
1933
|
+
const panelRef = React15.useRef(null);
|
|
1934
|
+
const titleId = React15.useId();
|
|
1935
|
+
const messageId = React15.useId();
|
|
1826
1936
|
const [shouldRender, setShouldRender] = useState(isOpen);
|
|
1827
1937
|
useFocusTrap(panelRef, isOpen);
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1938
|
+
useOverlayEscape(isOpen, () => dismiss());
|
|
1939
|
+
if (isOpen && !shouldRender) setShouldRender(true);
|
|
1940
|
+
const reduced = useReducedMotion();
|
|
1831
1941
|
const overlayStyle = useSpring({
|
|
1832
1942
|
opacity: isOpen ? 1 : 0,
|
|
1943
|
+
immediate: reduced,
|
|
1833
1944
|
config: { tension: 280, friction: 28, clamp: !isOpen },
|
|
1834
1945
|
onRest: (result) => {
|
|
1835
1946
|
if (!isOpen && result.finished) setShouldRender(false);
|
|
@@ -1838,9 +1949,31 @@ var AlertModal = ({
|
|
|
1838
1949
|
const panelStyle = useSpring({
|
|
1839
1950
|
opacity: isOpen ? 1 : 0,
|
|
1840
1951
|
transform: isOpen ? "scale(1) translateY(0px)" : "scale(0.96) translateY(-4px)",
|
|
1952
|
+
immediate: reduced,
|
|
1841
1953
|
config: { tension: 280, friction: 28, clamp: !isOpen }
|
|
1842
1954
|
});
|
|
1843
|
-
|
|
1955
|
+
React15.useEffect(() => {
|
|
1956
|
+
if (!shouldRender) return;
|
|
1957
|
+
const body = document.body;
|
|
1958
|
+
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
1959
|
+
if (openModals === 0) {
|
|
1960
|
+
body.dataset.originalOverflow = window.getComputedStyle(body).overflow;
|
|
1961
|
+
body.style.overflow = "hidden";
|
|
1962
|
+
}
|
|
1963
|
+
body.dataset.openModals = String(openModals + 1);
|
|
1964
|
+
return () => {
|
|
1965
|
+
const currentOpenModals = parseInt(body.dataset.openModals || "1", 10);
|
|
1966
|
+
const nextOpenModals = currentOpenModals - 1;
|
|
1967
|
+
if (nextOpenModals === 0) {
|
|
1968
|
+
body.style.overflow = body.dataset.originalOverflow || "";
|
|
1969
|
+
delete body.dataset.openModals;
|
|
1970
|
+
delete body.dataset.originalOverflow;
|
|
1971
|
+
} else {
|
|
1972
|
+
body.dataset.openModals = String(nextOpenModals);
|
|
1973
|
+
}
|
|
1974
|
+
};
|
|
1975
|
+
}, [shouldRender]);
|
|
1976
|
+
if (!isOpen && !shouldRender) return null;
|
|
1844
1977
|
const confirmVariant = "filled";
|
|
1845
1978
|
const cancelVariant = "outline";
|
|
1846
1979
|
const modalClassName = cn("alert_modal", `alert_variant_${variant}`);
|
|
@@ -1852,8 +1985,7 @@ var AlertModal = ({
|
|
|
1852
1985
|
className: "alert_overlay",
|
|
1853
1986
|
style: overlayStyle,
|
|
1854
1987
|
role: "presentation",
|
|
1855
|
-
onClick:
|
|
1856
|
-
onKeyDown: (e) => e.key === "Escape" && onClose(),
|
|
1988
|
+
onClick: () => closeOnOverlay && dismiss(),
|
|
1857
1989
|
children: /* @__PURE__ */ jsxs(
|
|
1858
1990
|
animated.div,
|
|
1859
1991
|
{
|
|
@@ -1933,12 +2065,12 @@ var Checkbox = ({
|
|
|
1933
2065
|
ref,
|
|
1934
2066
|
...props
|
|
1935
2067
|
}) => {
|
|
1936
|
-
const inputRef =
|
|
1937
|
-
|
|
2068
|
+
const inputRef = React15.useRef(null);
|
|
2069
|
+
React15.useImperativeHandle(
|
|
1938
2070
|
ref,
|
|
1939
2071
|
() => inputRef.current
|
|
1940
2072
|
);
|
|
1941
|
-
|
|
2073
|
+
React15.useEffect(() => {
|
|
1942
2074
|
if (!inputRef.current) return;
|
|
1943
2075
|
inputRef.current.indeterminate = Boolean(indeterminate);
|
|
1944
2076
|
}, [indeterminate]);
|
|
@@ -1949,7 +2081,16 @@ var Checkbox = ({
|
|
|
1949
2081
|
className
|
|
1950
2082
|
);
|
|
1951
2083
|
return /* @__PURE__ */ jsxs("label", { className: rootClassName, children: [
|
|
1952
|
-
/* @__PURE__ */ jsx(
|
|
2084
|
+
/* @__PURE__ */ jsx(
|
|
2085
|
+
"input",
|
|
2086
|
+
{
|
|
2087
|
+
...props,
|
|
2088
|
+
ref: inputRef,
|
|
2089
|
+
type: "checkbox",
|
|
2090
|
+
className: "checkbox_input",
|
|
2091
|
+
"aria-invalid": error || void 0
|
|
2092
|
+
}
|
|
2093
|
+
),
|
|
1953
2094
|
/* @__PURE__ */ jsx("span", { className: "checkbox_state_layer", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "checkbox_icon" }) }),
|
|
1954
2095
|
label ? /* @__PURE__ */ jsx("span", { className: "checkbox_label", children: label }) : null
|
|
1955
2096
|
] });
|
|
@@ -2012,9 +2153,11 @@ var Chip = ({
|
|
|
2012
2153
|
leadingIcon,
|
|
2013
2154
|
onClick,
|
|
2014
2155
|
onRemove,
|
|
2156
|
+
removeLabel,
|
|
2015
2157
|
className,
|
|
2016
2158
|
...props
|
|
2017
2159
|
}) => {
|
|
2160
|
+
const removeAriaLabel = removeLabel ?? `${label} \uC81C\uAC70`;
|
|
2018
2161
|
const [iconHovered, setIconHovered] = useState(false);
|
|
2019
2162
|
const isStatic = type === "static";
|
|
2020
2163
|
const hasLeading = !isStatic && selected;
|
|
@@ -2048,7 +2191,7 @@ var Chip = ({
|
|
|
2048
2191
|
className: "chip_trailing",
|
|
2049
2192
|
disabled,
|
|
2050
2193
|
onClick: onRemove,
|
|
2051
|
-
"aria-label":
|
|
2194
|
+
"aria-label": removeAriaLabel,
|
|
2052
2195
|
children: /* @__PURE__ */ jsx("span", { className: "chip_icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(CloseIcon, {}) })
|
|
2053
2196
|
}
|
|
2054
2197
|
)
|
|
@@ -2062,6 +2205,7 @@ var Chip = ({
|
|
|
2062
2205
|
className: "chip_content",
|
|
2063
2206
|
disabled,
|
|
2064
2207
|
onClick,
|
|
2208
|
+
"aria-pressed": type !== "filter" && selected !== void 0 ? selected : void 0,
|
|
2065
2209
|
...type === "filter" ? { "aria-haspopup": "listbox", "aria-expanded": !!open } : {},
|
|
2066
2210
|
children: [
|
|
2067
2211
|
hasLeading && /* @__PURE__ */ jsx(
|
|
@@ -2095,7 +2239,7 @@ var Chip = ({
|
|
|
2095
2239
|
className: "chip_trailing",
|
|
2096
2240
|
disabled,
|
|
2097
2241
|
onClick: onRemove,
|
|
2098
|
-
"aria-label":
|
|
2242
|
+
"aria-label": removeAriaLabel,
|
|
2099
2243
|
children: /* @__PURE__ */ jsx(
|
|
2100
2244
|
"span",
|
|
2101
2245
|
{
|
|
@@ -2123,7 +2267,8 @@ var Dropdown = (props) => {
|
|
|
2123
2267
|
searchable = false,
|
|
2124
2268
|
searchPlaceholder = "\uAC80\uC0C9\u2026",
|
|
2125
2269
|
emptyText = "\uACB0\uACFC \uC5C6\uC74C",
|
|
2126
|
-
selectedSummary = (count) => `${count}\uAC1C \uC120\uD0DD
|
|
2270
|
+
selectedSummary = (count) => `${count}\uAC1C \uC120\uD0DD`,
|
|
2271
|
+
name
|
|
2127
2272
|
} = props;
|
|
2128
2273
|
const multiple = props.multiple === true;
|
|
2129
2274
|
const internalId = useId();
|
|
@@ -2267,6 +2412,9 @@ var Dropdown = (props) => {
|
|
|
2267
2412
|
e.preventDefault();
|
|
2268
2413
|
setIsOpen(false);
|
|
2269
2414
|
break;
|
|
2415
|
+
case "Tab":
|
|
2416
|
+
setIsOpen(false);
|
|
2417
|
+
break;
|
|
2270
2418
|
}
|
|
2271
2419
|
};
|
|
2272
2420
|
const onSearchKeyDown = (e) => {
|
|
@@ -2288,6 +2436,9 @@ var Dropdown = (props) => {
|
|
|
2288
2436
|
e.preventDefault();
|
|
2289
2437
|
closePanel();
|
|
2290
2438
|
break;
|
|
2439
|
+
case "Tab":
|
|
2440
|
+
closePanel();
|
|
2441
|
+
break;
|
|
2291
2442
|
}
|
|
2292
2443
|
};
|
|
2293
2444
|
useEffect(() => {
|
|
@@ -2342,7 +2493,7 @@ var Dropdown = (props) => {
|
|
|
2342
2493
|
className: cn("dropdown_control", { is_disabled: disabled }),
|
|
2343
2494
|
"aria-haspopup": "listbox",
|
|
2344
2495
|
"aria-expanded": isOpen,
|
|
2345
|
-
"aria-controls": `${dropdownId}_listbox
|
|
2496
|
+
"aria-controls": isOpen ? `${dropdownId}_listbox` : void 0,
|
|
2346
2497
|
onClick: () => !disabled && setIsOpen((o) => !o),
|
|
2347
2498
|
onKeyDown: onControlKeyDown,
|
|
2348
2499
|
disabled,
|
|
@@ -2352,6 +2503,7 @@ var Dropdown = (props) => {
|
|
|
2352
2503
|
]
|
|
2353
2504
|
}
|
|
2354
2505
|
) }),
|
|
2506
|
+
name && (multiple ? selectedValues.map((v) => /* @__PURE__ */ jsx("input", { type: "hidden", name, value: v, disabled }, v)) : /* @__PURE__ */ jsx("input", { type: "hidden", name, value: selectedValues[0] ?? "", disabled })),
|
|
2355
2507
|
isOpen && /* @__PURE__ */ jsxs(animated.div, { className: listClassName, style: listStyle, children: [
|
|
2356
2508
|
searchable && /* @__PURE__ */ jsxs("div", { className: "dropdown_search", children: [
|
|
2357
2509
|
/* @__PURE__ */ jsx("span", { className: "dropdown_search_icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(Search, { size: iconSize.sm }) }),
|
|
@@ -2456,9 +2608,9 @@ var DatePicker = ({
|
|
|
2456
2608
|
minDateSrFormat = "Minimum date: {date}",
|
|
2457
2609
|
selectableRangeUntilTodaySrText = "Selectable up to today"
|
|
2458
2610
|
}) => {
|
|
2459
|
-
const groupId =
|
|
2460
|
-
const constraintId =
|
|
2461
|
-
const { todayYear, todayMonth, todayDay } =
|
|
2611
|
+
const groupId = React15.useId();
|
|
2612
|
+
const constraintId = React15.useId();
|
|
2613
|
+
const { todayYear, todayMonth, todayDay } = React15.useMemo(() => {
|
|
2462
2614
|
const now = /* @__PURE__ */ new Date();
|
|
2463
2615
|
return {
|
|
2464
2616
|
todayYear: now.getFullYear(),
|
|
@@ -2467,7 +2619,7 @@ var DatePicker = ({
|
|
|
2467
2619
|
};
|
|
2468
2620
|
}, []);
|
|
2469
2621
|
const endYear = endYearProp ?? todayYear + 10;
|
|
2470
|
-
const parsed =
|
|
2622
|
+
const parsed = React15.useMemo(() => {
|
|
2471
2623
|
if (!value) return { year: 0, month: 0, day: 0 };
|
|
2472
2624
|
const [y, m, d] = value.split("-").map(Number);
|
|
2473
2625
|
return {
|
|
@@ -2476,7 +2628,7 @@ var DatePicker = ({
|
|
|
2476
2628
|
day: d || 0
|
|
2477
2629
|
};
|
|
2478
2630
|
}, [value]);
|
|
2479
|
-
const min =
|
|
2631
|
+
const min = React15.useMemo(() => {
|
|
2480
2632
|
if (!minDate) return { year: 0, month: 0, day: 0 };
|
|
2481
2633
|
const [y, m, d] = minDate.split("-").map(Number);
|
|
2482
2634
|
return {
|
|
@@ -2496,7 +2648,7 @@ var DatePicker = ({
|
|
|
2496
2648
|
min.year > 0 && min.month > 0 && year === min.year && month === min.month ? min.day : 1
|
|
2497
2649
|
)
|
|
2498
2650
|
);
|
|
2499
|
-
const maxDay =
|
|
2651
|
+
const maxDay = React15.useMemo(() => {
|
|
2500
2652
|
if (!year || !month) return 31;
|
|
2501
2653
|
const daysInMonth = getDaysInMonth(year, month);
|
|
2502
2654
|
if (selectableRange === "until-today" && year === todayYear && month === todayMonth) {
|
|
@@ -2504,28 +2656,28 @@ var DatePicker = ({
|
|
|
2504
2656
|
}
|
|
2505
2657
|
return daysInMonth;
|
|
2506
2658
|
}, [year, month, selectableRange, todayYear, todayMonth, todayDay]);
|
|
2507
|
-
const yearOptions =
|
|
2659
|
+
const yearOptions = React15.useMemo(
|
|
2508
2660
|
() => range(startYear, maxYear).map((y) => ({
|
|
2509
2661
|
value: String(y),
|
|
2510
2662
|
label: String(y)
|
|
2511
2663
|
})),
|
|
2512
2664
|
[startYear, maxYear]
|
|
2513
2665
|
);
|
|
2514
|
-
const monthOptions =
|
|
2666
|
+
const monthOptions = React15.useMemo(
|
|
2515
2667
|
() => range(minMonth, Math.max(minMonth, maxMonth)).map((m) => ({
|
|
2516
2668
|
value: String(m),
|
|
2517
2669
|
label: pad(m)
|
|
2518
2670
|
})),
|
|
2519
2671
|
[minMonth, maxMonth]
|
|
2520
2672
|
);
|
|
2521
|
-
const dayOptions =
|
|
2673
|
+
const dayOptions = React15.useMemo(
|
|
2522
2674
|
() => range(minDay, Math.max(minDay, maxDay)).map((d) => ({
|
|
2523
2675
|
value: String(d),
|
|
2524
2676
|
label: pad(d)
|
|
2525
2677
|
})),
|
|
2526
2678
|
[minDay, maxDay]
|
|
2527
2679
|
);
|
|
2528
|
-
const emit =
|
|
2680
|
+
const emit = React15.useCallback(
|
|
2529
2681
|
(yy, mm, dd) => {
|
|
2530
2682
|
const cb = onValueChange ?? onChange;
|
|
2531
2683
|
if (mode === "year-month") {
|
|
@@ -2537,7 +2689,7 @@ var DatePicker = ({
|
|
|
2537
2689
|
},
|
|
2538
2690
|
[mode, onValueChange, onChange]
|
|
2539
2691
|
);
|
|
2540
|
-
const handleYearChange =
|
|
2692
|
+
const handleYearChange = React15.useCallback(
|
|
2541
2693
|
(raw) => {
|
|
2542
2694
|
if (!raw) return;
|
|
2543
2695
|
const newYear = Number(raw);
|
|
@@ -2554,14 +2706,14 @@ var DatePicker = ({
|
|
|
2554
2706
|
},
|
|
2555
2707
|
[month, day, min.year, min.month, selectableRange, todayYear, todayMonth, emit]
|
|
2556
2708
|
);
|
|
2557
|
-
const handleMonthChange =
|
|
2709
|
+
const handleMonthChange = React15.useCallback(
|
|
2558
2710
|
(raw) => {
|
|
2559
2711
|
if (!raw || !year) return;
|
|
2560
2712
|
emit(year, Number(raw), day || void 0);
|
|
2561
2713
|
},
|
|
2562
2714
|
[year, day, emit]
|
|
2563
2715
|
);
|
|
2564
|
-
const handleDayChange =
|
|
2716
|
+
const handleDayChange = React15.useCallback(
|
|
2565
2717
|
(raw) => {
|
|
2566
2718
|
if (!raw || !year || !month) return;
|
|
2567
2719
|
emit(year, month, Number(raw));
|
|
@@ -2656,11 +2808,13 @@ var Drawer = ({
|
|
|
2656
2808
|
className,
|
|
2657
2809
|
...props
|
|
2658
2810
|
}) => {
|
|
2659
|
-
const panelRef =
|
|
2660
|
-
const titleId =
|
|
2661
|
-
const [shouldRender, setShouldRender] =
|
|
2811
|
+
const panelRef = React15.useRef(null);
|
|
2812
|
+
const titleId = React15.useId();
|
|
2813
|
+
const [shouldRender, setShouldRender] = React15.useState(open);
|
|
2662
2814
|
const reduced = useReducedMotion();
|
|
2663
|
-
|
|
2815
|
+
const isMounted = useIsMounted();
|
|
2816
|
+
useFocusTrap(panelRef, open && isMounted);
|
|
2817
|
+
useOverlayEscape(open && isMounted, () => onClose?.());
|
|
2664
2818
|
if (open && !shouldRender) setShouldRender(true);
|
|
2665
2819
|
const overlayStyle = useSpringPresence({
|
|
2666
2820
|
visible: open,
|
|
@@ -2675,7 +2829,7 @@ var Drawer = ({
|
|
|
2675
2829
|
immediate: reduced,
|
|
2676
2830
|
config: { tension: 280, friction: 28, clamp: !open }
|
|
2677
2831
|
});
|
|
2678
|
-
|
|
2832
|
+
React15.useEffect(() => {
|
|
2679
2833
|
if (!open) return;
|
|
2680
2834
|
const body = document.body;
|
|
2681
2835
|
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
@@ -2697,55 +2851,53 @@ var Drawer = ({
|
|
|
2697
2851
|
};
|
|
2698
2852
|
}, [open]);
|
|
2699
2853
|
if (!open && !shouldRender) return null;
|
|
2854
|
+
if (typeof document === "undefined" || !isMounted) return null;
|
|
2700
2855
|
const hasTitle = !!title;
|
|
2701
2856
|
const sizeValue = typeof size === "number" ? `${size}px` : size;
|
|
2702
2857
|
const panelSizeStyle = placement === "bottom" ? { height: sizeValue } : { width: sizeValue };
|
|
2703
|
-
return
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
}
|
|
2747
|
-
)
|
|
2748
|
-
}
|
|
2858
|
+
return createPortal(
|
|
2859
|
+
/* @__PURE__ */ jsx(
|
|
2860
|
+
animated.div,
|
|
2861
|
+
{
|
|
2862
|
+
className: cn("drawer", `drawer_placement_${placement}`),
|
|
2863
|
+
style: overlayStyle,
|
|
2864
|
+
role: "dialog",
|
|
2865
|
+
"aria-modal": "true",
|
|
2866
|
+
"aria-labelledby": hasTitle && !ariaLabel ? titleId : void 0,
|
|
2867
|
+
"aria-label": !hasTitle ? ariaLabel ?? "Dialog" : ariaLabel,
|
|
2868
|
+
onClick: () => closeOnOverlay && onClose?.(),
|
|
2869
|
+
children: /* @__PURE__ */ jsxs(
|
|
2870
|
+
animated.div,
|
|
2871
|
+
{
|
|
2872
|
+
ref: panelRef,
|
|
2873
|
+
...props,
|
|
2874
|
+
className: cn("drawer_panel", className),
|
|
2875
|
+
style: { ...props.style, ...panelStyle, ...panelSizeStyle },
|
|
2876
|
+
role: "document",
|
|
2877
|
+
onClick: (e) => e.stopPropagation(),
|
|
2878
|
+
onKeyDown: (e) => {
|
|
2879
|
+
if (e.key !== "Escape") e.stopPropagation();
|
|
2880
|
+
},
|
|
2881
|
+
children: [
|
|
2882
|
+
showCloseIcon && onClose && /* @__PURE__ */ jsx(
|
|
2883
|
+
"button",
|
|
2884
|
+
{
|
|
2885
|
+
type: "button",
|
|
2886
|
+
className: "drawer_close",
|
|
2887
|
+
onClick: onClose,
|
|
2888
|
+
"aria-label": closeLabel,
|
|
2889
|
+
children: /* @__PURE__ */ jsx(X, { size: iconSize.md, "aria-hidden": "true" })
|
|
2890
|
+
}
|
|
2891
|
+
),
|
|
2892
|
+
title && /* @__PURE__ */ jsx("div", { className: "drawer_header", children: /* @__PURE__ */ jsx("h2", { id: titleId, className: "drawer_title", children: title }) }),
|
|
2893
|
+
children && /* @__PURE__ */ jsx("div", { className: "drawer_body", children }),
|
|
2894
|
+
footer && /* @__PURE__ */ jsx("div", { className: "drawer_footer", children: footer })
|
|
2895
|
+
]
|
|
2896
|
+
}
|
|
2897
|
+
)
|
|
2898
|
+
}
|
|
2899
|
+
),
|
|
2900
|
+
document.body
|
|
2749
2901
|
);
|
|
2750
2902
|
};
|
|
2751
2903
|
Drawer.displayName = "Drawer";
|
|
@@ -2762,11 +2914,11 @@ var FileInput = ({
|
|
|
2762
2914
|
onChange,
|
|
2763
2915
|
...props
|
|
2764
2916
|
}) => {
|
|
2765
|
-
const inputId =
|
|
2766
|
-
const helperId =
|
|
2767
|
-
const inputRef =
|
|
2768
|
-
const [previewUrls, setPreviewUrls] =
|
|
2769
|
-
const previewUrlsRef =
|
|
2917
|
+
const inputId = React15.useId();
|
|
2918
|
+
const helperId = React15.useId();
|
|
2919
|
+
const inputRef = React15.useRef(null);
|
|
2920
|
+
const [previewUrls, setPreviewUrls] = React15.useState([]);
|
|
2921
|
+
const previewUrlsRef = React15.useRef([]);
|
|
2770
2922
|
const isPreviewVariant = variant === "preview";
|
|
2771
2923
|
const showPreview = isPreviewVariant || preview;
|
|
2772
2924
|
const handleChange = (e) => {
|
|
@@ -2807,7 +2959,7 @@ var FileInput = ({
|
|
|
2807
2959
|
}
|
|
2808
2960
|
onFiles?.(null);
|
|
2809
2961
|
};
|
|
2810
|
-
|
|
2962
|
+
React15.useEffect(() => {
|
|
2811
2963
|
return () => {
|
|
2812
2964
|
for (const url of previewUrlsRef.current) {
|
|
2813
2965
|
URL.revokeObjectURL(url);
|
|
@@ -2884,6 +3036,10 @@ var FileInput = ({
|
|
|
2884
3036
|
)) })
|
|
2885
3037
|
] });
|
|
2886
3038
|
};
|
|
3039
|
+
var HeroActionButton = ({
|
|
3040
|
+
action,
|
|
3041
|
+
variant
|
|
3042
|
+
}) => action.href ? /* @__PURE__ */ jsx(Button, { as: "a", href: action.href, size: "lg", variant, onClick: action.onClick, children: action.label }) : /* @__PURE__ */ jsx(Button, { size: "lg", variant, onClick: action.onClick, children: action.label });
|
|
2887
3043
|
var Hero = ({
|
|
2888
3044
|
height = "md",
|
|
2889
3045
|
align = "left",
|
|
@@ -2922,8 +3078,8 @@ var Hero = ({
|
|
|
2922
3078
|
title && /* @__PURE__ */ jsx("h1", { className: "hero_title", children: title }),
|
|
2923
3079
|
subtitle && /* @__PURE__ */ jsx("p", { className: "hero_subtitle", children: subtitle }),
|
|
2924
3080
|
(primaryAction || secondaryAction || children) && /* @__PURE__ */ jsxs("div", { className: "hero_actions", children: [
|
|
2925
|
-
primaryAction && /* @__PURE__ */ jsx(
|
|
2926
|
-
secondaryAction && /* @__PURE__ */ jsx(
|
|
3081
|
+
primaryAction && /* @__PURE__ */ jsx(HeroActionButton, { action: primaryAction, variant: "filled" }),
|
|
3082
|
+
secondaryAction && /* @__PURE__ */ jsx(HeroActionButton, { action: secondaryAction, variant: "outline" }),
|
|
2927
3083
|
children
|
|
2928
3084
|
] })
|
|
2929
3085
|
] })
|
|
@@ -3035,7 +3191,7 @@ var ListItem = ({
|
|
|
3035
3191
|
role: onClick ? "button" : void 0,
|
|
3036
3192
|
tabIndex: onClick && !disabled ? 0 : void 0,
|
|
3037
3193
|
"aria-disabled": disabled || void 0,
|
|
3038
|
-
"aria-
|
|
3194
|
+
"aria-pressed": onClick && selected !== void 0 ? selected : void 0,
|
|
3039
3195
|
...props,
|
|
3040
3196
|
children: /* @__PURE__ */ jsxs("div", { className: "list_item_state_layer", children: [
|
|
3041
3197
|
leadingElement && /* @__PURE__ */ jsx("div", { className: "list_item_leading", children: leadingElement }),
|
|
@@ -3106,13 +3262,17 @@ var Modal = ({
|
|
|
3106
3262
|
ariaLabel,
|
|
3107
3263
|
...props
|
|
3108
3264
|
}) => {
|
|
3109
|
-
const panelRef =
|
|
3110
|
-
const titleId =
|
|
3111
|
-
const [shouldRender, setShouldRender] =
|
|
3112
|
-
|
|
3265
|
+
const panelRef = React15.useRef(null);
|
|
3266
|
+
const titleId = React15.useId();
|
|
3267
|
+
const [shouldRender, setShouldRender] = React15.useState(open);
|
|
3268
|
+
const isMounted = useIsMounted();
|
|
3269
|
+
useFocusTrap(panelRef, open && isMounted);
|
|
3270
|
+
useOverlayEscape(open && isMounted, () => onClose?.());
|
|
3113
3271
|
if (open && !shouldRender) setShouldRender(true);
|
|
3272
|
+
const reduced = useReducedMotion();
|
|
3114
3273
|
const overlayStyle = useSpring({
|
|
3115
3274
|
opacity: open ? 1 : 0,
|
|
3275
|
+
immediate: reduced,
|
|
3116
3276
|
config: { tension: 280, friction: 28, clamp: !open },
|
|
3117
3277
|
onRest: (result) => {
|
|
3118
3278
|
if (!open && result.finished) setShouldRender(false);
|
|
@@ -3121,9 +3281,10 @@ var Modal = ({
|
|
|
3121
3281
|
const panelStyle = useSpring({
|
|
3122
3282
|
opacity: open ? 1 : 0,
|
|
3123
3283
|
transform: open ? "scale(1) translateY(0px)" : "scale(0.96) translateY(-4px)",
|
|
3284
|
+
immediate: reduced,
|
|
3124
3285
|
config: { tension: 280, friction: 28, clamp: !open }
|
|
3125
3286
|
});
|
|
3126
|
-
|
|
3287
|
+
React15.useEffect(() => {
|
|
3127
3288
|
if (!open) return;
|
|
3128
3289
|
const body = document.body;
|
|
3129
3290
|
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
@@ -3145,54 +3306,52 @@ var Modal = ({
|
|
|
3145
3306
|
};
|
|
3146
3307
|
}, [open]);
|
|
3147
3308
|
if (!open && !shouldRender) return null;
|
|
3309
|
+
if (typeof document === "undefined" || !isMounted) return null;
|
|
3148
3310
|
const hasTitle = !!title;
|
|
3149
|
-
return
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
}
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
}
|
|
3194
|
-
)
|
|
3195
|
-
}
|
|
3311
|
+
return createPortal(
|
|
3312
|
+
/* @__PURE__ */ jsx(
|
|
3313
|
+
animated.div,
|
|
3314
|
+
{
|
|
3315
|
+
className: "modal",
|
|
3316
|
+
style: overlayStyle,
|
|
3317
|
+
role: "dialog",
|
|
3318
|
+
"aria-modal": "true",
|
|
3319
|
+
"aria-labelledby": hasTitle && !ariaLabel ? titleId : void 0,
|
|
3320
|
+
"aria-label": !hasTitle ? ariaLabel ?? "Dialog" : ariaLabel,
|
|
3321
|
+
onClick: () => closeOnOverlay && onClose?.(),
|
|
3322
|
+
children: /* @__PURE__ */ jsxs(
|
|
3323
|
+
animated.div,
|
|
3324
|
+
{
|
|
3325
|
+
ref: panelRef,
|
|
3326
|
+
...props,
|
|
3327
|
+
className: cn("modal_panel", className),
|
|
3328
|
+
style: { ...props.style, ...panelStyle, width },
|
|
3329
|
+
role: "document",
|
|
3330
|
+
onClick: (e) => e.stopPropagation(),
|
|
3331
|
+
onKeyDown: (e) => {
|
|
3332
|
+
if (e.key !== "Escape") e.stopPropagation();
|
|
3333
|
+
},
|
|
3334
|
+
children: [
|
|
3335
|
+
showCloseIcon && onClose && /* @__PURE__ */ jsx(
|
|
3336
|
+
"button",
|
|
3337
|
+
{
|
|
3338
|
+
type: "button",
|
|
3339
|
+
className: "modal_close",
|
|
3340
|
+
onClick: onClose,
|
|
3341
|
+
"aria-label": closeLabel,
|
|
3342
|
+
children: /* @__PURE__ */ jsx(X, { size: iconSize.md, "aria-hidden": "true" })
|
|
3343
|
+
}
|
|
3344
|
+
),
|
|
3345
|
+
title && /* @__PURE__ */ jsx("h2", { id: titleId, className: "modal_title", children: title }),
|
|
3346
|
+
description && /* @__PURE__ */ jsx("div", { className: "modal_description", children: description }),
|
|
3347
|
+
children && /* @__PURE__ */ jsx("div", { className: "modal_body", children }),
|
|
3348
|
+
footer && /* @__PURE__ */ jsx("div", { className: cn("modal_footer", `modal_footer_${footerAlign}`), children: footer })
|
|
3349
|
+
]
|
|
3350
|
+
}
|
|
3351
|
+
)
|
|
3352
|
+
}
|
|
3353
|
+
),
|
|
3354
|
+
document.body
|
|
3196
3355
|
);
|
|
3197
3356
|
};
|
|
3198
3357
|
var OtpInput = ({
|
|
@@ -3207,12 +3366,12 @@ var OtpInput = ({
|
|
|
3207
3366
|
ariaLabel = "OTP \uC785\uB825",
|
|
3208
3367
|
className
|
|
3209
3368
|
}) => {
|
|
3210
|
-
const inputsRef =
|
|
3211
|
-
const isTypingRef =
|
|
3212
|
-
|
|
3369
|
+
const inputsRef = React15.useRef([]);
|
|
3370
|
+
const isTypingRef = React15.useRef(false);
|
|
3371
|
+
React15.useEffect(() => {
|
|
3213
3372
|
if (autoFocus) inputsRef.current[0]?.focus();
|
|
3214
3373
|
}, [autoFocus]);
|
|
3215
|
-
const digits =
|
|
3374
|
+
const digits = React15.useMemo(() => {
|
|
3216
3375
|
const chars = value.split("").slice(0, length);
|
|
3217
3376
|
while (chars.length < length) chars.push("");
|
|
3218
3377
|
return chars;
|
|
@@ -3225,6 +3384,15 @@ var OtpInput = ({
|
|
|
3225
3384
|
};
|
|
3226
3385
|
const handleChange = (index, e) => {
|
|
3227
3386
|
const nextDigit = e.target.value;
|
|
3387
|
+
if (index === 0 && nextDigit.length > 1) {
|
|
3388
|
+
const filled = nextDigit.replace(/\D/g, "").slice(0, length);
|
|
3389
|
+
if (!filled) return;
|
|
3390
|
+
const newDigits2 = [...digits];
|
|
3391
|
+
for (let i = 0; i < filled.length; i++) newDigits2[i] = filled[i];
|
|
3392
|
+
updateValue(newDigits2);
|
|
3393
|
+
focusInput(Math.min(filled.length, length - 1));
|
|
3394
|
+
return;
|
|
3395
|
+
}
|
|
3228
3396
|
if (nextDigit && !/^\d$/.test(nextDigit)) return;
|
|
3229
3397
|
const newDigits = [...digits];
|
|
3230
3398
|
newDigits[index] = nextDigit;
|
|
@@ -3244,7 +3412,7 @@ var OtpInput = ({
|
|
|
3244
3412
|
focusInput(firstEmpty);
|
|
3245
3413
|
}
|
|
3246
3414
|
};
|
|
3247
|
-
const
|
|
3415
|
+
const handleKeyDown2 = (index, e) => {
|
|
3248
3416
|
if (e.key === "Backspace") {
|
|
3249
3417
|
if (digits[index]) {
|
|
3250
3418
|
const newDigits = [...digits];
|
|
@@ -3280,6 +3448,7 @@ var OtpInput = ({
|
|
|
3280
3448
|
focusInput(nextIndex);
|
|
3281
3449
|
};
|
|
3282
3450
|
const rootClassName = cn("otp_input", className);
|
|
3451
|
+
const supportingId = React15.useId();
|
|
3283
3452
|
return (
|
|
3284
3453
|
// biome-ignore lint/a11y/useSemanticElements: <fieldset> would force border/legend styles; role=group is the WAI-ARIA equivalent for OTP grouping
|
|
3285
3454
|
/* @__PURE__ */ jsxs("div", { className: rootClassName, role: "group", "aria-label": ariaLabel, children: [
|
|
@@ -3293,13 +3462,16 @@ var OtpInput = ({
|
|
|
3293
3462
|
inputMode: "numeric",
|
|
3294
3463
|
pattern: "\\d*",
|
|
3295
3464
|
maxLength: 1,
|
|
3465
|
+
autoComplete: i === 0 ? "one-time-code" : "off",
|
|
3296
3466
|
value: digit,
|
|
3297
3467
|
onChange: (e) => handleChange(i, e),
|
|
3298
3468
|
onFocus: () => handleFocus(i),
|
|
3299
|
-
onKeyDown: (e) =>
|
|
3469
|
+
onKeyDown: (e) => handleKeyDown2(i, e),
|
|
3300
3470
|
onPaste: handlePaste,
|
|
3301
3471
|
disabled,
|
|
3302
3472
|
"aria-label": `${i + 1}\uBC88\uC9F8 \uC790\uB9AC`,
|
|
3473
|
+
"aria-invalid": error || void 0,
|
|
3474
|
+
"aria-describedby": supportingText ? supportingId : void 0,
|
|
3303
3475
|
className: cn(
|
|
3304
3476
|
"otp_input_box",
|
|
3305
3477
|
error && "otp_input_box_error",
|
|
@@ -3308,7 +3480,14 @@ var OtpInput = ({
|
|
|
3308
3480
|
},
|
|
3309
3481
|
i
|
|
3310
3482
|
)) }),
|
|
3311
|
-
supportingText && /* @__PURE__ */ jsx(
|
|
3483
|
+
supportingText && /* @__PURE__ */ jsx(
|
|
3484
|
+
"span",
|
|
3485
|
+
{
|
|
3486
|
+
id: supportingId,
|
|
3487
|
+
className: cn("otp_input_supporting", error && "otp_input_supporting_error"),
|
|
3488
|
+
children: supportingText
|
|
3489
|
+
}
|
|
3490
|
+
)
|
|
3312
3491
|
] })
|
|
3313
3492
|
);
|
|
3314
3493
|
};
|
|
@@ -3353,7 +3532,7 @@ var Pagination = ({
|
|
|
3353
3532
|
const emit = onPageChange ?? onChange;
|
|
3354
3533
|
const prevDisabled = page <= 1;
|
|
3355
3534
|
const nextDisabled = page >= totalPages;
|
|
3356
|
-
const items =
|
|
3535
|
+
const items = React15.useMemo(() => getPaginationItems(page, totalPages), [page, totalPages]);
|
|
3357
3536
|
return /* @__PURE__ */ jsxs("nav", { className: "pagination", "aria-label": "Pagination", children: [
|
|
3358
3537
|
/* @__PURE__ */ jsx(
|
|
3359
3538
|
"button",
|
|
@@ -3398,9 +3577,9 @@ var Pagination = ({
|
|
|
3398
3577
|
)
|
|
3399
3578
|
] });
|
|
3400
3579
|
};
|
|
3401
|
-
var RadioGroupContext =
|
|
3580
|
+
var RadioGroupContext = React15.createContext(null);
|
|
3402
3581
|
function useRadioGroupContext() {
|
|
3403
|
-
return
|
|
3582
|
+
return React15.useContext(RadioGroupContext);
|
|
3404
3583
|
}
|
|
3405
3584
|
var RadioGroup = ({
|
|
3406
3585
|
value: controlledValue,
|
|
@@ -3418,21 +3597,21 @@ var RadioGroup = ({
|
|
|
3418
3597
|
...props
|
|
3419
3598
|
}) => {
|
|
3420
3599
|
const isControlled = controlledValue !== void 0;
|
|
3421
|
-
const [internalValue, setInternalValue] =
|
|
3600
|
+
const [internalValue, setInternalValue] = React15.useState(defaultValue);
|
|
3422
3601
|
const value = isControlled ? controlledValue : internalValue;
|
|
3423
|
-
const generatedName =
|
|
3602
|
+
const generatedName = React15.useId();
|
|
3424
3603
|
const name = nameProp ?? generatedName;
|
|
3425
|
-
const idPrefix =
|
|
3604
|
+
const idPrefix = React15.useId();
|
|
3426
3605
|
const labelId = label ? `${idPrefix}-label` : void 0;
|
|
3427
3606
|
const helperId = supportingText ? `${idPrefix}-help` : void 0;
|
|
3428
|
-
const onChange =
|
|
3607
|
+
const onChange = React15.useCallback(
|
|
3429
3608
|
(next) => {
|
|
3430
3609
|
if (!isControlled) setInternalValue(next);
|
|
3431
3610
|
onValueChange?.(next);
|
|
3432
3611
|
},
|
|
3433
3612
|
[isControlled, onValueChange]
|
|
3434
3613
|
);
|
|
3435
|
-
const ctx =
|
|
3614
|
+
const ctx = React15.useMemo(
|
|
3436
3615
|
() => ({ name, value, onChange, size, disabled }),
|
|
3437
3616
|
[name, value, onChange, size, disabled]
|
|
3438
3617
|
);
|
|
@@ -3481,7 +3660,7 @@ var Radio = ({
|
|
|
3481
3660
|
const size = sizeProp ?? group?.size ?? "md";
|
|
3482
3661
|
const name = nameProp ?? group?.name;
|
|
3483
3662
|
const disabled = disabledProp ?? group?.disabled;
|
|
3484
|
-
const resolvedChecked = group ? group.value === value : checked;
|
|
3663
|
+
const resolvedChecked = group ? value !== void 0 && group.value != null && String(group.value) === String(value) : checked;
|
|
3485
3664
|
const handleChange = (event) => {
|
|
3486
3665
|
if (group && value !== void 0) group.onChange(String(value));
|
|
3487
3666
|
onChange?.(event);
|
|
@@ -3581,8 +3760,8 @@ var Table = ({
|
|
|
3581
3760
|
const isEmpty = !isLoading && data.length === 0;
|
|
3582
3761
|
const getRowKey = (item, index) => rowKey?.(item) ?? String(index);
|
|
3583
3762
|
const allRowKeys = selectable ? data.map((item, index) => getRowKey(item, index)) : [];
|
|
3584
|
-
const rowClickHintId =
|
|
3585
|
-
const selectedSet =
|
|
3763
|
+
const rowClickHintId = React15.useId();
|
|
3764
|
+
const selectedSet = React15.useMemo(() => new Set(selectedKeys ?? []), [selectedKeys]);
|
|
3586
3765
|
const selectedCount = allRowKeys.filter((key) => selectedSet.has(key)).length;
|
|
3587
3766
|
const isAllSelected = allRowKeys.length > 0 && selectedCount === allRowKeys.length;
|
|
3588
3767
|
const isSomeSelected = selectedCount > 0 && !isAllSelected;
|
|
@@ -3601,7 +3780,7 @@ var Table = ({
|
|
|
3601
3780
|
onSortChange?.(next);
|
|
3602
3781
|
};
|
|
3603
3782
|
return /* @__PURE__ */ jsxs("div", { className: wrapperClassName, children: [
|
|
3604
|
-
/* @__PURE__ */ jsxs("table", { className: "table", "aria-label": ariaLabel, children: [
|
|
3783
|
+
/* @__PURE__ */ jsxs("table", { className: "table", "aria-label": ariaLabel, "aria-busy": isLoading || void 0, children: [
|
|
3605
3784
|
/* @__PURE__ */ jsx("thead", { className: "table_thead", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
3606
3785
|
selectable && /* @__PURE__ */ jsx("th", { scope: "col", className: "table_th table_th_checkbox", children: /* @__PURE__ */ jsx(
|
|
3607
3786
|
Checkbox,
|
|
@@ -3743,9 +3922,9 @@ var Table = ({
|
|
|
3743
3922
|
isEmpty && /* @__PURE__ */ jsx("div", { className: "table_empty", role: "status", children: emptyMessage })
|
|
3744
3923
|
] });
|
|
3745
3924
|
};
|
|
3746
|
-
var ThemeContext =
|
|
3925
|
+
var ThemeContext = React15.createContext(null);
|
|
3747
3926
|
var useTheme = () => {
|
|
3748
|
-
const ctx =
|
|
3927
|
+
const ctx = React15.useContext(ThemeContext);
|
|
3749
3928
|
if (!ctx) {
|
|
3750
3929
|
throw new Error(
|
|
3751
3930
|
'[Bigtablet DS] useTheme\uB294 <ThemeProvider> \uC548\uC5D0\uC11C\uB9CC \uC0AC\uC6A9 \uAC00\uB2A5\uD569\uB2C8\uB2E4.\n\n\uC571 \uCD5C\uC0C1\uB2E8\uC5D0 <ThemeProvider>\uB85C \uAC10\uC2F8\uC8FC\uC138\uC694:\n <ThemeProvider mode="system">\n <YourApp />\n </ThemeProvider>'
|
|
@@ -3769,15 +3948,15 @@ var ThemeProvider = ({
|
|
|
3769
3948
|
targetSelector,
|
|
3770
3949
|
children
|
|
3771
3950
|
}) => {
|
|
3772
|
-
const [mode, setModeState] =
|
|
3773
|
-
const [systemDark, setSystemDark] =
|
|
3774
|
-
|
|
3951
|
+
const [mode, setModeState] = React15.useState(defaultMode);
|
|
3952
|
+
const [systemDark, setSystemDark] = React15.useState(false);
|
|
3953
|
+
React15.useEffect(() => {
|
|
3775
3954
|
setModeState(readStored(storageKey) ?? defaultMode);
|
|
3776
3955
|
if (isClient) {
|
|
3777
3956
|
setSystemDark(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
|
3778
3957
|
}
|
|
3779
3958
|
}, [storageKey, defaultMode]);
|
|
3780
|
-
|
|
3959
|
+
React15.useEffect(() => {
|
|
3781
3960
|
if (!isClient) return;
|
|
3782
3961
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
3783
3962
|
const handler = (e) => setSystemDark(e.matches);
|
|
@@ -3785,7 +3964,7 @@ var ThemeProvider = ({
|
|
|
3785
3964
|
return () => mq.removeEventListener("change", handler);
|
|
3786
3965
|
}, []);
|
|
3787
3966
|
const resolved = mode === "system" ? systemDark ? "dark" : "light" : mode;
|
|
3788
|
-
|
|
3967
|
+
React15.useEffect(() => {
|
|
3789
3968
|
if (!isClient) return;
|
|
3790
3969
|
const target = targetSelector ? document.querySelector(targetSelector) : document.documentElement;
|
|
3791
3970
|
if (!target) return;
|
|
@@ -3795,7 +3974,7 @@ var ThemeProvider = ({
|
|
|
3795
3974
|
target.setAttribute("data-theme", mode);
|
|
3796
3975
|
}
|
|
3797
3976
|
}, [mode, targetSelector]);
|
|
3798
|
-
const setMode =
|
|
3977
|
+
const setMode = React15.useCallback(
|
|
3799
3978
|
(next) => {
|
|
3800
3979
|
setModeState(next);
|
|
3801
3980
|
if (storageKey && isClient) {
|
|
@@ -3807,7 +3986,7 @@ var ThemeProvider = ({
|
|
|
3807
3986
|
},
|
|
3808
3987
|
[storageKey]
|
|
3809
3988
|
);
|
|
3810
|
-
const value =
|
|
3989
|
+
const value = React15.useMemo(
|
|
3811
3990
|
() => ({ mode, resolved, setMode }),
|
|
3812
3991
|
[mode, resolved, setMode]
|
|
3813
3992
|
);
|
|
@@ -4055,7 +4234,7 @@ var Textarea = ({
|
|
|
4055
4234
|
] });
|
|
4056
4235
|
};
|
|
4057
4236
|
Textarea.displayName = "Textarea";
|
|
4058
|
-
var ToastContext =
|
|
4237
|
+
var ToastContext = React15.createContext(null);
|
|
4059
4238
|
var VARIANT_ICONS = {
|
|
4060
4239
|
success: /* @__PURE__ */ jsx(CheckCircle2, { size: iconSize.md }),
|
|
4061
4240
|
error: /* @__PURE__ */ jsx(XCircle, { size: iconSize.md }),
|
|
@@ -4064,15 +4243,29 @@ var VARIANT_ICONS = {
|
|
|
4064
4243
|
default: /* @__PURE__ */ jsx(Bell, { size: iconSize.md })
|
|
4065
4244
|
};
|
|
4066
4245
|
var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
4067
|
-
const [visible, setVisible] =
|
|
4068
|
-
const closingRef =
|
|
4246
|
+
const [visible, setVisible] = React15.useState(true);
|
|
4247
|
+
const closingRef = React15.useRef(false);
|
|
4248
|
+
const rootRef = React15.useRef(null);
|
|
4069
4249
|
const style = useSpringPresence({
|
|
4070
4250
|
visible,
|
|
4071
4251
|
from: "translateX(20px)",
|
|
4072
4252
|
// 우측에서 슬라이드 인
|
|
4073
|
-
onExitComplete: () =>
|
|
4253
|
+
onExitComplete: () => {
|
|
4254
|
+
const hadFocus = rootRef.current?.contains(document.activeElement) ?? false;
|
|
4255
|
+
if (hadFocus) {
|
|
4256
|
+
const closeButtons = Array.from(
|
|
4257
|
+
document.querySelectorAll(".toast_item .toast_close")
|
|
4258
|
+
);
|
|
4259
|
+
const currentIndex = closeButtons.findIndex((el) => rootRef.current?.contains(el));
|
|
4260
|
+
if (currentIndex !== -1) {
|
|
4261
|
+
const next = closeButtons[currentIndex + 1] || closeButtons[currentIndex - 1];
|
|
4262
|
+
next?.focus();
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
onRemove(item.id);
|
|
4266
|
+
}
|
|
4074
4267
|
});
|
|
4075
|
-
const close =
|
|
4268
|
+
const close = React15.useCallback(() => {
|
|
4076
4269
|
if (closingRef.current) return;
|
|
4077
4270
|
closingRef.current = true;
|
|
4078
4271
|
setVisible(false);
|
|
@@ -4080,6 +4273,7 @@ var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
|
4080
4273
|
return /* @__PURE__ */ jsxs(
|
|
4081
4274
|
animated.div,
|
|
4082
4275
|
{
|
|
4276
|
+
ref: rootRef,
|
|
4083
4277
|
className: "toast_item",
|
|
4084
4278
|
style,
|
|
4085
4279
|
role: item.variant === "error" ? "alert" : "status",
|
|
@@ -4105,22 +4299,19 @@ var ToastProvider = ({
|
|
|
4105
4299
|
maxCount = 5,
|
|
4106
4300
|
closeAriaLabel = "Close"
|
|
4107
4301
|
}) => {
|
|
4108
|
-
const [toasts, setToasts] =
|
|
4109
|
-
const
|
|
4110
|
-
|
|
4111
|
-
setIsMounted(true);
|
|
4112
|
-
}, []);
|
|
4113
|
-
const addToast = React19.useCallback(
|
|
4302
|
+
const [toasts, setToasts] = React15.useState([]);
|
|
4303
|
+
const isMounted = useIsMounted();
|
|
4304
|
+
const addToast = React15.useCallback(
|
|
4114
4305
|
(message, variant, duration = 3e3) => {
|
|
4115
4306
|
const id = crypto.randomUUID();
|
|
4116
4307
|
setToasts((prev) => [{ id, message, variant, duration }, ...prev].slice(0, maxCount));
|
|
4117
4308
|
},
|
|
4118
4309
|
[maxCount]
|
|
4119
4310
|
);
|
|
4120
|
-
const removeToast =
|
|
4311
|
+
const removeToast = React15.useCallback((id) => {
|
|
4121
4312
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
4122
4313
|
}, []);
|
|
4123
|
-
const contextValue =
|
|
4314
|
+
const contextValue = React15.useMemo(() => ({ addToast }), [addToast]);
|
|
4124
4315
|
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: contextValue, children: [
|
|
4125
4316
|
children,
|
|
4126
4317
|
isMounted && createPortal(
|
|
@@ -4181,10 +4372,11 @@ var Toggle = ({
|
|
|
4181
4372
|
...props
|
|
4182
4373
|
}) => {
|
|
4183
4374
|
const isControlled = checked !== void 0;
|
|
4184
|
-
const [innerChecked, setInnerChecked] =
|
|
4375
|
+
const [innerChecked, setInnerChecked] = React15.useState(!!defaultChecked);
|
|
4185
4376
|
const isOn = isControlled ? !!checked : innerChecked;
|
|
4186
|
-
const handleToggle = () => {
|
|
4187
|
-
|
|
4377
|
+
const handleToggle = (e) => {
|
|
4378
|
+
props.onClick?.(e);
|
|
4379
|
+
if (disabled || e.defaultPrevented) return;
|
|
4188
4380
|
const next = !isOn;
|
|
4189
4381
|
if (!isControlled) setInnerChecked(next);
|
|
4190
4382
|
(onCheckedChange ?? onChange)?.(next);
|
|
@@ -4198,6 +4390,7 @@ var Toggle = ({
|
|
|
4198
4390
|
return /* @__PURE__ */ jsx(
|
|
4199
4391
|
"button",
|
|
4200
4392
|
{
|
|
4393
|
+
...props,
|
|
4201
4394
|
ref,
|
|
4202
4395
|
type: "button",
|
|
4203
4396
|
role: "switch",
|
|
@@ -4206,7 +4399,6 @@ var Toggle = ({
|
|
|
4206
4399
|
disabled,
|
|
4207
4400
|
onClick: handleToggle,
|
|
4208
4401
|
className: rootClassName,
|
|
4209
|
-
...props,
|
|
4210
4402
|
children: /* @__PURE__ */ jsx("span", { className: "toggle_thumb" })
|
|
4211
4403
|
}
|
|
4212
4404
|
);
|