@uniai-fe/uds-primitives 0.12.14 → 0.13.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.
Files changed (38) hide show
  1. package/README.md +68 -0
  2. package/dist/styles.css +331 -52
  3. package/package.json +3 -3
  4. package/src/components/calendar/styles/mantine-calendar.scss +5 -0
  5. package/src/components/checkbox/styles/index.scss +1 -7
  6. package/src/components/chip/styles/chip.scss +0 -5
  7. package/src/components/fab/index.scss +1 -0
  8. package/src/components/fab/index.tsx +34 -0
  9. package/src/components/fab/markup/Base.tsx +62 -0
  10. package/src/components/fab/markup/Default.tsx +33 -0
  11. package/src/components/fab/markup/Extended.tsx +35 -0
  12. package/src/components/fab/markup/Label.tsx +16 -0
  13. package/src/components/fab/markup/Menu.tsx +114 -0
  14. package/src/components/fab/markup/Root.tsx +263 -0
  15. package/src/components/fab/markup/Template.tsx +79 -0
  16. package/src/components/fab/markup/Trigger.tsx +65 -0
  17. package/src/components/fab/markup/index.ts +7 -0
  18. package/src/components/fab/styles/composition.scss +80 -0
  19. package/src/components/fab/styles/fab.scss +135 -0
  20. package/src/components/fab/styles/index.scss +4 -0
  21. package/src/components/fab/styles/variables.scss +24 -0
  22. package/src/components/fab/types/composition.ts +288 -0
  23. package/src/components/fab/types/index.ts +3 -0
  24. package/src/components/fab/types/options.ts +39 -0
  25. package/src/components/fab/types/props.ts +124 -0
  26. package/src/components/navigation/styles/index.scss +0 -6
  27. package/src/components/radio/styles/index.scss +1 -8
  28. package/src/components/segmented-control/styles/index.scss +0 -5
  29. package/src/components/select/styles/select.scss +0 -5
  30. package/src/components/select/styles/variables.scss +0 -1
  31. package/src/components/switch/styles/switch.scss +0 -10
  32. package/src/components/switch/styles/variables.scss +0 -1
  33. package/src/components/tab/markup/TabTrigger.tsx +8 -8
  34. package/src/components/tab/styles/tab.scss +0 -5
  35. package/src/components/tooltip/markup/Text.tsx +10 -3
  36. package/src/components/tooltip/types/text.ts +8 -3
  37. package/src/index.scss +1 -0
  38. package/src/index.tsx +1 -0
package/README.md CHANGED
@@ -46,6 +46,74 @@ Button은 기존 priority 범위를 유지한다.
46
46
  `Input.Time.Template`과 standalone `TimePicker.Template`, `TimePickerUtils`도 root public
47
47
  entry에서 제공한다.
48
48
 
49
+ `Fab.Button`은 아이콘 전용 주요 액션, `Fab.Expand`는 아이콘과 라벨을 표시한다.
50
+ 필수 `icon`은 ReactNode이며 `size`는 `small | medium | large`다. Button과 같은
51
+ `fill="solid" | "outlined"`와 `priority`를 독립적으로 조합한다. 두 fill 모두 `priority`가
52
+ 필수이며 Button.Default와 같은 `primary`, `secondary`, `tertiary`, `green`, `yellow`,
53
+ `orange`, `teal`, `pink`, `red`, `darkGray`, `lightGray`를 지원한다. 색상과 상태별 배경은
54
+ Button 토큰을 재사용하며 outlined의 기본 면은 불투명 흰색이다.
55
+ 아이콘 전용 Button에는 행동 이름인 `aria-label`도 필수다. 화면 고정 배치는 소비자가 정한다.
56
+ `Fab.Default`, `Fab.Extended`, `Fab.Label`은 기존 사용처와의 호환을 유지한다.
57
+
58
+ ```tsx
59
+ import { Fab } from "@uniai-fe/uds-primitives";
60
+
61
+ <Fab.Button
62
+ icon={<span aria-hidden="true">+</span>}
63
+ aria-label="항목 추가"
64
+ fill="solid"
65
+ priority="primary"
66
+ size="medium"
67
+ />;
68
+ ```
69
+
70
+ 관련 액션을 원형 버튼으로 펼치는 구성은 `Fab.Template`으로 시작하거나
71
+ `Fab.Root` 안에 `Fab.Trigger`, `Fab.Menu.List`, `Fab.Menu.Item`을 직접 조립한다.
72
+ `Fab.Expand`는 라벨 확장형이고, 메뉴를 펼치는 동작은 `Fab.Trigger`가 담당한다.
73
+ `Root`는 hover·focus·click·keyboard, 메뉴 ID·ARIA 연결, 닫기와 focus 복귀를 소유한다.
74
+ `direction`은 `up | down | left | right`이며 기본값은 `up`이다. 열림 상태는
75
+ `open`과 `onOpenChange`로 제어하거나 `defaultOpen`으로 초기화한다.
76
+
77
+ ```tsx
78
+ <Fab.Template
79
+ triggerProps={{
80
+ icon: <span aria-hidden="true">+</span>,
81
+ "aria-label": "콘텐츠 추가 방법",
82
+ fill: "solid",
83
+ priority: "primary",
84
+ size: "medium",
85
+ }}
86
+ items={[
87
+ {
88
+ id: "write",
89
+ icon: <span aria-hidden="true">✎</span>,
90
+ "aria-label": "새 글 작성",
91
+ fill: "solid",
92
+ priority: "secondary",
93
+ size: "small",
94
+ onClick: () => console.info("새 글 작성"),
95
+ },
96
+ ]}
97
+ />
98
+ ```
99
+
100
+ `Root` 하나에 `Trigger` 하나와 `Menu.List` 하나를 두고 그 안에 `Menu.Item`을 조립한다.
101
+ 이 부품들은 Root 밖에서 사용하면 오류를 발생시킨다. `Menu.Item`의
102
+ `aria-label`은 행동 이름과 Tooltip 문구이며 `persistentTooltips`로 열린 메뉴의
103
+ 문구를 계속 표시할 수 있다. 항목은 native `onClick`을 실행한 뒤 닫고 trigger로
104
+ focus를 돌려준다. 소비자가 `event.preventDefault()`를 호출하면 이 자동 처리를 막는다.
105
+ `Fab.Menu.Label`은 기존 `Tooltip.Text`를 재사용하는 메뉴명 표현 부품이며 Tooltip의
106
+ 스타일 문맥에서 사용한다. Speed Dial은 이 조합의 사용 사례 이름이며 별도 namespace가 아니다.
107
+ Template 항목의 `id`는 DOM ID로도 쓰이므로 같은 화면에서 고유하게 지정한다.
108
+ Template의 `className`, `style`, ref는 Root 하나에만 적용한다. 내부 버튼의
109
+ `className`은 입력에서 제외하며 런타임 입력도 무시한다. 내부 스타일은 최상위
110
+ `className` 아래 nested selector 또는 data attribute로 조정한다. 직접 조립하는
111
+ Trigger·Menu.Item의 `className`은 유지한다.
112
+
113
+ Hover로 열린 메뉴의 첫 포인터 클릭은 열림을 유지하고 이후 클릭·Enter·Space는
114
+ 토글한다. 닫힌 Trigger에서는 모든 방향키로 첫 액션에 진입하며, 열린 메뉴의
115
+ 반대 방향키는 Trigger에서 멈춘다.
116
+
49
117
  Select와 Dropdown이 함께 사용하는 `SelectedValue`, `toSelectedValueKey`,
50
118
  `isSameSelectedValue`, `isSameSelectedValueList`, `normalizeSingleSelectedValue`,
51
119
  `normalizeSelectedValuesByMode`도 root public entry에서 제공한다.
package/dist/styles.css CHANGED
@@ -290,7 +290,6 @@
290
290
  --theme-checkbox-icon-default: transparent;
291
291
  --theme-checkbox-icon-selected: var(--color-common-100);
292
292
  --theme-checkbox-icon-disabled-selected: var(--color-common-100);
293
- --theme-checkbox-focus-ring: rgba(2, 84, 255, 0.32);
294
293
  --theme-chip-height: var(--theme-size-small-3);
295
294
  /* 변경: Figma text menu item은 기본 chip보다 낮은 24px height를 사용한다. */
296
295
  --theme-chip-height-text: 24px;
@@ -417,6 +416,27 @@
417
416
  --dropdown-option-padding-block-xsmall: 0px;
418
417
  --dropdown-option-radius-xsmall: 4px;
419
418
  --dropdown-text-weight-selected-xsmall: var(--dropdown-text-weight);
419
+ --fab-height-small: var(--theme-size-medium-1);
420
+ --fab-height-medium: var(--theme-size-medium-2);
421
+ --fab-height-large: var(--theme-size-medium-3);
422
+ --fab-content-size-small: var(--theme-size-xsmall-3);
423
+ --fab-content-size-medium: var(--theme-size-small-1);
424
+ --fab-content-size-large: var(--theme-size-small-2);
425
+ --fab-radius: 60px;
426
+ --fab-padding-inline: var(--spacing-padding-5);
427
+ --fab-padding-block: var(--spacing-padding-2);
428
+ --fab-extended-padding-inline: var(--spacing-padding-6);
429
+ --fab-gap: var(--spacing-gap-4);
430
+ --fab-font-family: var(--font-family-sans);
431
+ --fab-font-size-small: var(--font-body-xxsmall-size);
432
+ --fab-font-size-medium: var(--font-body-xsmall-size);
433
+ --fab-font-size-large: var(--font-body-small-size);
434
+ --fab-font-weight: var(--font-body-small-weight);
435
+ --fab-line-height: var(--font-body-small-line-height);
436
+ --fab-letter-spacing: var(--font-body-small-letter-spacing);
437
+ --fab-outlined-background: var(--button-default-outline-bg);
438
+ --fab-disabled-background: var(--button-default-neutral-disabled-bg);
439
+ --fab-disabled-foreground: var(--button-default-neutral-disabled-foreground);
420
440
  --form-field-width: auto;
421
441
  --form-field-flex: 0 0 auto;
422
442
  --form-field-gap-x: var(--spacing-gap-5);
@@ -649,7 +669,6 @@
649
669
  --theme-radio-card-description-color: var(--color-label-neutral);
650
670
  --theme-radio-card-badge-background: var(--color-surface-static-blue);
651
671
  --theme-radio-card-badge-color: var(--color-primary-default);
652
- --theme-radio-focus-ring: rgba(2, 84, 255, 0.32);
653
672
  --theme-radio-disabled-selected-opacity: 0.28;
654
673
  /* layout presets */
655
674
  --select-width: 100%;
@@ -790,7 +809,6 @@
790
809
  --select-multiple-chip-border-color: transparent;
791
810
  --select-multiple-chip-remove-color: var(--color-label-strong);
792
811
  --select-multiple-chip-remove-hover-color: var(--color-label-strong);
793
- --select-multiple-chip-remove-focus-outline-color: var(--color-border-strong);
794
812
  --select-multiple-chip-summary-color: var(--color-label-standard);
795
813
  --select-multiple-chip-summary-surface: var(--color-surface-standard);
796
814
  --select-multiple-chip-summary-border-color: transparent;
@@ -819,7 +837,6 @@
819
837
  0px 2px 8px rgba(0, 0, 0, 0.04), 0px 0px 4px rgba(0, 0, 0, 0.08);
820
838
  --switch-thumb-shadow-checked:
821
839
  0px 2px 8px rgba(0, 0, 0, 0.08), 0px 0px 4px rgba(0, 0, 0, 0.12);
822
- --switch-focus-ring: var(--color-primary-focus);
823
840
  --switch-disabled-opacity: 0.4;
824
841
  --switch-text-width: fit-content;
825
842
  --switch-text-height-medium: 32px;
@@ -2535,6 +2552,10 @@
2535
2552
  width: var(--calendar-body-width);
2536
2553
  }
2537
2554
 
2555
+ .calendar-grid .mantine-focus-auto:focus-visible {
2556
+ outline: none;
2557
+ }
2558
+
2538
2559
  .calendar-range-grid {
2539
2560
  width: var(--calendar-body-width);
2540
2561
  }
@@ -3016,8 +3037,7 @@
3016
3037
  transition:
3017
3038
  background-color 0.15s ease,
3018
3039
  border-color 0.15s ease,
3019
- opacity 0.15s ease,
3020
- box-shadow 0.15s ease;
3040
+ opacity 0.15s ease;
3021
3041
  }
3022
3042
  .checkbox[data-size="medium"] {
3023
3043
  inline-size: var(--theme-checkbox-frame-size-medium);
@@ -3033,10 +3053,6 @@
3033
3053
  cursor: not-allowed;
3034
3054
  }
3035
3055
 
3036
- .checkbox:focus-visible {
3037
- box-shadow: 0 0 0 2px var(--theme-checkbox-focus-ring);
3038
- }
3039
-
3040
3056
  .checkbox-surface {
3041
3057
  inline-size: var(--theme-checkbox-indicator-size-medium);
3042
3058
  block-size: var(--theme-checkbox-indicator-size-medium);
@@ -3196,11 +3212,6 @@ figure.chip {
3196
3212
  margin: 0;
3197
3213
  }
3198
3214
 
3199
- .chip:focus-visible {
3200
- outline: 2px solid var(--color-primary-default);
3201
- outline-offset: 2px;
3202
- }
3203
-
3204
3215
  .chip:where([data-style="filter"][data-fill="solid"]) {
3205
3216
  --chip-bg: var(--color-surface-standard);
3206
3217
  --chip-label-color: var(--color-label-neutral);
@@ -3770,6 +3781,310 @@ figure.chip {
3770
3781
  padding: 0;
3771
3782
  }
3772
3783
 
3784
+ .fab {
3785
+ --fab-hover-shadow: none;
3786
+ --fab-pressed-shadow: none;
3787
+ display: flex;
3788
+ flex: 0 0 auto;
3789
+ align-items: center;
3790
+ justify-content: center;
3791
+ box-sizing: border-box;
3792
+ width: var(--fab-height);
3793
+ height: var(--fab-height);
3794
+ padding: var(--fab-padding-block) var(--fab-padding-inline);
3795
+ border: 0;
3796
+ border-radius: var(--fab-radius);
3797
+ background-color: var(--fab-background);
3798
+ color: var(--fab-foreground);
3799
+ box-shadow: none;
3800
+ cursor: pointer;
3801
+ }
3802
+ .fab:where([data-fill="solid"][data-priority="primary"]) {
3803
+ --fab-background: var(--button-default-primary-solid-bg);
3804
+ --fab-foreground: var(--button-default-primary-solid-foreground);
3805
+ --fab-hover-background: var(--button-default-primary-solid-hover-bg);
3806
+ --fab-pressed-background: var(--button-default-primary-solid-active-bg);
3807
+ }
3808
+ .fab:where([data-fill="outlined"][data-priority="primary"]) {
3809
+ --fab-background: var(--fab-outlined-background);
3810
+ --fab-foreground: var(--button-default-primary-outline-foreground);
3811
+ --fab-hover-background: var(--button-default-primary-outline-hover-bg);
3812
+ border: 1px solid var(--button-default-primary-outline-border);
3813
+ }
3814
+ .fab:where([data-fill="solid"][data-priority="secondary"]) {
3815
+ --fab-background: var(--button-default-secondary-solid-bg);
3816
+ --fab-foreground: var(--button-default-secondary-solid-foreground);
3817
+ --fab-hover-background: var(--button-default-secondary-solid-hover-bg);
3818
+ --fab-pressed-background: var(--button-default-secondary-solid-active-bg);
3819
+ }
3820
+ .fab:where([data-fill="outlined"][data-priority="secondary"]) {
3821
+ --fab-background: var(--fab-outlined-background);
3822
+ --fab-foreground: var(--button-default-secondary-outline-foreground);
3823
+ --fab-hover-background: var(--button-default-secondary-outline-hover-bg);
3824
+ border: 1px solid var(--button-default-secondary-outline-border);
3825
+ }
3826
+ .fab:where([data-fill="solid"][data-priority="tertiary"]) {
3827
+ --fab-background: var(--button-default-tertiary-solid-bg);
3828
+ --fab-foreground: var(--button-default-tertiary-solid-foreground);
3829
+ --fab-hover-background: var(--button-default-tertiary-solid-hover-bg);
3830
+ --fab-pressed-background: var(--button-default-tertiary-solid-active-bg);
3831
+ }
3832
+ .fab:where([data-fill="outlined"][data-priority="tertiary"]) {
3833
+ --fab-background: var(--fab-outlined-background);
3834
+ --fab-foreground: var(--button-default-tertiary-outline-foreground);
3835
+ --fab-hover-background: var(--button-default-tertiary-outline-hover-bg);
3836
+ border: 1px solid var(--button-default-tertiary-outline-border);
3837
+ }
3838
+ .fab:where([data-fill="solid"][data-priority="green"]) {
3839
+ --fab-background: var(--button-default-green-solid-bg);
3840
+ --fab-foreground: var(--button-default-green-solid-foreground);
3841
+ --fab-hover-background: var(--button-default-green-solid-hover-bg);
3842
+ --fab-pressed-background: var(--button-default-green-solid-active-bg);
3843
+ }
3844
+ .fab:where([data-fill="outlined"][data-priority="green"]) {
3845
+ --fab-background: var(--fab-outlined-background);
3846
+ --fab-foreground: var(--button-default-green-outline-foreground);
3847
+ --fab-hover-background: var(--button-default-green-outline-hover-bg);
3848
+ --fab-pressed-background: var(--button-default-green-outline-active-bg);
3849
+ border: 1px solid var(--button-default-green-outline-border);
3850
+ }
3851
+ .fab:where([data-fill="solid"][data-priority="yellow"]) {
3852
+ --fab-background: var(--button-default-yellow-solid-bg);
3853
+ --fab-foreground: var(--button-default-yellow-solid-foreground);
3854
+ --fab-hover-background: var(--button-default-yellow-solid-hover-bg);
3855
+ --fab-pressed-background: var(--button-default-yellow-solid-active-bg);
3856
+ }
3857
+ .fab:where([data-fill="outlined"][data-priority="yellow"]) {
3858
+ --fab-background: var(--fab-outlined-background);
3859
+ --fab-foreground: var(--button-default-yellow-outline-foreground);
3860
+ --fab-hover-background: var(--button-default-yellow-outline-hover-bg);
3861
+ --fab-pressed-background: var(--button-default-yellow-outline-active-bg);
3862
+ border: 1px solid var(--button-default-yellow-outline-border);
3863
+ }
3864
+ .fab:where([data-fill="solid"][data-priority="orange"]) {
3865
+ --fab-background: var(--button-default-orange-solid-bg);
3866
+ --fab-foreground: var(--button-default-orange-solid-foreground);
3867
+ --fab-hover-background: var(--button-default-orange-solid-hover-bg);
3868
+ --fab-pressed-background: var(--button-default-orange-solid-active-bg);
3869
+ }
3870
+ .fab:where([data-fill="outlined"][data-priority="orange"]) {
3871
+ --fab-background: var(--fab-outlined-background);
3872
+ --fab-foreground: var(--button-default-orange-outline-foreground);
3873
+ --fab-hover-background: var(--button-default-orange-outline-hover-bg);
3874
+ --fab-pressed-background: var(--button-default-orange-outline-active-bg);
3875
+ border: 1px solid var(--button-default-orange-outline-border);
3876
+ }
3877
+ .fab:where([data-fill="solid"][data-priority="teal"]) {
3878
+ --fab-background: var(--button-default-teal-solid-bg);
3879
+ --fab-foreground: var(--button-default-teal-solid-foreground);
3880
+ --fab-hover-background: var(--button-default-teal-solid-hover-bg);
3881
+ --fab-pressed-background: var(--button-default-teal-solid-active-bg);
3882
+ }
3883
+ .fab:where([data-fill="outlined"][data-priority="teal"]) {
3884
+ --fab-background: var(--fab-outlined-background);
3885
+ --fab-foreground: var(--button-default-teal-outline-foreground);
3886
+ --fab-hover-background: var(--button-default-teal-outline-hover-bg);
3887
+ --fab-pressed-background: var(--button-default-teal-outline-active-bg);
3888
+ border: 1px solid var(--button-default-teal-outline-border);
3889
+ }
3890
+ .fab:where([data-fill="solid"][data-priority="pink"]) {
3891
+ --fab-background: var(--button-default-pink-solid-bg);
3892
+ --fab-foreground: var(--button-default-pink-solid-foreground);
3893
+ --fab-hover-background: var(--button-default-pink-solid-hover-bg);
3894
+ --fab-pressed-background: var(--button-default-pink-solid-active-bg);
3895
+ }
3896
+ .fab:where([data-fill="outlined"][data-priority="pink"]) {
3897
+ --fab-background: var(--fab-outlined-background);
3898
+ --fab-foreground: var(--button-default-pink-outline-foreground);
3899
+ --fab-hover-background: var(--button-default-pink-outline-hover-bg);
3900
+ --fab-pressed-background: var(--button-default-pink-outline-active-bg);
3901
+ border: 1px solid var(--button-default-pink-outline-border);
3902
+ }
3903
+ .fab:where([data-fill="solid"][data-priority="red"]) {
3904
+ --fab-background: var(--button-default-red-solid-bg);
3905
+ --fab-foreground: var(--button-default-red-solid-foreground);
3906
+ --fab-hover-background: var(--button-default-red-solid-hover-bg);
3907
+ --fab-pressed-background: var(--button-default-red-solid-active-bg);
3908
+ }
3909
+ .fab:where([data-fill="outlined"][data-priority="red"]) {
3910
+ --fab-background: var(--fab-outlined-background);
3911
+ --fab-foreground: var(--button-default-red-outline-foreground);
3912
+ --fab-hover-background: var(--button-default-red-outline-hover-bg);
3913
+ --fab-pressed-background: var(--button-default-red-outline-active-bg);
3914
+ border: 1px solid var(--button-default-red-outline-border);
3915
+ }
3916
+ .fab:where([data-fill="solid"][data-priority="darkGray"]) {
3917
+ --fab-background: var(--button-default-dark-gray-solid-bg);
3918
+ --fab-foreground: var(--button-default-dark-gray-solid-foreground);
3919
+ --fab-hover-background: var(--button-default-dark-gray-solid-hover-bg);
3920
+ --fab-pressed-background: var(--button-default-dark-gray-solid-active-bg);
3921
+ }
3922
+ .fab:where([data-fill="outlined"][data-priority="darkGray"]) {
3923
+ --fab-background: var(--fab-outlined-background);
3924
+ --fab-foreground: var(--button-default-dark-gray-outline-foreground);
3925
+ --fab-hover-background: var(--button-default-dark-gray-outline-hover-bg);
3926
+ --fab-pressed-background: var(--button-default-dark-gray-outline-active-bg);
3927
+ border: 1px solid var(--button-default-dark-gray-outline-border);
3928
+ }
3929
+ .fab:where([data-fill="solid"][data-priority="lightGray"]) {
3930
+ --fab-background: var(--button-default-light-gray-solid-bg);
3931
+ --fab-foreground: var(--button-default-light-gray-solid-foreground);
3932
+ --fab-hover-background: var(--button-default-light-gray-solid-hover-bg);
3933
+ --fab-pressed-background: var(--button-default-light-gray-solid-active-bg);
3934
+ }
3935
+ .fab:where([data-fill="outlined"][data-priority="lightGray"]) {
3936
+ --fab-background: var(--fab-outlined-background);
3937
+ --fab-foreground: var(--button-default-light-gray-outline-foreground);
3938
+ --fab-hover-background: var(--button-default-light-gray-outline-hover-bg);
3939
+ --fab-pressed-background: var(--button-default-light-gray-outline-active-bg);
3940
+ border: 1px solid var(--button-default-light-gray-outline-border);
3941
+ }
3942
+ .fab:where([data-fill="outlined"][data-priority="primary"]) {
3943
+ --fab-hover-background: var(--button-default-primary-overlay-outlined-bg);
3944
+ --fab-pressed-background: var(--fab-hover-background);
3945
+ --fab-hover-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.68);
3946
+ --fab-pressed-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.28);
3947
+ }
3948
+ .fab:where([data-fill="outlined"][data-priority="secondary"]) {
3949
+ --fab-hover-background: var(--button-default-secondary-overlay-outlined-bg);
3950
+ --fab-pressed-background: var(--fab-hover-background);
3951
+ --fab-hover-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.68);
3952
+ --fab-pressed-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.28);
3953
+ }
3954
+ .fab:where([data-fill="outlined"][data-priority="tertiary"]) {
3955
+ --fab-hover-background: var(--button-default-tertiary-overlay-outlined-bg);
3956
+ --fab-pressed-background: var(--fab-hover-background);
3957
+ --fab-hover-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.68);
3958
+ --fab-pressed-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.28);
3959
+ }
3960
+ .fab:where([data-fill="solid"][data-priority="tertiary"]) {
3961
+ --fab-hover-background: var(--button-default-tertiary-overlay-solid-bg);
3962
+ --fab-pressed-background: var(--fab-hover-background);
3963
+ --fab-hover-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.68);
3964
+ --fab-pressed-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.48);
3965
+ }
3966
+ .fab:where(:enabled:hover) {
3967
+ background-color: var(--fab-hover-background);
3968
+ box-shadow: var(--fab-hover-shadow);
3969
+ }
3970
+ .fab:where(:enabled:active) {
3971
+ background-color: var(--fab-pressed-background);
3972
+ box-shadow: var(--fab-pressed-shadow);
3973
+ }
3974
+ .fab:where(:disabled) {
3975
+ background-color: var(--fab-disabled-background);
3976
+ border-color: var(--fab-disabled-background);
3977
+ --fab-foreground: var(--fab-disabled-foreground);
3978
+ cursor: not-allowed;
3979
+ }
3980
+ .fab:where([data-size="small"]) {
3981
+ --fab-height: var(--fab-height-small);
3982
+ --fab-content-size: var(--fab-content-size-small);
3983
+ --fab-font-size: var(--fab-font-size-small);
3984
+ }
3985
+ .fab:where([data-size="medium"]) {
3986
+ --fab-height: var(--fab-height-medium);
3987
+ --fab-content-size: var(--fab-content-size-medium);
3988
+ --fab-font-size: var(--fab-font-size-medium);
3989
+ }
3990
+ .fab:where([data-size="large"]) {
3991
+ --fab-height: var(--fab-height-large);
3992
+ --fab-content-size: var(--fab-content-size-large);
3993
+ --fab-font-size: var(--fab-font-size-large);
3994
+ }
3995
+ .fab:where([data-extended="true"]) {
3996
+ width: fit-content;
3997
+ min-width: var(--fab-height);
3998
+ max-width: none;
3999
+ gap: var(--fab-gap);
4000
+ padding-inline: var(--fab-extended-padding-inline);
4001
+ }
4002
+ .fab :where(.fab-content) {
4003
+ display: flex;
4004
+ flex: 0 0 var(--fab-content-size);
4005
+ align-items: center;
4006
+ justify-content: center;
4007
+ width: var(--fab-content-size);
4008
+ height: var(--fab-content-size);
4009
+ color: var(--fab-foreground);
4010
+ }
4011
+ .fab :where(.fab-label) {
4012
+ color: var(--fab-foreground);
4013
+ font-family: var(--fab-font-family);
4014
+ font-size: var(--fab-font-size);
4015
+ font-weight: var(--fab-font-weight);
4016
+ line-height: var(--fab-line-height);
4017
+ letter-spacing: var(--fab-letter-spacing);
4018
+ white-space: nowrap;
4019
+ }
4020
+
4021
+ .fab-root,
4022
+ .fab-menu-list {
4023
+ display: flex;
4024
+ align-items: center;
4025
+ gap: 24px;
4026
+ }
4027
+
4028
+ .fab-menu-list[data-open="false"] {
4029
+ visibility: hidden;
4030
+ }
4031
+
4032
+ .fab-root {
4033
+ direction: ltr;
4034
+ }
4035
+ .fab-root[data-open="false"] {
4036
+ pointer-events: none;
4037
+ }
4038
+ .fab-root[data-open="false"] .fab-trigger {
4039
+ pointer-events: auto;
4040
+ }
4041
+ .fab-root[data-direction="up"],
4042
+ .fab-root[data-direction="up"] .fab-menu-list {
4043
+ flex-direction: column-reverse;
4044
+ }
4045
+ .fab-root[data-direction="down"],
4046
+ .fab-root[data-direction="down"] .fab-menu-list {
4047
+ flex-direction: column;
4048
+ }
4049
+ .fab-root[data-direction="left"],
4050
+ .fab-root[data-direction="left"] .fab-menu-list {
4051
+ flex-direction: row-reverse;
4052
+ }
4053
+ .fab-root[data-direction="right"],
4054
+ .fab-root[data-direction="right"] .fab-menu-list {
4055
+ flex-direction: row;
4056
+ }
4057
+ .fab-root[data-open="true"] .fab-trigger .fab-content {
4058
+ transform: rotate(45deg);
4059
+ }
4060
+
4061
+ .fab-trigger .fab-content {
4062
+ transition: transform 150ms ease;
4063
+ }
4064
+
4065
+ .fab-root[data-open="true"] .fab-menu-item {
4066
+ animation: fab-menu-enter 150ms ease-out;
4067
+ }
4068
+
4069
+ @keyframes fab-menu-enter {
4070
+ from {
4071
+ opacity: 0;
4072
+ transform: scale(0.75);
4073
+ }
4074
+ to {
4075
+ opacity: 1;
4076
+ transform: scale(1);
4077
+ }
4078
+ }
4079
+ @media (prefers-reduced-motion: reduce) {
4080
+ .fab-trigger .fab-content {
4081
+ transition: none;
4082
+ }
4083
+ .fab-root[data-open="true"] .fab-menu-item {
4084
+ animation: none;
4085
+ }
4086
+ }
4087
+
3773
4088
  .form-field-container {
3774
4089
  display: block;
3775
4090
  width: var(--form-field-width);
@@ -5003,12 +5318,6 @@ figure.chip {
5003
5318
  pointer-events: none;
5004
5319
  }
5005
5320
 
5006
- .bottom-navigation-trigger:focus-visible {
5007
- outline: none;
5008
- border-radius: var(--theme-radius-large-1, 12px);
5009
- box-shadow: 0 0 0 2px var(--color-primary-focus, rgba(0, 97, 255, 0.2));
5010
- }
5011
-
5012
5321
  .navigation-item-icon {
5013
5322
  display: inline-flex;
5014
5323
  align-items: center;
@@ -5247,9 +5556,7 @@ figure.chip {
5247
5556
  border-radius: 0;
5248
5557
  padding: 0;
5249
5558
  cursor: pointer;
5250
- transition:
5251
- box-shadow 0.15s ease,
5252
- transform 0.15s ease;
5559
+ transition: transform 0.15s ease;
5253
5560
  }
5254
5561
  .radio[data-size="large"] {
5255
5562
  inline-size: var(--theme-radio-frame-size-large);
@@ -5260,10 +5567,6 @@ figure.chip {
5260
5567
  opacity: 0.6;
5261
5568
  }
5262
5569
 
5263
- .radio:focus-visible {
5264
- box-shadow: 0 0 0 2px var(--theme-radio-focus-ring);
5265
- }
5266
-
5267
5570
  .radio-indicator {
5268
5571
  inline-size: var(--theme-radio-indicator-size-medium);
5269
5572
  block-size: var(--theme-radio-indicator-size-medium);
@@ -5544,11 +5847,6 @@ figure.chip {
5544
5847
  opacity: var(--segmented-disabled-opacity);
5545
5848
  }
5546
5849
 
5547
- .segmented-control-button:where(:focus-visible) {
5548
- outline: 2px solid var(--color-focus-ring, var(--color-primary-default));
5549
- outline-offset: 2px;
5550
- }
5551
-
5552
5850
  .segmented-control-label {
5553
5851
  display: flex;
5554
5852
  align-items: center;
@@ -6028,10 +6326,6 @@ figure.chip {
6028
6326
  border-radius: 9999px;
6029
6327
  transition: color 150ms ease;
6030
6328
  }
6031
- .select-tag-remove:focus-visible {
6032
- outline: 0.2rem solid var(--select-multiple-chip-remove-focus-outline-color);
6033
- outline-offset: 0.1rem;
6034
- }
6035
6329
  .select-tag-remove:hover {
6036
6330
  color: var(--select-multiple-chip-remove-hover-color);
6037
6331
  }
@@ -6104,7 +6398,6 @@ figure.chip {
6104
6398
  cursor: pointer;
6105
6399
  transition:
6106
6400
  background-color 0.2s ease,
6107
- box-shadow 0.2s ease,
6108
6401
  opacity 0.2s ease;
6109
6402
  }
6110
6403
 
@@ -6119,10 +6412,6 @@ figure.chip {
6119
6412
  background-color: var(--switch-track-background-checked);
6120
6413
  }
6121
6414
 
6122
- .switch:where(:focus-visible) {
6123
- box-shadow: 0 0 0 2px var(--switch-focus-ring);
6124
- }
6125
-
6126
6415
  .switch:where(:disabled) {
6127
6416
  cursor: not-allowed;
6128
6417
  opacity: var(--switch-disabled-opacity);
@@ -6251,11 +6540,6 @@ figure.chip {
6251
6540
  cursor: not-allowed;
6252
6541
  }
6253
6542
 
6254
- .switch-text-button:where(:focus-visible) {
6255
- outline: 2px solid var(--switch-focus-ring);
6256
- outline-offset: 2px;
6257
- }
6258
-
6259
6543
  .switch-text-label {
6260
6544
  display: flex;
6261
6545
  align-items: center;
@@ -6335,11 +6619,6 @@ figure.chip {
6335
6619
  transition: background-color 0.2s ease;
6336
6620
  }
6337
6621
 
6338
- .tab-trigger:where(:focus-visible) {
6339
- outline: 2px solid var(--color-primary-default);
6340
- outline-offset: 2px;
6341
- }
6342
-
6343
6622
  .tab-trigger:where([data-disabled="true"]) {
6344
6623
  cursor: not-allowed;
6345
6624
  opacity: var(--tab-disabled-opacity);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniai-fe/uds-primitives",
3
- "version": "0.12.14",
3
+ "version": "0.13.1",
4
4
  "description": "UNIAI Design System; Primitives Components Package",
5
5
  "type": "module",
6
6
  "private": false,
@@ -87,9 +87,9 @@
87
87
  "react-hook-form": "^7.86.0",
88
88
  "sass": "^1.102.0",
89
89
  "typescript": "6.0.3",
90
- "@uniai-fe/eslint-config": "0.4.4",
91
- "@uniai-fe/next-devkit": "0.4.1",
92
90
  "@uniai-fe/tsconfig": "0.2.0",
91
+ "@uniai-fe/next-devkit": "0.4.1",
92
+ "@uniai-fe/eslint-config": "0.4.4",
93
93
  "@uniai-fe/uds-foundation": "0.6.0",
94
94
  "@uniai-fe/util-functions": "0.4.3"
95
95
  },
@@ -59,6 +59,11 @@
59
59
  width: var(--calendar-body-width);
60
60
  }
61
61
 
62
+ .calendar-grid .mantine-focus-auto:focus-visible {
63
+ // Mantine의 공통 초점 테두리만 숨기고 날짜 상태 표시는 유지한다.
64
+ outline: none;
65
+ }
66
+
62
67
  .calendar-range-grid {
63
68
  width: var(--calendar-body-width);
64
69
  }
@@ -22,7 +22,6 @@
22
22
  --theme-checkbox-icon-default: transparent;
23
23
  --theme-checkbox-icon-selected: var(--color-common-100);
24
24
  --theme-checkbox-icon-disabled-selected: var(--color-common-100);
25
- --theme-checkbox-focus-ring: rgba(2, 84, 255, 0.32);
26
25
  }
27
26
 
28
27
  .checkbox {
@@ -38,8 +37,7 @@
38
37
  transition:
39
38
  background-color 0.15s ease,
40
39
  border-color 0.15s ease,
41
- opacity 0.15s ease,
42
- box-shadow 0.15s ease;
40
+ opacity 0.15s ease;
43
41
 
44
42
  &[data-size="medium"] {
45
43
  inline-size: var(--theme-checkbox-frame-size-medium);
@@ -58,10 +56,6 @@
58
56
  }
59
57
  }
60
58
 
61
- .checkbox:focus-visible {
62
- box-shadow: 0 0 0 2px var(--theme-checkbox-focus-ring);
63
- }
64
-
65
59
  .checkbox-surface {
66
60
  inline-size: var(--theme-checkbox-indicator-size-medium);
67
61
  block-size: var(--theme-checkbox-indicator-size-medium);
@@ -42,11 +42,6 @@ figure.chip {
42
42
  margin: 0;
43
43
  }
44
44
 
45
- .chip:focus-visible {
46
- outline: 2px solid var(--color-primary-default);
47
- outline-offset: 2px;
48
- }
49
-
50
45
  .chip:where([data-style="filter"][data-fill="solid"]) {
51
46
  --chip-bg: var(--color-surface-standard);
52
47
  --chip-label-color: var(--color-label-neutral);
@@ -0,0 +1 @@
1
+ @use "./styles";
@@ -0,0 +1,34 @@
1
+ import "./index.scss";
2
+
3
+ import { Tooltip } from "../tooltip";
4
+
5
+ import {
6
+ FabDefault,
7
+ FabExtended,
8
+ FabLabel,
9
+ FabRoot,
10
+ FabTrigger,
11
+ FabMenuList,
12
+ FabMenuItem,
13
+ FabTemplate,
14
+ } from "./markup";
15
+
16
+ export const Fab = {
17
+ Button: FabDefault,
18
+ Trigger: FabTrigger,
19
+ Expand: FabExtended,
20
+ Menu: {
21
+ List: FabMenuList,
22
+ Item: FabMenuItem,
23
+ Label: Tooltip.Text,
24
+ },
25
+ Root: FabRoot,
26
+ Template: FabTemplate,
27
+ Default: FabDefault,
28
+ Extended: FabExtended,
29
+ Label: FabLabel,
30
+ };
31
+
32
+ export * from "./types/options";
33
+ export type * from "./types";
34
+ export { FabContext, ARROW_KEYS, useFabContext } from "./markup";