@bigtablet/design-system 3.6.0 → 3.8.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/LICENSE +53 -0
- package/README.md +12 -9
- package/dist/index.css +46 -45
- package/dist/index.d.ts +85 -10
- package/dist/index.js +450 -267
- package/dist/styles/colors/_index.scss +30 -0
- package/dist/styles/layout/_index.scss +17 -3
- package/dist/styles/motion/_index.scss +14 -1
- package/dist/vanilla/bigtablet.min.css +7 -1
- package/dist/vanilla/bigtablet.min.js +21 -21
- package/package.json +7 -6
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import './index.css';
|
|
3
|
-
import * as
|
|
3
|
+
import * as React16 from 'react';
|
|
4
4
|
import { createContext, useRef, useState, useId, useEffect, useContext, useCallback, useMemo, Fragment, useImperativeHandle, useLayoutEffect } from 'react';
|
|
5
5
|
import { useSpring, animated } from '@react-spring/web';
|
|
6
6
|
import { ChevronDown, ChevronRight, Globe, ChevronLeft, ArrowUp, ArrowDown, ArrowUpDown, XCircle, AlertTriangle, CheckCircle2, Info, Bell, Search, Check, Image, X, TriangleAlert } from 'lucide-react';
|
|
@@ -58,15 +58,137 @@ function registerOverlay(onEscape) {
|
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
60
|
function useOverlayEscape(active, onEscape) {
|
|
61
|
-
const handlerRef =
|
|
62
|
-
|
|
61
|
+
const handlerRef = React16.useRef(onEscape);
|
|
62
|
+
React16.useEffect(() => {
|
|
63
63
|
handlerRef.current = onEscape;
|
|
64
64
|
});
|
|
65
|
-
|
|
65
|
+
React16.useEffect(() => {
|
|
66
66
|
if (!active) return;
|
|
67
67
|
return registerOverlay(() => handlerRef.current());
|
|
68
68
|
}, [active]);
|
|
69
69
|
}
|
|
70
|
+
var useSafeLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
71
|
+
|
|
72
|
+
// src/utils/use-anchored-position.ts
|
|
73
|
+
var OPPOSITE = {
|
|
74
|
+
top: "bottom",
|
|
75
|
+
bottom: "top",
|
|
76
|
+
left: "right",
|
|
77
|
+
right: "left"
|
|
78
|
+
};
|
|
79
|
+
var isVertical = (side) => side === "top" || side === "bottom";
|
|
80
|
+
var clamp = (value, min, max) => (
|
|
81
|
+
// max < min(가용 공간이 플로팅보다 작을 때)이면 min(가장자리 여백)에 고정.
|
|
82
|
+
Math.max(min, Math.min(max, value))
|
|
83
|
+
);
|
|
84
|
+
var mainAxisStart = (side, anchor, floating, gap) => {
|
|
85
|
+
switch (side) {
|
|
86
|
+
case "top":
|
|
87
|
+
return anchor.top - gap - floating.height;
|
|
88
|
+
case "bottom":
|
|
89
|
+
return anchor.top + anchor.height + gap;
|
|
90
|
+
case "left":
|
|
91
|
+
return anchor.left - gap - floating.width;
|
|
92
|
+
case "right":
|
|
93
|
+
return anchor.left + anchor.width + gap;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
var fitsMainAxis = (side, anchor, floating, viewport, gap, padding) => {
|
|
97
|
+
const start = mainAxisStart(side, anchor, floating, gap);
|
|
98
|
+
switch (side) {
|
|
99
|
+
case "top":
|
|
100
|
+
return start >= padding;
|
|
101
|
+
case "bottom":
|
|
102
|
+
return start + floating.height <= viewport.height - padding;
|
|
103
|
+
case "left":
|
|
104
|
+
return start >= padding;
|
|
105
|
+
case "right":
|
|
106
|
+
return start + floating.width <= viewport.width - padding;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
function computeAnchoredPosition(anchor, floating, viewport, options) {
|
|
110
|
+
const gap = options.gap ?? 8;
|
|
111
|
+
const padding = options.padding;
|
|
112
|
+
const available = viewport.width - padding * 2;
|
|
113
|
+
const maxWidth = available;
|
|
114
|
+
const sized = {
|
|
115
|
+
width: Math.min(floating.width, available),
|
|
116
|
+
height: floating.height
|
|
117
|
+
};
|
|
118
|
+
let side = options.placement;
|
|
119
|
+
if (!fitsMainAxis(side, anchor, sized, viewport, gap, padding) && fitsMainAxis(OPPOSITE[side], anchor, sized, viewport, gap, padding)) {
|
|
120
|
+
side = OPPOSITE[side];
|
|
121
|
+
}
|
|
122
|
+
let x;
|
|
123
|
+
let y;
|
|
124
|
+
if (isVertical(side)) {
|
|
125
|
+
y = mainAxisStart(side, anchor, sized, gap);
|
|
126
|
+
x = anchor.left + anchor.width / 2 - sized.width / 2;
|
|
127
|
+
x = clamp(x, padding, viewport.width - padding - sized.width);
|
|
128
|
+
} else {
|
|
129
|
+
x = mainAxisStart(side, anchor, sized, gap);
|
|
130
|
+
y = anchor.top + anchor.height / 2 - sized.height / 2;
|
|
131
|
+
y = clamp(y, padding, viewport.height - padding - sized.height);
|
|
132
|
+
}
|
|
133
|
+
return { x, y, placement: side, maxWidth };
|
|
134
|
+
}
|
|
135
|
+
function useAnchoredPosition({
|
|
136
|
+
open,
|
|
137
|
+
anchorRef,
|
|
138
|
+
floatingRef,
|
|
139
|
+
placement,
|
|
140
|
+
gap,
|
|
141
|
+
padding
|
|
142
|
+
}) {
|
|
143
|
+
const [state, setState] = React16.useState({
|
|
144
|
+
x: 0,
|
|
145
|
+
y: 0,
|
|
146
|
+
placement,
|
|
147
|
+
maxWidth: 0,
|
|
148
|
+
ready: false
|
|
149
|
+
});
|
|
150
|
+
useSafeLayoutEffect(() => {
|
|
151
|
+
if (!open) {
|
|
152
|
+
setState((prev) => prev.ready ? { ...prev, ready: false } : prev);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const anchor = anchorRef.current;
|
|
156
|
+
const floating = floatingRef.current;
|
|
157
|
+
if (!anchor || !floating) return;
|
|
158
|
+
const update = () => {
|
|
159
|
+
const a = anchor.getBoundingClientRect();
|
|
160
|
+
const f = floating.getBoundingClientRect();
|
|
161
|
+
const result = computeAnchoredPosition(
|
|
162
|
+
{ top: a.top, left: a.left, width: a.width, height: a.height },
|
|
163
|
+
{ width: f.width, height: f.height },
|
|
164
|
+
{ width: window.innerWidth, height: window.innerHeight },
|
|
165
|
+
{ placement, gap, padding }
|
|
166
|
+
);
|
|
167
|
+
setState({ ...result, ready: true });
|
|
168
|
+
};
|
|
169
|
+
let frame = 0;
|
|
170
|
+
const schedule = () => {
|
|
171
|
+
if (frame) return;
|
|
172
|
+
frame = requestAnimationFrame(() => {
|
|
173
|
+
frame = 0;
|
|
174
|
+
update();
|
|
175
|
+
});
|
|
176
|
+
};
|
|
177
|
+
update();
|
|
178
|
+
window.addEventListener("scroll", schedule, true);
|
|
179
|
+
window.addEventListener("resize", schedule);
|
|
180
|
+
const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(schedule) : null;
|
|
181
|
+
observer?.observe(floating);
|
|
182
|
+
observer?.observe(anchor);
|
|
183
|
+
return () => {
|
|
184
|
+
if (frame) cancelAnimationFrame(frame);
|
|
185
|
+
window.removeEventListener("scroll", schedule, true);
|
|
186
|
+
window.removeEventListener("resize", schedule);
|
|
187
|
+
observer?.disconnect();
|
|
188
|
+
};
|
|
189
|
+
}, [open, placement, gap, padding, anchorRef, floatingRef]);
|
|
190
|
+
return state;
|
|
191
|
+
}
|
|
70
192
|
var FOCUSABLE_SELECTORS = [
|
|
71
193
|
"a[href]",
|
|
72
194
|
"button:not([disabled])",
|
|
@@ -76,8 +198,8 @@ var FOCUSABLE_SELECTORS = [
|
|
|
76
198
|
'[tabindex]:not([tabindex="-1"])'
|
|
77
199
|
].join(", ");
|
|
78
200
|
function useFocusTrap(containerRef, isActive) {
|
|
79
|
-
const previousActiveElement =
|
|
80
|
-
|
|
201
|
+
const previousActiveElement = React16.useRef(null);
|
|
202
|
+
React16.useEffect(() => {
|
|
81
203
|
if (!isActive) return;
|
|
82
204
|
const container = containerRef.current;
|
|
83
205
|
if (!container) return;
|
|
@@ -126,8 +248,8 @@ function useFocusTrap(containerRef, isActive) {
|
|
|
126
248
|
}, [isActive, containerRef]);
|
|
127
249
|
}
|
|
128
250
|
function useIsMounted() {
|
|
129
|
-
const [mounted, setMounted] =
|
|
130
|
-
|
|
251
|
+
const [mounted, setMounted] = React16.useState(false);
|
|
252
|
+
React16.useEffect(() => {
|
|
131
253
|
setMounted(true);
|
|
132
254
|
}, []);
|
|
133
255
|
return mounted;
|
|
@@ -161,14 +283,13 @@ function getServerSnapshot() {
|
|
|
161
283
|
return false;
|
|
162
284
|
}
|
|
163
285
|
function useReducedMotion() {
|
|
164
|
-
return
|
|
286
|
+
return React16.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
165
287
|
}
|
|
166
|
-
var useSafeLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
167
288
|
function useSpringHover({
|
|
168
289
|
scale = 1.02,
|
|
169
290
|
lift = -2
|
|
170
291
|
} = {}) {
|
|
171
|
-
const [hovered, setHovered] =
|
|
292
|
+
const [hovered, setHovered] = React16.useState(false);
|
|
172
293
|
const reduced = useReducedMotion();
|
|
173
294
|
const style = useSpring({
|
|
174
295
|
transform: hovered ? `translateY(${lift}px) scale(${scale})` : "translateY(0px) scale(1)",
|
|
@@ -232,9 +353,9 @@ var Accordion = ({
|
|
|
232
353
|
...props
|
|
233
354
|
}) => {
|
|
234
355
|
const isControlled = controlledKeys !== void 0;
|
|
235
|
-
const [internalKeys, setInternalKeys] =
|
|
356
|
+
const [internalKeys, setInternalKeys] = React16.useState(defaultOpenKeys);
|
|
236
357
|
const open = isControlled ? controlledKeys ?? [] : internalKeys;
|
|
237
|
-
const idPrefix =
|
|
358
|
+
const idPrefix = React16.useId();
|
|
238
359
|
const toggle = (key) => {
|
|
239
360
|
const isOpen = open.includes(key);
|
|
240
361
|
const next = isOpen ? open.filter((k) => k !== key) : multiple ? [...open, key] : [key];
|
|
@@ -300,7 +421,7 @@ var Avatar = ({
|
|
|
300
421
|
style,
|
|
301
422
|
...props
|
|
302
423
|
}) => {
|
|
303
|
-
const [imgFailed, setImgFailed] =
|
|
424
|
+
const [imgFailed, setImgFailed] = React16.useState(false);
|
|
304
425
|
const showImage = src && !imgFailed;
|
|
305
426
|
const initials = getInitials(name);
|
|
306
427
|
return /* @__PURE__ */ jsx(
|
|
@@ -519,12 +640,12 @@ var Breadcrumb = ({
|
|
|
519
640
|
}) }) });
|
|
520
641
|
};
|
|
521
642
|
var Menu = ({ items, trigger, align = "start" }) => {
|
|
522
|
-
const [open, setOpen] =
|
|
523
|
-
const wrapperRef =
|
|
524
|
-
const itemRefs =
|
|
525
|
-
const menuId =
|
|
643
|
+
const [open, setOpen] = React16.useState(false);
|
|
644
|
+
const wrapperRef = React16.useRef(null);
|
|
645
|
+
const itemRefs = React16.useRef([]);
|
|
646
|
+
const menuId = React16.useId();
|
|
526
647
|
const style = useSpringPresence({ visible: open, from: "translateY(-4px)" });
|
|
527
|
-
|
|
648
|
+
React16.useEffect(() => {
|
|
528
649
|
if (!open) return;
|
|
529
650
|
const handleClick = (e) => {
|
|
530
651
|
if (!wrapperRef.current?.contains(e.target)) setOpen(false);
|
|
@@ -539,7 +660,7 @@ var Menu = ({ items, trigger, align = "start" }) => {
|
|
|
539
660
|
document.removeEventListener("keydown", handleEsc);
|
|
540
661
|
};
|
|
541
662
|
}, [open]);
|
|
542
|
-
|
|
663
|
+
React16.useEffect(() => {
|
|
543
664
|
const active = document.activeElement;
|
|
544
665
|
if (!open || active && itemRefs.current.includes(active)) return;
|
|
545
666
|
const first = items.findIndex((it) => !it.disabled);
|
|
@@ -585,7 +706,7 @@ var Menu = ({ items, trigger, align = "start" }) => {
|
|
|
585
706
|
break;
|
|
586
707
|
}
|
|
587
708
|
};
|
|
588
|
-
const triggerWithProps =
|
|
709
|
+
const triggerWithProps = React16.cloneElement(
|
|
589
710
|
trigger,
|
|
590
711
|
{
|
|
591
712
|
onClick: () => setOpen((o) => !o),
|
|
@@ -727,6 +848,7 @@ var LocaleSwitcher = ({ locale }) => {
|
|
|
727
848
|
const itemRefs = useRef([]);
|
|
728
849
|
const menuId = useId();
|
|
729
850
|
const currentOption = locale.options.find((o) => o.value === locale.current);
|
|
851
|
+
const currentLabel = currentOption?.label ?? locale.current.toUpperCase();
|
|
730
852
|
useEffect(() => {
|
|
731
853
|
if (!open) return;
|
|
732
854
|
const handler = (e) => {
|
|
@@ -800,10 +922,11 @@ var LocaleSwitcher = ({ locale }) => {
|
|
|
800
922
|
"aria-haspopup": "menu",
|
|
801
923
|
"aria-expanded": open,
|
|
802
924
|
"aria-controls": menuId,
|
|
925
|
+
"aria-label": locale.ariaLabel ?? currentLabel,
|
|
803
926
|
onClick: () => setOpen((p) => !p),
|
|
804
927
|
children: [
|
|
805
928
|
/* @__PURE__ */ jsx(Globe, { size: iconSize.sm, "aria-hidden": "true" }),
|
|
806
|
-
!locale.hideLabel && /* @__PURE__ */ jsx("span", { className: "nav_bar_locale_label", children:
|
|
929
|
+
!locale.hideLabel && /* @__PURE__ */ jsx("span", { className: "nav_bar_locale_label", children: currentLabel }),
|
|
807
930
|
/* @__PURE__ */ jsx(
|
|
808
931
|
ChevronDown,
|
|
809
932
|
{
|
|
@@ -876,9 +999,9 @@ var Sidebar = ({
|
|
|
876
999
|
...props
|
|
877
1000
|
}) => {
|
|
878
1001
|
const isControlled = collapsedProp !== void 0;
|
|
879
|
-
const [internalCollapsed, setInternalCollapsed] =
|
|
1002
|
+
const [internalCollapsed, setInternalCollapsed] = React16.useState(defaultCollapsed);
|
|
880
1003
|
const collapsed = isControlled ? collapsedProp : internalCollapsed;
|
|
881
|
-
const toggle =
|
|
1004
|
+
const toggle = React16.useCallback(() => {
|
|
882
1005
|
const next = !collapsed;
|
|
883
1006
|
if (!isControlled) setInternalCollapsed(next);
|
|
884
1007
|
onCollapsedChange?.(next);
|
|
@@ -951,9 +1074,9 @@ var SidebarSection = ({ label, className, children, ...props }) => {
|
|
|
951
1074
|
children
|
|
952
1075
|
] });
|
|
953
1076
|
};
|
|
954
|
-
var TabsContext =
|
|
1077
|
+
var TabsContext = React16.createContext(null);
|
|
955
1078
|
function useTabsContext() {
|
|
956
|
-
const ctx =
|
|
1079
|
+
const ctx = React16.useContext(TabsContext);
|
|
957
1080
|
if (!ctx) {
|
|
958
1081
|
throw new Error(
|
|
959
1082
|
'[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>'
|
|
@@ -972,18 +1095,18 @@ var Tabs = ({
|
|
|
972
1095
|
...props
|
|
973
1096
|
}) => {
|
|
974
1097
|
const isControlled = controlledValue !== void 0;
|
|
975
|
-
const [internalValue, setInternalValue] =
|
|
1098
|
+
const [internalValue, setInternalValue] = React16.useState(defaultValue);
|
|
976
1099
|
const value = isControlled ? controlledValue : internalValue;
|
|
977
|
-
const setValue =
|
|
1100
|
+
const setValue = React16.useCallback(
|
|
978
1101
|
(v) => {
|
|
979
1102
|
if (!isControlled) setInternalValue(v);
|
|
980
1103
|
onValueChange?.(v);
|
|
981
1104
|
},
|
|
982
1105
|
[isControlled, onValueChange]
|
|
983
1106
|
);
|
|
984
|
-
const orderRef =
|
|
985
|
-
const [firstTabValue, setFirstTabValue] =
|
|
986
|
-
const registerTab =
|
|
1107
|
+
const orderRef = React16.useRef([]);
|
|
1108
|
+
const [firstTabValue, setFirstTabValue] = React16.useState();
|
|
1109
|
+
const registerTab = React16.useCallback((v) => {
|
|
987
1110
|
if (!orderRef.current.includes(v)) {
|
|
988
1111
|
orderRef.current = [...orderRef.current, v];
|
|
989
1112
|
setFirstTabValue(orderRef.current[0]);
|
|
@@ -993,8 +1116,8 @@ var Tabs = ({
|
|
|
993
1116
|
setFirstTabValue(orderRef.current[0]);
|
|
994
1117
|
};
|
|
995
1118
|
}, []);
|
|
996
|
-
const idPrefix =
|
|
997
|
-
const ctx =
|
|
1119
|
+
const idPrefix = React16.useId();
|
|
1120
|
+
const ctx = React16.useMemo(
|
|
998
1121
|
() => ({ value, setValue, variant, size, idPrefix, registerTab, firstTabValue }),
|
|
999
1122
|
[value, setValue, variant, size, idPrefix, registerTab, firstTabValue]
|
|
1000
1123
|
);
|
|
@@ -1002,9 +1125,9 @@ var Tabs = ({
|
|
|
1002
1125
|
};
|
|
1003
1126
|
var TabList = ({ ariaLabel, className, children, ...props }) => {
|
|
1004
1127
|
const { variant } = useTabsContext();
|
|
1005
|
-
const listRef =
|
|
1006
|
-
const [indicator, setIndicator] =
|
|
1007
|
-
const [hasMounted, setHasMounted] =
|
|
1128
|
+
const listRef = React16.useRef(null);
|
|
1129
|
+
const [indicator, setIndicator] = React16.useState(null);
|
|
1130
|
+
const [hasMounted, setHasMounted] = React16.useState(false);
|
|
1008
1131
|
useSafeLayoutEffect(() => {
|
|
1009
1132
|
const list = listRef.current;
|
|
1010
1133
|
if (!list) return;
|
|
@@ -1067,7 +1190,7 @@ var Tab = ({ value, className, children, onClick, onKeyDown, ...props }) => {
|
|
|
1067
1190
|
const panelId = `${ctx.idPrefix}-panel-${value}`;
|
|
1068
1191
|
const tabId = `${ctx.idPrefix}-tab-${value}`;
|
|
1069
1192
|
const { registerTab } = ctx;
|
|
1070
|
-
|
|
1193
|
+
React16.useEffect(() => registerTab(value), [registerTab, value]);
|
|
1071
1194
|
const handleClick = (e) => {
|
|
1072
1195
|
ctx.setValue(value);
|
|
1073
1196
|
onClick?.(e);
|
|
@@ -1137,14 +1260,7 @@ var TabPanel = ({
|
|
|
1137
1260
|
}
|
|
1138
1261
|
);
|
|
1139
1262
|
};
|
|
1140
|
-
var
|
|
1141
|
-
"a[href]",
|
|
1142
|
-
"button:not([disabled])",
|
|
1143
|
-
"input:not([disabled])",
|
|
1144
|
-
"select:not([disabled])",
|
|
1145
|
-
"textarea:not([disabled])",
|
|
1146
|
-
'[tabindex]:not([tabindex="-1"])'
|
|
1147
|
-
].join(", ");
|
|
1263
|
+
var POPOVER_GAP = 8;
|
|
1148
1264
|
var Popover = ({
|
|
1149
1265
|
trigger,
|
|
1150
1266
|
content,
|
|
@@ -1157,23 +1273,31 @@ var Popover = ({
|
|
|
1157
1273
|
className
|
|
1158
1274
|
}) => {
|
|
1159
1275
|
const isControlled = openProp !== void 0;
|
|
1160
|
-
const [internalOpen, setInternalOpen] =
|
|
1276
|
+
const [internalOpen, setInternalOpen] = React16.useState(defaultOpen);
|
|
1161
1277
|
const open = isControlled ? openProp : internalOpen;
|
|
1162
|
-
const [shouldRender, setShouldRender] =
|
|
1278
|
+
const [shouldRender, setShouldRender] = React16.useState(open ?? false);
|
|
1163
1279
|
if (open && !shouldRender) setShouldRender(true);
|
|
1164
|
-
const wrapperRef =
|
|
1165
|
-
const
|
|
1166
|
-
const
|
|
1167
|
-
const popoverId =
|
|
1168
|
-
const setOpen =
|
|
1280
|
+
const wrapperRef = React16.useRef(null);
|
|
1281
|
+
const positionRef = React16.useRef(null);
|
|
1282
|
+
const popoverRef = React16.useRef(null);
|
|
1283
|
+
const popoverId = React16.useId();
|
|
1284
|
+
const setOpen = React16.useCallback(
|
|
1169
1285
|
(next) => {
|
|
1170
1286
|
if (!isControlled) setInternalOpen(next);
|
|
1171
1287
|
onOpenChange?.(next);
|
|
1172
1288
|
},
|
|
1173
1289
|
[isControlled, onOpenChange]
|
|
1174
1290
|
);
|
|
1291
|
+
const pos = useAnchoredPosition({
|
|
1292
|
+
open: shouldRender,
|
|
1293
|
+
anchorRef: wrapperRef,
|
|
1294
|
+
floatingRef: positionRef,
|
|
1295
|
+
placement,
|
|
1296
|
+
gap: POPOVER_GAP,
|
|
1297
|
+
padding: 8
|
|
1298
|
+
});
|
|
1175
1299
|
const fromTransform = (() => {
|
|
1176
|
-
switch (placement) {
|
|
1300
|
+
switch (pos.placement) {
|
|
1177
1301
|
case "top":
|
|
1178
1302
|
return "translateY(4px)";
|
|
1179
1303
|
case "bottom":
|
|
@@ -1184,28 +1308,27 @@ var Popover = ({
|
|
|
1184
1308
|
return "translateX(-4px)";
|
|
1185
1309
|
}
|
|
1186
1310
|
})();
|
|
1187
|
-
const style = useSpringPresence({
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
(focusable ?? node).focus();
|
|
1195
|
-
}, [open]);
|
|
1196
|
-
React15.useEffect(() => {
|
|
1311
|
+
const style = useSpringPresence({
|
|
1312
|
+
visible: open,
|
|
1313
|
+
from: fromTransform,
|
|
1314
|
+
onExitComplete: () => setShouldRender(false)
|
|
1315
|
+
});
|
|
1316
|
+
useFocusTrap(popoverRef, open);
|
|
1317
|
+
React16.useEffect(() => {
|
|
1197
1318
|
if (!open) return;
|
|
1198
1319
|
const handleClick = (e) => {
|
|
1199
|
-
|
|
1320
|
+
const target = e.target;
|
|
1321
|
+
if (!wrapperRef.current?.contains(target) && !popoverRef.current?.contains(target)) {
|
|
1322
|
+
setOpen(false);
|
|
1323
|
+
}
|
|
1200
1324
|
};
|
|
1201
1325
|
document.addEventListener("mousedown", handleClick);
|
|
1202
1326
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
1203
1327
|
}, [open, setOpen]);
|
|
1204
1328
|
useOverlayEscape(open, () => {
|
|
1205
1329
|
setOpen(false);
|
|
1206
|
-
previousFocusRef.current?.focus();
|
|
1207
1330
|
});
|
|
1208
|
-
const triggerWithProps =
|
|
1331
|
+
const triggerWithProps = React16.cloneElement(
|
|
1209
1332
|
trigger,
|
|
1210
1333
|
{
|
|
1211
1334
|
onClick: (e) => {
|
|
@@ -1220,23 +1343,43 @@ var Popover = ({
|
|
|
1220
1343
|
);
|
|
1221
1344
|
return /* @__PURE__ */ jsxs("div", { className: "popover_wrapper", ref: wrapperRef, children: [
|
|
1222
1345
|
triggerWithProps,
|
|
1223
|
-
shouldRender &&
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1346
|
+
shouldRender && typeof document !== "undefined" && createPortal(
|
|
1347
|
+
/* @__PURE__ */ jsx(
|
|
1348
|
+
"div",
|
|
1349
|
+
{
|
|
1350
|
+
ref: positionRef,
|
|
1351
|
+
className: "popover_position",
|
|
1352
|
+
style: {
|
|
1353
|
+
position: "fixed",
|
|
1354
|
+
left: pos.x,
|
|
1355
|
+
top: pos.y,
|
|
1356
|
+
// 최초 측정 전(ready=false)에는 maxWidth(=0)를 걸지 않는다 - 걸면 자연 폭 대신
|
|
1357
|
+
// 0px 로 측정돼 첫 프레임 좌표가 어긋난다. ready 후에만 상한 적용.
|
|
1358
|
+
maxWidth: pos.ready ? pos.maxWidth : void 0,
|
|
1359
|
+
visibility: pos.ready ? void 0 : "hidden"
|
|
1360
|
+
},
|
|
1361
|
+
children: /* @__PURE__ */ jsx(
|
|
1362
|
+
animated.div,
|
|
1363
|
+
{
|
|
1364
|
+
id: popoverId,
|
|
1365
|
+
ref: popoverRef,
|
|
1366
|
+
role: "dialog",
|
|
1367
|
+
tabIndex: -1,
|
|
1368
|
+
"aria-label": ariaLabelledby ? ariaLabel : ariaLabel ?? "Dialog",
|
|
1369
|
+
"aria-labelledby": ariaLabelledby,
|
|
1370
|
+
style,
|
|
1371
|
+
className: cn("popover", className),
|
|
1372
|
+
children: content
|
|
1373
|
+
}
|
|
1374
|
+
)
|
|
1375
|
+
}
|
|
1376
|
+
),
|
|
1377
|
+
document.body
|
|
1378
|
+
)
|
|
1237
1379
|
] });
|
|
1238
1380
|
};
|
|
1239
1381
|
Popover.displayName = "Popover";
|
|
1382
|
+
var TOOLTIP_GAP = 6;
|
|
1240
1383
|
var Tooltip = ({
|
|
1241
1384
|
content,
|
|
1242
1385
|
placement = "top",
|
|
@@ -1244,33 +1387,45 @@ var Tooltip = ({
|
|
|
1244
1387
|
disabled = false,
|
|
1245
1388
|
children
|
|
1246
1389
|
}) => {
|
|
1247
|
-
const [open, setOpen] =
|
|
1248
|
-
const
|
|
1249
|
-
|
|
1390
|
+
const [open, setOpen] = React16.useState(false);
|
|
1391
|
+
const [shouldRender, setShouldRender] = React16.useState(false);
|
|
1392
|
+
if (open && !shouldRender) setShouldRender(true);
|
|
1393
|
+
const timerRef = React16.useRef(null);
|
|
1394
|
+
const tooltipId = React16.useId();
|
|
1395
|
+
const wrapperRef = React16.useRef(null);
|
|
1396
|
+
const positionRef = React16.useRef(null);
|
|
1250
1397
|
const HIDE_DELAY = 120;
|
|
1251
|
-
const show =
|
|
1398
|
+
const show = React16.useCallback(() => {
|
|
1252
1399
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1253
1400
|
timerRef.current = setTimeout(() => setOpen(true), delay);
|
|
1254
1401
|
}, [delay]);
|
|
1255
|
-
const hideNow =
|
|
1402
|
+
const hideNow = React16.useCallback(() => {
|
|
1256
1403
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1257
1404
|
setOpen(false);
|
|
1258
1405
|
}, []);
|
|
1259
|
-
const hide =
|
|
1406
|
+
const hide = React16.useCallback(() => {
|
|
1260
1407
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1261
1408
|
timerRef.current = setTimeout(() => setOpen(false), HIDE_DELAY);
|
|
1262
1409
|
}, []);
|
|
1263
|
-
const cancelHide =
|
|
1410
|
+
const cancelHide = React16.useCallback(() => {
|
|
1264
1411
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1265
1412
|
}, []);
|
|
1266
|
-
|
|
1413
|
+
React16.useEffect(() => {
|
|
1267
1414
|
return () => {
|
|
1268
1415
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1269
1416
|
};
|
|
1270
1417
|
}, []);
|
|
1271
1418
|
useOverlayEscape(open, hideNow);
|
|
1419
|
+
const pos = useAnchoredPosition({
|
|
1420
|
+
open: shouldRender,
|
|
1421
|
+
anchorRef: wrapperRef,
|
|
1422
|
+
floatingRef: positionRef,
|
|
1423
|
+
placement,
|
|
1424
|
+
gap: TOOLTIP_GAP,
|
|
1425
|
+
padding: 8
|
|
1426
|
+
});
|
|
1272
1427
|
const fromTransform = (() => {
|
|
1273
|
-
switch (placement) {
|
|
1428
|
+
switch (pos.placement) {
|
|
1274
1429
|
case "top":
|
|
1275
1430
|
return "translateY(4px)";
|
|
1276
1431
|
case "bottom":
|
|
@@ -1281,10 +1436,14 @@ var Tooltip = ({
|
|
|
1281
1436
|
return "translateX(-4px)";
|
|
1282
1437
|
}
|
|
1283
1438
|
})();
|
|
1284
|
-
const style = useSpringPresence({
|
|
1439
|
+
const style = useSpringPresence({
|
|
1440
|
+
visible: open,
|
|
1441
|
+
from: fromTransform,
|
|
1442
|
+
onExitComplete: () => setShouldRender(false)
|
|
1443
|
+
});
|
|
1285
1444
|
const child = children;
|
|
1286
1445
|
const childProps = child.props;
|
|
1287
|
-
const trigger =
|
|
1446
|
+
const trigger = React16.cloneElement(child, {
|
|
1288
1447
|
onMouseEnter: (e) => {
|
|
1289
1448
|
childProps.onMouseEnter?.(e);
|
|
1290
1449
|
show();
|
|
@@ -1305,25 +1464,29 @@ var Tooltip = ({
|
|
|
1305
1464
|
"aria-describedby": open ? [childProps["aria-describedby"], tooltipId].filter(Boolean).join(" ") : childProps["aria-describedby"]
|
|
1306
1465
|
});
|
|
1307
1466
|
if (disabled) return children;
|
|
1308
|
-
return /* @__PURE__ */ jsxs("span", { className: "tooltip_wrapper", children: [
|
|
1467
|
+
return /* @__PURE__ */ jsxs("span", { className: "tooltip_wrapper", ref: wrapperRef, children: [
|
|
1309
1468
|
trigger,
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
|
-
|
|
1469
|
+
shouldRender && typeof document !== "undefined" && createPortal(
|
|
1470
|
+
/* @__PURE__ */ jsx(
|
|
1471
|
+
"span",
|
|
1472
|
+
{
|
|
1473
|
+
ref: positionRef,
|
|
1474
|
+
className: "tooltip_position",
|
|
1475
|
+
style: {
|
|
1476
|
+
position: "fixed",
|
|
1477
|
+
left: pos.x,
|
|
1478
|
+
top: pos.y,
|
|
1479
|
+
// 최초 측정 전(ready=false)에는 maxWidth(=0)를 걸지 않는다 - 걸면 자연 폭 대신
|
|
1480
|
+
// 0px 로 측정돼 첫 프레임 좌표가 어긋난다. ready 후에만 상한 적용.
|
|
1481
|
+
maxWidth: pos.ready ? pos.maxWidth : void 0,
|
|
1482
|
+
visibility: pos.ready ? void 0 : "hidden"
|
|
1483
|
+
},
|
|
1484
|
+
onMouseEnter: cancelHide,
|
|
1485
|
+
onMouseLeave: hide,
|
|
1486
|
+
children: /* @__PURE__ */ jsx(animated.span, { id: tooltipId, role: "tooltip", style, className: "tooltip", children: content })
|
|
1487
|
+
}
|
|
1488
|
+
),
|
|
1489
|
+
document.body
|
|
1327
1490
|
)
|
|
1328
1491
|
] });
|
|
1329
1492
|
};
|
|
@@ -2251,12 +2414,12 @@ var Checkbox = ({
|
|
|
2251
2414
|
ref,
|
|
2252
2415
|
...props
|
|
2253
2416
|
}) => {
|
|
2254
|
-
const inputRef =
|
|
2255
|
-
|
|
2417
|
+
const inputRef = React16.useRef(null);
|
|
2418
|
+
React16.useImperativeHandle(
|
|
2256
2419
|
ref,
|
|
2257
2420
|
() => inputRef.current
|
|
2258
2421
|
);
|
|
2259
|
-
|
|
2422
|
+
React16.useEffect(() => {
|
|
2260
2423
|
if (!inputRef.current) return;
|
|
2261
2424
|
inputRef.current.indeterminate = Boolean(indeterminate);
|
|
2262
2425
|
}, [indeterminate]);
|
|
@@ -2314,8 +2477,8 @@ var Table = ({
|
|
|
2314
2477
|
const isEmpty = !isLoading && data.length === 0;
|
|
2315
2478
|
const getRowKey = (item, index) => rowKey?.(item) ?? String(index);
|
|
2316
2479
|
const allRowKeys = selectable ? data.map((item, index) => getRowKey(item, index)) : [];
|
|
2317
|
-
const rowClickHintId =
|
|
2318
|
-
const selectedSet =
|
|
2480
|
+
const rowClickHintId = React16.useId();
|
|
2481
|
+
const selectedSet = React16.useMemo(() => new Set(selectedKeys ?? []), [selectedKeys]);
|
|
2319
2482
|
const selectedCount = allRowKeys.filter((key) => selectedSet.has(key)).length;
|
|
2320
2483
|
const isAllSelected = allRowKeys.length > 0 && selectedCount === allRowKeys.length;
|
|
2321
2484
|
const isSomeSelected = selectedCount > 0 && !isAllSelected;
|
|
@@ -2538,9 +2701,9 @@ var AlertModal = ({
|
|
|
2538
2701
|
onClose
|
|
2539
2702
|
}) => {
|
|
2540
2703
|
const dismiss = onCancel ?? onClose;
|
|
2541
|
-
const panelRef =
|
|
2542
|
-
const titleId =
|
|
2543
|
-
const messageId =
|
|
2704
|
+
const panelRef = React16.useRef(null);
|
|
2705
|
+
const titleId = React16.useId();
|
|
2706
|
+
const messageId = React16.useId();
|
|
2544
2707
|
const [shouldRender, setShouldRender] = useState(isOpen);
|
|
2545
2708
|
useFocusTrap(panelRef, isOpen);
|
|
2546
2709
|
useOverlayEscape(isOpen, () => dismiss());
|
|
@@ -2560,7 +2723,7 @@ var AlertModal = ({
|
|
|
2560
2723
|
immediate: reduced,
|
|
2561
2724
|
config: { tension: 280, friction: 28, clamp: !isOpen }
|
|
2562
2725
|
});
|
|
2563
|
-
|
|
2726
|
+
React16.useEffect(() => {
|
|
2564
2727
|
if (!shouldRender) return;
|
|
2565
2728
|
const body = document.body;
|
|
2566
2729
|
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
@@ -2687,7 +2850,7 @@ var Spinner = ({ size = 24, ariaLabel = "Loading" }) => {
|
|
|
2687
2850
|
}
|
|
2688
2851
|
);
|
|
2689
2852
|
};
|
|
2690
|
-
var ToastContext =
|
|
2853
|
+
var ToastContext = React16.createContext(null);
|
|
2691
2854
|
var VARIANT_ICONS = {
|
|
2692
2855
|
success: /* @__PURE__ */ jsx(CheckCircle2, { size: iconSize.md }),
|
|
2693
2856
|
error: /* @__PURE__ */ jsx(XCircle, { size: iconSize.md }),
|
|
@@ -2696,9 +2859,9 @@ var VARIANT_ICONS = {
|
|
|
2696
2859
|
default: /* @__PURE__ */ jsx(Bell, { size: iconSize.md })
|
|
2697
2860
|
};
|
|
2698
2861
|
var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
2699
|
-
const [visible, setVisible] =
|
|
2700
|
-
const closingRef =
|
|
2701
|
-
const rootRef =
|
|
2862
|
+
const [visible, setVisible] = React16.useState(true);
|
|
2863
|
+
const closingRef = React16.useRef(false);
|
|
2864
|
+
const rootRef = React16.useRef(null);
|
|
2702
2865
|
const style = useSpringPresence({
|
|
2703
2866
|
visible,
|
|
2704
2867
|
from: "translateX(20px)",
|
|
@@ -2718,7 +2881,7 @@ var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
|
2718
2881
|
onRemove(item.id);
|
|
2719
2882
|
}
|
|
2720
2883
|
});
|
|
2721
|
-
const close =
|
|
2884
|
+
const close = React16.useCallback(() => {
|
|
2722
2885
|
if (closingRef.current) return;
|
|
2723
2886
|
closingRef.current = true;
|
|
2724
2887
|
setVisible(false);
|
|
@@ -2752,19 +2915,19 @@ var ToastProvider = ({
|
|
|
2752
2915
|
maxCount = 5,
|
|
2753
2916
|
closeAriaLabel = "Close"
|
|
2754
2917
|
}) => {
|
|
2755
|
-
const [toasts, setToasts] =
|
|
2918
|
+
const [toasts, setToasts] = React16.useState([]);
|
|
2756
2919
|
const isMounted = useIsMounted();
|
|
2757
|
-
const addToast =
|
|
2920
|
+
const addToast = React16.useCallback(
|
|
2758
2921
|
(message, variant, duration = 3e3) => {
|
|
2759
2922
|
const id = crypto.randomUUID();
|
|
2760
2923
|
setToasts((prev) => [{ id, message, variant, duration }, ...prev].slice(0, maxCount));
|
|
2761
2924
|
},
|
|
2762
2925
|
[maxCount]
|
|
2763
2926
|
);
|
|
2764
|
-
const removeToast =
|
|
2927
|
+
const removeToast = React16.useCallback((id) => {
|
|
2765
2928
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
2766
2929
|
}, []);
|
|
2767
|
-
const contextValue =
|
|
2930
|
+
const contextValue = React16.useMemo(() => ({ addToast }), [addToast]);
|
|
2768
2931
|
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: contextValue, children: [
|
|
2769
2932
|
children,
|
|
2770
2933
|
isMounted && createPortal(
|
|
@@ -3198,9 +3361,9 @@ var DatePicker = ({
|
|
|
3198
3361
|
minDateSrFormat = "Minimum date: {date}",
|
|
3199
3362
|
selectableRangeUntilTodaySrText = "Selectable up to today"
|
|
3200
3363
|
}) => {
|
|
3201
|
-
const groupId =
|
|
3202
|
-
const constraintId =
|
|
3203
|
-
const { todayYear, todayMonth, todayDay } =
|
|
3364
|
+
const groupId = React16.useId();
|
|
3365
|
+
const constraintId = React16.useId();
|
|
3366
|
+
const { todayYear, todayMonth, todayDay } = React16.useMemo(() => {
|
|
3204
3367
|
const now = /* @__PURE__ */ new Date();
|
|
3205
3368
|
return {
|
|
3206
3369
|
todayYear: now.getFullYear(),
|
|
@@ -3209,7 +3372,7 @@ var DatePicker = ({
|
|
|
3209
3372
|
};
|
|
3210
3373
|
}, []);
|
|
3211
3374
|
const endYear = endYearProp ?? todayYear + 10;
|
|
3212
|
-
const parsed =
|
|
3375
|
+
const parsed = React16.useMemo(() => {
|
|
3213
3376
|
if (!value) return { year: 0, month: 0, day: 0 };
|
|
3214
3377
|
const [y, m, d] = value.split("-").map(Number);
|
|
3215
3378
|
return {
|
|
@@ -3218,7 +3381,7 @@ var DatePicker = ({
|
|
|
3218
3381
|
day: d || 0
|
|
3219
3382
|
};
|
|
3220
3383
|
}, [value]);
|
|
3221
|
-
const min =
|
|
3384
|
+
const min = React16.useMemo(() => {
|
|
3222
3385
|
if (!minDate) return { year: 0, month: 0, day: 0 };
|
|
3223
3386
|
const [y, m, d] = minDate.split("-").map(Number);
|
|
3224
3387
|
return {
|
|
@@ -3238,7 +3401,7 @@ var DatePicker = ({
|
|
|
3238
3401
|
min.year > 0 && min.month > 0 && year === min.year && month === min.month ? min.day : 1
|
|
3239
3402
|
)
|
|
3240
3403
|
);
|
|
3241
|
-
const maxDay =
|
|
3404
|
+
const maxDay = React16.useMemo(() => {
|
|
3242
3405
|
if (!year || !month) return 31;
|
|
3243
3406
|
const daysInMonth = getDaysInMonth(year, month);
|
|
3244
3407
|
if (selectableRange === "until-today" && year === todayYear && month === todayMonth) {
|
|
@@ -3246,28 +3409,28 @@ var DatePicker = ({
|
|
|
3246
3409
|
}
|
|
3247
3410
|
return daysInMonth;
|
|
3248
3411
|
}, [year, month, selectableRange, todayYear, todayMonth, todayDay]);
|
|
3249
|
-
const yearOptions =
|
|
3412
|
+
const yearOptions = React16.useMemo(
|
|
3250
3413
|
() => range(startYear, maxYear).map((y) => ({
|
|
3251
3414
|
value: String(y),
|
|
3252
3415
|
label: String(y)
|
|
3253
3416
|
})),
|
|
3254
3417
|
[startYear, maxYear]
|
|
3255
3418
|
);
|
|
3256
|
-
const monthOptions =
|
|
3419
|
+
const monthOptions = React16.useMemo(
|
|
3257
3420
|
() => range(minMonth, Math.max(minMonth, maxMonth)).map((m) => ({
|
|
3258
3421
|
value: String(m),
|
|
3259
3422
|
label: pad(m)
|
|
3260
3423
|
})),
|
|
3261
3424
|
[minMonth, maxMonth]
|
|
3262
3425
|
);
|
|
3263
|
-
const dayOptions =
|
|
3426
|
+
const dayOptions = React16.useMemo(
|
|
3264
3427
|
() => range(minDay, Math.max(minDay, maxDay)).map((d) => ({
|
|
3265
3428
|
value: String(d),
|
|
3266
3429
|
label: pad(d)
|
|
3267
3430
|
})),
|
|
3268
3431
|
[minDay, maxDay]
|
|
3269
3432
|
);
|
|
3270
|
-
const emit =
|
|
3433
|
+
const emit = React16.useCallback(
|
|
3271
3434
|
(yy, mm, dd) => {
|
|
3272
3435
|
const cb = onValueChange ?? onChange;
|
|
3273
3436
|
if (mode === "year-month") {
|
|
@@ -3279,7 +3442,7 @@ var DatePicker = ({
|
|
|
3279
3442
|
},
|
|
3280
3443
|
[mode, onValueChange, onChange]
|
|
3281
3444
|
);
|
|
3282
|
-
const handleYearChange =
|
|
3445
|
+
const handleYearChange = React16.useCallback(
|
|
3283
3446
|
(raw) => {
|
|
3284
3447
|
if (!raw) return;
|
|
3285
3448
|
const newYear = Number(raw);
|
|
@@ -3296,14 +3459,14 @@ var DatePicker = ({
|
|
|
3296
3459
|
},
|
|
3297
3460
|
[month, day, min.year, min.month, selectableRange, todayYear, todayMonth, emit]
|
|
3298
3461
|
);
|
|
3299
|
-
const handleMonthChange =
|
|
3462
|
+
const handleMonthChange = React16.useCallback(
|
|
3300
3463
|
(raw) => {
|
|
3301
3464
|
if (!raw || !year) return;
|
|
3302
3465
|
emit(year, Number(raw), day || void 0);
|
|
3303
3466
|
},
|
|
3304
3467
|
[year, day, emit]
|
|
3305
3468
|
);
|
|
3306
|
-
const handleDayChange =
|
|
3469
|
+
const handleDayChange = React16.useCallback(
|
|
3307
3470
|
(raw) => {
|
|
3308
3471
|
if (!raw || !year || !month) return;
|
|
3309
3472
|
emit(year, month, Number(raw));
|
|
@@ -3387,11 +3550,11 @@ var FileInput = ({
|
|
|
3387
3550
|
onChange,
|
|
3388
3551
|
...props
|
|
3389
3552
|
}) => {
|
|
3390
|
-
const inputId =
|
|
3391
|
-
const helperId =
|
|
3392
|
-
const inputRef =
|
|
3393
|
-
const [previewUrls, setPreviewUrls] =
|
|
3394
|
-
const previewUrlsRef =
|
|
3553
|
+
const inputId = React16.useId();
|
|
3554
|
+
const helperId = React16.useId();
|
|
3555
|
+
const inputRef = React16.useRef(null);
|
|
3556
|
+
const [previewUrls, setPreviewUrls] = React16.useState([]);
|
|
3557
|
+
const previewUrlsRef = React16.useRef([]);
|
|
3395
3558
|
const isPreviewVariant = variant === "preview";
|
|
3396
3559
|
const showPreview = isPreviewVariant || preview;
|
|
3397
3560
|
const handleChange = (e) => {
|
|
@@ -3432,7 +3595,7 @@ var FileInput = ({
|
|
|
3432
3595
|
}
|
|
3433
3596
|
onFiles?.(null);
|
|
3434
3597
|
};
|
|
3435
|
-
|
|
3598
|
+
React16.useEffect(() => {
|
|
3436
3599
|
return () => {
|
|
3437
3600
|
for (const url of previewUrlsRef.current) {
|
|
3438
3601
|
URL.revokeObjectURL(url);
|
|
@@ -3561,12 +3724,20 @@ function ImageCropper({
|
|
|
3561
3724
|
onReady,
|
|
3562
3725
|
onError,
|
|
3563
3726
|
className,
|
|
3564
|
-
label = "\uC774\uBBF8\uC9C0 \uC704\uCE58\uC640 \uBC30\uC728 \uC870\uC815"
|
|
3727
|
+
label = "\uC774\uBBF8\uC9C0 \uC704\uCE58\uC640 \uBC30\uC728 \uC870\uC815",
|
|
3728
|
+
hint = "\uB4DC\uB798\uADF8(\uB610\uB294 \uBC29\uD5A5\uD0A4)\uB85C \uC704\uCE58, \uD720\xB7\uC2AC\uB77C\uC774\uB354\uB85C \uBC30\uC728\uC744 \uB9DE\uCD94\uC138\uC694.",
|
|
3729
|
+
zoomOutLabel = "\uCD95\uC18C",
|
|
3730
|
+
zoomLabel = "\uBC30\uC728",
|
|
3731
|
+
zoomInLabel = "\uD655\uB300",
|
|
3732
|
+
noPanHint = "\uC774\uBBF8\uC9C0\uAC00 \uBDF0\uD3EC\uD2B8\uB97C \uB531 \uCC44\uC6CC \uC774\uB3D9 \uC5EC\uC720\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
3733
|
+
...rest
|
|
3565
3734
|
}) {
|
|
3566
3735
|
const imageRef = useRef(null);
|
|
3736
|
+
const viewportRef = useRef(null);
|
|
3567
3737
|
const dragRef = useRef(
|
|
3568
3738
|
null
|
|
3569
3739
|
);
|
|
3740
|
+
const hintId = useId();
|
|
3570
3741
|
const [previewUrl, setPreviewUrl] = useState("");
|
|
3571
3742
|
const [srcType, setSrcType] = useState("");
|
|
3572
3743
|
useEffect(() => {
|
|
@@ -3582,11 +3753,13 @@ function ImageCropper({
|
|
|
3582
3753
|
}, [src]);
|
|
3583
3754
|
const [imageSize, setImageSize] = useState(null);
|
|
3584
3755
|
const [zoom, setZoom] = useState(minZoom);
|
|
3756
|
+
const zoomRef = useRef(zoom);
|
|
3585
3757
|
const [offset, setOffset] = useState({ x: 0, y: 0 });
|
|
3586
3758
|
const [dragging, setDragging] = useState(false);
|
|
3587
3759
|
useEffect(() => {
|
|
3588
3760
|
setImageSize(null);
|
|
3589
3761
|
setZoom(minZoom);
|
|
3762
|
+
zoomRef.current = minZoom;
|
|
3590
3763
|
setOffset({ x: 0, y: 0 });
|
|
3591
3764
|
}, [src, minZoom]);
|
|
3592
3765
|
const handleImageLoad = (event) => {
|
|
@@ -3601,6 +3774,7 @@ function ImageCropper({
|
|
|
3601
3774
|
(next) => {
|
|
3602
3775
|
const clampedZoom = Math.min(maxZoom, Math.max(minZoom, next));
|
|
3603
3776
|
setZoom(clampedZoom);
|
|
3777
|
+
zoomRef.current = clampedZoom;
|
|
3604
3778
|
if (imageSize) {
|
|
3605
3779
|
setOffset((prev) => clampCropOffset(prev, imageSize, viewportSize, clampedZoom));
|
|
3606
3780
|
}
|
|
@@ -3637,11 +3811,16 @@ function ImageCropper({
|
|
|
3637
3811
|
setDragging(false);
|
|
3638
3812
|
}
|
|
3639
3813
|
};
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3814
|
+
useEffect(() => {
|
|
3815
|
+
const viewport = viewportRef.current;
|
|
3816
|
+
if (!viewport || !imageSize) return;
|
|
3817
|
+
const handleWheel = (event) => {
|
|
3818
|
+
event.preventDefault();
|
|
3819
|
+
applyZoom(zoomRef.current - event.deltaY * WHEEL_ZOOM_FACTOR * zoomRef.current);
|
|
3820
|
+
};
|
|
3821
|
+
viewport.addEventListener("wheel", handleWheel, { passive: false });
|
|
3822
|
+
return () => viewport.removeEventListener("wheel", handleWheel);
|
|
3823
|
+
}, [imageSize, applyZoom]);
|
|
3645
3824
|
const handleKeyDown2 = (event) => {
|
|
3646
3825
|
if (!imageSize) return;
|
|
3647
3826
|
switch (event.key) {
|
|
@@ -3675,6 +3854,7 @@ function ImageCropper({
|
|
|
3675
3854
|
() => ({
|
|
3676
3855
|
reset: () => {
|
|
3677
3856
|
setZoom(minZoom);
|
|
3857
|
+
zoomRef.current = minZoom;
|
|
3678
3858
|
setOffset({ x: 0, y: 0 });
|
|
3679
3859
|
},
|
|
3680
3860
|
crop: () => new Promise((resolve, reject) => {
|
|
@@ -3722,92 +3902,95 @@ function ImageCropper({
|
|
|
3722
3902
|
height: imageSize.height * scale,
|
|
3723
3903
|
transform: `translate(calc(-50% + ${offset.x}px), calc(-50% + ${offset.y}px))`
|
|
3724
3904
|
} : { visibility: "hidden" };
|
|
3725
|
-
return
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
style: viewportStyle,
|
|
3731
|
-
role: "group",
|
|
3732
|
-
"aria-label": label,
|
|
3733
|
-
"aria-describedby": "image_cropper_hint",
|
|
3734
|
-
tabIndex: imageSize ? 0 : -1,
|
|
3735
|
-
onPointerDown: handlePointerDown,
|
|
3736
|
-
onPointerMove: handlePointerMove,
|
|
3737
|
-
onPointerUp: handlePointerEnd,
|
|
3738
|
-
onPointerCancel: handlePointerEnd,
|
|
3739
|
-
onWheel: handleWheel,
|
|
3740
|
-
onKeyDown: handleKeyDown2,
|
|
3741
|
-
children: [
|
|
3742
|
-
/* @__PURE__ */ jsx(
|
|
3743
|
-
"img",
|
|
3744
|
-
{
|
|
3745
|
-
ref: imageRef,
|
|
3746
|
-
src: previewUrl || void 0,
|
|
3747
|
-
alt: "",
|
|
3748
|
-
className: "image_cropper_image",
|
|
3749
|
-
draggable: false,
|
|
3750
|
-
crossOrigin: typeof src === "string" ? "anonymous" : void 0,
|
|
3751
|
-
onLoad: handleImageLoad,
|
|
3752
|
-
onError,
|
|
3753
|
-
style: imageStyle
|
|
3754
|
-
}
|
|
3755
|
-
),
|
|
3756
|
-
/* @__PURE__ */ jsx(
|
|
3757
|
-
"div",
|
|
3758
|
-
{
|
|
3759
|
-
className: cn(
|
|
3760
|
-
"image_cropper_mask",
|
|
3761
|
-
circular && "image_cropper_mask_circular",
|
|
3762
|
-
dragging && "image_cropper_mask_active"
|
|
3763
|
-
),
|
|
3764
|
-
"aria-hidden": "true"
|
|
3765
|
-
}
|
|
3766
|
-
)
|
|
3767
|
-
]
|
|
3768
|
-
}
|
|
3769
|
-
),
|
|
3770
|
-
/* @__PURE__ */ jsx("p", { id: "image_cropper_hint", className: "image_cropper_hint", children: "\uB4DC\uB798\uADF8(\uB610\uB294 \uBC29\uD5A5\uD0A4)\uB85C \uC704\uCE58, \uD720\xB7\uC2AC\uB77C\uC774\uB354\uB85C \uBC30\uC728\uC744 \uB9DE\uCD94\uC138\uC694." }),
|
|
3771
|
-
/* @__PURE__ */ jsxs("div", { className: "image_cropper_zoom", children: [
|
|
3772
|
-
/* @__PURE__ */ jsx(
|
|
3773
|
-
"button",
|
|
3774
|
-
{
|
|
3775
|
-
type: "button",
|
|
3776
|
-
className: "image_cropper_zoom_button",
|
|
3777
|
-
"aria-label": "\uCD95\uC18C",
|
|
3778
|
-
disabled: !imageSize || zoom <= minZoom,
|
|
3779
|
-
onClick: () => applyZoom(zoom - ZOOM_KEY_STEP),
|
|
3780
|
-
children: "\u2212"
|
|
3781
|
-
}
|
|
3782
|
-
),
|
|
3783
|
-
/* @__PURE__ */ jsx(
|
|
3784
|
-
"input",
|
|
3905
|
+
return (
|
|
3906
|
+
// className 은 위에서 별도 구조분해되어 rest 에 없으므로 spread 순서와 무관하게 충돌하지 않는다.
|
|
3907
|
+
/* @__PURE__ */ jsxs("div", { ...rest, className: cn("image_cropper", className), children: [
|
|
3908
|
+
/* @__PURE__ */ jsxs(
|
|
3909
|
+
"div",
|
|
3785
3910
|
{
|
|
3786
|
-
|
|
3787
|
-
className: "
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3911
|
+
ref: viewportRef,
|
|
3912
|
+
className: cn("image_cropper_viewport", dragging && "image_cropper_viewport_dragging"),
|
|
3913
|
+
style: viewportStyle,
|
|
3914
|
+
role: "group",
|
|
3915
|
+
"aria-label": label,
|
|
3916
|
+
"aria-describedby": hintId,
|
|
3917
|
+
tabIndex: imageSize ? 0 : -1,
|
|
3918
|
+
onPointerDown: handlePointerDown,
|
|
3919
|
+
onPointerMove: handlePointerMove,
|
|
3920
|
+
onPointerUp: handlePointerEnd,
|
|
3921
|
+
onPointerCancel: handlePointerEnd,
|
|
3922
|
+
onKeyDown: handleKeyDown2,
|
|
3923
|
+
children: [
|
|
3924
|
+
/* @__PURE__ */ jsx(
|
|
3925
|
+
"img",
|
|
3926
|
+
{
|
|
3927
|
+
ref: imageRef,
|
|
3928
|
+
src: previewUrl || void 0,
|
|
3929
|
+
alt: "",
|
|
3930
|
+
className: "image_cropper_image",
|
|
3931
|
+
draggable: false,
|
|
3932
|
+
crossOrigin: typeof src === "string" ? "anonymous" : void 0,
|
|
3933
|
+
onLoad: handleImageLoad,
|
|
3934
|
+
onError,
|
|
3935
|
+
style: imageStyle
|
|
3936
|
+
}
|
|
3937
|
+
),
|
|
3938
|
+
/* @__PURE__ */ jsx(
|
|
3939
|
+
"div",
|
|
3940
|
+
{
|
|
3941
|
+
className: cn(
|
|
3942
|
+
"image_cropper_mask",
|
|
3943
|
+
circular && "image_cropper_mask_circular",
|
|
3944
|
+
dragging && "image_cropper_mask_active"
|
|
3945
|
+
),
|
|
3946
|
+
"aria-hidden": "true"
|
|
3947
|
+
}
|
|
3948
|
+
)
|
|
3949
|
+
]
|
|
3795
3950
|
}
|
|
3796
3951
|
),
|
|
3797
|
-
/* @__PURE__ */ jsx(
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3952
|
+
/* @__PURE__ */ jsx("p", { id: hintId, className: "image_cropper_hint", children: hint }),
|
|
3953
|
+
/* @__PURE__ */ jsxs("div", { className: "image_cropper_zoom", children: [
|
|
3954
|
+
/* @__PURE__ */ jsx(
|
|
3955
|
+
"button",
|
|
3956
|
+
{
|
|
3957
|
+
type: "button",
|
|
3958
|
+
className: "image_cropper_zoom_button",
|
|
3959
|
+
"aria-label": zoomOutLabel,
|
|
3960
|
+
disabled: !imageSize || zoom <= minZoom,
|
|
3961
|
+
onClick: () => applyZoom(zoom - ZOOM_KEY_STEP),
|
|
3962
|
+
children: "\u2212"
|
|
3963
|
+
}
|
|
3964
|
+
),
|
|
3965
|
+
/* @__PURE__ */ jsx(
|
|
3966
|
+
"input",
|
|
3967
|
+
{
|
|
3968
|
+
type: "range",
|
|
3969
|
+
className: "image_cropper_zoom_slider",
|
|
3970
|
+
"aria-label": zoomLabel,
|
|
3971
|
+
min: minZoom,
|
|
3972
|
+
max: maxZoom,
|
|
3973
|
+
step: ZOOM_STEP,
|
|
3974
|
+
value: zoom,
|
|
3975
|
+
disabled: !imageSize,
|
|
3976
|
+
onChange: (event) => applyZoom(Number(event.target.value))
|
|
3977
|
+
}
|
|
3978
|
+
),
|
|
3979
|
+
/* @__PURE__ */ jsx(
|
|
3980
|
+
"button",
|
|
3981
|
+
{
|
|
3982
|
+
type: "button",
|
|
3983
|
+
className: "image_cropper_zoom_button",
|
|
3984
|
+
"aria-label": zoomInLabel,
|
|
3985
|
+
disabled: !imageSize || zoom >= maxZoom,
|
|
3986
|
+
onClick: () => applyZoom(zoom + ZOOM_KEY_STEP),
|
|
3987
|
+
children: "\uFF0B"
|
|
3988
|
+
}
|
|
3989
|
+
)
|
|
3990
|
+
] }),
|
|
3991
|
+
/* @__PURE__ */ jsx("span", { className: "image_cropper_sr_only", "aria-live": "polite", children: imageSize && !canPan ? noPanHint : "" })
|
|
3992
|
+
] })
|
|
3993
|
+
);
|
|
3811
3994
|
}
|
|
3812
3995
|
var OtpInput = ({
|
|
3813
3996
|
length = 6,
|
|
@@ -3821,12 +4004,12 @@ var OtpInput = ({
|
|
|
3821
4004
|
ariaLabel = "OTP \uC785\uB825",
|
|
3822
4005
|
className
|
|
3823
4006
|
}) => {
|
|
3824
|
-
const inputsRef =
|
|
3825
|
-
const isTypingRef =
|
|
3826
|
-
|
|
4007
|
+
const inputsRef = React16.useRef([]);
|
|
4008
|
+
const isTypingRef = React16.useRef(false);
|
|
4009
|
+
React16.useEffect(() => {
|
|
3827
4010
|
if (autoFocus) inputsRef.current[0]?.focus();
|
|
3828
4011
|
}, [autoFocus]);
|
|
3829
|
-
const digits =
|
|
4012
|
+
const digits = React16.useMemo(() => {
|
|
3830
4013
|
const chars = value.split("").slice(0, length);
|
|
3831
4014
|
while (chars.length < length) chars.push("");
|
|
3832
4015
|
return chars;
|
|
@@ -3903,7 +4086,7 @@ var OtpInput = ({
|
|
|
3903
4086
|
focusInput(nextIndex);
|
|
3904
4087
|
};
|
|
3905
4088
|
const rootClassName = cn("otp_input", className);
|
|
3906
|
-
const supportingId =
|
|
4089
|
+
const supportingId = React16.useId();
|
|
3907
4090
|
return (
|
|
3908
4091
|
// biome-ignore lint/a11y/useSemanticElements: <fieldset> would force border/legend styles; role=group is the WAI-ARIA equivalent for OTP grouping
|
|
3909
4092
|
/* @__PURE__ */ jsxs("div", { className: rootClassName, role: "group", "aria-label": ariaLabel, children: [
|
|
@@ -3947,9 +4130,9 @@ var OtpInput = ({
|
|
|
3947
4130
|
);
|
|
3948
4131
|
};
|
|
3949
4132
|
OtpInput.displayName = "OtpInput";
|
|
3950
|
-
var RadioGroupContext =
|
|
4133
|
+
var RadioGroupContext = React16.createContext(null);
|
|
3951
4134
|
function useRadioGroupContext() {
|
|
3952
|
-
return
|
|
4135
|
+
return React16.useContext(RadioGroupContext);
|
|
3953
4136
|
}
|
|
3954
4137
|
var RadioGroup = ({
|
|
3955
4138
|
value: controlledValue,
|
|
@@ -3967,21 +4150,21 @@ var RadioGroup = ({
|
|
|
3967
4150
|
...props
|
|
3968
4151
|
}) => {
|
|
3969
4152
|
const isControlled = controlledValue !== void 0;
|
|
3970
|
-
const [internalValue, setInternalValue] =
|
|
4153
|
+
const [internalValue, setInternalValue] = React16.useState(defaultValue);
|
|
3971
4154
|
const value = isControlled ? controlledValue : internalValue;
|
|
3972
|
-
const generatedName =
|
|
4155
|
+
const generatedName = React16.useId();
|
|
3973
4156
|
const name = nameProp ?? generatedName;
|
|
3974
|
-
const idPrefix =
|
|
4157
|
+
const idPrefix = React16.useId();
|
|
3975
4158
|
const labelId = label ? `${idPrefix}-label` : void 0;
|
|
3976
4159
|
const helperId = supportingText ? `${idPrefix}-help` : void 0;
|
|
3977
|
-
const onChange =
|
|
4160
|
+
const onChange = React16.useCallback(
|
|
3978
4161
|
(next) => {
|
|
3979
4162
|
if (!isControlled) setInternalValue(next);
|
|
3980
4163
|
onValueChange?.(next);
|
|
3981
4164
|
},
|
|
3982
4165
|
[isControlled, onValueChange]
|
|
3983
4166
|
);
|
|
3984
|
-
const ctx =
|
|
4167
|
+
const ctx = React16.useMemo(
|
|
3985
4168
|
() => ({ name, value, onChange, size, disabled }),
|
|
3986
4169
|
[name, value, onChange, size, disabled]
|
|
3987
4170
|
);
|
|
@@ -4311,7 +4494,7 @@ var Toggle = ({
|
|
|
4311
4494
|
...props
|
|
4312
4495
|
}) => {
|
|
4313
4496
|
const isControlled = checked !== void 0;
|
|
4314
|
-
const [innerChecked, setInnerChecked] =
|
|
4497
|
+
const [innerChecked, setInnerChecked] = React16.useState(!!defaultChecked);
|
|
4315
4498
|
const isOn = isControlled ? !!checked : innerChecked;
|
|
4316
4499
|
const handleToggle = (e) => {
|
|
4317
4500
|
props.onClick?.(e);
|
|
@@ -4400,7 +4583,7 @@ var Pagination = ({
|
|
|
4400
4583
|
const emit = onPageChange ?? onChange;
|
|
4401
4584
|
const prevDisabled = page <= 1;
|
|
4402
4585
|
const nextDisabled = page >= totalPages;
|
|
4403
|
-
const items =
|
|
4586
|
+
const items = React16.useMemo(() => getPaginationItems(page, totalPages), [page, totalPages]);
|
|
4404
4587
|
return /* @__PURE__ */ jsxs("nav", { className: "pagination", "aria-label": "Pagination", children: [
|
|
4405
4588
|
/* @__PURE__ */ jsx(
|
|
4406
4589
|
"button",
|
|
@@ -4465,9 +4648,9 @@ var Drawer = ({
|
|
|
4465
4648
|
className,
|
|
4466
4649
|
...props
|
|
4467
4650
|
}) => {
|
|
4468
|
-
const panelRef =
|
|
4469
|
-
const titleId =
|
|
4470
|
-
const [shouldRender, setShouldRender] =
|
|
4651
|
+
const panelRef = React16.useRef(null);
|
|
4652
|
+
const titleId = React16.useId();
|
|
4653
|
+
const [shouldRender, setShouldRender] = React16.useState(open);
|
|
4471
4654
|
const reduced = useReducedMotion();
|
|
4472
4655
|
const isMounted = useIsMounted();
|
|
4473
4656
|
useFocusTrap(panelRef, open && isMounted);
|
|
@@ -4486,7 +4669,7 @@ var Drawer = ({
|
|
|
4486
4669
|
immediate: reduced,
|
|
4487
4670
|
config: { tension: 280, friction: 28, clamp: !open }
|
|
4488
4671
|
});
|
|
4489
|
-
|
|
4672
|
+
React16.useEffect(() => {
|
|
4490
4673
|
if (!open) return;
|
|
4491
4674
|
const body = document.body;
|
|
4492
4675
|
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
@@ -4574,9 +4757,9 @@ var Modal = ({
|
|
|
4574
4757
|
ariaLabel,
|
|
4575
4758
|
...props
|
|
4576
4759
|
}) => {
|
|
4577
|
-
const panelRef =
|
|
4578
|
-
const titleId =
|
|
4579
|
-
const [shouldRender, setShouldRender] =
|
|
4760
|
+
const panelRef = React16.useRef(null);
|
|
4761
|
+
const titleId = React16.useId();
|
|
4762
|
+
const [shouldRender, setShouldRender] = React16.useState(open);
|
|
4580
4763
|
const isMounted = useIsMounted();
|
|
4581
4764
|
useFocusTrap(panelRef, open && isMounted);
|
|
4582
4765
|
useOverlayEscape(open && isMounted, () => onClose?.());
|
|
@@ -4596,7 +4779,7 @@ var Modal = ({
|
|
|
4596
4779
|
immediate: reduced,
|
|
4597
4780
|
config: { tension: 280, friction: 28, clamp: !open }
|
|
4598
4781
|
});
|
|
4599
|
-
|
|
4782
|
+
React16.useEffect(() => {
|
|
4600
4783
|
if (!open) return;
|
|
4601
4784
|
const body = document.body;
|
|
4602
4785
|
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
@@ -4666,9 +4849,9 @@ var Modal = ({
|
|
|
4666
4849
|
document.body
|
|
4667
4850
|
);
|
|
4668
4851
|
};
|
|
4669
|
-
var ThemeContext =
|
|
4852
|
+
var ThemeContext = React16.createContext(null);
|
|
4670
4853
|
var useTheme = () => {
|
|
4671
|
-
const ctx =
|
|
4854
|
+
const ctx = React16.useContext(ThemeContext);
|
|
4672
4855
|
if (!ctx) {
|
|
4673
4856
|
throw new Error(
|
|
4674
4857
|
'[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>'
|
|
@@ -4692,15 +4875,15 @@ var ThemeProvider = ({
|
|
|
4692
4875
|
targetSelector,
|
|
4693
4876
|
children
|
|
4694
4877
|
}) => {
|
|
4695
|
-
const [mode, setModeState] =
|
|
4696
|
-
const [systemDark, setSystemDark] =
|
|
4697
|
-
|
|
4878
|
+
const [mode, setModeState] = React16.useState(defaultMode);
|
|
4879
|
+
const [systemDark, setSystemDark] = React16.useState(false);
|
|
4880
|
+
React16.useEffect(() => {
|
|
4698
4881
|
setModeState(readStored(storageKey) ?? defaultMode);
|
|
4699
4882
|
if (isClient) {
|
|
4700
4883
|
setSystemDark(window.matchMedia("(prefers-color-scheme: dark)").matches);
|
|
4701
4884
|
}
|
|
4702
4885
|
}, [storageKey, defaultMode]);
|
|
4703
|
-
|
|
4886
|
+
React16.useEffect(() => {
|
|
4704
4887
|
if (!isClient) return;
|
|
4705
4888
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
4706
4889
|
const handler = (e) => setSystemDark(e.matches);
|
|
@@ -4708,7 +4891,7 @@ var ThemeProvider = ({
|
|
|
4708
4891
|
return () => mq.removeEventListener("change", handler);
|
|
4709
4892
|
}, []);
|
|
4710
4893
|
const resolved = mode === "system" ? systemDark ? "dark" : "light" : mode;
|
|
4711
|
-
|
|
4894
|
+
React16.useEffect(() => {
|
|
4712
4895
|
if (!isClient) return;
|
|
4713
4896
|
const target = targetSelector ? document.querySelector(targetSelector) : document.documentElement;
|
|
4714
4897
|
if (!target) return;
|
|
@@ -4718,7 +4901,7 @@ var ThemeProvider = ({
|
|
|
4718
4901
|
target.setAttribute("data-theme", mode);
|
|
4719
4902
|
}
|
|
4720
4903
|
}, [mode, targetSelector]);
|
|
4721
|
-
const setMode =
|
|
4904
|
+
const setMode = React16.useCallback(
|
|
4722
4905
|
(next) => {
|
|
4723
4906
|
setModeState(next);
|
|
4724
4907
|
if (storageKey && isClient) {
|
|
@@ -4730,7 +4913,7 @@ var ThemeProvider = ({
|
|
|
4730
4913
|
},
|
|
4731
4914
|
[storageKey]
|
|
4732
4915
|
);
|
|
4733
|
-
const value =
|
|
4916
|
+
const value = React16.useMemo(
|
|
4734
4917
|
() => ({ mode, resolved, setMode }),
|
|
4735
4918
|
[mode, resolved, setMode]
|
|
4736
4919
|
);
|
|
@@ -4843,4 +5026,4 @@ var Stack = ({
|
|
|
4843
5026
|
);
|
|
4844
5027
|
};
|
|
4845
5028
|
|
|
4846
|
-
export { Accordion, AlertProvider, Avatar, Badge, BottomNav, BottomNavItem, BottomNavSpacer, Breadcrumb, Button, Card, Checkbox, Chip, Container, DatePicker, Divider, Drawer, Dropdown, EmptyState, ErrorState, FileInput, Grid, Hero, Icon, IconButton, ImageCropper, LinearProgress, ListItem, MediaCard, Menu, Modal, NavBar, NavLink, OtpInput, Pagination, Popover, Radio, RadioGroup, Section, Sidebar, SidebarItem, SidebarSection, Skeleton, Spinner, Stack, Tab, TabList, TabPanel, Table, Tabs, TextField, Textarea, ThemeProvider, ToastProvider, Toggle, Tooltip, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, cn, colors, elevation, iconSize, motion, opacity, radius, skeleton, spacing, typography, useAlert, useFocusTrap, useReducedMotion, useSpringHover, useSpringPresence, useTheme, useToast, zIndex };
|
|
5029
|
+
export { Accordion, AlertProvider, Avatar, Badge, BottomNav, BottomNavItem, BottomNavSpacer, Breadcrumb, Button, Card, Checkbox, Chip, Container, DatePicker, Divider, Drawer, Dropdown, EmptyState, ErrorState, FileInput, Grid, Hero, Icon, IconButton, ImageCropper, LinearProgress, ListItem, MediaCard, Menu, Modal, NavBar, NavLink, OtpInput, Pagination, Popover, Radio, RadioGroup, Section, Sidebar, SidebarItem, SidebarSection, Skeleton, Spinner, Stack, Tab, TabList, TabPanel, Table, Tabs, TextField, Textarea, ThemeProvider, ToastProvider, Toggle, Tooltip, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, cn, colors, elevation, iconSize, motion, opacity, radius, skeleton, spacing, typography, useAlert, useFocusTrap, useRadioGroupContext, useReducedMotion, useSpringHover, useSpringPresence, useTheme, useToast, zIndex };
|