@uniai-fe/uds-primitives 0.12.14 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -0
- package/dist/styles.css +330 -0
- package/package.json +1 -1
- package/src/components/fab/index.scss +1 -0
- package/src/components/fab/index.tsx +34 -0
- package/src/components/fab/markup/Base.tsx +62 -0
- package/src/components/fab/markup/Default.tsx +33 -0
- package/src/components/fab/markup/Extended.tsx +35 -0
- package/src/components/fab/markup/Label.tsx +16 -0
- package/src/components/fab/markup/Menu.tsx +114 -0
- package/src/components/fab/markup/Root.tsx +263 -0
- package/src/components/fab/markup/Template.tsx +79 -0
- package/src/components/fab/markup/Trigger.tsx +65 -0
- package/src/components/fab/markup/index.ts +7 -0
- package/src/components/fab/styles/composition.scss +80 -0
- package/src/components/fab/styles/fab.scss +140 -0
- package/src/components/fab/styles/index.scss +4 -0
- package/src/components/fab/styles/variables.scss +25 -0
- package/src/components/fab/types/composition.ts +288 -0
- package/src/components/fab/types/index.ts +3 -0
- package/src/components/fab/types/options.ts +39 -0
- package/src/components/fab/types/props.ts +124 -0
- package/src/components/tooltip/markup/Text.tsx +10 -3
- package/src/components/tooltip/types/text.ts +8 -3
- package/src/index.scss +1 -0
- package/src/index.tsx +1 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
.fab {
|
|
2
|
+
--fab-hover-shadow: none;
|
|
3
|
+
--fab-pressed-shadow: none;
|
|
4
|
+
display: flex;
|
|
5
|
+
flex: 0 0 auto;
|
|
6
|
+
align-items: center;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
width: var(--fab-height);
|
|
10
|
+
height: var(--fab-height);
|
|
11
|
+
padding: var(--fab-padding-block) var(--fab-padding-inline);
|
|
12
|
+
border: 0;
|
|
13
|
+
border-radius: var(--fab-radius);
|
|
14
|
+
background-color: var(--fab-background);
|
|
15
|
+
color: var(--fab-foreground);
|
|
16
|
+
box-shadow: none;
|
|
17
|
+
cursor: pointer;
|
|
18
|
+
|
|
19
|
+
// Button의 색상 토큰을 재사용하며 camelCase preset만 CSS token 이름으로 연결한다.
|
|
20
|
+
@each $priority,
|
|
21
|
+
$token
|
|
22
|
+
in (
|
|
23
|
+
"primary": "primary",
|
|
24
|
+
"secondary": "secondary",
|
|
25
|
+
"tertiary": "tertiary",
|
|
26
|
+
"green": "green",
|
|
27
|
+
"yellow": "yellow",
|
|
28
|
+
"orange": "orange",
|
|
29
|
+
"teal": "teal",
|
|
30
|
+
"pink": "pink",
|
|
31
|
+
"red": "red",
|
|
32
|
+
"darkGray": "dark-gray",
|
|
33
|
+
"lightGray": "light-gray"
|
|
34
|
+
)
|
|
35
|
+
{
|
|
36
|
+
&:where([data-fill="solid"][data-priority="#{$priority}"]) {
|
|
37
|
+
--fab-background: var(--button-default-#{$token}-solid-bg);
|
|
38
|
+
--fab-foreground: var(--button-default-#{$token}-solid-foreground);
|
|
39
|
+
--fab-hover-background: var(--button-default-#{$token}-solid-hover-bg);
|
|
40
|
+
--fab-pressed-background: var(--button-default-#{$token}-solid-active-bg);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&:where([data-fill="outlined"][data-priority="#{$priority}"]) {
|
|
44
|
+
--fab-background: var(--fab-outlined-background);
|
|
45
|
+
--fab-foreground: var(--button-default-#{$token}-outline-foreground);
|
|
46
|
+
--fab-hover-background: var(--button-default-#{$token}-outline-hover-bg);
|
|
47
|
+
// Semantic outlined의 pressed 색상은 아래 overlay에서 결정한다.
|
|
48
|
+
@if $priority !=
|
|
49
|
+
primary and
|
|
50
|
+
$priority !=
|
|
51
|
+
secondary and
|
|
52
|
+
$priority !=
|
|
53
|
+
tertiary
|
|
54
|
+
{
|
|
55
|
+
--fab-pressed-background: var(
|
|
56
|
+
--button-default-#{$token}-outline-active-bg
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
border: 1px solid var(--button-default-#{$token}-outline-border);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Button의 semantic outlined와 solid tertiary는 동일한 흰색 inset overlay를 사용한다.
|
|
64
|
+
@each $priority in (primary, secondary, tertiary) {
|
|
65
|
+
&:where([data-fill="outlined"][data-priority="#{$priority}"]) {
|
|
66
|
+
--fab-hover-background: var(
|
|
67
|
+
--button-default-#{$priority}-overlay-outlined-bg
|
|
68
|
+
);
|
|
69
|
+
--fab-pressed-background: var(--fab-hover-background);
|
|
70
|
+
--fab-hover-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.68);
|
|
71
|
+
--fab-pressed-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.28);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&:where([data-fill="solid"][data-priority="tertiary"]) {
|
|
76
|
+
--fab-hover-background: var(--button-default-tertiary-overlay-solid-bg);
|
|
77
|
+
--fab-pressed-background: var(--fab-hover-background);
|
|
78
|
+
--fab-hover-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.68);
|
|
79
|
+
--fab-pressed-shadow: inset 0 0 0 999px rgba(255, 255, 255, 0.48);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&:where(:enabled:hover) {
|
|
83
|
+
background-color: var(--fab-hover-background);
|
|
84
|
+
box-shadow: var(--fab-hover-shadow);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&:where(:enabled:active) {
|
|
88
|
+
background-color: var(--fab-pressed-background);
|
|
89
|
+
box-shadow: var(--fab-pressed-shadow);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
&:where(:focus-visible) {
|
|
93
|
+
outline: 2px solid var(--fab-focus-color);
|
|
94
|
+
outline-offset: 2px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
&:where(:disabled) {
|
|
98
|
+
background-color: var(--fab-disabled-background);
|
|
99
|
+
border-color: var(--fab-disabled-background);
|
|
100
|
+
--fab-foreground: var(--fab-disabled-foreground);
|
|
101
|
+
cursor: not-allowed;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@each $size in (small, medium, large) {
|
|
105
|
+
&:where([data-size="#{$size}"]) {
|
|
106
|
+
--fab-height: var(--fab-height-#{$size});
|
|
107
|
+
--fab-content-size: var(--fab-content-size-#{$size});
|
|
108
|
+
--fab-font-size: var(--fab-font-size-#{$size});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&:where([data-extended="true"]) {
|
|
113
|
+
width: fit-content;
|
|
114
|
+
min-width: var(--fab-height);
|
|
115
|
+
// 전역 button max-width가 줄바꿈 없는 라벨의 자연 너비를 제한하지 않게 한다.
|
|
116
|
+
max-width: none;
|
|
117
|
+
gap: var(--fab-gap);
|
|
118
|
+
padding-inline: var(--fab-extended-padding-inline);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
:where(.fab-content) {
|
|
122
|
+
display: flex;
|
|
123
|
+
flex: 0 0 var(--fab-content-size);
|
|
124
|
+
align-items: center;
|
|
125
|
+
justify-content: center;
|
|
126
|
+
width: var(--fab-content-size);
|
|
127
|
+
height: var(--fab-content-size);
|
|
128
|
+
color: var(--fab-foreground);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
:where(.fab-label) {
|
|
132
|
+
color: var(--fab-foreground);
|
|
133
|
+
font-family: var(--fab-font-family);
|
|
134
|
+
font-size: var(--fab-font-size);
|
|
135
|
+
font-weight: var(--fab-font-weight);
|
|
136
|
+
line-height: var(--fab-line-height);
|
|
137
|
+
letter-spacing: var(--fab-letter-spacing);
|
|
138
|
+
white-space: nowrap;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--fab-height-small: var(--theme-size-medium-1);
|
|
3
|
+
--fab-height-medium: var(--theme-size-medium-2);
|
|
4
|
+
--fab-height-large: var(--theme-size-medium-3);
|
|
5
|
+
--fab-content-size-small: var(--theme-size-xsmall-3);
|
|
6
|
+
--fab-content-size-medium: var(--theme-size-small-1);
|
|
7
|
+
--fab-content-size-large: var(--theme-size-small-2);
|
|
8
|
+
// Figma의 60px radius는 Foundation에 동일한 token이 없다.
|
|
9
|
+
--fab-radius: 60px;
|
|
10
|
+
--fab-padding-inline: var(--spacing-padding-5);
|
|
11
|
+
--fab-padding-block: var(--spacing-padding-2);
|
|
12
|
+
--fab-extended-padding-inline: var(--spacing-padding-6);
|
|
13
|
+
--fab-gap: var(--spacing-gap-4);
|
|
14
|
+
--fab-font-family: var(--font-family-sans);
|
|
15
|
+
--fab-font-size-small: var(--font-body-xxsmall-size);
|
|
16
|
+
--fab-font-size-medium: var(--font-body-xsmall-size);
|
|
17
|
+
--fab-font-size-large: var(--font-body-small-size);
|
|
18
|
+
--fab-font-weight: var(--font-body-small-weight);
|
|
19
|
+
--fab-line-height: var(--font-body-small-line-height);
|
|
20
|
+
--fab-letter-spacing: var(--font-body-small-letter-spacing);
|
|
21
|
+
--fab-outlined-background: var(--button-default-outline-bg);
|
|
22
|
+
--fab-focus-color: var(--color-primary-default);
|
|
23
|
+
--fab-disabled-background: var(--button-default-neutral-disabled-bg);
|
|
24
|
+
--fab-disabled-foreground: var(--button-default-neutral-disabled-foreground);
|
|
25
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ComponentPropsWithoutRef,
|
|
3
|
+
FocusEventHandler,
|
|
4
|
+
MouseEventHandler,
|
|
5
|
+
ReactNode,
|
|
6
|
+
RefObject,
|
|
7
|
+
} from "react";
|
|
8
|
+
import type { FabDefaultProps } from "./props";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Fab Types; 액션이 펼쳐지는 물리 방향
|
|
12
|
+
* @desc "up" | "down" | "left" | "right"를 지원하며 RTL에서도 물리 방향을 유지한다.
|
|
13
|
+
*/
|
|
14
|
+
export type FabDirection = "up" | "down" | "left" | "right";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Fab Types; Root가 조립 부품에 제공하는 컨텍스트 값
|
|
18
|
+
* @property {boolean} open 현재 열림 상태. 제어형 open 또는 비제어형 내부 상태에서 계산한다.
|
|
19
|
+
* @property {"up" | "down" | "left" | "right"} direction 액션의 물리 펼침 방향. RTL에서도 좌우를 반전하지 않는다.
|
|
20
|
+
* @property {boolean} persistentTooltips 열린 액션의 이름을 hover 여부와 관계없이 계속 표시할지 결정한다.
|
|
21
|
+
* @property {string} triggerId Root가 생성한 Trigger ID. 별도 메뉴 이름이 없으면 목록의 aria-labelledby에 연결한다.
|
|
22
|
+
* @property {string} menuId Root가 생성한 목록 ID. Trigger의 aria-controls에 연결한다.
|
|
23
|
+
* @property {React.RefObject<HTMLButtonElement | null>} triggerRef Trigger DOM ref. 메뉴 탐색과 닫힘 뒤 focus 복귀에 사용한다.
|
|
24
|
+
* @property {React.RefObject<HTMLDivElement | null>} menuRef 목록 DOM ref. 액션 조회와 내부 focus 판별에 사용한다.
|
|
25
|
+
* @property {(restoreFocus: boolean) => void} onClose 닫힘을 요청하고 대기 중인 focus와 hover 진입을 초기화한다. true이면 Trigger로 focus를 복귀한다.
|
|
26
|
+
* @property {React.MouseEventHandler<HTMLButtonElement>} onTriggerClick Trigger 클릭의 열림 처리를 수행한다. hover로 열린 첫 포인터 클릭은 열림을 유지하고 이후 클릭·Enter·Space는 토글한다.
|
|
27
|
+
* @property {React.FocusEventHandler<HTMLButtonElement>} onTriggerFocus 키보드 focus 진입이면 열림을 요청한다. 메뉴에서 Trigger로 복귀하는 내부 focus 이동은 다시 열지 않는다.
|
|
28
|
+
* @desc FabRoot의 Provider가 값을 소유하고 Trigger·Menu 부품이 useFabContext로 조회한다. Provider 밖의 기본값 null은 이 값 타입에 포함하지 않으며 Hook이 오류로 처리한다. 제어형 상태에서 handler는 변경을 요청하고 소비자가 open에 반영한다.
|
|
29
|
+
*/
|
|
30
|
+
export interface FabContextValue {
|
|
31
|
+
/**
|
|
32
|
+
* 제어형 open 또는 비제어형 내부 상태에서 계산한 현재 열림 상태.
|
|
33
|
+
*/
|
|
34
|
+
open: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* 허용 값: "up" | "down" | "left" | "right". RTL에서도 물리 방향을 유지한다.
|
|
37
|
+
*/
|
|
38
|
+
direction: FabDirection;
|
|
39
|
+
/**
|
|
40
|
+
* true이면 열린 액션의 이름을 hover 여부와 관계없이 계속 표시한다.
|
|
41
|
+
*/
|
|
42
|
+
persistentTooltips: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Root가 생성한 Trigger ID. 별도 메뉴 이름이 없으면 목록의 aria-labelledby에 연결한다.
|
|
45
|
+
*/
|
|
46
|
+
triggerId: string;
|
|
47
|
+
/**
|
|
48
|
+
* Root가 생성한 목록 ID. Trigger의 aria-controls에 연결한다.
|
|
49
|
+
*/
|
|
50
|
+
menuId: string;
|
|
51
|
+
/**
|
|
52
|
+
* 실제 Trigger 버튼의 DOM ref. 메뉴 탐색과 닫힘 뒤 focus 복귀에 사용한다.
|
|
53
|
+
*/
|
|
54
|
+
triggerRef: RefObject<HTMLButtonElement | null>;
|
|
55
|
+
/**
|
|
56
|
+
* 실제 목록 div의 DOM ref. 액션 조회와 내부 focus 판별에 사용한다.
|
|
57
|
+
*/
|
|
58
|
+
menuRef: RefObject<HTMLDivElement | null>;
|
|
59
|
+
/**
|
|
60
|
+
* 닫힘을 요청하고 대기 중인 focus와 hover 진입을 초기화한다.
|
|
61
|
+
* restoreFocus가 true이면 Trigger로 focus를 복귀한다. 제어형 open은 소비자가 반영한다.
|
|
62
|
+
*/
|
|
63
|
+
onClose: (restoreFocus: boolean) => void;
|
|
64
|
+
/**
|
|
65
|
+
* hover로 열린 첫 포인터 클릭은 열림을 유지하고 이후 클릭·Enter·Space는 토글한다.
|
|
66
|
+
* Trigger가 소비자 onClick을 먼저 호출하고 preventDefault하지 않은 이벤트를 전달한다.
|
|
67
|
+
*/
|
|
68
|
+
onTriggerClick: MouseEventHandler<HTMLButtonElement>;
|
|
69
|
+
/**
|
|
70
|
+
* 키보드 focus 진입이면 열림을 요청하며 메뉴에서 Trigger로 돌아오는 내부 이동은 생략한다.
|
|
71
|
+
* Trigger가 소비자 onFocus를 먼저 호출하고 preventDefault하지 않은 이벤트를 전달한다.
|
|
72
|
+
*/
|
|
73
|
+
onTriggerFocus: FocusEventHandler<HTMLButtonElement>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Fab Props; 공통 액션 조합과 열림 상태
|
|
78
|
+
* @property {ReactNode} children Trigger 하나와 Menu.List 하나의 조합.
|
|
79
|
+
* @property {"up" | "down" | "left" | "right"} [direction="up"] 액션의 물리 펼침 방향. RTL에서도 물리 좌우를 유지한다.
|
|
80
|
+
* @property {boolean} [persistentTooltips=false] 열린 액션의 이름을 hover 여부와 관계없이 계속 표시한다.
|
|
81
|
+
* @property {boolean} [open] 제어형 열림 상태. 지정하면 소비자가 onOpenChange의 요청을 반영한다.
|
|
82
|
+
* @property {boolean} [defaultOpen=false] 비제어형 최초 열림 상태. open이 지정되면 사용하지 않는다.
|
|
83
|
+
* @property {(open: boolean) => void} [onOpenChange] 현재 open과 다른 열림 변경 요청을 전달한다. 제어형·비제어형 모두에서 호출한다.
|
|
84
|
+
* @property {string} [className] 최상위 Root div에 병합하는 추가 클래스.
|
|
85
|
+
* @property {React.CSSProperties} [style] 최상위 Root div에 전달하는 inline style.
|
|
86
|
+
* @property {(event: React.FocusEvent<HTMLDivElement>) => void} [onBlur] Root의 닫힘 처리 전에 호출한다. preventDefault하면 외부 focus 이동에 따른 닫힘만 생략한다.
|
|
87
|
+
* @property {(event: React.KeyboardEvent<HTMLDivElement>) => void} [onKeyDown] Root의 방향키·Home·End·Escape 처리 전에 호출한다. preventDefault하면 Root의 해당 처리를 생략한다. 열린 Tooltip의 Escape는 document capture에서 먼저 닫는다.
|
|
88
|
+
* @property {(event: React.PointerEvent<HTMLDivElement>) => void} [onPointerEnter] Root의 mouse hover 열림 전에 호출한다. 닫힌 상태의 포인터 진입 대상은 Trigger다. preventDefault하거나 Trigger가 disabled이면 hover로 열지 않는다.
|
|
89
|
+
* @property {(event: React.PointerEvent<HTMLDivElement>) => void} [onPointerLeave] Root의 포인터 이탈 닫힘 전에 호출한다. preventDefault하거나 focus가 Root 안에 있으면 닫지 않는다.
|
|
90
|
+
* @property {(event: React.MouseEvent<HTMLDivElement>) => void} [onClick] Root div의 native 클릭 handler. Trigger·Menu.Item의 클릭이 버블링되며 해당 부품의 처리는 먼저 실행된다.
|
|
91
|
+
* @desc native div 입력과 컴포넌트의 Root DOM ref를 유지한다. Root 하나에 Trigger 하나와 Menu.List 하나를 조립한다. Escape·항목 선택은 닫고 Trigger로 focus를 복귀하며 외부 Tab은 이동한 focus를 유지한다. 열린 Tooltip의 Escape는 document capture에서 먼저 처리하므로 onKeyDown 취소보다 앞선다. 화면 배치와 액션 실행은 소비자의 책임이다.
|
|
92
|
+
*/
|
|
93
|
+
export interface FabRootProps extends ComponentPropsWithoutRef<"div"> {
|
|
94
|
+
/**
|
|
95
|
+
* Root의 상태를 공유하는 Trigger 하나와 Menu.List 하나의 조합.
|
|
96
|
+
*/
|
|
97
|
+
children: ReactNode;
|
|
98
|
+
/**
|
|
99
|
+
* 허용 값: "up" | "down" | "left" | "right". 기본값은 "up"이다.
|
|
100
|
+
*/
|
|
101
|
+
direction?: FabDirection;
|
|
102
|
+
/**
|
|
103
|
+
* 기본값 false. true이면 열린 액션의 툴팁을 hover 여부와 관계없이 계속 표시한다.
|
|
104
|
+
*/
|
|
105
|
+
persistentTooltips?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* 제어형 상태. onOpenChange의 변경 요청을 소비자가 반영한다.
|
|
108
|
+
*/
|
|
109
|
+
open?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* 기본값 false인 비제어형 최초 열림 상태. open이 지정되면 사용하지 않는다.
|
|
112
|
+
*/
|
|
113
|
+
defaultOpen?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* 현재 open과 다른 열림 변경 요청을 제어형·비제어형 모두에서 전달한다.
|
|
116
|
+
* 제어형에서는 소비자가 요청한 값을 open에 반영한다.
|
|
117
|
+
*/
|
|
118
|
+
onOpenChange?: (open: boolean) => void;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Fab Props; Root와 연결하는 아이콘 버튼
|
|
123
|
+
* @property {"small" | "medium" | "large"} size 필수 크기. small/medium/large의 높이는 40/48/56px, icon 영역은 16/20/24px다.
|
|
124
|
+
* @property {"solid" | "outlined"} fill 모든 priority에서 선택하는 필수 채움 스타일.
|
|
125
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} priority solid와 outlined 모두에서 필수인 색상.
|
|
126
|
+
* @property {ReactNode} icon 필수 장식용 콘텐츠. icon 영역은 aria-hidden이므로 행동 이름을 대신하지 않는다.
|
|
127
|
+
* @property {string} aria-label 필수 행동 이름. icon 콘텐츠는 접근 가능한 이름에서 제외된다.
|
|
128
|
+
* @property {"button" | "submit" | "reset"} [type="button"] native 버튼 종류. submit과 reset은 소비자가 명시한다.
|
|
129
|
+
* @property {boolean} [disabled] native 클릭·키보드 실행을 차단한다.
|
|
130
|
+
* @property {string} [className] 최상위 native 버튼에 병합하는 추가 클래스.
|
|
131
|
+
* @property {React.CSSProperties} [style] 최상위 native 버튼에 전달하는 inline style.
|
|
132
|
+
* @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [onClick] 기본 클릭 처리 전에 호출한다. preventDefault하면 처리를 생략한다. hover로 열린 첫 pointer 클릭은 열림을 유지하고 이후 클릭과 Enter·Space는 토글한다.
|
|
133
|
+
* @property {(event: React.FocusEvent<HTMLButtonElement>) => void} [onFocus] 키보드 focus 진입에 따른 열림 전에 호출한다. preventDefault하면 해당 열림을 생략한다.
|
|
134
|
+
* @property {(event: React.KeyboardEvent<HTMLButtonElement>) => void} [onKeyDown] native 버튼 handler. Root로 버블링되는 메뉴 탐색을 preventDefault로 취소할 수 있다. 열린 Tooltip의 Escape는 document capture에서 먼저 처리한다.
|
|
135
|
+
* @desc FabDefaultProps의 native 버튼 계약에서 id·aria-haspopup·aria-expanded·aria-controls를 제외한다. 해당 ID와 menu ARIA는 Root가 생성하며 DOM ref도 Root와 공유한다. Root 밖에서 사용하면 오류를 발생시킨다.
|
|
136
|
+
* @see FabDefaultProps
|
|
137
|
+
*/
|
|
138
|
+
export type FabTriggerProps = Omit<
|
|
139
|
+
FabDefaultProps,
|
|
140
|
+
"id" | "aria-haspopup" | "aria-expanded" | "aria-controls"
|
|
141
|
+
>;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Fab Props; 원점을 유지하는 액션 목록
|
|
145
|
+
* @property {ReactNode} [children] 공개 Menu.Item의 조합.
|
|
146
|
+
* @property {string} [aria-label] 별도 메뉴 이름. 없거나 빈 문자열이면 Root가 Trigger의 ID로 aria-labelledby를 연결한다.
|
|
147
|
+
* @property {string} [className] 메뉴 목록 div에 병합하는 추가 클래스.
|
|
148
|
+
* @property {React.CSSProperties} [style] 메뉴 목록 div에 전달하는 inline style.
|
|
149
|
+
* @property {(event: React.MouseEvent<HTMLDivElement>) => void} [onClick] 목록 div의 native 클릭 handler. Menu.Item의 클릭 처리 뒤 버블링된다.
|
|
150
|
+
* @property {(event: React.KeyboardEvent<HTMLDivElement>) => void} [onKeyDown] 목록 div의 native handler. Root로 버블링되는 메뉴 탐색을 preventDefault로 취소할 수 있다. 열린 Tooltip의 Escape는 먼저 처리한다.
|
|
151
|
+
* @desc native div 입력에서 id·role·hidden·inert·aria-hidden·aria-orientation·aria-labelledby를 제외한다. Root가 ID·menu role·orientation과 Trigger 이름을 연결한다. 닫히면 배치 공간을 유지하고 aria-hidden=true·inert=true로 접근성·focus 탐색에서 제외한다. ref는 실제 목록 div에 연결한다. Root 밖에서 사용하면 오류를 발생시킨다.
|
|
152
|
+
*/
|
|
153
|
+
export type FabMenuListProps = Omit<
|
|
154
|
+
ComponentPropsWithoutRef<"div">,
|
|
155
|
+
| "id"
|
|
156
|
+
| "role"
|
|
157
|
+
| "hidden"
|
|
158
|
+
| "inert"
|
|
159
|
+
| "aria-hidden"
|
|
160
|
+
| "aria-orientation"
|
|
161
|
+
| "aria-labelledby"
|
|
162
|
+
>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Fab Props; 이름과 선택 동작을 가진 액션 버튼
|
|
166
|
+
* @property {"small" | "medium" | "large"} size 필수 크기. small/medium/large의 높이는 40/48/56px, icon 영역은 16/20/24px다.
|
|
167
|
+
* @property {"solid" | "outlined"} fill 모든 priority에서 선택하는 필수 채움 스타일.
|
|
168
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} priority solid와 outlined 모두에서 필수인 색상.
|
|
169
|
+
* @property {ReactNode} icon 필수 장식용 콘텐츠. icon 영역은 aria-hidden이므로 행동 이름을 대신하지 않는다.
|
|
170
|
+
* @property {string} aria-label 필수 행동 이름. icon 콘텐츠는 접근 가능한 이름에서 제외된다.
|
|
171
|
+
* @property {"button" | "submit" | "reset"} [type="button"] native 버튼 종류. submit과 reset은 소비자가 명시한다.
|
|
172
|
+
* @property {boolean} [disabled] native 클릭·키보드 실행을 차단한다. 방향키 탐색에서도 제외한다.
|
|
173
|
+
* @property {string} [className] 최상위 native 버튼에 병합하는 추가 클래스.
|
|
174
|
+
* @property {React.CSSProperties} [style] 최상위 native 버튼에 전달하는 inline style.
|
|
175
|
+
* @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [onClick] 선택 시 먼저 호출한다. preventDefault하지 않으면 닫고 Trigger로 focus를 복귀한다. 서비스 실행과 결과 상태는 소비자가 처리한다.
|
|
176
|
+
* @property {string} [id] native 버튼의 DOM ID.
|
|
177
|
+
* @property {"top" | "right" | "bottom" | "left"} [tooltipSide] Tooltip 방향. 세로 메뉴는 left, 가로 메뉴는 top이 기본이다.
|
|
178
|
+
* @property {(event: React.FocusEvent<HTMLButtonElement>) => void} [onFocus] native 액션 버튼 focus handler.
|
|
179
|
+
* @property {(event: React.KeyboardEvent<HTMLButtonElement>) => void} [onKeyDown] native 액션 버튼 handler. Root로 버블링되는 탐색을 preventDefault로 취소할 수 있다. 열린 Tooltip의 Escape는 document capture에서 먼저 닫는다.
|
|
180
|
+
* @desc FabDefaultProps에서 role·tabIndex를 제외하고 tooltipSide를 추가한다. aria-label은 버튼 이름과 Tooltip 문구로 사용한다. role=menuitem과 tabIndex=-1은 메뉴 탐색이 소유한다. DOM ref는 실제 액션 버튼에 연결한다. Root 밖에서 사용하면 오류를 발생시킨다.
|
|
181
|
+
* @see FabDefaultProps
|
|
182
|
+
*/
|
|
183
|
+
export type FabMenuItemProps = Omit<FabDefaultProps, "role" | "tabIndex"> & {
|
|
184
|
+
/**
|
|
185
|
+
* 허용 값: "top" | "right" | "bottom" | "left".
|
|
186
|
+
* 생략하면 세로 메뉴는 "left", 가로 메뉴는 "top"을 사용한다.
|
|
187
|
+
*/
|
|
188
|
+
tooltipSide?: "top" | "right" | "bottom" | "left";
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Fab Types; 기본 조합에 전달하는 액션 항목
|
|
193
|
+
* @property {string} id 필수 고유 DOM ID와 React 조합 key. 같은 화면에서 중복하지 않는다.
|
|
194
|
+
* @property {"small" | "medium" | "large"} size 필수 크기. small/medium/large의 높이는 40/48/56px, icon 영역은 16/20/24px다.
|
|
195
|
+
* @property {"solid" | "outlined"} fill 모든 priority에서 선택하는 필수 채움 스타일.
|
|
196
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} priority solid와 outlined 모두에서 필수인 색상.
|
|
197
|
+
* @property {ReactNode} icon 필수 장식용 콘텐츠. icon 영역은 aria-hidden이므로 행동 이름을 대신하지 않는다.
|
|
198
|
+
* @property {string} aria-label 필수 행동 이름. icon 콘텐츠는 접근 가능한 이름에서 제외된다.
|
|
199
|
+
* @property {"button" | "submit" | "reset"} [type="button"] native 버튼 종류. submit과 reset은 소비자가 명시한다.
|
|
200
|
+
* @property {boolean} [disabled] native 클릭·키보드 실행을 차단한다. 방향키 탐색에서도 제외한다.
|
|
201
|
+
* @property {React.CSSProperties} [style] 최상위 native 버튼에 전달하는 inline style.
|
|
202
|
+
* @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [onClick] 선택 시 먼저 호출한다. preventDefault하지 않으면 닫고 Trigger로 focus를 복귀한다. 서비스 실행과 결과 상태는 소비자가 처리한다.
|
|
203
|
+
* @property {"top" | "right" | "bottom" | "left"} [tooltipSide] Tooltip 방향. 세로 메뉴는 left, 가로 메뉴는 top이 기본이다.
|
|
204
|
+
* @property {(event: React.FocusEvent<HTMLButtonElement>) => void} [onFocus] native 액션 버튼 focus handler.
|
|
205
|
+
* @property {(event: React.KeyboardEvent<HTMLButtonElement>) => void} [onKeyDown] native 액션 버튼 handler. Root로 버블링되는 탐색을 preventDefault로 취소할 수 있다. 열린 Tooltip의 Escape는 document capture에서 먼저 닫는다.
|
|
206
|
+
* @desc FabMenuItemProps에서 className을 제외하고 필수 id를 추가한다. 내부 스타일은 Template 최상위 className의 nested selector 또는 data attribute로 조정한다. Template이 id를 버튼 DOM ID와 조합 key로 사용하며 필수 icon·size·fill·priority·aria-label과 native 버튼 callback을 각 Menu.Item에 전달한다. 액션 실행과 결과 상태는 소비자의 책임이다.
|
|
207
|
+
* @see FabMenuItemProps
|
|
208
|
+
*/
|
|
209
|
+
export type FabTemplateItem = Omit<FabMenuItemProps, "className"> & {
|
|
210
|
+
/**
|
|
211
|
+
* 버튼의 고유 DOM ID와 목록 key로 사용한다. 같은 화면에서 중복하지 않는다.
|
|
212
|
+
*/
|
|
213
|
+
id: string;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Fab Props; 공개 부품으로 구성한 기본 액션 조합
|
|
218
|
+
* @property {"up" | "down" | "left" | "right"} [direction="up"] 액션의 물리 펼침 방향. RTL에서도 물리 좌우를 유지한다.
|
|
219
|
+
* @property {boolean} [persistentTooltips=false] 열린 액션의 이름을 hover 여부와 관계없이 계속 표시한다.
|
|
220
|
+
* @property {boolean} [open] 제어형 열림 상태. 지정하면 소비자가 onOpenChange의 요청을 반영한다.
|
|
221
|
+
* @property {boolean} [defaultOpen=false] 비제어형 최초 열림 상태. open이 지정되면 사용하지 않는다.
|
|
222
|
+
* @property {(open: boolean) => void} [onOpenChange] 현재 open과 다른 열림 변경 요청을 전달한다. 제어형·비제어형 모두에서 호출한다.
|
|
223
|
+
* @property {string} [className] 최상위 Root div에 병합하는 추가 클래스.
|
|
224
|
+
* @property {React.CSSProperties} [style] 최상위 Root div에 전달하는 inline style.
|
|
225
|
+
* @property {(event: React.FocusEvent<HTMLDivElement>) => void} [onBlur] Root의 닫힘 처리 전에 호출한다. preventDefault하면 외부 focus 이동에 따른 닫힘만 생략한다.
|
|
226
|
+
* @property {(event: React.KeyboardEvent<HTMLDivElement>) => void} [onKeyDown] Root의 방향키·Home·End·Escape 처리 전에 호출한다. preventDefault하면 Root의 해당 처리를 생략한다. 열린 Tooltip의 Escape는 document capture에서 먼저 닫는다.
|
|
227
|
+
* @property {(event: React.PointerEvent<HTMLDivElement>) => void} [onPointerEnter] Root의 mouse hover 열림 전에 호출한다. 닫힌 상태의 포인터 진입 대상은 Trigger다. preventDefault하거나 Trigger가 disabled이면 hover로 열지 않는다.
|
|
228
|
+
* @property {(event: React.PointerEvent<HTMLDivElement>) => void} [onPointerLeave] Root의 포인터 이탈 닫힘 전에 호출한다. preventDefault하거나 focus가 Root 안에 있으면 닫지 않는다.
|
|
229
|
+
* @property {(event: React.MouseEvent<HTMLDivElement>) => void} [onClick] Root div의 native 클릭 handler. Trigger·Menu.Item의 클릭이 버블링되며 해당 부품의 처리는 먼저 실행된다.
|
|
230
|
+
* @property {Omit<FabTriggerProps, "className">} triggerProps 필수 Trigger 입력. id와 menu ARIA는 Root가 생성한다.
|
|
231
|
+
* @property {ReactNode} triggerProps.icon Trigger의 필수 장식용 콘텐츠.
|
|
232
|
+
* @property {"small" | "medium" | "large"} triggerProps.size Trigger의 필수 크기. 높이는 40/48/56px, icon 영역은 16/20/24px다.
|
|
233
|
+
* @property {"solid" | "outlined"} triggerProps.fill Trigger의 필수 채움 스타일.
|
|
234
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} triggerProps.priority Trigger의 필수 색상.
|
|
235
|
+
* @property {string} triggerProps.aria-label Trigger와 기본 메뉴 이름으로 쓰는 필수 행동 이름.
|
|
236
|
+
* @property {"button" | "submit" | "reset"} [triggerProps.type="button"] Trigger의 native 버튼 종류.
|
|
237
|
+
* @property {boolean} [triggerProps.disabled] Trigger의 native 실행과 Root mouse hover 열림을 차단한다.
|
|
238
|
+
* @property {React.CSSProperties} [triggerProps.style] Trigger 버튼에 전달하는 inline style.
|
|
239
|
+
* @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [triggerProps.onClick] 기본 클릭 처리 전에 호출한다. preventDefault하면 처리를 생략한다. hover로 열린 첫 pointer 클릭은 열림을 유지하고 이후 클릭과 Enter·Space는 토글한다.
|
|
240
|
+
* @property {(event: React.FocusEvent<HTMLButtonElement>) => void} [triggerProps.onFocus] 키보드 focus 진입 열림 전에 호출한다. preventDefault하면 해당 열림을 생략한다.
|
|
241
|
+
* @property {(event: React.KeyboardEvent<HTMLButtonElement>) => void} [triggerProps.onKeyDown] Trigger의 native handler. Root 탐색 취소 범위와 Tooltip Escape 선처리 제한은 FabTriggerProps와 같다.
|
|
242
|
+
* @property {FabTemplateItem[]} items 필수 액션 배열. 빈 배열도 허용한다.
|
|
243
|
+
* @property {string} items[].id 각 항목의 필수 고유 DOM ID와 React 조합 key. 같은 화면에서 중복하지 않는다.
|
|
244
|
+
* @property {ReactNode} items[].icon 각 액션의 필수 장식용 콘텐츠.
|
|
245
|
+
* @property {"small" | "medium" | "large"} items[].size 각 액션의 필수 크기. 높이는 40/48/56px, icon 영역은 16/20/24px다.
|
|
246
|
+
* @property {"solid" | "outlined"} items[].fill 각 액션의 필수 채움 스타일.
|
|
247
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} items[].priority 각 액션의 필수 색상.
|
|
248
|
+
* @property {string} items[].aria-label 각 액션의 필수 행동 이름과 Tooltip 문구.
|
|
249
|
+
* @property {"button" | "submit" | "reset"} [items[].type="button"] 각 액션의 native 버튼 종류.
|
|
250
|
+
* @property {boolean} [items[].disabled] 해당 액션의 native 실행과 방향키 탐색을 차단한다.
|
|
251
|
+
* @property {React.CSSProperties} [items[].style] 해당 액션 버튼에 전달하는 inline style.
|
|
252
|
+
* @property {"top" | "right" | "bottom" | "left"} [items[].tooltipSide] Tooltip 방향. 생략하면 세로 메뉴 left, 가로 메뉴 top을 사용한다.
|
|
253
|
+
* @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [items[].onClick] 해당 액션 선택 callback. preventDefault하지 않으면 닫고 Trigger로 focus를 복귀한다.
|
|
254
|
+
* @property {(event: React.FocusEvent<HTMLButtonElement>) => void} [items[].onFocus] 해당 액션 버튼의 native focus handler.
|
|
255
|
+
* @property {(event: React.KeyboardEvent<HTMLButtonElement>) => void} [items[].onKeyDown] 해당 액션의 native handler. Root 탐색 취소 범위와 Tooltip Escape 선처리 제한은 FabMenuItemProps와 같다.
|
|
256
|
+
* @desc FabRootProps에서 children을 제외하고 triggerProps와 items를 추가한다. 공개 Root·Trigger·Menu.List·Menu.Item으로 조립하며 상속받은 상태·이벤트·className·style과 컴포넌트 ref는 최상위 Root에만 적용한다. Trigger와 각 액션의 native 입력은 nested props로 전달하되 className은 받지 않는다. 내부 스타일은 최상위 className의 nested selector 또는 data attribute로 조정한다. 서비스 실행·선택 결과는 items의 callback을 통해 소비자가 처리한다.
|
|
257
|
+
* @see FabRootProps
|
|
258
|
+
* @see FabTriggerProps
|
|
259
|
+
* @see FabTemplateItem
|
|
260
|
+
*/
|
|
261
|
+
export interface FabTemplateProps extends Omit<FabRootProps, "children"> {
|
|
262
|
+
/**
|
|
263
|
+
* Root의 메뉴를 여는 필수 아이콘 버튼 입력.
|
|
264
|
+
* icon: ReactNode와 aria-label: string이 필수다.
|
|
265
|
+
* size는 필수이며 허용 값은 "small" | "medium" | "large"다.
|
|
266
|
+
* fill은 필수이며 허용 값은 "solid" | "outlined"다.
|
|
267
|
+
* priority는 필수이며 허용 값은 "primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"다.
|
|
268
|
+
* type 허용 값: "button" | "submit" | "reset". 기본값은 "button"이다.
|
|
269
|
+
* disabled, style과 native 이벤트를 Trigger에 전달한다. className은 받지 않으며 런타임 입력도 무시한다.
|
|
270
|
+
* onClick/onFocus가 preventDefault하면 해당 기본 클릭/열림을 생략한다.
|
|
271
|
+
* hover로 열린 첫 pointer 클릭은 열림을 유지하고 이후 클릭과 Enter·Space는 토글한다.
|
|
272
|
+
* id와 menu ARIA는 Root가 생성하며 이 object로 override하지 않는다.
|
|
273
|
+
*/
|
|
274
|
+
triggerProps: Omit<FabTriggerProps, "className">;
|
|
275
|
+
/**
|
|
276
|
+
* 필수 액션 배열. 빈 배열도 허용한다.
|
|
277
|
+
* 각 항목의 id: string, icon: ReactNode, aria-label: string이 필수다.
|
|
278
|
+
* id는 버튼 DOM ID와 React 조합 key이며 같은 화면에서 중복하지 않는다.
|
|
279
|
+
* size는 필수이며 허용 값은 "small" | "medium" | "large"다.
|
|
280
|
+
* fill은 필수이며 허용 값은 "solid" | "outlined"다.
|
|
281
|
+
* priority는 필수이며 허용 값은 "primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"다.
|
|
282
|
+
* type 허용 값: "button" | "submit" | "reset". 기본값은 "button"이다.
|
|
283
|
+
* tooltipSide 허용 값: "top" | "right" | "bottom" | "left". 생략하면 세로 메뉴 left, 가로 메뉴 top을 사용한다.
|
|
284
|
+
* disabled, style과 native 이벤트를 각 Menu.Item에 전달한다. className은 받지 않으며 런타임 입력도 무시한다.
|
|
285
|
+
* onClick 뒤 preventDefault가 없으면 닫고 Trigger로 focus를 복귀한다.
|
|
286
|
+
*/
|
|
287
|
+
items: FabTemplateItem[];
|
|
288
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { BUTTON_FILLS, BUTTON_PRIORITIES } from "../../button/types/options";
|
|
2
|
+
import type { ButtonFill, ButtonPriority } from "../../button/types/props";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fab Types; 크기 옵션
|
|
6
|
+
* @desc Figma small 40px, medium 48px, large 56px에 대응한다.
|
|
7
|
+
*/
|
|
8
|
+
export type FabSize = "small" | "medium" | "large";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Fab Types; 채움 스타일
|
|
12
|
+
* @desc Button과 같은 "solid" | "outlined" 축이며 모든 priority에 적용한다.
|
|
13
|
+
*/
|
|
14
|
+
export type FabFill = ButtonFill;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Fab Types; 색상 priority
|
|
18
|
+
* @desc Button과 같은 "primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"를 두 fill 모두에 적용한다.
|
|
19
|
+
* @see ButtonPriority
|
|
20
|
+
*/
|
|
21
|
+
export type FabPriority = ButtonPriority;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Fab Options; 공개 크기 목록
|
|
25
|
+
* @desc Controls와 소비 예시에서 Figma 크기 축을 공유한다.
|
|
26
|
+
*/
|
|
27
|
+
export const FAB_SIZES = ["small", "medium", "large"] as const;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Fab Options; 공개 채움 스타일 목록
|
|
31
|
+
* @desc 채움과 외곽선을 독립된 시각 옵션으로 선택한다.
|
|
32
|
+
*/
|
|
33
|
+
export const FAB_FILLS = [...BUTTON_FILLS] as const;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Fab Options; 공개 색상 priority 목록
|
|
37
|
+
* @desc Button의 semantic priority와 고정 색상 preset 목록을 공유한다.
|
|
38
|
+
*/
|
|
39
|
+
export const FAB_PRIORITIES = [...BUTTON_PRIORITIES] as const;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
|
+
import type { FabFill, FabPriority, FabSize } from "./options";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fab Types; 시각 옵션의 조합 계약
|
|
6
|
+
* @property {"solid" | "outlined"} fill 모든 priority에서 선택하는 필수 채움 스타일.
|
|
7
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} priority 두 fill 모두에서 필수인 색상.
|
|
8
|
+
* @desc Button의 색상 계약을 재사용하며 priority와 fill을 독립적으로 조합한다. outlined의 기본 면은 불투명 흰색이다.
|
|
9
|
+
*/
|
|
10
|
+
export type FabStyleOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* 허용 값: "solid" | "outlined". 모든 priority에서 필수다.
|
|
13
|
+
*/
|
|
14
|
+
fill: FabFill;
|
|
15
|
+
/**
|
|
16
|
+
* 허용 값: "primary" | "secondary" | "tertiary" | "green" | "yellow" |
|
|
17
|
+
* "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray".
|
|
18
|
+
* 두 fill 모두에서 필수이며 배경·외곽선·콘텐츠 색상을 결정한다.
|
|
19
|
+
*/
|
|
20
|
+
priority: FabPriority;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Fab Props; 공통 native 버튼 계약
|
|
25
|
+
* @property {"small" | "medium" | "large"} size 필수 크기. small/medium/large의 높이는 40/48/56px, icon 영역은 16/20/24px다.
|
|
26
|
+
* @property {"solid" | "outlined"} fill 모든 priority에서 선택하는 필수 채움 스타일.
|
|
27
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} priority solid와 outlined 모두에서 필수인 색상.
|
|
28
|
+
* @property {ReactNode} icon 필수 장식용 콘텐츠. icon 영역은 aria-hidden이므로 행동 이름을 대신하지 않는다.
|
|
29
|
+
* @property {string} [aria-label] native 접근 가능한 이름. 표시 라벨과 별도 이름이 필요할 때 제공한다.
|
|
30
|
+
* @property {"button" | "submit" | "reset"} [type="button"] native 버튼 종류. submit과 reset은 소비자가 명시한다.
|
|
31
|
+
* @property {boolean} [disabled] native 클릭·키보드 실행을 차단한다.
|
|
32
|
+
* @property {string} [className] 최상위 native 버튼에 병합하는 추가 클래스.
|
|
33
|
+
* @property {React.CSSProperties} [style] 최상위 native 버튼에 전달하는 inline style.
|
|
34
|
+
* @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [onClick] native 클릭 handler. Enter·Space의 native 버튼 실행에서도 호출한다.
|
|
35
|
+
* @desc FabStyleOptions와 children을 제외한 native button 입력을 조합한다. size·fill·priority·icon은 필수이며 나머지 native button 이벤트와 aria attribute를 유지한다. ref는 각 컴포넌트의 forwardRef로 native 버튼에 연결한다. viewport 배치는 소비자의 책임이다.
|
|
36
|
+
* @see FabStyleOptions
|
|
37
|
+
*/
|
|
38
|
+
export type FabProps = Omit<ComponentPropsWithoutRef<"button">, "children"> &
|
|
39
|
+
FabStyleOptions & {
|
|
40
|
+
/**
|
|
41
|
+
* 필수 크기. 허용 값: "small" | "medium" | "large".
|
|
42
|
+
* 높이는 각각 40/48/56px, icon 영역은 16/20/24px다.
|
|
43
|
+
*/
|
|
44
|
+
size: FabSize;
|
|
45
|
+
/**
|
|
46
|
+
* 필수 ReactNode 영역. 아이콘 외에도 비인터랙티브 콘텐츠를 받을 수 있다.
|
|
47
|
+
* 내부 콘텐츠는 aria-hidden으로 처리하므로 행동 이름은 버튼 라벨로 제공한다.
|
|
48
|
+
*/
|
|
49
|
+
icon: ReactNode;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Fab Props; 아이콘 전용 액션
|
|
54
|
+
* @property {"small" | "medium" | "large"} size 필수 크기. small/medium/large의 높이는 40/48/56px, icon 영역은 16/20/24px다.
|
|
55
|
+
* @property {"solid" | "outlined"} fill 모든 priority에서 선택하는 필수 채움 스타일.
|
|
56
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} priority solid와 outlined 모두에서 필수인 색상.
|
|
57
|
+
* @property {ReactNode} icon 필수 장식용 콘텐츠. icon 영역은 aria-hidden이므로 행동 이름을 대신하지 않는다.
|
|
58
|
+
* @property {string} aria-label 필수 행동 이름. icon 콘텐츠는 접근 가능한 이름에서 제외된다.
|
|
59
|
+
* @property {"button" | "submit" | "reset"} [type="button"] native 버튼 종류. submit과 reset은 소비자가 명시한다.
|
|
60
|
+
* @property {boolean} [disabled] native 클릭·키보드 실행을 차단한다.
|
|
61
|
+
* @property {string} [className] 최상위 native 버튼에 병합하는 추가 클래스.
|
|
62
|
+
* @property {React.CSSProperties} [style] 최상위 native 버튼에 전달하는 inline style.
|
|
63
|
+
* @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [onClick] native 클릭 handler. Enter·Space의 native 버튼 실행에서도 호출한다.
|
|
64
|
+
* @desc FabProps에 필수 aria-label을 추가한 Fab.Button과 호환 이름 Fab.Default의 계약이다. children을 받지 않으며 icon은 장식용으로 처리한다. 다른 native button 입력과 컴포넌트의 DOM ref를 유지한다.
|
|
65
|
+
* @see FabProps
|
|
66
|
+
*/
|
|
67
|
+
export type FabDefaultProps = FabProps & {
|
|
68
|
+
/**
|
|
69
|
+
* 아이콘이 실행하는 행동을 설명하는 필수 접근 가능한 이름.
|
|
70
|
+
*/
|
|
71
|
+
"aria-label": string;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Fab Props; 아이콘과 라벨을 나란히 표시하는 확장형 액션
|
|
76
|
+
* @property {"small" | "medium" | "large"} size 필수 크기. small/medium/large의 높이는 40/48/56px, icon 영역은 16/20/24px다.
|
|
77
|
+
* @property {"solid" | "outlined"} fill 모든 priority에서 선택하는 필수 채움 스타일.
|
|
78
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} priority solid와 outlined 모두에서 필수인 색상.
|
|
79
|
+
* @property {ReactNode} icon 필수 장식용 콘텐츠. icon 영역은 aria-hidden이므로 행동 이름을 대신하지 않는다.
|
|
80
|
+
* @property {string} [aria-label] native 접근 가능한 이름. 표시 라벨과 별도 이름이 필요할 때 제공한다.
|
|
81
|
+
* @property {"button" | "submit" | "reset"} [type="button"] native 버튼 종류. submit과 reset은 소비자가 명시한다.
|
|
82
|
+
* @property {boolean} [disabled] native 클릭·키보드 실행을 차단한다.
|
|
83
|
+
* @property {string} [className] 최상위 native 버튼에 병합하는 추가 클래스.
|
|
84
|
+
* @property {React.CSSProperties} [style] 최상위 native 버튼에 전달하는 inline style.
|
|
85
|
+
* @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [onClick] native 클릭 handler. Enter·Space의 native 버튼 실행에서도 호출한다.
|
|
86
|
+
* @property {ReactNode} children 필수 행동 라벨. 문자열·숫자는 Fab.Label로 감싸고 다른 ReactNode는 그대로 표시한다.
|
|
87
|
+
* @desc FabProps에 필수 children을 추가한 Fab.Expand와 호환 이름 Fab.Extended의 계약이다. icon과 행동 라벨을 나란히 표시하며 다른 native button 입력과 컴포넌트의 DOM ref를 유지한다. 액션 목록의 열림을 담당하지 않는다.
|
|
88
|
+
* @see FabProps
|
|
89
|
+
*/
|
|
90
|
+
export type FabExtendedProps = FabProps & {
|
|
91
|
+
/**
|
|
92
|
+
* 필수 행동 라벨. 문자열·숫자는 Fab.Label로 감싸고 복합 JSX는 그대로 표시한다.
|
|
93
|
+
* 복합 JSX에도 접근 가능한 이름과 필요한 라벨 스타일을 제공한다.
|
|
94
|
+
*/
|
|
95
|
+
children: ReactNode;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Fab Props; 내부 공통 마크업 입력
|
|
100
|
+
* @property {"small" | "medium" | "large"} size 필수 크기. small/medium/large의 높이는 40/48/56px, icon 영역은 16/20/24px다.
|
|
101
|
+
* @property {"solid" | "outlined"} fill 모든 priority에서 선택하는 필수 채움 스타일.
|
|
102
|
+
* @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} priority solid와 outlined 모두에서 필수인 색상.
|
|
103
|
+
* @property {ReactNode} icon 필수 장식용 콘텐츠. icon 영역은 aria-hidden이므로 행동 이름을 대신하지 않는다.
|
|
104
|
+
* @property {string} [aria-label] native 접근 가능한 이름. 표시 라벨과 별도 이름이 필요할 때 제공한다.
|
|
105
|
+
* @property {"button" | "submit" | "reset"} [type="button"] native 버튼 종류. submit과 reset은 소비자가 명시한다.
|
|
106
|
+
* @property {boolean} [disabled] native 클릭·키보드 실행을 차단한다.
|
|
107
|
+
* @property {string} [className] 최상위 native 버튼에 병합하는 추가 클래스.
|
|
108
|
+
* @property {React.CSSProperties} [style] 최상위 native 버튼에 전달하는 inline style.
|
|
109
|
+
* @property {(event: React.MouseEvent<HTMLButtonElement>) => void} [onClick] native 클릭 handler. Enter·Space의 native 버튼 실행에서도 호출한다.
|
|
110
|
+
* @property {ReactNode} [children] extended가 true일 때 표시하는 행동 라벨.
|
|
111
|
+
* @property {boolean} [extended=false] true이면 라벨과 자연 너비 규격을 적용한다. false이면 원형 icon 버튼 규격을 적용한다.
|
|
112
|
+
* @desc FabProps를 상속한 내부 마크업 계약이다. Fab.Button/Fab.Default는 extended=false, Fab.Expand/Fab.Extended는 extended=true로 같은 native button을 사용한다. 다른 native button 입력과 컴포넌트의 DOM ref를 유지한다.
|
|
113
|
+
* @see FabProps
|
|
114
|
+
*/
|
|
115
|
+
export type FabButtonProps = FabProps & {
|
|
116
|
+
/**
|
|
117
|
+
* 확장형에서 사용하는 라벨.
|
|
118
|
+
*/
|
|
119
|
+
children?: ReactNode;
|
|
120
|
+
/**
|
|
121
|
+
* 기본값 false. true이면 라벨과 자연 너비 규격을, false이면 원형 아이콘 규격을 적용한다.
|
|
122
|
+
*/
|
|
123
|
+
extended?: boolean;
|
|
124
|
+
};
|