@bigtablet/design-system 3.2.1 → 3.2.2
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 +94 -3
- package/dist/index.js +139 -102
- package/dist/styles/colors/_index.scss +5 -0
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
--bt-color-brand-primary-container: rgba(0, 0, 0, 0.05);
|
|
8
8
|
--bt-color-text-heading: #121212;
|
|
9
9
|
--bt-color-text-body: #666666;
|
|
10
|
-
--bt-color-text-caption: #
|
|
10
|
+
--bt-color-text-caption: #6F6F6F;
|
|
11
11
|
--bt-color-text-brand: #121212;
|
|
12
12
|
--bt-color-text-inverse: #FFFFFF;
|
|
13
13
|
--bt-color-text-disabled: rgba(26, 26, 26, 0.38);
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
-moz-osx-font-smoothing: grayscale;
|
|
73
73
|
--bt-color-text-heading: rgba(255, 255, 255, 0.95);
|
|
74
74
|
--bt-color-text-body: #B3B3B3;
|
|
75
|
-
--bt-color-text-caption: #
|
|
75
|
+
--bt-color-text-caption: #808080;
|
|
76
76
|
--bt-color-text-inverse: #121212;
|
|
77
77
|
--bt-color-text-disabled: rgba(255, 255, 255, 0.38);
|
|
78
78
|
--bt-color-bg-solid: #0A0A0A;
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
-moz-osx-font-smoothing: grayscale;
|
|
131
131
|
--bt-color-text-heading: rgba(255, 255, 255, 0.95);
|
|
132
132
|
--bt-color-text-body: #B3B3B3;
|
|
133
|
-
--bt-color-text-caption: #
|
|
133
|
+
--bt-color-text-caption: #808080;
|
|
134
134
|
--bt-color-text-inverse: #121212;
|
|
135
135
|
--bt-color-text-disabled: rgba(255, 255, 255, 0.38);
|
|
136
136
|
--bt-color-bg-solid: #0A0A0A;
|
|
@@ -830,6 +830,11 @@
|
|
|
830
830
|
cursor: not-allowed;
|
|
831
831
|
opacity: 0.38;
|
|
832
832
|
}
|
|
833
|
+
@media (prefers-reduced-motion: reduce) {
|
|
834
|
+
.menu_item {
|
|
835
|
+
transition: none;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
833
838
|
|
|
834
839
|
/* src/ui/navigation/nav-bar/style.scss */
|
|
835
840
|
@keyframes skeleton_loading {
|
|
@@ -1095,6 +1100,14 @@
|
|
|
1095
1100
|
.nav_bar_variant_transparent .nav_bar_indicator {
|
|
1096
1101
|
background: var(--bt-color-brand-on-primary);
|
|
1097
1102
|
}
|
|
1103
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1104
|
+
.nav_bar_indicator_animated {
|
|
1105
|
+
transition: none;
|
|
1106
|
+
}
|
|
1107
|
+
.nav_bar_locale_chevron {
|
|
1108
|
+
transition: none;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1098
1111
|
|
|
1099
1112
|
/* src/ui/navigation/sidebar/style.scss */
|
|
1100
1113
|
@keyframes skeleton_loading {
|
|
@@ -1392,6 +1405,19 @@
|
|
|
1392
1405
|
clip: auto;
|
|
1393
1406
|
}
|
|
1394
1407
|
}
|
|
1408
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1409
|
+
.sidebar,
|
|
1410
|
+
.sidebar_header,
|
|
1411
|
+
.sidebar_header_layer,
|
|
1412
|
+
.sidebar_item,
|
|
1413
|
+
.sidebar_item_label,
|
|
1414
|
+
.sidebar_collapse_btn {
|
|
1415
|
+
transition: none;
|
|
1416
|
+
}
|
|
1417
|
+
.sidebar_collapse_btn:hover {
|
|
1418
|
+
transform: none;
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1395
1421
|
|
|
1396
1422
|
/* src/ui/navigation/tabs/style.scss */
|
|
1397
1423
|
@keyframes skeleton_loading {
|
|
@@ -1512,6 +1538,12 @@
|
|
|
1512
1538
|
box-shadow: var(--bt-focus-ring);
|
|
1513
1539
|
border-radius: 6px;
|
|
1514
1540
|
}
|
|
1541
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1542
|
+
.tabs_indicator_animated,
|
|
1543
|
+
.tabs_tab {
|
|
1544
|
+
transition: none;
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1515
1547
|
|
|
1516
1548
|
/* src/ui/overlay/popover/style.scss */
|
|
1517
1549
|
@keyframes skeleton_loading {
|
|
@@ -1878,6 +1910,15 @@
|
|
|
1878
1910
|
.button_danger.button_variant_text:hover:not(:disabled) {
|
|
1879
1911
|
background: color-mix(in srgb, var(--bt-color-status-error) 8%, transparent);
|
|
1880
1912
|
}
|
|
1913
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1914
|
+
.button,
|
|
1915
|
+
.button::before {
|
|
1916
|
+
transition: none;
|
|
1917
|
+
}
|
|
1918
|
+
.button:active {
|
|
1919
|
+
transform: none;
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1881
1922
|
|
|
1882
1923
|
/* src/ui/feedback/alert/style.scss */
|
|
1883
1924
|
@keyframes skeleton_loading {
|
|
@@ -2252,6 +2293,11 @@
|
|
|
2252
2293
|
transform: translate(-50%, -50%) scaleX(1);
|
|
2253
2294
|
}
|
|
2254
2295
|
}
|
|
2296
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2297
|
+
.checkbox_icon::after {
|
|
2298
|
+
animation: none;
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2255
2301
|
|
|
2256
2302
|
/* src/ui/display/chip/style.scss */
|
|
2257
2303
|
@keyframes skeleton_loading {
|
|
@@ -2753,6 +2799,11 @@
|
|
|
2753
2799
|
border: none;
|
|
2754
2800
|
margin: 0;
|
|
2755
2801
|
}
|
|
2802
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2803
|
+
.dropdown_icon {
|
|
2804
|
+
transition: none;
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2756
2807
|
|
|
2757
2808
|
/* src/ui/forms/date-picker/style.scss */
|
|
2758
2809
|
@keyframes skeleton_loading {
|
|
@@ -2993,6 +3044,14 @@
|
|
|
2993
3044
|
.file_input_variant_preview .file_input_helper {
|
|
2994
3045
|
display: block;
|
|
2995
3046
|
}
|
|
3047
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3048
|
+
.file_input_preview_remove {
|
|
3049
|
+
transition: none;
|
|
3050
|
+
}
|
|
3051
|
+
.file_input_preview_remove:hover {
|
|
3052
|
+
transform: none;
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
2996
3055
|
|
|
2997
3056
|
/* src/ui/display/hero/style.scss */
|
|
2998
3057
|
@keyframes skeleton_loading {
|
|
@@ -3653,6 +3712,14 @@
|
|
|
3653
3712
|
.media_card_image_overlay .media_card_meta {
|
|
3654
3713
|
color: rgba(255, 255, 255, 0.6);
|
|
3655
3714
|
}
|
|
3715
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3716
|
+
.media_card {
|
|
3717
|
+
transition: none;
|
|
3718
|
+
}
|
|
3719
|
+
.media_card_clickable:hover {
|
|
3720
|
+
transform: none;
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3656
3723
|
|
|
3657
3724
|
/* src/ui/overlay/modal/style.scss */
|
|
3658
3725
|
@keyframes skeleton_loading {
|
|
@@ -4090,6 +4157,11 @@
|
|
|
4090
4157
|
transform: translate(-50%, -50%) scale(1);
|
|
4091
4158
|
}
|
|
4092
4159
|
}
|
|
4160
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4161
|
+
.radio_dot::after {
|
|
4162
|
+
animation: none;
|
|
4163
|
+
}
|
|
4164
|
+
}
|
|
4093
4165
|
|
|
4094
4166
|
/* src/ui/feedback/skeleton/style.scss */
|
|
4095
4167
|
@keyframes skeleton_loading {
|
|
@@ -4150,6 +4222,11 @@
|
|
|
4150
4222
|
background-position: 0 0;
|
|
4151
4223
|
}
|
|
4152
4224
|
}
|
|
4225
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4226
|
+
.skeleton {
|
|
4227
|
+
animation: none;
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4153
4230
|
|
|
4154
4231
|
/* src/ui/feedback/spinner/style.scss */
|
|
4155
4232
|
@keyframes skeleton_loading {
|
|
@@ -4952,6 +5029,12 @@
|
|
|
4952
5029
|
.toggle_disabled .toggle_thumb {
|
|
4953
5030
|
background: var(--bt-color-brand-on-primary);
|
|
4954
5031
|
}
|
|
5032
|
+
@media (prefers-reduced-motion: reduce) {
|
|
5033
|
+
.toggle,
|
|
5034
|
+
.toggle_thumb {
|
|
5035
|
+
transition: none;
|
|
5036
|
+
}
|
|
5037
|
+
}
|
|
4955
5038
|
|
|
4956
5039
|
/* src/ui/feedback/top-loading/style.scss */
|
|
4957
5040
|
@keyframes skeleton_loading {
|
|
@@ -4988,6 +5071,14 @@
|
|
|
4988
5071
|
transform: translateX(400%);
|
|
4989
5072
|
}
|
|
4990
5073
|
}
|
|
5074
|
+
@media (prefers-reduced-motion: reduce) {
|
|
5075
|
+
.top_loading_bar {
|
|
5076
|
+
transition: none;
|
|
5077
|
+
}
|
|
5078
|
+
.top_loading_indeterminate {
|
|
5079
|
+
animation: none;
|
|
5080
|
+
}
|
|
5081
|
+
}
|
|
4991
5082
|
|
|
4992
5083
|
/* src/ui/layout/container/style.scss */
|
|
4993
5084
|
@keyframes skeleton_loading {
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import './index.css';
|
|
3
|
-
import * as
|
|
3
|
+
import * as React20 from 'react';
|
|
4
4
|
import { createContext, useRef, useState, useLayoutEffect, useId, useEffect, useContext, useCallback, useMemo, Fragment } from 'react';
|
|
5
5
|
import { useSpring, animated } from '@react-spring/web';
|
|
6
6
|
import { ChevronDown, Globe, ChevronRight, ChevronLeft, Check, Image, X, TriangleAlert, XCircle, AlertTriangle, CheckCircle2, Info, Bell } from 'lucide-react';
|
|
@@ -38,8 +38,8 @@ var FOCUSABLE_SELECTORS = [
|
|
|
38
38
|
'[tabindex]:not([tabindex="-1"])'
|
|
39
39
|
].join(", ");
|
|
40
40
|
function useFocusTrap(containerRef, isActive) {
|
|
41
|
-
const previousActiveElement =
|
|
42
|
-
|
|
41
|
+
const previousActiveElement = React20.useRef(null);
|
|
42
|
+
React20.useEffect(() => {
|
|
43
43
|
if (!isActive) return;
|
|
44
44
|
const container = containerRef.current;
|
|
45
45
|
if (!container) return;
|
|
@@ -87,14 +87,48 @@ function useFocusTrap(containerRef, isActive) {
|
|
|
87
87
|
};
|
|
88
88
|
}, [isActive, containerRef]);
|
|
89
89
|
}
|
|
90
|
+
var QUERY = "(prefers-reduced-motion: reduce)";
|
|
91
|
+
var mqCache = null;
|
|
92
|
+
var cachedFor = null;
|
|
93
|
+
function getMediaQuery() {
|
|
94
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
95
|
+
mqCache = null;
|
|
96
|
+
cachedFor = null;
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
if (!mqCache || cachedFor !== window.matchMedia) {
|
|
100
|
+
mqCache = window.matchMedia(QUERY);
|
|
101
|
+
cachedFor = window.matchMedia;
|
|
102
|
+
}
|
|
103
|
+
return mqCache;
|
|
104
|
+
}
|
|
105
|
+
function subscribe(onStoreChange) {
|
|
106
|
+
const mq = getMediaQuery();
|
|
107
|
+
if (!mq) return () => {
|
|
108
|
+
};
|
|
109
|
+
mq.addEventListener("change", onStoreChange);
|
|
110
|
+
return () => mq.removeEventListener("change", onStoreChange);
|
|
111
|
+
}
|
|
112
|
+
function getSnapshot() {
|
|
113
|
+
return getMediaQuery()?.matches ?? false;
|
|
114
|
+
}
|
|
115
|
+
function getServerSnapshot() {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
function useReducedMotion() {
|
|
119
|
+
return React20.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
120
|
+
}
|
|
90
121
|
var useSafeLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
91
122
|
function useSpringHover({
|
|
92
123
|
scale = 1.02,
|
|
93
124
|
lift = -2
|
|
94
125
|
} = {}) {
|
|
95
|
-
const [hovered, setHovered] =
|
|
126
|
+
const [hovered, setHovered] = React20.useState(false);
|
|
127
|
+
const reduced = useReducedMotion();
|
|
96
128
|
const style = useSpring({
|
|
97
129
|
transform: hovered ? `translateY(${lift}px) scale(${scale})` : "translateY(0px) scale(1)",
|
|
130
|
+
// reduced-motion: lift/scale 모션 제거 (WCAG 2.3.3)
|
|
131
|
+
immediate: reduced,
|
|
98
132
|
config: { tension: 320, friction: 22 }
|
|
99
133
|
});
|
|
100
134
|
const bind = {
|
|
@@ -110,12 +144,15 @@ function useSpringPresence({
|
|
|
110
144
|
from = "translateY(8px)",
|
|
111
145
|
onExitComplete
|
|
112
146
|
}) {
|
|
147
|
+
const reduced = useReducedMotion();
|
|
113
148
|
return useSpring({
|
|
114
149
|
from: { opacity: 0, transform: from },
|
|
115
150
|
to: {
|
|
116
151
|
opacity: visible ? 1 : 0,
|
|
117
152
|
transform: visible ? "translateY(0px)" : from
|
|
118
153
|
},
|
|
154
|
+
// reduced-motion: 진입/퇴출 모션 없이 즉시 최종 상태로 점프 (WCAG 2.3.3). onRest는 그대로 발화.
|
|
155
|
+
immediate: reduced,
|
|
119
156
|
config: {
|
|
120
157
|
tension: 280,
|
|
121
158
|
// Vercel 식 부드러운 spring
|
|
@@ -140,7 +177,7 @@ var Accordion = ({
|
|
|
140
177
|
...props
|
|
141
178
|
}) => {
|
|
142
179
|
const isControlled = controlledKeys !== void 0;
|
|
143
|
-
const [internalKeys, setInternalKeys] =
|
|
180
|
+
const [internalKeys, setInternalKeys] = React20.useState(defaultOpenKeys);
|
|
144
181
|
const open = isControlled ? controlledKeys ?? [] : internalKeys;
|
|
145
182
|
const toggle = (key) => {
|
|
146
183
|
const isOpen = open.includes(key);
|
|
@@ -206,7 +243,7 @@ var Avatar = ({
|
|
|
206
243
|
style,
|
|
207
244
|
...props
|
|
208
245
|
}) => {
|
|
209
|
-
const [imgFailed, setImgFailed] =
|
|
246
|
+
const [imgFailed, setImgFailed] = React20.useState(false);
|
|
210
247
|
const showImage = src && !imgFailed;
|
|
211
248
|
const initials = getInitials(name);
|
|
212
249
|
return /* @__PURE__ */ jsx(
|
|
@@ -424,11 +461,11 @@ var ErrorState = ({
|
|
|
424
461
|
);
|
|
425
462
|
};
|
|
426
463
|
var Menu = ({ items, trigger, align = "start" }) => {
|
|
427
|
-
const [open, setOpen] =
|
|
428
|
-
const wrapperRef =
|
|
429
|
-
const menuId =
|
|
464
|
+
const [open, setOpen] = React20.useState(false);
|
|
465
|
+
const wrapperRef = React20.useRef(null);
|
|
466
|
+
const menuId = React20.useId();
|
|
430
467
|
const style = useSpringPresence({ visible: open, from: "translateY(-4px)" });
|
|
431
|
-
|
|
468
|
+
React20.useEffect(() => {
|
|
432
469
|
if (!open) return;
|
|
433
470
|
const handleClick = (e) => {
|
|
434
471
|
if (!wrapperRef.current?.contains(e.target)) setOpen(false);
|
|
@@ -443,7 +480,7 @@ var Menu = ({ items, trigger, align = "start" }) => {
|
|
|
443
480
|
document.removeEventListener("keydown", handleEsc);
|
|
444
481
|
};
|
|
445
482
|
}, [open]);
|
|
446
|
-
const triggerWithProps =
|
|
483
|
+
const triggerWithProps = React20.cloneElement(
|
|
447
484
|
trigger,
|
|
448
485
|
{
|
|
449
486
|
onClick: () => setOpen((o) => !o),
|
|
@@ -662,9 +699,9 @@ var Sidebar = ({
|
|
|
662
699
|
...props
|
|
663
700
|
}) => {
|
|
664
701
|
const isControlled = collapsedProp !== void 0;
|
|
665
|
-
const [internalCollapsed, setInternalCollapsed] =
|
|
702
|
+
const [internalCollapsed, setInternalCollapsed] = React20.useState(defaultCollapsed);
|
|
666
703
|
const collapsed = isControlled ? collapsedProp : internalCollapsed;
|
|
667
|
-
const toggle =
|
|
704
|
+
const toggle = React20.useCallback(() => {
|
|
668
705
|
const next = !collapsed;
|
|
669
706
|
if (!isControlled) setInternalCollapsed(next);
|
|
670
707
|
onCollapsedChange?.(next);
|
|
@@ -737,9 +774,9 @@ var SidebarSection = ({ label, className, children, ...props }) => {
|
|
|
737
774
|
children
|
|
738
775
|
] });
|
|
739
776
|
};
|
|
740
|
-
var TabsContext =
|
|
777
|
+
var TabsContext = React20.createContext(null);
|
|
741
778
|
function useTabsContext() {
|
|
742
|
-
const ctx =
|
|
779
|
+
const ctx = React20.useContext(TabsContext);
|
|
743
780
|
if (!ctx) {
|
|
744
781
|
throw new Error(
|
|
745
782
|
'[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>'
|
|
@@ -758,17 +795,17 @@ var Tabs = ({
|
|
|
758
795
|
...props
|
|
759
796
|
}) => {
|
|
760
797
|
const isControlled = controlledValue !== void 0;
|
|
761
|
-
const [internalValue, setInternalValue] =
|
|
798
|
+
const [internalValue, setInternalValue] = React20.useState(defaultValue);
|
|
762
799
|
const value = isControlled ? controlledValue : internalValue;
|
|
763
|
-
const setValue =
|
|
800
|
+
const setValue = React20.useCallback(
|
|
764
801
|
(v) => {
|
|
765
802
|
if (!isControlled) setInternalValue(v);
|
|
766
803
|
onValueChange?.(v);
|
|
767
804
|
},
|
|
768
805
|
[isControlled, onValueChange]
|
|
769
806
|
);
|
|
770
|
-
const idPrefix =
|
|
771
|
-
const ctx =
|
|
807
|
+
const idPrefix = React20.useId();
|
|
808
|
+
const ctx = React20.useMemo(
|
|
772
809
|
() => ({ value, setValue, variant, size, idPrefix }),
|
|
773
810
|
[value, setValue, variant, size, idPrefix]
|
|
774
811
|
);
|
|
@@ -776,10 +813,10 @@ var Tabs = ({
|
|
|
776
813
|
};
|
|
777
814
|
var TabList = ({ ariaLabel, className, children, ...props }) => {
|
|
778
815
|
const { variant } = useTabsContext();
|
|
779
|
-
const listRef =
|
|
780
|
-
const [indicator, setIndicator] =
|
|
781
|
-
const [hasMounted, setHasMounted] =
|
|
782
|
-
|
|
816
|
+
const listRef = React20.useRef(null);
|
|
817
|
+
const [indicator, setIndicator] = React20.useState(null);
|
|
818
|
+
const [hasMounted, setHasMounted] = React20.useState(false);
|
|
819
|
+
React20.useLayoutEffect(() => {
|
|
783
820
|
const list = listRef.current;
|
|
784
821
|
if (!list) return;
|
|
785
822
|
const update = () => {
|
|
@@ -927,15 +964,15 @@ var Popover = ({
|
|
|
927
964
|
className
|
|
928
965
|
}) => {
|
|
929
966
|
const isControlled = openProp !== void 0;
|
|
930
|
-
const [internalOpen, setInternalOpen] =
|
|
967
|
+
const [internalOpen, setInternalOpen] = React20.useState(defaultOpen);
|
|
931
968
|
const open = isControlled ? openProp : internalOpen;
|
|
932
|
-
const [shouldRender, setShouldRender] =
|
|
969
|
+
const [shouldRender, setShouldRender] = React20.useState(open ?? false);
|
|
933
970
|
if (open && !shouldRender) setShouldRender(true);
|
|
934
|
-
const wrapperRef =
|
|
935
|
-
const popoverRef =
|
|
936
|
-
const previousFocusRef =
|
|
937
|
-
const popoverId =
|
|
938
|
-
const setOpen =
|
|
971
|
+
const wrapperRef = React20.useRef(null);
|
|
972
|
+
const popoverRef = React20.useRef(null);
|
|
973
|
+
const previousFocusRef = React20.useRef(null);
|
|
974
|
+
const popoverId = React20.useId();
|
|
975
|
+
const setOpen = React20.useCallback(
|
|
939
976
|
(next) => {
|
|
940
977
|
if (!isControlled) setInternalOpen(next);
|
|
941
978
|
onOpenChange?.(next);
|
|
@@ -955,7 +992,7 @@ var Popover = ({
|
|
|
955
992
|
}
|
|
956
993
|
})();
|
|
957
994
|
const style = useSpringPresence({ visible: open, from: fromTransform, onExitComplete: () => setShouldRender(false) });
|
|
958
|
-
|
|
995
|
+
React20.useEffect(() => {
|
|
959
996
|
if (!open) return;
|
|
960
997
|
previousFocusRef.current = document.activeElement;
|
|
961
998
|
const node = popoverRef.current;
|
|
@@ -963,7 +1000,7 @@ var Popover = ({
|
|
|
963
1000
|
const focusable = node.querySelector(FOCUSABLE_SELECTORS2);
|
|
964
1001
|
(focusable ?? node).focus();
|
|
965
1002
|
}, [open]);
|
|
966
|
-
|
|
1003
|
+
React20.useEffect(() => {
|
|
967
1004
|
if (!open) return;
|
|
968
1005
|
const handleClick = (e) => {
|
|
969
1006
|
if (!wrapperRef.current?.contains(e.target)) setOpen(false);
|
|
@@ -981,7 +1018,7 @@ var Popover = ({
|
|
|
981
1018
|
document.removeEventListener("keydown", handleKeyDown);
|
|
982
1019
|
};
|
|
983
1020
|
}, [open, setOpen]);
|
|
984
|
-
const triggerWithProps =
|
|
1021
|
+
const triggerWithProps = React20.cloneElement(
|
|
985
1022
|
trigger,
|
|
986
1023
|
{
|
|
987
1024
|
onClick: (e) => {
|
|
@@ -1020,18 +1057,18 @@ var Tooltip = ({
|
|
|
1020
1057
|
disabled = false,
|
|
1021
1058
|
children
|
|
1022
1059
|
}) => {
|
|
1023
|
-
const [open, setOpen] =
|
|
1024
|
-
const timerRef =
|
|
1025
|
-
const tooltipId =
|
|
1026
|
-
const show =
|
|
1060
|
+
const [open, setOpen] = React20.useState(false);
|
|
1061
|
+
const timerRef = React20.useRef(null);
|
|
1062
|
+
const tooltipId = React20.useId();
|
|
1063
|
+
const show = React20.useCallback(() => {
|
|
1027
1064
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1028
1065
|
timerRef.current = setTimeout(() => setOpen(true), delay);
|
|
1029
1066
|
}, [delay]);
|
|
1030
|
-
const hide =
|
|
1067
|
+
const hide = React20.useCallback(() => {
|
|
1031
1068
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1032
1069
|
setOpen(false);
|
|
1033
1070
|
}, []);
|
|
1034
|
-
|
|
1071
|
+
React20.useEffect(() => {
|
|
1035
1072
|
return () => {
|
|
1036
1073
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
1037
1074
|
};
|
|
@@ -1049,7 +1086,7 @@ var Tooltip = ({
|
|
|
1049
1086
|
}
|
|
1050
1087
|
})();
|
|
1051
1088
|
const style = useSpringPresence({ visible: open, from: fromTransform });
|
|
1052
|
-
const trigger =
|
|
1089
|
+
const trigger = React20.cloneElement(children, {
|
|
1053
1090
|
onMouseEnter: show,
|
|
1054
1091
|
onMouseLeave: hide,
|
|
1055
1092
|
onFocus: show,
|
|
@@ -1634,12 +1671,12 @@ var AlertModal = ({
|
|
|
1634
1671
|
onCancel,
|
|
1635
1672
|
onClose
|
|
1636
1673
|
}) => {
|
|
1637
|
-
const panelRef =
|
|
1638
|
-
const titleId =
|
|
1639
|
-
const messageId =
|
|
1674
|
+
const panelRef = React20.useRef(null);
|
|
1675
|
+
const titleId = React20.useId();
|
|
1676
|
+
const messageId = React20.useId();
|
|
1640
1677
|
const [shouldRender, setShouldRender] = useState(isOpen);
|
|
1641
1678
|
useFocusTrap(panelRef, isOpen);
|
|
1642
|
-
|
|
1679
|
+
React20.useEffect(() => {
|
|
1643
1680
|
if (isOpen) setShouldRender(true);
|
|
1644
1681
|
}, [isOpen]);
|
|
1645
1682
|
const overlayStyle = useSpring({
|
|
@@ -1746,12 +1783,12 @@ var Checkbox = ({
|
|
|
1746
1783
|
ref,
|
|
1747
1784
|
...props
|
|
1748
1785
|
}) => {
|
|
1749
|
-
const inputRef =
|
|
1750
|
-
|
|
1786
|
+
const inputRef = React20.useRef(null);
|
|
1787
|
+
React20.useImperativeHandle(
|
|
1751
1788
|
ref,
|
|
1752
1789
|
() => inputRef.current
|
|
1753
1790
|
);
|
|
1754
|
-
|
|
1791
|
+
React20.useEffect(() => {
|
|
1755
1792
|
if (!inputRef.current) return;
|
|
1756
1793
|
inputRef.current.indeterminate = Boolean(indeterminate);
|
|
1757
1794
|
}, [indeterminate]);
|
|
@@ -2156,9 +2193,9 @@ var DatePicker = ({
|
|
|
2156
2193
|
minDateSrFormat = "Minimum date: {date}",
|
|
2157
2194
|
selectableRangeUntilTodaySrText = "Selectable up to today"
|
|
2158
2195
|
}) => {
|
|
2159
|
-
const groupId =
|
|
2160
|
-
const constraintId =
|
|
2161
|
-
const { todayYear, todayMonth, todayDay } =
|
|
2196
|
+
const groupId = React20.useId();
|
|
2197
|
+
const constraintId = React20.useId();
|
|
2198
|
+
const { todayYear, todayMonth, todayDay } = React20.useMemo(() => {
|
|
2162
2199
|
const now = /* @__PURE__ */ new Date();
|
|
2163
2200
|
return {
|
|
2164
2201
|
todayYear: now.getFullYear(),
|
|
@@ -2167,7 +2204,7 @@ var DatePicker = ({
|
|
|
2167
2204
|
};
|
|
2168
2205
|
}, []);
|
|
2169
2206
|
const endYear = endYearProp ?? todayYear + 10;
|
|
2170
|
-
const parsed =
|
|
2207
|
+
const parsed = React20.useMemo(() => {
|
|
2171
2208
|
if (!value) return { year: 0, month: 0, day: 0 };
|
|
2172
2209
|
const [y, m, d] = value.split("-").map(Number);
|
|
2173
2210
|
return {
|
|
@@ -2176,7 +2213,7 @@ var DatePicker = ({
|
|
|
2176
2213
|
day: d || 0
|
|
2177
2214
|
};
|
|
2178
2215
|
}, [value]);
|
|
2179
|
-
const min =
|
|
2216
|
+
const min = React20.useMemo(() => {
|
|
2180
2217
|
if (!minDate) return { year: 0, month: 0, day: 0 };
|
|
2181
2218
|
const [y, m, d] = minDate.split("-").map(Number);
|
|
2182
2219
|
return {
|
|
@@ -2196,7 +2233,7 @@ var DatePicker = ({
|
|
|
2196
2233
|
min.year > 0 && min.month > 0 && year === min.year && month === min.month ? min.day : 1
|
|
2197
2234
|
)
|
|
2198
2235
|
);
|
|
2199
|
-
const maxDay =
|
|
2236
|
+
const maxDay = React20.useMemo(() => {
|
|
2200
2237
|
if (!year || !month) return 31;
|
|
2201
2238
|
const daysInMonth = getDaysInMonth(year, month);
|
|
2202
2239
|
if (selectableRange === "until-today" && year === todayYear && month === todayMonth) {
|
|
@@ -2204,28 +2241,28 @@ var DatePicker = ({
|
|
|
2204
2241
|
}
|
|
2205
2242
|
return daysInMonth;
|
|
2206
2243
|
}, [year, month, selectableRange, todayYear, todayMonth, todayDay]);
|
|
2207
|
-
const yearOptions =
|
|
2244
|
+
const yearOptions = React20.useMemo(
|
|
2208
2245
|
() => range(startYear, maxYear).map((y) => ({
|
|
2209
2246
|
value: String(y),
|
|
2210
2247
|
label: String(y)
|
|
2211
2248
|
})),
|
|
2212
2249
|
[startYear, maxYear]
|
|
2213
2250
|
);
|
|
2214
|
-
const monthOptions =
|
|
2251
|
+
const monthOptions = React20.useMemo(
|
|
2215
2252
|
() => range(minMonth, Math.max(minMonth, maxMonth)).map((m) => ({
|
|
2216
2253
|
value: String(m),
|
|
2217
2254
|
label: pad(m)
|
|
2218
2255
|
})),
|
|
2219
2256
|
[minMonth, maxMonth]
|
|
2220
2257
|
);
|
|
2221
|
-
const dayOptions =
|
|
2258
|
+
const dayOptions = React20.useMemo(
|
|
2222
2259
|
() => range(minDay, Math.max(minDay, maxDay)).map((d) => ({
|
|
2223
2260
|
value: String(d),
|
|
2224
2261
|
label: pad(d)
|
|
2225
2262
|
})),
|
|
2226
2263
|
[minDay, maxDay]
|
|
2227
2264
|
);
|
|
2228
|
-
const emit =
|
|
2265
|
+
const emit = React20.useCallback(
|
|
2229
2266
|
(yy, mm, dd) => {
|
|
2230
2267
|
if (mode === "year-month") {
|
|
2231
2268
|
onChange(`${yy}-${pad(mm)}`);
|
|
@@ -2236,7 +2273,7 @@ var DatePicker = ({
|
|
|
2236
2273
|
},
|
|
2237
2274
|
[mode, onChange]
|
|
2238
2275
|
);
|
|
2239
|
-
const handleYearChange =
|
|
2276
|
+
const handleYearChange = React20.useCallback(
|
|
2240
2277
|
(raw) => {
|
|
2241
2278
|
if (!raw) return;
|
|
2242
2279
|
const newYear = Number(raw);
|
|
@@ -2253,14 +2290,14 @@ var DatePicker = ({
|
|
|
2253
2290
|
},
|
|
2254
2291
|
[month, day, min.year, min.month, selectableRange, todayYear, todayMonth, emit]
|
|
2255
2292
|
);
|
|
2256
|
-
const handleMonthChange =
|
|
2293
|
+
const handleMonthChange = React20.useCallback(
|
|
2257
2294
|
(raw) => {
|
|
2258
2295
|
if (!raw || !year) return;
|
|
2259
2296
|
emit(year, Number(raw), day || void 0);
|
|
2260
2297
|
},
|
|
2261
2298
|
[year, day, emit]
|
|
2262
2299
|
);
|
|
2263
|
-
const handleDayChange =
|
|
2300
|
+
const handleDayChange = React20.useCallback(
|
|
2264
2301
|
(raw) => {
|
|
2265
2302
|
if (!raw || !year || !month) return;
|
|
2266
2303
|
emit(year, month, Number(raw));
|
|
@@ -2348,10 +2385,10 @@ var FileInput = ({
|
|
|
2348
2385
|
onChange,
|
|
2349
2386
|
...props
|
|
2350
2387
|
}) => {
|
|
2351
|
-
const inputId =
|
|
2352
|
-
const helperId =
|
|
2353
|
-
const inputRef =
|
|
2354
|
-
const [previewUrls, setPreviewUrls] =
|
|
2388
|
+
const inputId = React20.useId();
|
|
2389
|
+
const helperId = React20.useId();
|
|
2390
|
+
const inputRef = React20.useRef(null);
|
|
2391
|
+
const [previewUrls, setPreviewUrls] = React20.useState([]);
|
|
2355
2392
|
const isPreviewVariant = variant === "preview";
|
|
2356
2393
|
const showPreview = isPreviewVariant || preview;
|
|
2357
2394
|
const handleChange = (e) => {
|
|
@@ -2389,7 +2426,7 @@ var FileInput = ({
|
|
|
2389
2426
|
}
|
|
2390
2427
|
onFiles?.(null);
|
|
2391
2428
|
};
|
|
2392
|
-
|
|
2429
|
+
React20.useEffect(() => {
|
|
2393
2430
|
return () => {
|
|
2394
2431
|
for (const url of previewUrls) {
|
|
2395
2432
|
URL.revokeObjectURL(url);
|
|
@@ -2686,11 +2723,11 @@ var Modal = ({
|
|
|
2686
2723
|
ariaLabel,
|
|
2687
2724
|
...props
|
|
2688
2725
|
}) => {
|
|
2689
|
-
const panelRef =
|
|
2690
|
-
const titleId =
|
|
2691
|
-
const [shouldRender, setShouldRender] =
|
|
2726
|
+
const panelRef = React20.useRef(null);
|
|
2727
|
+
const titleId = React20.useId();
|
|
2728
|
+
const [shouldRender, setShouldRender] = React20.useState(open);
|
|
2692
2729
|
useFocusTrap(panelRef, open);
|
|
2693
|
-
|
|
2730
|
+
React20.useEffect(() => {
|
|
2694
2731
|
if (open) setShouldRender(true);
|
|
2695
2732
|
}, [open]);
|
|
2696
2733
|
const overlayStyle = useSpring({
|
|
@@ -2705,15 +2742,15 @@ var Modal = ({
|
|
|
2705
2742
|
transform: open ? "scale(1) translateY(0px)" : "scale(0.96) translateY(-4px)",
|
|
2706
2743
|
config: { tension: 280, friction: 28, clamp: !open }
|
|
2707
2744
|
});
|
|
2708
|
-
const handleEscape =
|
|
2745
|
+
const handleEscape = React20.useEffectEvent((e) => {
|
|
2709
2746
|
if (e.key === "Escape") onClose?.();
|
|
2710
2747
|
});
|
|
2711
|
-
|
|
2748
|
+
React20.useEffect(() => {
|
|
2712
2749
|
if (!open) return;
|
|
2713
2750
|
document.addEventListener("keydown", handleEscape);
|
|
2714
2751
|
return () => document.removeEventListener("keydown", handleEscape);
|
|
2715
2752
|
}, [open]);
|
|
2716
|
-
|
|
2753
|
+
React20.useEffect(() => {
|
|
2717
2754
|
if (!open) return;
|
|
2718
2755
|
const body = document.body;
|
|
2719
2756
|
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
@@ -2793,12 +2830,12 @@ var OtpInput = ({
|
|
|
2793
2830
|
ariaLabel = "OTP \uC785\uB825",
|
|
2794
2831
|
className
|
|
2795
2832
|
}) => {
|
|
2796
|
-
const inputsRef =
|
|
2797
|
-
const isTypingRef =
|
|
2798
|
-
|
|
2833
|
+
const inputsRef = React20.useRef([]);
|
|
2834
|
+
const isTypingRef = React20.useRef(false);
|
|
2835
|
+
React20.useEffect(() => {
|
|
2799
2836
|
if (autoFocus) inputsRef.current[0]?.focus();
|
|
2800
2837
|
}, [autoFocus]);
|
|
2801
|
-
const digits =
|
|
2838
|
+
const digits = React20.useMemo(() => {
|
|
2802
2839
|
const chars = value.split("").slice(0, length);
|
|
2803
2840
|
while (chars.length < length) chars.push("");
|
|
2804
2841
|
return chars;
|
|
@@ -2937,7 +2974,7 @@ var Pagination = ({
|
|
|
2937
2974
|
}) => {
|
|
2938
2975
|
const prevDisabled = page <= 1;
|
|
2939
2976
|
const nextDisabled = page >= totalPages;
|
|
2940
|
-
const items =
|
|
2977
|
+
const items = React20.useMemo(() => getPaginationItems(page, totalPages), [page, totalPages]);
|
|
2941
2978
|
return /* @__PURE__ */ jsxs("nav", { className: "pagination", "aria-label": "Pagination", children: [
|
|
2942
2979
|
/* @__PURE__ */ jsx(
|
|
2943
2980
|
"button",
|
|
@@ -2982,9 +3019,9 @@ var Pagination = ({
|
|
|
2982
3019
|
)
|
|
2983
3020
|
] });
|
|
2984
3021
|
};
|
|
2985
|
-
var RadioGroupContext =
|
|
3022
|
+
var RadioGroupContext = React20.createContext(null);
|
|
2986
3023
|
function useRadioGroupContext() {
|
|
2987
|
-
return
|
|
3024
|
+
return React20.useContext(RadioGroupContext);
|
|
2988
3025
|
}
|
|
2989
3026
|
var RadioGroup = ({
|
|
2990
3027
|
value: controlledValue,
|
|
@@ -3002,21 +3039,21 @@ var RadioGroup = ({
|
|
|
3002
3039
|
...props
|
|
3003
3040
|
}) => {
|
|
3004
3041
|
const isControlled = controlledValue !== void 0;
|
|
3005
|
-
const [internalValue, setInternalValue] =
|
|
3042
|
+
const [internalValue, setInternalValue] = React20.useState(defaultValue);
|
|
3006
3043
|
const value = isControlled ? controlledValue : internalValue;
|
|
3007
|
-
const generatedName =
|
|
3044
|
+
const generatedName = React20.useId();
|
|
3008
3045
|
const name = nameProp ?? generatedName;
|
|
3009
|
-
const idPrefix =
|
|
3046
|
+
const idPrefix = React20.useId();
|
|
3010
3047
|
const labelId = label ? `${idPrefix}-label` : void 0;
|
|
3011
3048
|
const helperId = supportingText ? `${idPrefix}-help` : void 0;
|
|
3012
|
-
const onChange =
|
|
3049
|
+
const onChange = React20.useCallback(
|
|
3013
3050
|
(next) => {
|
|
3014
3051
|
if (!isControlled) setInternalValue(next);
|
|
3015
3052
|
onValueChange?.(next);
|
|
3016
3053
|
},
|
|
3017
3054
|
[isControlled, onValueChange]
|
|
3018
3055
|
);
|
|
3019
|
-
const ctx =
|
|
3056
|
+
const ctx = React20.useMemo(
|
|
3020
3057
|
() => ({ name, value, onChange, size, disabled }),
|
|
3021
3058
|
[name, value, onChange, size, disabled]
|
|
3022
3059
|
);
|
|
@@ -3214,9 +3251,9 @@ var Table = ({
|
|
|
3214
3251
|
isEmpty && /* @__PURE__ */ jsx("div", { className: "table_empty", role: "status", children: emptyMessage })
|
|
3215
3252
|
] });
|
|
3216
3253
|
};
|
|
3217
|
-
var ThemeContext =
|
|
3254
|
+
var ThemeContext = React20.createContext(null);
|
|
3218
3255
|
var useTheme = () => {
|
|
3219
|
-
const ctx =
|
|
3256
|
+
const ctx = React20.useContext(ThemeContext);
|
|
3220
3257
|
if (!ctx) {
|
|
3221
3258
|
throw new Error(
|
|
3222
3259
|
'[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>'
|
|
@@ -3240,14 +3277,14 @@ var ThemeProvider = ({
|
|
|
3240
3277
|
targetSelector,
|
|
3241
3278
|
children
|
|
3242
3279
|
}) => {
|
|
3243
|
-
const [mode, setModeState] =
|
|
3280
|
+
const [mode, setModeState] = React20.useState(() => {
|
|
3244
3281
|
return readStored(storageKey) ?? defaultMode;
|
|
3245
3282
|
});
|
|
3246
|
-
const [systemDark, setSystemDark] =
|
|
3283
|
+
const [systemDark, setSystemDark] = React20.useState(() => {
|
|
3247
3284
|
if (!isClient) return false;
|
|
3248
3285
|
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
3249
3286
|
});
|
|
3250
|
-
|
|
3287
|
+
React20.useEffect(() => {
|
|
3251
3288
|
if (!isClient) return;
|
|
3252
3289
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
3253
3290
|
const handler = (e) => setSystemDark(e.matches);
|
|
@@ -3255,7 +3292,7 @@ var ThemeProvider = ({
|
|
|
3255
3292
|
return () => mq.removeEventListener("change", handler);
|
|
3256
3293
|
}, []);
|
|
3257
3294
|
const resolved = mode === "system" ? systemDark ? "dark" : "light" : mode;
|
|
3258
|
-
|
|
3295
|
+
React20.useEffect(() => {
|
|
3259
3296
|
if (!isClient) return;
|
|
3260
3297
|
const target = targetSelector ? document.querySelector(targetSelector) : document.documentElement;
|
|
3261
3298
|
if (!target) return;
|
|
@@ -3265,7 +3302,7 @@ var ThemeProvider = ({
|
|
|
3265
3302
|
target.setAttribute("data-theme", mode);
|
|
3266
3303
|
}
|
|
3267
3304
|
}, [mode, targetSelector]);
|
|
3268
|
-
const setMode =
|
|
3305
|
+
const setMode = React20.useCallback(
|
|
3269
3306
|
(next) => {
|
|
3270
3307
|
setModeState(next);
|
|
3271
3308
|
if (storageKey && isClient) {
|
|
@@ -3277,7 +3314,7 @@ var ThemeProvider = ({
|
|
|
3277
3314
|
},
|
|
3278
3315
|
[storageKey]
|
|
3279
3316
|
);
|
|
3280
|
-
const value =
|
|
3317
|
+
const value = React20.useMemo(
|
|
3281
3318
|
() => ({ mode, resolved, setMode }),
|
|
3282
3319
|
[mode, resolved, setMode]
|
|
3283
3320
|
);
|
|
@@ -3523,7 +3560,7 @@ var Textarea = ({
|
|
|
3523
3560
|
] });
|
|
3524
3561
|
};
|
|
3525
3562
|
Textarea.displayName = "Textarea";
|
|
3526
|
-
var ToastContext =
|
|
3563
|
+
var ToastContext = React20.createContext(null);
|
|
3527
3564
|
var VARIANT_ICONS = {
|
|
3528
3565
|
success: /* @__PURE__ */ jsx(CheckCircle2, { size: 18 }),
|
|
3529
3566
|
error: /* @__PURE__ */ jsx(XCircle, { size: 18 }),
|
|
@@ -3532,15 +3569,15 @@ var VARIANT_ICONS = {
|
|
|
3532
3569
|
default: /* @__PURE__ */ jsx(Bell, { size: 18 })
|
|
3533
3570
|
};
|
|
3534
3571
|
var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
3535
|
-
const [visible, setVisible] =
|
|
3536
|
-
const closingRef =
|
|
3572
|
+
const [visible, setVisible] = React20.useState(true);
|
|
3573
|
+
const closingRef = React20.useRef(false);
|
|
3537
3574
|
const style = useSpringPresence({
|
|
3538
3575
|
visible,
|
|
3539
3576
|
from: "translateX(20px)",
|
|
3540
3577
|
// 우측에서 슬라이드 인
|
|
3541
3578
|
onExitComplete: () => onRemove(item.id)
|
|
3542
3579
|
});
|
|
3543
|
-
const close =
|
|
3580
|
+
const close = React20.useCallback(() => {
|
|
3544
3581
|
if (closingRef.current) return;
|
|
3545
3582
|
closingRef.current = true;
|
|
3546
3583
|
setVisible(false);
|
|
@@ -3573,19 +3610,19 @@ var ToastProvider = ({
|
|
|
3573
3610
|
maxCount = 5,
|
|
3574
3611
|
closeAriaLabel = "Close"
|
|
3575
3612
|
}) => {
|
|
3576
|
-
const [toasts, setToasts] =
|
|
3577
|
-
const [isMounted, setIsMounted] =
|
|
3578
|
-
|
|
3613
|
+
const [toasts, setToasts] = React20.useState([]);
|
|
3614
|
+
const [isMounted, setIsMounted] = React20.useState(false);
|
|
3615
|
+
React20.useEffect(() => {
|
|
3579
3616
|
setIsMounted(true);
|
|
3580
3617
|
}, []);
|
|
3581
|
-
const addToast =
|
|
3618
|
+
const addToast = React20.useCallback(
|
|
3582
3619
|
(message, variant, duration = 3e3) => {
|
|
3583
3620
|
const id = crypto.randomUUID();
|
|
3584
3621
|
setToasts((prev) => [{ id, message, variant, duration }, ...prev].slice(0, maxCount));
|
|
3585
3622
|
},
|
|
3586
3623
|
[maxCount]
|
|
3587
3624
|
);
|
|
3588
|
-
const removeToast =
|
|
3625
|
+
const removeToast = React20.useCallback((id) => {
|
|
3589
3626
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
3590
3627
|
}, []);
|
|
3591
3628
|
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: { addToast }, children: [
|
|
@@ -3647,7 +3684,7 @@ var Toggle = ({
|
|
|
3647
3684
|
...props
|
|
3648
3685
|
}) => {
|
|
3649
3686
|
const isControlled = checked !== void 0;
|
|
3650
|
-
const [innerChecked, setInnerChecked] =
|
|
3687
|
+
const [innerChecked, setInnerChecked] = React20.useState(!!defaultChecked);
|
|
3651
3688
|
const isOn = isControlled ? !!checked : innerChecked;
|
|
3652
3689
|
const handleToggle = () => {
|
|
3653
3690
|
if (disabled) return;
|
|
@@ -32,6 +32,11 @@ $color_base_neutral_800: #333333;
|
|
|
32
32
|
$color_base_neutral_900: #121212;
|
|
33
33
|
$color_base_neutral_925: #141414; // dark panel/card bg (Vercel-style)
|
|
34
34
|
$color_base_neutral_950: #0A0A0A; // darkest page bg (Vercel-style)
|
|
35
|
+
|
|
36
|
+
// Text caption - AA 전용값 (neutral scale 과 분리: neutral_500/600 은 border-hover 등 재사용되므로 caption 만 따로)
|
|
37
|
+
$color_base_text_caption_light: #6F6F6F; // on #fff 5.0:1 / on #F4F4F4 4.57:1 (WCAG AA)
|
|
38
|
+
$color_base_text_caption_dark: #808080; // on #0A0A0A 5.0:1 / on #141414 4.66:1 (WCAG AA)
|
|
39
|
+
|
|
35
40
|
// Status - light mode default (darkened for AA on #fff text, 5+:1)
|
|
36
41
|
// 이전 값 (#EF4444 등) 은 #fff 텍스트 조합 시 AA 미달 (2.0~3.7:1) - Tailwind 700 계열로 교체.
|
|
37
42
|
$color_base_status_error: #B91C1C; // red-700, with #fff = 6.4:1
|