@bigtablet/design-system 3.0.0 → 3.1.1
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 +357 -0
- package/dist/index.d.ts +76 -8
- package/dist/index.js +192 -112
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -718,6 +718,267 @@
|
|
|
718
718
|
color: #fff;
|
|
719
719
|
}
|
|
720
720
|
|
|
721
|
+
/* src/ui/navigation/bottom-nav/style.scss */
|
|
722
|
+
:root {
|
|
723
|
+
--bt-color-brand-primary: #121212;
|
|
724
|
+
--bt-color-brand-on-primary: #FFFFFF;
|
|
725
|
+
--bt-color-brand-primary-container: rgba(0, 0, 0, 0.05);
|
|
726
|
+
--bt-color-text-heading: #121212;
|
|
727
|
+
--bt-color-text-body: #666666;
|
|
728
|
+
--bt-color-text-caption: #888888;
|
|
729
|
+
--bt-color-text-brand: #121212;
|
|
730
|
+
--bt-color-text-inverse: #FFFFFF;
|
|
731
|
+
--bt-color-text-disabled: rgba(26, 26, 26, 0.38);
|
|
732
|
+
--bt-color-bg-solid: #FFFFFF;
|
|
733
|
+
--bt-color-bg-solid-dim: #F4F4F4;
|
|
734
|
+
--bt-color-bg-additive: rgba(0, 0, 0, 0.05);
|
|
735
|
+
--bt-color-bg-disabled: rgba(26, 26, 26, 0.12);
|
|
736
|
+
--bt-color-bg-overlay: rgba(0, 0, 0, 0.5);
|
|
737
|
+
--bt-color-bg-inverse-surface: #333333;
|
|
738
|
+
--bt-color-state-hover-on-light: rgba(0, 0, 0, 0.05);
|
|
739
|
+
--bt-color-state-pressed-on-light: rgba(26, 26, 26, 0.12);
|
|
740
|
+
--bt-color-state-focus-on-light: rgba(0, 0, 0, 0.08);
|
|
741
|
+
--bt-color-state-hover-on-dark: rgba(255, 255, 255, 0.05);
|
|
742
|
+
--bt-color-state-pressed-on-dark: rgba(255, 255, 255, 0.12);
|
|
743
|
+
--bt-color-state-focus-on-dark: rgba(255, 255, 255, 0.08);
|
|
744
|
+
--bt-color-border-default: #E5E5E5;
|
|
745
|
+
--bt-color-border-hover: #B3B3B3;
|
|
746
|
+
--bt-color-border-subtle: rgba(0, 0, 0, 0.08);
|
|
747
|
+
--bt-color-border-focus: #121212;
|
|
748
|
+
--bt-color-border-disabled: #F2F2F2;
|
|
749
|
+
--bt-color-status-error: #EF4444;
|
|
750
|
+
--bt-color-status-success: #10B981;
|
|
751
|
+
--bt-color-status-warning: #F59E0B;
|
|
752
|
+
--bt-color-status-info: #3B82F6;
|
|
753
|
+
--bt-color-accent-subtle: rgba(0, 0, 0, 0.05);
|
|
754
|
+
--bt-color-accent-muted: rgba(26, 26, 26, 0.12);
|
|
755
|
+
--bt-color-accent-light: #B3B3B3;
|
|
756
|
+
--bt-color-accent-default: #121212;
|
|
757
|
+
--bt-color-accent-strong: #121212;
|
|
758
|
+
--bt-color-accent-on-surface: #FFFFFF;
|
|
759
|
+
--bt-color-skeleton-base: #F3F3F3;
|
|
760
|
+
--bt-color-skeleton-wave: #f0f0f0;
|
|
761
|
+
--bt-color-skeleton-highlight: #fafafa;
|
|
762
|
+
}
|
|
763
|
+
[data-theme=dark] {
|
|
764
|
+
color-scheme: dark;
|
|
765
|
+
-webkit-font-smoothing: antialiased;
|
|
766
|
+
-moz-osx-font-smoothing: grayscale;
|
|
767
|
+
--bt-color-text-heading: rgba(255, 255, 255, 0.95);
|
|
768
|
+
--bt-color-text-body: #B4C2CD;
|
|
769
|
+
--bt-color-text-caption: #B3B3B3;
|
|
770
|
+
--bt-color-text-inverse: #121212;
|
|
771
|
+
--bt-color-text-disabled: rgba(255, 255, 255, 0.38);
|
|
772
|
+
--bt-color-bg-solid: #1F2630;
|
|
773
|
+
--bt-color-bg-solid-dim: #303841;
|
|
774
|
+
--bt-color-bg-additive: rgba(255, 255, 255, 0.05);
|
|
775
|
+
--bt-color-bg-disabled: rgba(255, 255, 255, 0.12);
|
|
776
|
+
--bt-color-bg-overlay: rgba(0, 0, 0, 0.7);
|
|
777
|
+
--bt-color-bg-inverse-surface: #F4F4F4;
|
|
778
|
+
--bt-color-state-hover-on-light: rgba(255, 255, 255, 0.08);
|
|
779
|
+
--bt-color-state-pressed-on-light: rgba(255, 255, 255, 0.12);
|
|
780
|
+
--bt-color-state-focus-on-light: rgba(255, 255, 255, 0.12);
|
|
781
|
+
--bt-color-state-hover-on-dark: rgba(0, 0, 0, 0.08);
|
|
782
|
+
--bt-color-state-pressed-on-dark: rgba(26, 26, 26, 0.12);
|
|
783
|
+
--bt-color-state-focus-on-dark: rgba(26, 26, 26, 0.12);
|
|
784
|
+
--bt-color-border-default: #3D4852;
|
|
785
|
+
--bt-color-border-hover: #5A8DCB;
|
|
786
|
+
--bt-color-border-subtle: rgba(255, 255, 255, 0.12);
|
|
787
|
+
--bt-color-border-focus: #FFFFFF;
|
|
788
|
+
--bt-color-border-disabled: #303841;
|
|
789
|
+
--bt-color-brand-primary-container: rgba(255, 255, 255, 0.08);
|
|
790
|
+
--bt-color-accent-subtle: rgba(255, 255, 255, 0.08);
|
|
791
|
+
--bt-color-accent-muted: rgba(255, 255, 255, 0.12);
|
|
792
|
+
--bt-color-accent-light: #999999;
|
|
793
|
+
--bt-color-accent-default: #FFFFFF;
|
|
794
|
+
--bt-color-accent-strong: #FFFFFF;
|
|
795
|
+
--bt-color-accent-on-surface: #121212;
|
|
796
|
+
--bt-color-skeleton-base: #3D4852;
|
|
797
|
+
--bt-color-skeleton-wave: #3D4852;
|
|
798
|
+
--bt-color-skeleton-highlight: #47555E;
|
|
799
|
+
}
|
|
800
|
+
@media (prefers-color-scheme: dark) {
|
|
801
|
+
:root:not([data-theme]) {
|
|
802
|
+
color-scheme: dark;
|
|
803
|
+
-webkit-font-smoothing: antialiased;
|
|
804
|
+
-moz-osx-font-smoothing: grayscale;
|
|
805
|
+
--bt-color-text-heading: rgba(255, 255, 255, 0.95);
|
|
806
|
+
--bt-color-text-body: #B4C2CD;
|
|
807
|
+
--bt-color-text-caption: #B3B3B3;
|
|
808
|
+
--bt-color-text-inverse: #121212;
|
|
809
|
+
--bt-color-text-disabled: rgba(255, 255, 255, 0.38);
|
|
810
|
+
--bt-color-bg-solid: #1F2630;
|
|
811
|
+
--bt-color-bg-solid-dim: #303841;
|
|
812
|
+
--bt-color-bg-additive: rgba(255, 255, 255, 0.05);
|
|
813
|
+
--bt-color-bg-disabled: rgba(255, 255, 255, 0.12);
|
|
814
|
+
--bt-color-bg-overlay: rgba(0, 0, 0, 0.7);
|
|
815
|
+
--bt-color-bg-inverse-surface: #F4F4F4;
|
|
816
|
+
--bt-color-state-hover-on-light: rgba(255, 255, 255, 0.08);
|
|
817
|
+
--bt-color-state-pressed-on-light: rgba(255, 255, 255, 0.12);
|
|
818
|
+
--bt-color-state-focus-on-light: rgba(255, 255, 255, 0.12);
|
|
819
|
+
--bt-color-state-hover-on-dark: rgba(0, 0, 0, 0.08);
|
|
820
|
+
--bt-color-state-pressed-on-dark: rgba(26, 26, 26, 0.12);
|
|
821
|
+
--bt-color-state-focus-on-dark: rgba(26, 26, 26, 0.12);
|
|
822
|
+
--bt-color-border-default: #3D4852;
|
|
823
|
+
--bt-color-border-hover: #5A8DCB;
|
|
824
|
+
--bt-color-border-subtle: rgba(255, 255, 255, 0.12);
|
|
825
|
+
--bt-color-border-focus: #FFFFFF;
|
|
826
|
+
--bt-color-border-disabled: #303841;
|
|
827
|
+
--bt-color-brand-primary-container: rgba(255, 255, 255, 0.08);
|
|
828
|
+
--bt-color-accent-subtle: rgba(255, 255, 255, 0.08);
|
|
829
|
+
--bt-color-accent-muted: rgba(255, 255, 255, 0.12);
|
|
830
|
+
--bt-color-accent-light: #999999;
|
|
831
|
+
--bt-color-accent-default: #FFFFFF;
|
|
832
|
+
--bt-color-accent-strong: #FFFFFF;
|
|
833
|
+
--bt-color-accent-on-surface: #121212;
|
|
834
|
+
--bt-color-skeleton-base: #3D4852;
|
|
835
|
+
--bt-color-skeleton-wave: #3D4852;
|
|
836
|
+
--bt-color-skeleton-highlight: #47555E;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
:root {
|
|
840
|
+
--bt-focus-ring: 0 0 0 3px rgba(0, 0, 0, 0.15);
|
|
841
|
+
--bt-focus-ring-error: 0 0 0 3px rgba(239, 68, 68, 0.30);
|
|
842
|
+
--bt-focus-ring-success: 0 0 0 3px rgba(16, 185, 129, 0.30);
|
|
843
|
+
}
|
|
844
|
+
[data-theme=dark] {
|
|
845
|
+
--bt-focus-ring: 0 0 0 3px rgba(255, 255, 255, 0.35);
|
|
846
|
+
--bt-focus-ring-error: 0 0 0 3px rgba(239, 68, 68, 0.45);
|
|
847
|
+
--bt-focus-ring-success: 0 0 0 3px rgba(16, 185, 129, 0.45);
|
|
848
|
+
}
|
|
849
|
+
@media (prefers-color-scheme: dark) {
|
|
850
|
+
:root:not([data-theme]) {
|
|
851
|
+
--bt-focus-ring: 0 0 0 3px rgba(255, 255, 255, 0.35);
|
|
852
|
+
--bt-focus-ring-error: 0 0 0 3px rgba(239, 68, 68, 0.45);
|
|
853
|
+
--bt-focus-ring-success: 0 0 0 3px rgba(16, 185, 129, 0.45);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
:root {
|
|
857
|
+
--bt-elevation-level1: 0 1px 1px -1px rgba(0, 0, 0, 0.20), 0 3px 3px 0px rgba(0, 0, 0, 0.12);
|
|
858
|
+
--bt-elevation-level2: 0 2px 2px -2px rgba(0, 0, 0, 0.20), 0 6px 6px 0px rgba(0, 0, 0, 0.12);
|
|
859
|
+
--bt-elevation-level3: 0 3px 3px -3px rgba(0, 0, 0, 0.20), 0 9px 9px 0px rgba(0, 0, 0, 0.12);
|
|
860
|
+
--bt-elevation-level4: 0 5px 5px -5px rgba(0, 0, 0, 0.20), 0 15px 15px 0px rgba(0, 0, 0, 0.12);
|
|
861
|
+
--bt-elevation-level5: 0 8px 10px -5px rgba(0, 0, 0, 0.20), 0 20px 20px 0px rgba(0, 0, 0, 0.12);
|
|
862
|
+
}
|
|
863
|
+
[data-theme=dark] {
|
|
864
|
+
--bt-elevation-level1: 0 1px 2px 0 rgba(0, 0, 0, 0.45), 0 3px 6px 0 rgba(0, 0, 0, 0.30);
|
|
865
|
+
--bt-elevation-level2: 0 2px 4px 0 rgba(0, 0, 0, 0.45), 0 6px 12px 0 rgba(0, 0, 0, 0.30);
|
|
866
|
+
--bt-elevation-level3: 0 3px 6px 0 rgba(0, 0, 0, 0.50), 0 9px 18px 0 rgba(0, 0, 0, 0.35);
|
|
867
|
+
--bt-elevation-level4: 0 5px 10px 0 rgba(0, 0, 0, 0.55), 0 15px 30px 0 rgba(0, 0, 0, 0.40);
|
|
868
|
+
--bt-elevation-level5: 0 8px 16px 0 rgba(0, 0, 0, 0.60), 0 20px 40px 0 rgba(0, 0, 0, 0.45);
|
|
869
|
+
}
|
|
870
|
+
@media (prefers-color-scheme: dark) {
|
|
871
|
+
:root:not([data-theme]) {
|
|
872
|
+
--bt-elevation-level1: 0 1px 2px 0 rgba(0, 0, 0, 0.45), 0 3px 6px 0 rgba(0, 0, 0, 0.30);
|
|
873
|
+
--bt-elevation-level2: 0 2px 4px 0 rgba(0, 0, 0, 0.45), 0 6px 12px 0 rgba(0, 0, 0, 0.30);
|
|
874
|
+
--bt-elevation-level3: 0 3px 6px 0 rgba(0, 0, 0, 0.50), 0 9px 18px 0 rgba(0, 0, 0, 0.35);
|
|
875
|
+
--bt-elevation-level4: 0 5px 10px 0 rgba(0, 0, 0, 0.55), 0 15px 30px 0 rgba(0, 0, 0, 0.40);
|
|
876
|
+
--bt-elevation-level5: 0 8px 16px 0 rgba(0, 0, 0, 0.60), 0 20px 40px 0 rgba(0, 0, 0, 0.45);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
@keyframes skeleton_loading {
|
|
880
|
+
0% {
|
|
881
|
+
background-position: 100% 0;
|
|
882
|
+
}
|
|
883
|
+
100% {
|
|
884
|
+
background-position: 0 0;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
:root {
|
|
888
|
+
--bt-bottom-nav-height: 56px;
|
|
889
|
+
--bt-bottom-nav-safe-area: env(safe-area-inset-bottom, 0px);
|
|
890
|
+
--bt-bottom-nav-total-height: calc( var(--bt-bottom-nav-height) + var(--bt-bottom-nav-safe-area) );
|
|
891
|
+
}
|
|
892
|
+
.bottom_nav {
|
|
893
|
+
position: fixed;
|
|
894
|
+
left: 0;
|
|
895
|
+
right: 0;
|
|
896
|
+
bottom: 0;
|
|
897
|
+
z-index: 100;
|
|
898
|
+
display: flex;
|
|
899
|
+
align-items: stretch;
|
|
900
|
+
justify-content: space-around;
|
|
901
|
+
height: var(--bt-bottom-nav-total-height);
|
|
902
|
+
padding-bottom: var(--bt-bottom-nav-safe-area);
|
|
903
|
+
background: var(--bt-color-bg-solid);
|
|
904
|
+
border-top: 1px solid var(--bt-color-border-default);
|
|
905
|
+
}
|
|
906
|
+
.bottom_nav_item {
|
|
907
|
+
flex: 1;
|
|
908
|
+
min-width: 0;
|
|
909
|
+
display: inline-flex;
|
|
910
|
+
flex-direction: column;
|
|
911
|
+
align-items: center;
|
|
912
|
+
justify-content: center;
|
|
913
|
+
gap: 2px;
|
|
914
|
+
padding: 8px 4px;
|
|
915
|
+
border: none;
|
|
916
|
+
background: transparent;
|
|
917
|
+
color: var(--bt-color-text-caption);
|
|
918
|
+
cursor: pointer;
|
|
919
|
+
text-decoration: none;
|
|
920
|
+
min-height: 56px;
|
|
921
|
+
transition: color 0.1s cubic-bezier(0.16, 1, 0.3, 1), background 0.1s cubic-bezier(0.16, 1, 0.3, 1);
|
|
922
|
+
}
|
|
923
|
+
.bottom_nav_item:hover:not(.bottom_nav_item_active) {
|
|
924
|
+
background: var(--bt-color-state-hover-on-light);
|
|
925
|
+
color: var(--bt-color-text-heading);
|
|
926
|
+
}
|
|
927
|
+
.bottom_nav_item:active:not(.bottom_nav_item_active) {
|
|
928
|
+
background: var(--bt-color-state-pressed-on-light);
|
|
929
|
+
}
|
|
930
|
+
.bottom_nav_item:focus-visible {
|
|
931
|
+
outline: none;
|
|
932
|
+
box-shadow: var(--bt-focus-ring);
|
|
933
|
+
}
|
|
934
|
+
.bottom_nav_item:disabled,
|
|
935
|
+
.bottom_nav_item_disabled {
|
|
936
|
+
opacity: 0.4;
|
|
937
|
+
cursor: not-allowed;
|
|
938
|
+
pointer-events: none;
|
|
939
|
+
}
|
|
940
|
+
.bottom_nav_item_active {
|
|
941
|
+
color: var(--bt-color-accent-default);
|
|
942
|
+
}
|
|
943
|
+
.bottom_nav_item_active .bottom_nav_item_label {
|
|
944
|
+
font-weight: 600;
|
|
945
|
+
}
|
|
946
|
+
.bottom_nav_item_icon {
|
|
947
|
+
position: relative;
|
|
948
|
+
display: inline-flex;
|
|
949
|
+
align-items: center;
|
|
950
|
+
justify-content: center;
|
|
951
|
+
width: 24px;
|
|
952
|
+
height: 24px;
|
|
953
|
+
}
|
|
954
|
+
.bottom_nav_item_badge {
|
|
955
|
+
position: absolute;
|
|
956
|
+
top: -4px;
|
|
957
|
+
right: -8px;
|
|
958
|
+
pointer-events: none;
|
|
959
|
+
}
|
|
960
|
+
.bottom_nav_item_label {
|
|
961
|
+
font-size: 12px;
|
|
962
|
+
font-weight: 500;
|
|
963
|
+
line-height: 16px;
|
|
964
|
+
letter-spacing: 0px;
|
|
965
|
+
line-height: 1.2;
|
|
966
|
+
text-align: center;
|
|
967
|
+
max-width: 100%;
|
|
968
|
+
overflow: hidden;
|
|
969
|
+
text-overflow: ellipsis;
|
|
970
|
+
white-space: nowrap;
|
|
971
|
+
}
|
|
972
|
+
.bottom_nav_spacer {
|
|
973
|
+
height: var(--bt-bottom-nav-total-height);
|
|
974
|
+
flex-shrink: 0;
|
|
975
|
+
}
|
|
976
|
+
@media (prefers-reduced-motion: reduce) {
|
|
977
|
+
.bottom_nav_item {
|
|
978
|
+
transition: none;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
721
982
|
/* src/ui/navigation/breadcrumb/style.scss */
|
|
722
983
|
:root {
|
|
723
984
|
--bt-color-brand-primary: #121212;
|
|
@@ -2175,6 +2436,102 @@
|
|
|
2175
2436
|
padding: 8px;
|
|
2176
2437
|
gap: 0;
|
|
2177
2438
|
}
|
|
2439
|
+
@media (max-width: 599px) {
|
|
2440
|
+
:root {
|
|
2441
|
+
--bt-sidebar-height: 56px;
|
|
2442
|
+
--bt-sidebar-safe-area: env(safe-area-inset-bottom, 0px);
|
|
2443
|
+
--bt-sidebar-total-height: calc( var(--bt-sidebar-height) + var(--bt-sidebar-safe-area) );
|
|
2444
|
+
}
|
|
2445
|
+
.sidebar:not(.sidebar_static) {
|
|
2446
|
+
position: fixed;
|
|
2447
|
+
inset: auto 0 0 0;
|
|
2448
|
+
width: 100% !important;
|
|
2449
|
+
height: auto;
|
|
2450
|
+
min-height: 0;
|
|
2451
|
+
flex-direction: row;
|
|
2452
|
+
border-right: none;
|
|
2453
|
+
border-top: 1px solid var(--bt-color-border-default);
|
|
2454
|
+
box-shadow: var(--bt-elevation-level2);
|
|
2455
|
+
z-index: 100;
|
|
2456
|
+
padding-bottom: var(--bt-sidebar-safe-area);
|
|
2457
|
+
}
|
|
2458
|
+
.sidebar:not(.sidebar_static) .sidebar_header,
|
|
2459
|
+
.sidebar:not(.sidebar_static) .sidebar_footer,
|
|
2460
|
+
.sidebar:not(.sidebar_static) .sidebar_collapse_btn,
|
|
2461
|
+
.sidebar:not(.sidebar_static) .sidebar_section_label {
|
|
2462
|
+
display: none;
|
|
2463
|
+
}
|
|
2464
|
+
.sidebar:not(.sidebar_static) .sidebar_nav {
|
|
2465
|
+
flex: 1;
|
|
2466
|
+
flex-direction: row;
|
|
2467
|
+
align-items: stretch;
|
|
2468
|
+
padding: 0;
|
|
2469
|
+
gap: 0;
|
|
2470
|
+
overflow: visible;
|
|
2471
|
+
}
|
|
2472
|
+
.sidebar:not(.sidebar_static) .sidebar_section {
|
|
2473
|
+
display: contents;
|
|
2474
|
+
}
|
|
2475
|
+
.sidebar:not(.sidebar_static) .sidebar_item {
|
|
2476
|
+
flex: 1;
|
|
2477
|
+
flex-direction: column;
|
|
2478
|
+
align-items: center;
|
|
2479
|
+
justify-content: center;
|
|
2480
|
+
gap: 4px;
|
|
2481
|
+
padding: 6px 4px;
|
|
2482
|
+
min-height: 56px;
|
|
2483
|
+
border-radius: 0;
|
|
2484
|
+
color: var(--bt-color-text-body);
|
|
2485
|
+
}
|
|
2486
|
+
.sidebar:not(.sidebar_static) .sidebar_item:hover:not(.sidebar_item_active) {
|
|
2487
|
+
background: var(--bt-color-state-hover-on-light);
|
|
2488
|
+
color: var(--bt-color-text-heading);
|
|
2489
|
+
}
|
|
2490
|
+
.sidebar:not(.sidebar_static) .sidebar_item_active {
|
|
2491
|
+
background: transparent;
|
|
2492
|
+
color: var(--bt-color-text-heading);
|
|
2493
|
+
}
|
|
2494
|
+
.sidebar:not(.sidebar_static) .sidebar_item_active .sidebar_item_icon {
|
|
2495
|
+
background: var(--bt-color-brand-primary);
|
|
2496
|
+
color: var(--bt-color-brand-on-primary);
|
|
2497
|
+
border-radius: 9999px;
|
|
2498
|
+
padding: 0 16px;
|
|
2499
|
+
width: auto;
|
|
2500
|
+
height: 32px;
|
|
2501
|
+
min-width: 56px;
|
|
2502
|
+
}
|
|
2503
|
+
.sidebar:not(.sidebar_static) .sidebar_item_active .sidebar_item_label {
|
|
2504
|
+
font-weight: 600;
|
|
2505
|
+
}
|
|
2506
|
+
.sidebar:not(.sidebar_static) .sidebar_item_icon {
|
|
2507
|
+
width: 24px;
|
|
2508
|
+
height: 24px;
|
|
2509
|
+
transition: background 0.1s ease-in-out, color 0.1s ease-in-out;
|
|
2510
|
+
}
|
|
2511
|
+
.sidebar:not(.sidebar_static) .sidebar_item_label {
|
|
2512
|
+
font-size: 12px;
|
|
2513
|
+
font-weight: 500;
|
|
2514
|
+
line-height: 16px;
|
|
2515
|
+
letter-spacing: 0px;
|
|
2516
|
+
flex: 0 0 auto;
|
|
2517
|
+
line-height: 1.2;
|
|
2518
|
+
text-align: center;
|
|
2519
|
+
max-width: 100%;
|
|
2520
|
+
white-space: nowrap;
|
|
2521
|
+
}
|
|
2522
|
+
.sidebar:not(.sidebar_static) .sidebar_item_trailing {
|
|
2523
|
+
display: none;
|
|
2524
|
+
}
|
|
2525
|
+
.sidebar:not(.sidebar_static).sidebar_collapsed .sidebar_item_label {
|
|
2526
|
+
position: static;
|
|
2527
|
+
width: auto;
|
|
2528
|
+
height: auto;
|
|
2529
|
+
padding: 0;
|
|
2530
|
+
margin: 0;
|
|
2531
|
+
overflow: visible;
|
|
2532
|
+
clip: auto;
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2178
2535
|
|
|
2179
2536
|
/* src/ui/navigation/tabs/style.scss */
|
|
2180
2537
|
:root {
|
package/dist/index.d.ts
CHANGED
|
@@ -171,6 +171,62 @@ interface BadgeProps extends React$1.HTMLAttributes<HTMLSpanElement> {
|
|
|
171
171
|
*/
|
|
172
172
|
declare const Badge: ({ variant, shape, size, count, max, className, children, ...props }: BadgeProps) => react_jsx_runtime.JSX.Element;
|
|
173
173
|
|
|
174
|
+
interface BottomNavProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "onChange"> {
|
|
175
|
+
/** 스크린 리더 레이블 (기본 "주요 메뉴") */
|
|
176
|
+
ariaLabel?: string;
|
|
177
|
+
/** 2–5 개의 `BottomNavItem` */
|
|
178
|
+
children: React$1.ReactNode;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* 모바일 하단 네비게이션 바.
|
|
182
|
+
*
|
|
183
|
+
* `position: fixed; bottom: 0` 으로 viewport 하단 고정. iOS 홈 인디케이터 영역
|
|
184
|
+
* (`env(safe-area-inset-bottom)`) 자동 패딩. 본문이 가려지지 않게 페이지 끝에
|
|
185
|
+
* `<BottomNavSpacer />` 를 깔거나 `--bt-bottom-nav-height` CSS 변수로 padding 계산.
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```tsx
|
|
189
|
+
* <BottomNav>
|
|
190
|
+
* <BottomNavItem icon={<Home />} label="주문" active />
|
|
191
|
+
* <BottomNavItem icon={<Menu />} label="메뉴" />
|
|
192
|
+
* <BottomNavItem icon={<Chart />} label="매출" />
|
|
193
|
+
* </BottomNav>
|
|
194
|
+
* <BottomNavSpacer />
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
declare const BottomNav: ({ ariaLabel, className, children, ...props }: BottomNavProps) => react_jsx_runtime.JSX.Element;
|
|
198
|
+
interface BottomNavItemCommon {
|
|
199
|
+
/** 아이콘 (필수) */
|
|
200
|
+
icon: React$1.ReactNode;
|
|
201
|
+
/** 라벨 텍스트 (필수, 짧게 — 2–4자) */
|
|
202
|
+
label: string;
|
|
203
|
+
/** 활성 상태 */
|
|
204
|
+
active?: boolean;
|
|
205
|
+
/** 아이콘 우상단 dot/카운트 (Badge 등) */
|
|
206
|
+
badge?: React$1.ReactNode;
|
|
207
|
+
}
|
|
208
|
+
type BottomNavItemButton = BottomNavItemCommon & {
|
|
209
|
+
as?: "button";
|
|
210
|
+
href?: never;
|
|
211
|
+
} & Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, "children">;
|
|
212
|
+
type BottomNavItemAnchor = BottomNavItemCommon & {
|
|
213
|
+
as: "a";
|
|
214
|
+
href: string;
|
|
215
|
+
/** anchor 에 native `disabled` 없음 — `aria-disabled` + `preventDefault` 로 처리. */
|
|
216
|
+
disabled?: boolean;
|
|
217
|
+
} & Omit<React$1.AnchorHTMLAttributes<HTMLAnchorElement>, "children" | "type">;
|
|
218
|
+
type BottomNavItemProps = BottomNavItemButton | BottomNavItemAnchor;
|
|
219
|
+
/**
|
|
220
|
+
* `BottomNav` 의 항목. icon + label 수직 스택.
|
|
221
|
+
* active 시 `aria-current="page"` 자동 부여.
|
|
222
|
+
*/
|
|
223
|
+
declare const BottomNavItem: (props: BottomNavItemProps) => react_jsx_runtime.JSX.Element;
|
|
224
|
+
/**
|
|
225
|
+
* 페이지 본문 끝에 두면 `BottomNav` 가 콘텐츠를 가리지 않게 빈 공간 확보.
|
|
226
|
+
* `--bt-bottom-nav-height` (+ safe-area) 만큼 height.
|
|
227
|
+
*/
|
|
228
|
+
declare const BottomNavSpacer: ({ className, ...props }: React$1.HTMLAttributes<HTMLDivElement>) => react_jsx_runtime.JSX.Element;
|
|
229
|
+
|
|
174
230
|
interface BreadcrumbItem {
|
|
175
231
|
/** 표시 텍스트 */
|
|
176
232
|
label: React$1.ReactNode;
|
|
@@ -326,6 +382,7 @@ interface NavLinkProps extends React$1.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
|
326
382
|
}
|
|
327
383
|
declare const NavLink: ({ active, className, children, ...props }: NavLinkProps) => react_jsx_runtime.JSX.Element;
|
|
328
384
|
|
|
385
|
+
type SidebarMode = "auto" | "static";
|
|
329
386
|
interface SidebarProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "onChange"> {
|
|
330
387
|
/** 상단 brand 영역 (펼친 상태 로고) */
|
|
331
388
|
header?: React$1.ReactNode;
|
|
@@ -347,6 +404,12 @@ interface SidebarProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "onChan
|
|
|
347
404
|
width?: number;
|
|
348
405
|
/** collapsed 너비 (기본 64px) */
|
|
349
406
|
collapsedWidth?: number;
|
|
407
|
+
/**
|
|
408
|
+
* 반응형 모드 (기본 `"auto"`).
|
|
409
|
+
* - `"auto"`: viewport `< 600px` 에서 자동으로 하단 bar 로 변신.
|
|
410
|
+
* - `"static"`: 어떤 viewport 에서도 좌측 rail 유지 (admin desktop-only).
|
|
411
|
+
*/
|
|
412
|
+
mode?: SidebarMode;
|
|
350
413
|
}
|
|
351
414
|
/**
|
|
352
415
|
* admin/dashboard 좌측 네비게이션.
|
|
@@ -363,20 +426,25 @@ interface SidebarProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "onChan
|
|
|
363
426
|
* </Sidebar>
|
|
364
427
|
* ```
|
|
365
428
|
*/
|
|
366
|
-
declare const Sidebar: ({ header, headerCollapsed, footer, collapsed: collapsedProp, defaultCollapsed, onCollapsedChange, collapsible, toggleLabel, width, collapsedWidth, className, children, style, ...props }: SidebarProps) => react_jsx_runtime.JSX.Element;
|
|
367
|
-
interface
|
|
429
|
+
declare const Sidebar: ({ header, headerCollapsed, footer, collapsed: collapsedProp, defaultCollapsed, onCollapsedChange, collapsible, toggleLabel, width, collapsedWidth, mode, className, children, style, ...props }: SidebarProps) => react_jsx_runtime.JSX.Element;
|
|
430
|
+
interface SidebarItemCommon {
|
|
368
431
|
/** 왼쪽 아이콘 */
|
|
369
432
|
icon?: React$1.ReactNode;
|
|
370
433
|
/** 현재 활성 상태 */
|
|
371
434
|
active?: boolean;
|
|
372
435
|
/** 오른쪽 trailing (Badge 등) */
|
|
373
436
|
trailing?: React$1.ReactNode;
|
|
374
|
-
/** 링크 컴포넌트 (Next Link 등). `asChild` 패턴 — `as="a" href="..."` */
|
|
375
|
-
as?: "button" | "a";
|
|
376
|
-
/** as="a"일 때 사용 */
|
|
377
|
-
href?: string;
|
|
378
437
|
}
|
|
379
|
-
|
|
438
|
+
type SidebarItemButton = SidebarItemCommon & {
|
|
439
|
+
as?: "button";
|
|
440
|
+
href?: never;
|
|
441
|
+
} & React$1.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
442
|
+
type SidebarItemAnchor = SidebarItemCommon & {
|
|
443
|
+
as: "a";
|
|
444
|
+
href: string;
|
|
445
|
+
} & Omit<React$1.AnchorHTMLAttributes<HTMLAnchorElement>, "type">;
|
|
446
|
+
type SidebarItemProps = SidebarItemButton | SidebarItemAnchor;
|
|
447
|
+
declare const SidebarItem: (props: SidebarItemProps) => react_jsx_runtime.JSX.Element;
|
|
380
448
|
interface SidebarSectionProps extends React$1.HTMLAttributes<HTMLDivElement> {
|
|
381
449
|
/** 섹션 라벨 (collapsed 상태에선 hidden) */
|
|
382
450
|
label?: string;
|
|
@@ -1866,4 +1934,4 @@ interface GridProps extends React$1.HTMLAttributes<HTMLDivElement> {
|
|
|
1866
1934
|
*/
|
|
1867
1935
|
declare const Grid: ({ cols, minColWidth, gap, rowGap, colGap, singleColOnMobile, as: Tag, className, children, style, ...props }: GridProps) => react_jsx_runtime.JSX.Element;
|
|
1868
1936
|
|
|
1869
|
-
export { Accordion, type AccordionItem, type AccordionProps, AlertProvider, Avatar, type AvatarProps, type AvatarShape, type AvatarSize, Badge, type BadgeProps, type BadgeShape, type BadgeSize, type BadgeVariant, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipProps, type ChipSize, type ChipTone, type ChipType, Container, type ContainerProps, type ContainerSize, DatePicker, type DatePickerProps, Divider, type DividerProps, Dropdown, type DropdownOption, type DropdownProps, type DropdownSize, EmptyState, type EmptyStateProps, FileInput, type FileInputProps, Grid, type GridCols, type GridGap, type GridProps, Hero, type HeroAction, type HeroAlign, type HeroHeight, type HeroOverlay, type HeroProps, Icon, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, type IconProps, LinearProgress, type LinearProgressProps, ListItem, type ListItemProps, MediaCard, type MediaCardImage, type MediaCardImagePosition, type MediaCardProps, type MediaCardShadow, Menu, type MenuItem, type MenuProps, Modal, type ModalProps, NavBar, type NavBarLayout, type NavBarLocaleConfig, type NavBarLocaleOption, type NavBarProps, type NavBarVariant, NavLink, type NavLinkProps, OtpInput, type OtpInputProps, Pagination, type PaginationProps, Radio, type RadioProps, type ResolvedTheme, Section, type SectionBg, type SectionProps, type SectionSpacing, Sidebar, SidebarItem, type SidebarItemProps, type SidebarProps, SidebarSection, type SidebarSectionProps, Skeleton, type SkeletonProps, type SkeletonVariant, Spinner, type SpinnerProps, Stack, type StackAlign, type StackDirection, type StackGap, type StackJustify, type StackProps, type StackWrap, Tab, TabList, type TabListProps, TabPanel, type TabPanelProps, type TabProps, Table, type TableColumn, type TableProps, type TableSize, Tabs, type TabsProps, type TabsSize, type TabsVariant, TextField, type TextFieldProps, type ThemeMode, ThemeProvider, type ThemeProviderProps, ToastProvider, Toggle, type ToggleProps, Tooltip, type TooltipPlacement, type TooltipProps, TopLoading, type TopLoadingProps, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, cn, colors, elevation, motion, opacity, radius, skeleton, spacing, typography, useAlert, useFocusTrap, useSpringHover, useSpringPresence, useTheme, useToast, zIndex };
|
|
1937
|
+
export { Accordion, type AccordionItem, type AccordionProps, AlertProvider, Avatar, type AvatarProps, type AvatarShape, type AvatarSize, Badge, type BadgeProps, type BadgeShape, type BadgeSize, type BadgeVariant, BottomNav, BottomNavItem, type BottomNavItemProps, type BottomNavProps, BottomNavSpacer, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, Chip, type ChipProps, type ChipSize, type ChipTone, type ChipType, Container, type ContainerProps, type ContainerSize, DatePicker, type DatePickerProps, Divider, type DividerProps, Dropdown, type DropdownOption, type DropdownProps, type DropdownSize, EmptyState, type EmptyStateProps, FileInput, type FileInputProps, Grid, type GridCols, type GridGap, type GridProps, Hero, type HeroAction, type HeroAlign, type HeroHeight, type HeroOverlay, type HeroProps, Icon, IconButton, type IconButtonProps, type IconButtonSize, type IconButtonVariant, type IconProps, LinearProgress, type LinearProgressProps, ListItem, type ListItemProps, MediaCard, type MediaCardImage, type MediaCardImagePosition, type MediaCardProps, type MediaCardShadow, Menu, type MenuItem, type MenuProps, Modal, type ModalProps, NavBar, type NavBarLayout, type NavBarLocaleConfig, type NavBarLocaleOption, type NavBarProps, type NavBarVariant, NavLink, type NavLinkProps, OtpInput, type OtpInputProps, Pagination, type PaginationProps, Radio, type RadioProps, type ResolvedTheme, Section, type SectionBg, type SectionProps, type SectionSpacing, Sidebar, SidebarItem, type SidebarItemProps, type SidebarMode, type SidebarProps, SidebarSection, type SidebarSectionProps, Skeleton, type SkeletonProps, type SkeletonVariant, Spinner, type SpinnerProps, Stack, type StackAlign, type StackDirection, type StackGap, type StackJustify, type StackProps, type StackWrap, Tab, TabList, type TabListProps, TabPanel, type TabPanelProps, type TabProps, Table, type TableColumn, type TableProps, type TableSize, Tabs, type TabsProps, type TabsSize, type TabsVariant, TextField, type TextFieldProps, type ThemeMode, ThemeProvider, type ThemeProviderProps, ToastProvider, Toggle, type ToggleProps, Tooltip, type TooltipPlacement, type TooltipProps, TopLoading, type TopLoadingProps, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, cn, colors, elevation, motion, opacity, radius, skeleton, spacing, typography, useAlert, useFocusTrap, useSpringHover, useSpringPresence, useTheme, useToast, zIndex };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import './index.css';
|
|
3
|
-
import * as
|
|
3
|
+
import * as React17 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, XCircle, AlertTriangle, CheckCircle2, Info, Bell } from 'lucide-react';
|
|
7
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
8
8
|
import { createPortal } from 'react-dom';
|
|
9
9
|
|
|
10
10
|
// src/utils/cn.ts
|
|
@@ -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 = React17.useRef(null);
|
|
42
|
+
React17.useEffect(() => {
|
|
43
43
|
if (!isActive) return;
|
|
44
44
|
const container = containerRef.current;
|
|
45
45
|
if (!container) return;
|
|
@@ -91,7 +91,7 @@ function useSpringHover({
|
|
|
91
91
|
scale = 1.02,
|
|
92
92
|
lift = -2
|
|
93
93
|
} = {}) {
|
|
94
|
-
const [hovered, setHovered] =
|
|
94
|
+
const [hovered, setHovered] = React17.useState(false);
|
|
95
95
|
const style = useSpring({
|
|
96
96
|
transform: hovered ? `translateY(${lift}px) scale(${scale})` : "translateY(0px) scale(1)",
|
|
97
97
|
config: { tension: 320, friction: 22 }
|
|
@@ -139,7 +139,7 @@ var Accordion = ({
|
|
|
139
139
|
...props
|
|
140
140
|
}) => {
|
|
141
141
|
const isControlled = controlledKeys !== void 0;
|
|
142
|
-
const [internalKeys, setInternalKeys] =
|
|
142
|
+
const [internalKeys, setInternalKeys] = React17.useState(defaultOpenKeys);
|
|
143
143
|
const open = isControlled ? controlledKeys ?? [] : internalKeys;
|
|
144
144
|
const toggle = (key) => {
|
|
145
145
|
const isOpen = open.includes(key);
|
|
@@ -205,7 +205,7 @@ var Avatar = ({
|
|
|
205
205
|
style,
|
|
206
206
|
...props
|
|
207
207
|
}) => {
|
|
208
|
-
const [imgFailed, setImgFailed] =
|
|
208
|
+
const [imgFailed, setImgFailed] = React17.useState(false);
|
|
209
209
|
const showImage = src && !imgFailed;
|
|
210
210
|
const initials = getInitials(name);
|
|
211
211
|
return /* @__PURE__ */ jsx(
|
|
@@ -263,6 +263,89 @@ var Badge = ({
|
|
|
263
263
|
}
|
|
264
264
|
);
|
|
265
265
|
};
|
|
266
|
+
var BottomNav = ({
|
|
267
|
+
ariaLabel = "\uC8FC\uC694 \uBA54\uB274",
|
|
268
|
+
className,
|
|
269
|
+
children,
|
|
270
|
+
...props
|
|
271
|
+
}) => {
|
|
272
|
+
return /* @__PURE__ */ jsx(
|
|
273
|
+
"nav",
|
|
274
|
+
{
|
|
275
|
+
className: cn("bottom_nav", className),
|
|
276
|
+
"aria-label": ariaLabel,
|
|
277
|
+
...props,
|
|
278
|
+
children
|
|
279
|
+
}
|
|
280
|
+
);
|
|
281
|
+
};
|
|
282
|
+
var BottomNavItem = (props) => {
|
|
283
|
+
const {
|
|
284
|
+
icon,
|
|
285
|
+
label,
|
|
286
|
+
active,
|
|
287
|
+
badge,
|
|
288
|
+
as = "button",
|
|
289
|
+
className,
|
|
290
|
+
disabled,
|
|
291
|
+
...rest
|
|
292
|
+
} = props;
|
|
293
|
+
const classes = cn(
|
|
294
|
+
"bottom_nav_item",
|
|
295
|
+
active && "bottom_nav_item_active",
|
|
296
|
+
disabled && "bottom_nav_item_disabled",
|
|
297
|
+
className
|
|
298
|
+
);
|
|
299
|
+
const ariaCurrent = active ? "page" : void 0;
|
|
300
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
301
|
+
/* @__PURE__ */ jsxs("span", { className: "bottom_nav_item_icon", "aria-hidden": "true", children: [
|
|
302
|
+
icon,
|
|
303
|
+
badge && /* @__PURE__ */ jsx("span", { className: "bottom_nav_item_badge", children: badge })
|
|
304
|
+
] }),
|
|
305
|
+
/* @__PURE__ */ jsx("span", { className: "bottom_nav_item_label", children: label })
|
|
306
|
+
] });
|
|
307
|
+
if (as === "a") {
|
|
308
|
+
const { href, onClick: onClick2, ...anchorRest } = rest;
|
|
309
|
+
return (
|
|
310
|
+
// biome-ignore lint/a11y/useValidAnchor: navigation link with optional active state
|
|
311
|
+
/* @__PURE__ */ jsx(
|
|
312
|
+
"a",
|
|
313
|
+
{
|
|
314
|
+
className: classes,
|
|
315
|
+
href,
|
|
316
|
+
"aria-current": ariaCurrent,
|
|
317
|
+
"aria-disabled": disabled ? "true" : void 0,
|
|
318
|
+
tabIndex: disabled ? -1 : void 0,
|
|
319
|
+
onClick: (e) => {
|
|
320
|
+
if (disabled) {
|
|
321
|
+
e.preventDefault();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
onClick2?.(e);
|
|
325
|
+
},
|
|
326
|
+
...anchorRest,
|
|
327
|
+
children: content
|
|
328
|
+
}
|
|
329
|
+
)
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
const { type, onClick, ...buttonRest } = rest;
|
|
333
|
+
return /* @__PURE__ */ jsx(
|
|
334
|
+
"button",
|
|
335
|
+
{
|
|
336
|
+
type: type ?? "button",
|
|
337
|
+
className: classes,
|
|
338
|
+
disabled,
|
|
339
|
+
"aria-current": ariaCurrent,
|
|
340
|
+
onClick,
|
|
341
|
+
...buttonRest,
|
|
342
|
+
children: content
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
};
|
|
346
|
+
var BottomNavSpacer = ({ className, ...props }) => {
|
|
347
|
+
return /* @__PURE__ */ jsx("div", { className: cn("bottom_nav_spacer", className), "aria-hidden": "true", ...props });
|
|
348
|
+
};
|
|
266
349
|
var Breadcrumb = ({
|
|
267
350
|
items,
|
|
268
351
|
separator,
|
|
@@ -309,11 +392,11 @@ var EmptyState = ({
|
|
|
309
392
|
] });
|
|
310
393
|
};
|
|
311
394
|
var Menu = ({ items, trigger, align = "start" }) => {
|
|
312
|
-
const [open, setOpen] =
|
|
313
|
-
const wrapperRef =
|
|
314
|
-
const menuId =
|
|
395
|
+
const [open, setOpen] = React17.useState(false);
|
|
396
|
+
const wrapperRef = React17.useRef(null);
|
|
397
|
+
const menuId = React17.useId();
|
|
315
398
|
const style = useSpringPresence({ visible: open, from: "translateY(-4px)" });
|
|
316
|
-
|
|
399
|
+
React17.useEffect(() => {
|
|
317
400
|
if (!open) return;
|
|
318
401
|
const handleClick = (e) => {
|
|
319
402
|
if (!wrapperRef.current?.contains(e.target)) setOpen(false);
|
|
@@ -328,7 +411,7 @@ var Menu = ({ items, trigger, align = "start" }) => {
|
|
|
328
411
|
document.removeEventListener("keydown", handleEsc);
|
|
329
412
|
};
|
|
330
413
|
}, [open]);
|
|
331
|
-
const triggerWithProps =
|
|
414
|
+
const triggerWithProps = React17.cloneElement(
|
|
332
415
|
trigger,
|
|
333
416
|
{
|
|
334
417
|
onClick: () => setOpen((o) => !o),
|
|
@@ -540,23 +623,30 @@ var Sidebar = ({
|
|
|
540
623
|
toggleLabel = "\uC0AC\uC774\uB4DC\uBC14 \uD1A0\uAE00",
|
|
541
624
|
width = 240,
|
|
542
625
|
collapsedWidth = 64,
|
|
626
|
+
mode = "auto",
|
|
543
627
|
className,
|
|
544
628
|
children,
|
|
545
629
|
style,
|
|
546
630
|
...props
|
|
547
631
|
}) => {
|
|
548
632
|
const isControlled = collapsedProp !== void 0;
|
|
549
|
-
const [internalCollapsed, setInternalCollapsed] =
|
|
633
|
+
const [internalCollapsed, setInternalCollapsed] = React17.useState(defaultCollapsed);
|
|
550
634
|
const collapsed = isControlled ? collapsedProp : internalCollapsed;
|
|
551
|
-
const toggle =
|
|
635
|
+
const toggle = React17.useCallback(() => {
|
|
552
636
|
const next = !collapsed;
|
|
553
637
|
if (!isControlled) setInternalCollapsed(next);
|
|
554
638
|
onCollapsedChange?.(next);
|
|
555
639
|
}, [collapsed, isControlled, onCollapsedChange]);
|
|
640
|
+
const isStatic = mode === "static";
|
|
556
641
|
return /* @__PURE__ */ jsxs(
|
|
557
642
|
"aside",
|
|
558
643
|
{
|
|
559
|
-
className: cn(
|
|
644
|
+
className: cn(
|
|
645
|
+
"sidebar",
|
|
646
|
+
collapsed && "sidebar_collapsed",
|
|
647
|
+
isStatic && "sidebar_static",
|
|
648
|
+
className
|
|
649
|
+
),
|
|
560
650
|
style: { width: collapsed ? collapsedWidth : width, ...style },
|
|
561
651
|
...props,
|
|
562
652
|
children: [
|
|
@@ -581,41 +671,31 @@ var Sidebar = ({
|
|
|
581
671
|
}
|
|
582
672
|
);
|
|
583
673
|
};
|
|
584
|
-
var SidebarItem = ({
|
|
585
|
-
icon,
|
|
586
|
-
active,
|
|
587
|
-
trailing,
|
|
588
|
-
as = "button",
|
|
589
|
-
href,
|
|
590
|
-
className,
|
|
591
|
-
children,
|
|
592
|
-
type,
|
|
593
|
-
...props
|
|
594
|
-
}) => {
|
|
674
|
+
var SidebarItem = (props) => {
|
|
675
|
+
const { icon, active, trailing, as = "button", className, children, ...rest } = props;
|
|
595
676
|
const classes = cn("sidebar_item", active && "sidebar_item_active", className);
|
|
596
677
|
const ariaCurrent = active ? "page" : void 0;
|
|
597
|
-
|
|
678
|
+
const inner = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
679
|
+
icon && /* @__PURE__ */ jsx("span", { className: "sidebar_item_icon", "aria-hidden": "true", children: icon }),
|
|
680
|
+
/* @__PURE__ */ jsx("span", { className: "sidebar_item_label", children }),
|
|
681
|
+
trailing && /* @__PURE__ */ jsx("span", { className: "sidebar_item_trailing", children: trailing })
|
|
682
|
+
] });
|
|
683
|
+
if (as === "a") {
|
|
684
|
+
const { href, ...anchorRest } = rest;
|
|
598
685
|
return (
|
|
599
686
|
// biome-ignore lint/a11y/useValidAnchor: navigation link with optional active state
|
|
600
|
-
/* @__PURE__ */
|
|
601
|
-
icon && /* @__PURE__ */ jsx("span", { className: "sidebar_item_icon", "aria-hidden": "true", children: icon }),
|
|
602
|
-
/* @__PURE__ */ jsx("span", { className: "sidebar_item_label", children }),
|
|
603
|
-
trailing && /* @__PURE__ */ jsx("span", { className: "sidebar_item_trailing", children: trailing })
|
|
604
|
-
] })
|
|
687
|
+
/* @__PURE__ */ jsx("a", { className: classes, href, "aria-current": ariaCurrent, ...anchorRest, children: inner })
|
|
605
688
|
);
|
|
606
689
|
}
|
|
607
|
-
|
|
690
|
+
const { type, ...buttonRest } = rest;
|
|
691
|
+
return /* @__PURE__ */ jsx(
|
|
608
692
|
"button",
|
|
609
693
|
{
|
|
610
694
|
type: type ?? "button",
|
|
611
695
|
className: classes,
|
|
612
696
|
"aria-current": ariaCurrent,
|
|
613
|
-
...
|
|
614
|
-
children:
|
|
615
|
-
icon && /* @__PURE__ */ jsx("span", { className: "sidebar_item_icon", "aria-hidden": "true", children: icon }),
|
|
616
|
-
/* @__PURE__ */ jsx("span", { className: "sidebar_item_label", children }),
|
|
617
|
-
trailing && /* @__PURE__ */ jsx("span", { className: "sidebar_item_trailing", children: trailing })
|
|
618
|
-
]
|
|
697
|
+
...buttonRest,
|
|
698
|
+
children: inner
|
|
619
699
|
}
|
|
620
700
|
);
|
|
621
701
|
};
|
|
@@ -625,9 +705,9 @@ var SidebarSection = ({ label, className, children, ...props }) => {
|
|
|
625
705
|
children
|
|
626
706
|
] });
|
|
627
707
|
};
|
|
628
|
-
var TabsContext =
|
|
708
|
+
var TabsContext = React17.createContext(null);
|
|
629
709
|
function useTabsContext() {
|
|
630
|
-
const ctx =
|
|
710
|
+
const ctx = React17.useContext(TabsContext);
|
|
631
711
|
if (!ctx) {
|
|
632
712
|
throw new Error(
|
|
633
713
|
'[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>'
|
|
@@ -646,17 +726,17 @@ var Tabs = ({
|
|
|
646
726
|
...props
|
|
647
727
|
}) => {
|
|
648
728
|
const isControlled = controlledValue !== void 0;
|
|
649
|
-
const [internalValue, setInternalValue] =
|
|
729
|
+
const [internalValue, setInternalValue] = React17.useState(defaultValue);
|
|
650
730
|
const value = isControlled ? controlledValue : internalValue;
|
|
651
|
-
const setValue =
|
|
731
|
+
const setValue = React17.useCallback(
|
|
652
732
|
(v) => {
|
|
653
733
|
if (!isControlled) setInternalValue(v);
|
|
654
734
|
onValueChange?.(v);
|
|
655
735
|
},
|
|
656
736
|
[isControlled, onValueChange]
|
|
657
737
|
);
|
|
658
|
-
const idPrefix =
|
|
659
|
-
const ctx =
|
|
738
|
+
const idPrefix = React17.useId();
|
|
739
|
+
const ctx = React17.useMemo(
|
|
660
740
|
() => ({ value, setValue, variant, size, idPrefix }),
|
|
661
741
|
[value, setValue, variant, size, idPrefix]
|
|
662
742
|
);
|
|
@@ -664,10 +744,10 @@ var Tabs = ({
|
|
|
664
744
|
};
|
|
665
745
|
var TabList = ({ ariaLabel, className, children, ...props }) => {
|
|
666
746
|
const { variant } = useTabsContext();
|
|
667
|
-
const listRef =
|
|
668
|
-
const [indicator, setIndicator] =
|
|
669
|
-
const [hasMounted, setHasMounted] =
|
|
670
|
-
|
|
747
|
+
const listRef = React17.useRef(null);
|
|
748
|
+
const [indicator, setIndicator] = React17.useState(null);
|
|
749
|
+
const [hasMounted, setHasMounted] = React17.useState(false);
|
|
750
|
+
React17.useLayoutEffect(() => {
|
|
671
751
|
const list = listRef.current;
|
|
672
752
|
if (!list) return;
|
|
673
753
|
const update = () => {
|
|
@@ -802,18 +882,18 @@ var Tooltip = ({
|
|
|
802
882
|
disabled = false,
|
|
803
883
|
children
|
|
804
884
|
}) => {
|
|
805
|
-
const [open, setOpen] =
|
|
806
|
-
const timerRef =
|
|
807
|
-
const tooltipId =
|
|
808
|
-
const show =
|
|
885
|
+
const [open, setOpen] = React17.useState(false);
|
|
886
|
+
const timerRef = React17.useRef(null);
|
|
887
|
+
const tooltipId = React17.useId();
|
|
888
|
+
const show = React17.useCallback(() => {
|
|
809
889
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
810
890
|
timerRef.current = setTimeout(() => setOpen(true), delay);
|
|
811
891
|
}, [delay]);
|
|
812
|
-
const hide =
|
|
892
|
+
const hide = React17.useCallback(() => {
|
|
813
893
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
814
894
|
setOpen(false);
|
|
815
895
|
}, []);
|
|
816
|
-
|
|
896
|
+
React17.useEffect(() => {
|
|
817
897
|
return () => {
|
|
818
898
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
819
899
|
};
|
|
@@ -831,7 +911,7 @@ var Tooltip = ({
|
|
|
831
911
|
}
|
|
832
912
|
})();
|
|
833
913
|
const style = useSpringPresence({ visible: open, from: fromTransform });
|
|
834
|
-
const trigger =
|
|
914
|
+
const trigger = React17.cloneElement(children, {
|
|
835
915
|
onMouseEnter: show,
|
|
836
916
|
onMouseLeave: hide,
|
|
837
917
|
onFocus: show,
|
|
@@ -1425,12 +1505,12 @@ var AlertModal = ({
|
|
|
1425
1505
|
onCancel,
|
|
1426
1506
|
onClose
|
|
1427
1507
|
}) => {
|
|
1428
|
-
const panelRef =
|
|
1429
|
-
const titleId =
|
|
1430
|
-
const messageId =
|
|
1508
|
+
const panelRef = React17.useRef(null);
|
|
1509
|
+
const titleId = React17.useId();
|
|
1510
|
+
const messageId = React17.useId();
|
|
1431
1511
|
const [shouldRender, setShouldRender] = useState(isOpen);
|
|
1432
1512
|
useFocusTrap(panelRef, isOpen);
|
|
1433
|
-
|
|
1513
|
+
React17.useEffect(() => {
|
|
1434
1514
|
if (isOpen) setShouldRender(true);
|
|
1435
1515
|
}, [isOpen]);
|
|
1436
1516
|
const overlayStyle = useSpring({
|
|
@@ -1533,12 +1613,12 @@ var Checkbox = ({
|
|
|
1533
1613
|
ref,
|
|
1534
1614
|
...props
|
|
1535
1615
|
}) => {
|
|
1536
|
-
const inputRef =
|
|
1537
|
-
|
|
1616
|
+
const inputRef = React17.useRef(null);
|
|
1617
|
+
React17.useImperativeHandle(
|
|
1538
1618
|
ref,
|
|
1539
1619
|
() => inputRef.current
|
|
1540
1620
|
);
|
|
1541
|
-
|
|
1621
|
+
React17.useEffect(() => {
|
|
1542
1622
|
if (!inputRef.current) return;
|
|
1543
1623
|
inputRef.current.indeterminate = Boolean(indeterminate);
|
|
1544
1624
|
}, [indeterminate]);
|
|
@@ -1943,9 +2023,9 @@ var DatePicker = ({
|
|
|
1943
2023
|
minDateSrFormat = "Minimum date: {date}",
|
|
1944
2024
|
selectableRangeUntilTodaySrText = "Selectable up to today"
|
|
1945
2025
|
}) => {
|
|
1946
|
-
const groupId =
|
|
1947
|
-
const constraintId =
|
|
1948
|
-
const { todayYear, todayMonth, todayDay } =
|
|
2026
|
+
const groupId = React17.useId();
|
|
2027
|
+
const constraintId = React17.useId();
|
|
2028
|
+
const { todayYear, todayMonth, todayDay } = React17.useMemo(() => {
|
|
1949
2029
|
const now = /* @__PURE__ */ new Date();
|
|
1950
2030
|
return {
|
|
1951
2031
|
todayYear: now.getFullYear(),
|
|
@@ -1954,7 +2034,7 @@ var DatePicker = ({
|
|
|
1954
2034
|
};
|
|
1955
2035
|
}, []);
|
|
1956
2036
|
const endYear = endYearProp ?? todayYear + 10;
|
|
1957
|
-
const parsed =
|
|
2037
|
+
const parsed = React17.useMemo(() => {
|
|
1958
2038
|
if (!value) return { year: 0, month: 0, day: 0 };
|
|
1959
2039
|
const [y, m, d] = value.split("-").map(Number);
|
|
1960
2040
|
return {
|
|
@@ -1963,7 +2043,7 @@ var DatePicker = ({
|
|
|
1963
2043
|
day: d || 0
|
|
1964
2044
|
};
|
|
1965
2045
|
}, [value]);
|
|
1966
|
-
const min =
|
|
2046
|
+
const min = React17.useMemo(() => {
|
|
1967
2047
|
if (!minDate) return { year: 0, month: 0, day: 0 };
|
|
1968
2048
|
const [y, m, d] = minDate.split("-").map(Number);
|
|
1969
2049
|
return {
|
|
@@ -1983,7 +2063,7 @@ var DatePicker = ({
|
|
|
1983
2063
|
min.year > 0 && min.month > 0 && year === min.year && month === min.month ? min.day : 1
|
|
1984
2064
|
)
|
|
1985
2065
|
);
|
|
1986
|
-
const maxDay =
|
|
2066
|
+
const maxDay = React17.useMemo(() => {
|
|
1987
2067
|
if (!year || !month) return 31;
|
|
1988
2068
|
const daysInMonth = getDaysInMonth(year, month);
|
|
1989
2069
|
if (selectableRange === "until-today" && year === todayYear && month === todayMonth) {
|
|
@@ -1991,28 +2071,28 @@ var DatePicker = ({
|
|
|
1991
2071
|
}
|
|
1992
2072
|
return daysInMonth;
|
|
1993
2073
|
}, [year, month, selectableRange, todayYear, todayMonth, todayDay]);
|
|
1994
|
-
const yearOptions =
|
|
2074
|
+
const yearOptions = React17.useMemo(
|
|
1995
2075
|
() => range(startYear, maxYear).map((y) => ({
|
|
1996
2076
|
value: String(y),
|
|
1997
2077
|
label: String(y)
|
|
1998
2078
|
})),
|
|
1999
2079
|
[startYear, maxYear]
|
|
2000
2080
|
);
|
|
2001
|
-
const monthOptions =
|
|
2081
|
+
const monthOptions = React17.useMemo(
|
|
2002
2082
|
() => range(minMonth, Math.max(minMonth, maxMonth)).map((m) => ({
|
|
2003
2083
|
value: String(m),
|
|
2004
2084
|
label: pad(m)
|
|
2005
2085
|
})),
|
|
2006
2086
|
[minMonth, maxMonth]
|
|
2007
2087
|
);
|
|
2008
|
-
const dayOptions =
|
|
2088
|
+
const dayOptions = React17.useMemo(
|
|
2009
2089
|
() => range(minDay, Math.max(minDay, maxDay)).map((d) => ({
|
|
2010
2090
|
value: String(d),
|
|
2011
2091
|
label: pad(d)
|
|
2012
2092
|
})),
|
|
2013
2093
|
[minDay, maxDay]
|
|
2014
2094
|
);
|
|
2015
|
-
const emit =
|
|
2095
|
+
const emit = React17.useCallback(
|
|
2016
2096
|
(yy, mm, dd) => {
|
|
2017
2097
|
if (mode === "year-month") {
|
|
2018
2098
|
onChange(`${yy}-${pad(mm)}`);
|
|
@@ -2023,7 +2103,7 @@ var DatePicker = ({
|
|
|
2023
2103
|
},
|
|
2024
2104
|
[mode, onChange]
|
|
2025
2105
|
);
|
|
2026
|
-
const handleYearChange =
|
|
2106
|
+
const handleYearChange = React17.useCallback(
|
|
2027
2107
|
(raw) => {
|
|
2028
2108
|
if (!raw) return;
|
|
2029
2109
|
const newYear = Number(raw);
|
|
@@ -2040,14 +2120,14 @@ var DatePicker = ({
|
|
|
2040
2120
|
},
|
|
2041
2121
|
[month, day, min.year, min.month, selectableRange, todayYear, todayMonth, emit]
|
|
2042
2122
|
);
|
|
2043
|
-
const handleMonthChange =
|
|
2123
|
+
const handleMonthChange = React17.useCallback(
|
|
2044
2124
|
(raw) => {
|
|
2045
2125
|
if (!raw || !year) return;
|
|
2046
2126
|
emit(year, Number(raw), day || void 0);
|
|
2047
2127
|
},
|
|
2048
2128
|
[year, day, emit]
|
|
2049
2129
|
);
|
|
2050
|
-
const handleDayChange =
|
|
2130
|
+
const handleDayChange = React17.useCallback(
|
|
2051
2131
|
(raw) => {
|
|
2052
2132
|
if (!raw || !year || !month) return;
|
|
2053
2133
|
emit(year, month, Number(raw));
|
|
@@ -2135,10 +2215,10 @@ var FileInput = ({
|
|
|
2135
2215
|
onChange,
|
|
2136
2216
|
...props
|
|
2137
2217
|
}) => {
|
|
2138
|
-
const inputId =
|
|
2139
|
-
const helperId =
|
|
2140
|
-
const inputRef =
|
|
2141
|
-
const [previewUrls, setPreviewUrls] =
|
|
2218
|
+
const inputId = React17.useId();
|
|
2219
|
+
const helperId = React17.useId();
|
|
2220
|
+
const inputRef = React17.useRef(null);
|
|
2221
|
+
const [previewUrls, setPreviewUrls] = React17.useState([]);
|
|
2142
2222
|
const isPreviewVariant = variant === "preview";
|
|
2143
2223
|
const showPreview = isPreviewVariant || preview;
|
|
2144
2224
|
const handleChange = (e) => {
|
|
@@ -2176,7 +2256,7 @@ var FileInput = ({
|
|
|
2176
2256
|
}
|
|
2177
2257
|
onFiles?.(null);
|
|
2178
2258
|
};
|
|
2179
|
-
|
|
2259
|
+
React17.useEffect(() => {
|
|
2180
2260
|
return () => {
|
|
2181
2261
|
for (const url of previewUrls) {
|
|
2182
2262
|
URL.revokeObjectURL(url);
|
|
@@ -2473,11 +2553,11 @@ var Modal = ({
|
|
|
2473
2553
|
ariaLabel,
|
|
2474
2554
|
...props
|
|
2475
2555
|
}) => {
|
|
2476
|
-
const panelRef =
|
|
2477
|
-
const titleId =
|
|
2478
|
-
const [shouldRender, setShouldRender] =
|
|
2556
|
+
const panelRef = React17.useRef(null);
|
|
2557
|
+
const titleId = React17.useId();
|
|
2558
|
+
const [shouldRender, setShouldRender] = React17.useState(open);
|
|
2479
2559
|
useFocusTrap(panelRef, open);
|
|
2480
|
-
|
|
2560
|
+
React17.useEffect(() => {
|
|
2481
2561
|
if (open) setShouldRender(true);
|
|
2482
2562
|
}, [open]);
|
|
2483
2563
|
const overlayStyle = useSpring({
|
|
@@ -2492,15 +2572,15 @@ var Modal = ({
|
|
|
2492
2572
|
transform: open ? "scale(1) translateY(0px)" : "scale(0.96) translateY(-4px)",
|
|
2493
2573
|
config: { tension: 280, friction: 28, clamp: !open }
|
|
2494
2574
|
});
|
|
2495
|
-
const handleEscape =
|
|
2575
|
+
const handleEscape = React17.useEffectEvent((e) => {
|
|
2496
2576
|
if (e.key === "Escape") onClose?.();
|
|
2497
2577
|
});
|
|
2498
|
-
|
|
2578
|
+
React17.useEffect(() => {
|
|
2499
2579
|
if (!open) return;
|
|
2500
2580
|
document.addEventListener("keydown", handleEscape);
|
|
2501
2581
|
return () => document.removeEventListener("keydown", handleEscape);
|
|
2502
2582
|
}, [open]);
|
|
2503
|
-
|
|
2583
|
+
React17.useEffect(() => {
|
|
2504
2584
|
if (!open) return;
|
|
2505
2585
|
const body = document.body;
|
|
2506
2586
|
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
@@ -2580,12 +2660,12 @@ var OtpInput = ({
|
|
|
2580
2660
|
ariaLabel = "OTP \uC785\uB825",
|
|
2581
2661
|
className
|
|
2582
2662
|
}) => {
|
|
2583
|
-
const inputsRef =
|
|
2584
|
-
const isTypingRef =
|
|
2585
|
-
|
|
2663
|
+
const inputsRef = React17.useRef([]);
|
|
2664
|
+
const isTypingRef = React17.useRef(false);
|
|
2665
|
+
React17.useEffect(() => {
|
|
2586
2666
|
if (autoFocus) inputsRef.current[0]?.focus();
|
|
2587
2667
|
}, [autoFocus]);
|
|
2588
|
-
const digits =
|
|
2668
|
+
const digits = React17.useMemo(() => {
|
|
2589
2669
|
const chars = value.split("").slice(0, length);
|
|
2590
2670
|
while (chars.length < length) chars.push("");
|
|
2591
2671
|
return chars;
|
|
@@ -2724,7 +2804,7 @@ var Pagination = ({
|
|
|
2724
2804
|
}) => {
|
|
2725
2805
|
const prevDisabled = page <= 1;
|
|
2726
2806
|
const nextDisabled = page >= totalPages;
|
|
2727
|
-
const items =
|
|
2807
|
+
const items = React17.useMemo(() => getPaginationItems(page, totalPages), [page, totalPages]);
|
|
2728
2808
|
return /* @__PURE__ */ jsxs("nav", { className: "pagination", "aria-label": "Pagination", children: [
|
|
2729
2809
|
/* @__PURE__ */ jsx(
|
|
2730
2810
|
"button",
|
|
@@ -2906,9 +2986,9 @@ var Table = ({
|
|
|
2906
2986
|
isEmpty && /* @__PURE__ */ jsx("div", { className: "table_empty", role: "status", children: emptyMessage })
|
|
2907
2987
|
] });
|
|
2908
2988
|
};
|
|
2909
|
-
var ThemeContext =
|
|
2989
|
+
var ThemeContext = React17.createContext(null);
|
|
2910
2990
|
var useTheme = () => {
|
|
2911
|
-
const ctx =
|
|
2991
|
+
const ctx = React17.useContext(ThemeContext);
|
|
2912
2992
|
if (!ctx) {
|
|
2913
2993
|
throw new Error(
|
|
2914
2994
|
'[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>'
|
|
@@ -2932,14 +3012,14 @@ var ThemeProvider = ({
|
|
|
2932
3012
|
targetSelector,
|
|
2933
3013
|
children
|
|
2934
3014
|
}) => {
|
|
2935
|
-
const [mode, setModeState] =
|
|
3015
|
+
const [mode, setModeState] = React17.useState(() => {
|
|
2936
3016
|
return readStored(storageKey) ?? defaultMode;
|
|
2937
3017
|
});
|
|
2938
|
-
const [systemDark, setSystemDark] =
|
|
3018
|
+
const [systemDark, setSystemDark] = React17.useState(() => {
|
|
2939
3019
|
if (!isClient) return false;
|
|
2940
3020
|
return window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
2941
3021
|
});
|
|
2942
|
-
|
|
3022
|
+
React17.useEffect(() => {
|
|
2943
3023
|
if (!isClient) return;
|
|
2944
3024
|
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
2945
3025
|
const handler = (e) => setSystemDark(e.matches);
|
|
@@ -2947,7 +3027,7 @@ var ThemeProvider = ({
|
|
|
2947
3027
|
return () => mq.removeEventListener("change", handler);
|
|
2948
3028
|
}, []);
|
|
2949
3029
|
const resolved = mode === "system" ? systemDark ? "dark" : "light" : mode;
|
|
2950
|
-
|
|
3030
|
+
React17.useEffect(() => {
|
|
2951
3031
|
if (!isClient) return;
|
|
2952
3032
|
const target = targetSelector ? document.querySelector(targetSelector) : document.documentElement;
|
|
2953
3033
|
if (!target) return;
|
|
@@ -2957,7 +3037,7 @@ var ThemeProvider = ({
|
|
|
2957
3037
|
target.setAttribute("data-theme", mode);
|
|
2958
3038
|
}
|
|
2959
3039
|
}, [mode, targetSelector]);
|
|
2960
|
-
const setMode =
|
|
3040
|
+
const setMode = React17.useCallback(
|
|
2961
3041
|
(next) => {
|
|
2962
3042
|
setModeState(next);
|
|
2963
3043
|
if (storageKey && isClient) {
|
|
@@ -2969,7 +3049,7 @@ var ThemeProvider = ({
|
|
|
2969
3049
|
},
|
|
2970
3050
|
[storageKey]
|
|
2971
3051
|
);
|
|
2972
|
-
const value =
|
|
3052
|
+
const value = React17.useMemo(
|
|
2973
3053
|
() => ({ mode, resolved, setMode }),
|
|
2974
3054
|
[mode, resolved, setMode]
|
|
2975
3055
|
);
|
|
@@ -3075,7 +3155,7 @@ var TextField = ({
|
|
|
3075
3155
|
] });
|
|
3076
3156
|
};
|
|
3077
3157
|
TextField.displayName = "TextField";
|
|
3078
|
-
var ToastContext =
|
|
3158
|
+
var ToastContext = React17.createContext(null);
|
|
3079
3159
|
var VARIANT_ICONS = {
|
|
3080
3160
|
success: /* @__PURE__ */ jsx(CheckCircle2, { size: 18 }),
|
|
3081
3161
|
error: /* @__PURE__ */ jsx(XCircle, { size: 18 }),
|
|
@@ -3084,15 +3164,15 @@ var VARIANT_ICONS = {
|
|
|
3084
3164
|
default: /* @__PURE__ */ jsx(Bell, { size: 18 })
|
|
3085
3165
|
};
|
|
3086
3166
|
var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
3087
|
-
const [visible, setVisible] =
|
|
3088
|
-
const closingRef =
|
|
3167
|
+
const [visible, setVisible] = React17.useState(true);
|
|
3168
|
+
const closingRef = React17.useRef(false);
|
|
3089
3169
|
const style = useSpringPresence({
|
|
3090
3170
|
visible,
|
|
3091
3171
|
from: "translateX(20px)",
|
|
3092
3172
|
// 우측에서 슬라이드 인
|
|
3093
3173
|
onExitComplete: () => onRemove(item.id)
|
|
3094
3174
|
});
|
|
3095
|
-
const close =
|
|
3175
|
+
const close = React17.useCallback(() => {
|
|
3096
3176
|
if (closingRef.current) return;
|
|
3097
3177
|
closingRef.current = true;
|
|
3098
3178
|
setVisible(false);
|
|
@@ -3125,19 +3205,19 @@ var ToastProvider = ({
|
|
|
3125
3205
|
maxCount = 5,
|
|
3126
3206
|
closeAriaLabel = "Close"
|
|
3127
3207
|
}) => {
|
|
3128
|
-
const [toasts, setToasts] =
|
|
3129
|
-
const [isMounted, setIsMounted] =
|
|
3130
|
-
|
|
3208
|
+
const [toasts, setToasts] = React17.useState([]);
|
|
3209
|
+
const [isMounted, setIsMounted] = React17.useState(false);
|
|
3210
|
+
React17.useEffect(() => {
|
|
3131
3211
|
setIsMounted(true);
|
|
3132
3212
|
}, []);
|
|
3133
|
-
const addToast =
|
|
3213
|
+
const addToast = React17.useCallback(
|
|
3134
3214
|
(message, variant, duration = 3e3) => {
|
|
3135
3215
|
const id = crypto.randomUUID();
|
|
3136
3216
|
setToasts((prev) => [{ id, message, variant, duration }, ...prev].slice(0, maxCount));
|
|
3137
3217
|
},
|
|
3138
3218
|
[maxCount]
|
|
3139
3219
|
);
|
|
3140
|
-
const removeToast =
|
|
3220
|
+
const removeToast = React17.useCallback((id) => {
|
|
3141
3221
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
3142
3222
|
}, []);
|
|
3143
3223
|
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: { addToast }, children: [
|
|
@@ -3199,7 +3279,7 @@ var Toggle = ({
|
|
|
3199
3279
|
...props
|
|
3200
3280
|
}) => {
|
|
3201
3281
|
const isControlled = checked !== void 0;
|
|
3202
|
-
const [innerChecked, setInnerChecked] =
|
|
3282
|
+
const [innerChecked, setInnerChecked] = React17.useState(!!defaultChecked);
|
|
3203
3283
|
const isOn = isControlled ? !!checked : innerChecked;
|
|
3204
3284
|
const handleToggle = () => {
|
|
3205
3285
|
if (disabled) return;
|
|
@@ -3361,4 +3441,4 @@ var Grid = ({
|
|
|
3361
3441
|
);
|
|
3362
3442
|
};
|
|
3363
3443
|
|
|
3364
|
-
export { Accordion, AlertProvider, Avatar, Badge, Breadcrumb, Button, Card, Checkbox, Chip, Container, DatePicker, Divider, Dropdown, EmptyState, FileInput, Grid, Hero, Icon, IconButton, LinearProgress, ListItem, MediaCard, Menu, Modal, NavBar, NavLink, OtpInput, Pagination, Radio, Section, Sidebar, SidebarItem, SidebarSection, Skeleton, Spinner, Stack, Tab, TabList, TabPanel, Table, Tabs, TextField, ThemeProvider, ToastProvider, Toggle, Tooltip, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, cn, colors, elevation, motion, opacity, radius, skeleton, spacing, typography, useAlert, useFocusTrap, useSpringHover, useSpringPresence, useTheme, useToast, zIndex };
|
|
3444
|
+
export { Accordion, AlertProvider, Avatar, Badge, BottomNav, BottomNavItem, BottomNavSpacer, Breadcrumb, Button, Card, Checkbox, Chip, Container, DatePicker, Divider, Dropdown, EmptyState, FileInput, Grid, Hero, Icon, IconButton, LinearProgress, ListItem, MediaCard, Menu, Modal, NavBar, NavLink, OtpInput, Pagination, Radio, Section, Sidebar, SidebarItem, SidebarSection, Skeleton, Spinner, Stack, Tab, TabList, TabPanel, Table, Tabs, TextField, ThemeProvider, ToastProvider, Toggle, Tooltip, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, cn, colors, elevation, motion, opacity, radius, skeleton, spacing, typography, useAlert, useFocusTrap, useSpringHover, useSpringPresence, useTheme, useToast, zIndex };
|