@fluentui/react-tabs 9.8.2 → 9.9.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/CHANGELOG.md +21 -2
- package/lib/components/Tab/useTab.js.map +1 -1
- package/lib/components/Tab/useTabAnimatedIndicator.styles.raw.js +124 -0
- package/lib/components/Tab/useTabAnimatedIndicator.styles.raw.js.map +1 -0
- package/lib/components/Tab/useTabStyles.styles.raw.js +676 -0
- package/lib/components/Tab/useTabStyles.styles.raw.js.map +1 -0
- package/lib/components/TabList/useTabListStyles.styles.raw.js +40 -0
- package/lib/components/TabList/useTabListStyles.styles.raw.js.map +1 -0
- package/lib-commonjs/components/Tab/useTab.js.map +1 -1
- package/lib-commonjs/components/Tab/useTabAnimatedIndicator.styles.raw.js +133 -0
- package/lib-commonjs/components/Tab/useTabAnimatedIndicator.styles.raw.js.map +1 -0
- package/lib-commonjs/components/Tab/useTabStyles.styles.raw.js +672 -0
- package/lib-commonjs/components/Tab/useTabStyles.styles.raw.js.map +1 -0
- package/lib-commonjs/components/TabList/useTabListStyles.styles.raw.js +56 -0
- package/lib-commonjs/components/TabList/useTabListStyles.styles.raw.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,676 @@
|
|
|
1
|
+
import { makeStyles, mergeClasses, shorthands } from '@griffel/react';
|
|
2
|
+
import { createCustomFocusIndicatorStyle } from '@fluentui/react-tabster';
|
|
3
|
+
import { tokens, typographyStyles } from '@fluentui/react-theme';
|
|
4
|
+
import { useTabAnimatedIndicatorStyles_unstable } from './useTabAnimatedIndicator.styles';
|
|
5
|
+
export const tabClassNames = {
|
|
6
|
+
root: 'fui-Tab',
|
|
7
|
+
icon: 'fui-Tab__icon',
|
|
8
|
+
content: 'fui-Tab__content'
|
|
9
|
+
};
|
|
10
|
+
const reservedSpaceClassNames = {
|
|
11
|
+
content: 'fui-Tab__content--reserved-space'
|
|
12
|
+
};
|
|
13
|
+
// These should match the constants defined in @fluentui/react-icons
|
|
14
|
+
// This package avoids taking a dependency on the icons package for only the constants.
|
|
15
|
+
const iconClassNames = {
|
|
16
|
+
filled: 'fui-Icon-filled',
|
|
17
|
+
regular: 'fui-Icon-regular'
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Styles for the root slot
|
|
21
|
+
*/ const useRootStyles = makeStyles({
|
|
22
|
+
root: {
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
display: 'grid',
|
|
25
|
+
flexShrink: 0,
|
|
26
|
+
gridAutoFlow: 'column',
|
|
27
|
+
gridTemplateColumns: 'auto',
|
|
28
|
+
gridTemplateRows: 'auto',
|
|
29
|
+
outlineStyle: 'none',
|
|
30
|
+
position: 'relative'
|
|
31
|
+
},
|
|
32
|
+
button: {
|
|
33
|
+
alignItems: 'center',
|
|
34
|
+
border: 'none',
|
|
35
|
+
borderRadius: tokens.borderRadiusMedium,
|
|
36
|
+
cursor: 'pointer',
|
|
37
|
+
display: 'grid',
|
|
38
|
+
flexShrink: 0,
|
|
39
|
+
gridAutoFlow: 'column',
|
|
40
|
+
gridTemplateColumns: 'auto',
|
|
41
|
+
gridTemplateRows: 'auto',
|
|
42
|
+
fontFamily: tokens.fontFamilyBase,
|
|
43
|
+
lineHeight: tokens.lineHeightBase300,
|
|
44
|
+
outlineStyle: 'none',
|
|
45
|
+
position: 'relative',
|
|
46
|
+
overflow: 'hidden',
|
|
47
|
+
textTransform: 'none'
|
|
48
|
+
},
|
|
49
|
+
horizontal: {
|
|
50
|
+
justifyContent: 'center'
|
|
51
|
+
},
|
|
52
|
+
vertical: {
|
|
53
|
+
justifyContent: 'start'
|
|
54
|
+
},
|
|
55
|
+
smallHorizontal: {
|
|
56
|
+
columnGap: tokens.spacingHorizontalXXS,
|
|
57
|
+
padding: `${tokens.spacingVerticalSNudge} ${tokens.spacingHorizontalSNudge}`
|
|
58
|
+
},
|
|
59
|
+
smallVertical: {
|
|
60
|
+
// horizontal spacing is deliberate. This is the gap between icon and content.
|
|
61
|
+
columnGap: tokens.spacingHorizontalXXS,
|
|
62
|
+
padding: `${tokens.spacingVerticalXXS} ${tokens.spacingHorizontalSNudge}`
|
|
63
|
+
},
|
|
64
|
+
mediumHorizontal: {
|
|
65
|
+
columnGap: tokens.spacingHorizontalSNudge,
|
|
66
|
+
padding: `${tokens.spacingVerticalM} ${tokens.spacingHorizontalMNudge}`
|
|
67
|
+
},
|
|
68
|
+
mediumVertical: {
|
|
69
|
+
// horizontal spacing is deliberate. This is the gap between icon and content.
|
|
70
|
+
columnGap: tokens.spacingHorizontalSNudge,
|
|
71
|
+
padding: `${tokens.spacingVerticalSNudge} ${tokens.spacingHorizontalMNudge}`
|
|
72
|
+
},
|
|
73
|
+
largeHorizontal: {
|
|
74
|
+
columnGap: tokens.spacingHorizontalSNudge,
|
|
75
|
+
padding: `${tokens.spacingVerticalL} ${tokens.spacingHorizontalMNudge}`
|
|
76
|
+
},
|
|
77
|
+
largeVertical: {
|
|
78
|
+
// horizontal spacing is deliberate. This is the gap between icon and content.
|
|
79
|
+
columnGap: tokens.spacingHorizontalSNudge,
|
|
80
|
+
padding: `${tokens.spacingVerticalS} ${tokens.spacingHorizontalMNudge}`
|
|
81
|
+
},
|
|
82
|
+
transparent: {
|
|
83
|
+
backgroundColor: tokens.colorTransparentBackground,
|
|
84
|
+
':enabled:hover': {
|
|
85
|
+
backgroundColor: tokens.colorTransparentBackgroundHover
|
|
86
|
+
},
|
|
87
|
+
':enabled:active': {
|
|
88
|
+
backgroundColor: tokens.colorTransparentBackgroundPressed
|
|
89
|
+
},
|
|
90
|
+
[`& .${tabClassNames.icon}`]: {
|
|
91
|
+
color: tokens.colorNeutralForeground2
|
|
92
|
+
},
|
|
93
|
+
[`:enabled:hover .${tabClassNames.icon}`]: {
|
|
94
|
+
color: tokens.colorNeutralForeground2Hover
|
|
95
|
+
},
|
|
96
|
+
[`:enabled:active .${tabClassNames.icon}`]: {
|
|
97
|
+
color: tokens.colorNeutralForeground2Pressed
|
|
98
|
+
},
|
|
99
|
+
[`& .${tabClassNames.content}`]: {
|
|
100
|
+
color: tokens.colorNeutralForeground2
|
|
101
|
+
},
|
|
102
|
+
[`:enabled:hover .${tabClassNames.content}`]: {
|
|
103
|
+
color: tokens.colorNeutralForeground2Hover
|
|
104
|
+
},
|
|
105
|
+
[`:enabled:active .${tabClassNames.content}`]: {
|
|
106
|
+
color: tokens.colorNeutralForeground2Pressed
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
subtle: {
|
|
110
|
+
backgroundColor: tokens.colorSubtleBackground,
|
|
111
|
+
':enabled:hover': {
|
|
112
|
+
backgroundColor: tokens.colorSubtleBackgroundHover
|
|
113
|
+
},
|
|
114
|
+
':enabled:active': {
|
|
115
|
+
backgroundColor: tokens.colorSubtleBackgroundPressed
|
|
116
|
+
},
|
|
117
|
+
[`& .${tabClassNames.icon}`]: {
|
|
118
|
+
color: tokens.colorNeutralForeground2
|
|
119
|
+
},
|
|
120
|
+
[`:enabled:hover .${tabClassNames.icon}`]: {
|
|
121
|
+
color: tokens.colorNeutralForeground2Hover
|
|
122
|
+
},
|
|
123
|
+
[`:enabled:active .${tabClassNames.icon}`]: {
|
|
124
|
+
color: tokens.colorNeutralForeground2Pressed
|
|
125
|
+
},
|
|
126
|
+
[`& .${tabClassNames.content}`]: {
|
|
127
|
+
color: tokens.colorNeutralForeground2
|
|
128
|
+
},
|
|
129
|
+
[`:enabled:hover .${tabClassNames.content}`]: {
|
|
130
|
+
color: tokens.colorNeutralForeground2Hover
|
|
131
|
+
},
|
|
132
|
+
[`:enabled:active .${tabClassNames.content}`]: {
|
|
133
|
+
color: tokens.colorNeutralForeground2Pressed
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
disabledCursor: {
|
|
137
|
+
cursor: 'not-allowed'
|
|
138
|
+
},
|
|
139
|
+
disabled: {
|
|
140
|
+
backgroundColor: tokens.colorTransparentBackground,
|
|
141
|
+
[`& .${tabClassNames.icon}`]: {
|
|
142
|
+
color: tokens.colorNeutralForegroundDisabled
|
|
143
|
+
},
|
|
144
|
+
[`& .${tabClassNames.content}`]: {
|
|
145
|
+
color: tokens.colorNeutralForegroundDisabled
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
selected: {
|
|
149
|
+
[`& .${tabClassNames.icon}`]: {
|
|
150
|
+
color: tokens.colorCompoundBrandForeground1
|
|
151
|
+
},
|
|
152
|
+
[`:enabled:hover .${tabClassNames.icon}`]: {
|
|
153
|
+
color: tokens.colorCompoundBrandForeground1Hover
|
|
154
|
+
},
|
|
155
|
+
[`:enabled:active .${tabClassNames.icon}`]: {
|
|
156
|
+
color: tokens.colorCompoundBrandForeground1Pressed
|
|
157
|
+
},
|
|
158
|
+
[`& .${tabClassNames.content}`]: {
|
|
159
|
+
color: tokens.colorNeutralForeground1
|
|
160
|
+
},
|
|
161
|
+
[`:enabled:hover .${tabClassNames.content}`]: {
|
|
162
|
+
color: tokens.colorNeutralForeground1Hover
|
|
163
|
+
},
|
|
164
|
+
[`:enabled:active .${tabClassNames.content}`]: {
|
|
165
|
+
color: tokens.colorNeutralForeground1Pressed
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
const useCircularAppearanceStyles = makeStyles({
|
|
170
|
+
base: {
|
|
171
|
+
borderRadius: tokens.borderRadiusCircular,
|
|
172
|
+
border: `solid ${tokens.strokeWidthThin} ${tokens.colorTransparentStroke}`,
|
|
173
|
+
[`& .${tabClassNames.icon}`]: {
|
|
174
|
+
color: 'inherit'
|
|
175
|
+
},
|
|
176
|
+
[`& .${tabClassNames.content}`]: {
|
|
177
|
+
color: 'inherit'
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
medium: {
|
|
181
|
+
paddingBlock: `${tokens.spacingVerticalSNudge}`
|
|
182
|
+
},
|
|
183
|
+
subtle: {
|
|
184
|
+
backgroundColor: tokens.colorSubtleBackground,
|
|
185
|
+
color: tokens.colorNeutralForeground2,
|
|
186
|
+
':enabled:hover': {
|
|
187
|
+
backgroundColor: tokens.colorSubtleBackgroundHover,
|
|
188
|
+
border: `solid ${tokens.strokeWidthThin} ${tokens.colorNeutralStroke1Hover}`,
|
|
189
|
+
color: tokens.colorNeutralForeground2Hover
|
|
190
|
+
},
|
|
191
|
+
':enabled:active': {
|
|
192
|
+
backgroundColor: tokens.colorSubtleBackgroundPressed,
|
|
193
|
+
border: `solid ${tokens.strokeWidthThin} ${tokens.colorNeutralStroke1Pressed}`,
|
|
194
|
+
color: tokens.colorNeutralForeground2Pressed
|
|
195
|
+
},
|
|
196
|
+
'@media (forced-colors: active)': {
|
|
197
|
+
border: `solid ${tokens.strokeWidthThin} Canvas`
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
subtleSelected: {
|
|
201
|
+
backgroundColor: tokens.colorBrandBackground2,
|
|
202
|
+
border: `solid ${tokens.strokeWidthThin} ${tokens.colorCompoundBrandStroke}`,
|
|
203
|
+
color: tokens.colorBrandForeground2,
|
|
204
|
+
':enabled:hover': {
|
|
205
|
+
backgroundColor: tokens.colorBrandBackground2Hover,
|
|
206
|
+
border: `solid ${tokens.strokeWidthThin} ${tokens.colorCompoundBrandStrokeHover}`,
|
|
207
|
+
color: tokens.colorBrandForeground2Hover
|
|
208
|
+
},
|
|
209
|
+
':enabled:active': {
|
|
210
|
+
backgroundColor: tokens.colorBrandBackground2Pressed,
|
|
211
|
+
border: `solid ${tokens.strokeWidthThin} ${tokens.colorCompoundBrandStrokePressed}`,
|
|
212
|
+
color: tokens.colorBrandForeground2Pressed
|
|
213
|
+
},
|
|
214
|
+
'@media (forced-colors: active)': {
|
|
215
|
+
border: `solid ${tokens.strokeWidthThin} Highlight`
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
subtleDisabled: {
|
|
219
|
+
backgroundColor: tokens.colorSubtleBackground,
|
|
220
|
+
color: tokens.colorNeutralForegroundDisabled
|
|
221
|
+
},
|
|
222
|
+
subtleDisabledSelected: {
|
|
223
|
+
backgroundColor: tokens.colorNeutralBackgroundDisabled,
|
|
224
|
+
border: `solid ${tokens.strokeWidthThin} ${tokens.colorNeutralStrokeDisabled}`,
|
|
225
|
+
color: tokens.colorNeutralForegroundDisabled
|
|
226
|
+
},
|
|
227
|
+
filled: {
|
|
228
|
+
backgroundColor: tokens.colorNeutralBackground3,
|
|
229
|
+
color: tokens.colorNeutralForeground2,
|
|
230
|
+
':enabled:hover': {
|
|
231
|
+
backgroundColor: tokens.colorNeutralBackground3Hover,
|
|
232
|
+
color: tokens.colorNeutralForeground2Hover
|
|
233
|
+
},
|
|
234
|
+
':enabled:active': {
|
|
235
|
+
backgroundColor: tokens.colorNeutralBackground3Pressed,
|
|
236
|
+
color: tokens.colorNeutralForeground2Pressed
|
|
237
|
+
},
|
|
238
|
+
'@media (forced-colors: active)': {
|
|
239
|
+
':enabled:hover': {
|
|
240
|
+
backgroundColor: 'Highlight',
|
|
241
|
+
forcedColorAdjust: 'none',
|
|
242
|
+
[`& .${tabClassNames.content}`]: {
|
|
243
|
+
color: 'HighlightText'
|
|
244
|
+
},
|
|
245
|
+
[`& .${iconClassNames.filled}`]: {
|
|
246
|
+
color: 'HighlightText'
|
|
247
|
+
},
|
|
248
|
+
[`& .${iconClassNames.regular}`]: {
|
|
249
|
+
color: 'HighlightText'
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
filledSelected: {
|
|
255
|
+
backgroundColor: tokens.colorBrandBackground,
|
|
256
|
+
color: tokens.colorNeutralForegroundOnBrand,
|
|
257
|
+
':enabled:hover': {
|
|
258
|
+
backgroundColor: tokens.colorBrandBackgroundHover,
|
|
259
|
+
color: tokens.colorNeutralForegroundOnBrand
|
|
260
|
+
},
|
|
261
|
+
':enabled:active': {
|
|
262
|
+
backgroundColor: tokens.colorBrandBackgroundPressed,
|
|
263
|
+
color: tokens.colorNeutralForegroundOnBrand
|
|
264
|
+
},
|
|
265
|
+
'@media (forced-colors: active)': {
|
|
266
|
+
':enabled': {
|
|
267
|
+
backgroundColor: 'ButtonText',
|
|
268
|
+
[`& .${tabClassNames.content}`]: {
|
|
269
|
+
color: 'ButtonFace',
|
|
270
|
+
forcedColorAdjust: 'none'
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
[`:enabled .${tabClassNames.icon}`]: {
|
|
274
|
+
color: 'ButtonFace'
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
filledDisabled: {
|
|
279
|
+
backgroundColor: tokens.colorNeutralBackgroundDisabled,
|
|
280
|
+
color: tokens.colorNeutralForegroundDisabled
|
|
281
|
+
},
|
|
282
|
+
filledDisabledSelected: {
|
|
283
|
+
backgroundColor: tokens.colorNeutralBackgroundDisabled,
|
|
284
|
+
border: `solid ${tokens.strokeWidthThin} ${tokens.colorNeutralStrokeDisabled}`,
|
|
285
|
+
color: tokens.colorNeutralForegroundDisabled
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
/**
|
|
289
|
+
* Focus styles for the root slot
|
|
290
|
+
*/ const useFocusStyles = makeStyles({
|
|
291
|
+
// Tab creates a custom focus indicator because the default focus indicator
|
|
292
|
+
// is applied using an ::after pseudo-element on the root. Since the selection
|
|
293
|
+
// indicator uses an ::after pseudo-element on the root, there is a conflict.
|
|
294
|
+
base: createCustomFocusIndicatorStyle({
|
|
295
|
+
...shorthands.borderColor('transparent'),
|
|
296
|
+
outlineWidth: tokens.strokeWidthThick,
|
|
297
|
+
outlineColor: 'transparent',
|
|
298
|
+
outlineStyle: 'solid',
|
|
299
|
+
boxShadow: `
|
|
300
|
+
${tokens.shadow4},
|
|
301
|
+
0 0 0 ${tokens.strokeWidthThick} ${tokens.colorStrokeFocus2}
|
|
302
|
+
`,
|
|
303
|
+
zIndex: 1
|
|
304
|
+
}, {
|
|
305
|
+
enableOutline: true
|
|
306
|
+
}),
|
|
307
|
+
circular: createCustomFocusIndicatorStyle({
|
|
308
|
+
...shorthands.borderColor('transparent'),
|
|
309
|
+
outlineWidth: tokens.strokeWidthThick,
|
|
310
|
+
outlineColor: 'transparent',
|
|
311
|
+
outlineStyle: 'solid',
|
|
312
|
+
boxShadow: `
|
|
313
|
+
${tokens.shadow4},
|
|
314
|
+
0 0 0 ${tokens.strokeWidthThick} ${tokens.colorStrokeFocus2},
|
|
315
|
+
0 0 0 ${tokens.strokeWidthThin} ${tokens.colorNeutralStrokeOnBrand} inset
|
|
316
|
+
`,
|
|
317
|
+
zIndex: 1
|
|
318
|
+
}, {
|
|
319
|
+
enableOutline: true
|
|
320
|
+
})
|
|
321
|
+
});
|
|
322
|
+
/** Indicator styles for when pending selection */ const usePendingIndicatorStyles = makeStyles({
|
|
323
|
+
base: {
|
|
324
|
+
':hover::before': {
|
|
325
|
+
backgroundColor: tokens.colorNeutralStroke1Hover,
|
|
326
|
+
borderRadius: tokens.borderRadiusCircular,
|
|
327
|
+
content: '""',
|
|
328
|
+
position: 'absolute'
|
|
329
|
+
},
|
|
330
|
+
':active::before': {
|
|
331
|
+
backgroundColor: tokens.colorNeutralStroke1Pressed,
|
|
332
|
+
borderRadius: tokens.borderRadiusCircular,
|
|
333
|
+
content: '""',
|
|
334
|
+
position: 'absolute'
|
|
335
|
+
},
|
|
336
|
+
'@media (forced-colors: active)': {
|
|
337
|
+
':hover::before': {
|
|
338
|
+
backgroundColor: 'Highlight'
|
|
339
|
+
},
|
|
340
|
+
':active::before': {
|
|
341
|
+
backgroundColor: 'Highlight'
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
disabled: {
|
|
346
|
+
':hover::before': {
|
|
347
|
+
backgroundColor: tokens.colorTransparentStroke
|
|
348
|
+
},
|
|
349
|
+
':active::before': {
|
|
350
|
+
backgroundColor: tokens.colorTransparentStroke
|
|
351
|
+
},
|
|
352
|
+
'@media (forced-colors: active)': {
|
|
353
|
+
':hover::before': {
|
|
354
|
+
backgroundColor: 'transparent'
|
|
355
|
+
},
|
|
356
|
+
':active::before': {
|
|
357
|
+
backgroundColor: 'transparent'
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
},
|
|
361
|
+
smallHorizontal: {
|
|
362
|
+
'::before': {
|
|
363
|
+
bottom: 0,
|
|
364
|
+
height: tokens.strokeWidthThick,
|
|
365
|
+
left: tokens.spacingHorizontalSNudge,
|
|
366
|
+
right: tokens.spacingHorizontalSNudge
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
smallVertical: {
|
|
370
|
+
'::before': {
|
|
371
|
+
bottom: tokens.spacingVerticalXS,
|
|
372
|
+
left: 0,
|
|
373
|
+
top: tokens.spacingVerticalXS,
|
|
374
|
+
width: tokens.strokeWidthThicker
|
|
375
|
+
}
|
|
376
|
+
},
|
|
377
|
+
mediumHorizontal: {
|
|
378
|
+
'::before': {
|
|
379
|
+
bottom: 0,
|
|
380
|
+
height: tokens.strokeWidthThicker,
|
|
381
|
+
left: tokens.spacingHorizontalM,
|
|
382
|
+
right: tokens.spacingHorizontalM
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
mediumVertical: {
|
|
386
|
+
'::before': {
|
|
387
|
+
bottom: tokens.spacingVerticalS,
|
|
388
|
+
left: 0,
|
|
389
|
+
top: tokens.spacingVerticalS,
|
|
390
|
+
width: tokens.strokeWidthThicker
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
largeHorizontal: {
|
|
394
|
+
'::before': {
|
|
395
|
+
bottom: 0,
|
|
396
|
+
height: tokens.strokeWidthThicker,
|
|
397
|
+
left: tokens.spacingHorizontalM,
|
|
398
|
+
right: tokens.spacingHorizontalM
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
largeVertical: {
|
|
402
|
+
'::before': {
|
|
403
|
+
bottom: tokens.spacingVerticalMNudge,
|
|
404
|
+
left: 0,
|
|
405
|
+
top: tokens.spacingVerticalMNudge,
|
|
406
|
+
width: tokens.strokeWidthThicker
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
const useActiveIndicatorStyles = makeStyles({
|
|
411
|
+
base: {
|
|
412
|
+
'::after': {
|
|
413
|
+
backgroundColor: tokens.colorTransparentStroke,
|
|
414
|
+
borderRadius: tokens.borderRadiusCircular,
|
|
415
|
+
content: '""',
|
|
416
|
+
position: 'absolute'
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
selected: {
|
|
420
|
+
'::after': {
|
|
421
|
+
backgroundColor: tokens.colorCompoundBrandStroke
|
|
422
|
+
},
|
|
423
|
+
':enabled:hover::after': {
|
|
424
|
+
backgroundColor: tokens.colorCompoundBrandStrokeHover
|
|
425
|
+
},
|
|
426
|
+
':enabled:active::after': {
|
|
427
|
+
backgroundColor: tokens.colorCompoundBrandStrokePressed
|
|
428
|
+
},
|
|
429
|
+
'@media (forced-colors: active)': {
|
|
430
|
+
'::after': {
|
|
431
|
+
backgroundColor: 'ButtonText'
|
|
432
|
+
},
|
|
433
|
+
':enabled:hover::after': {
|
|
434
|
+
backgroundColor: 'ButtonText'
|
|
435
|
+
},
|
|
436
|
+
':enabled:active::after': {
|
|
437
|
+
backgroundColor: 'ButtonText'
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
disabled: {
|
|
442
|
+
'::after': {
|
|
443
|
+
backgroundColor: tokens.colorNeutralForegroundDisabled
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
smallHorizontal: {
|
|
447
|
+
'::after': {
|
|
448
|
+
bottom: 0,
|
|
449
|
+
height: tokens.strokeWidthThick,
|
|
450
|
+
left: tokens.spacingHorizontalSNudge,
|
|
451
|
+
right: tokens.spacingHorizontalSNudge
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
smallVertical: {
|
|
455
|
+
'::after': {
|
|
456
|
+
bottom: tokens.spacingVerticalXS,
|
|
457
|
+
left: '0',
|
|
458
|
+
top: tokens.spacingVerticalXS,
|
|
459
|
+
width: tokens.strokeWidthThicker
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
mediumHorizontal: {
|
|
463
|
+
'::after': {
|
|
464
|
+
bottom: '0',
|
|
465
|
+
height: tokens.strokeWidthThicker,
|
|
466
|
+
left: tokens.spacingHorizontalM,
|
|
467
|
+
right: tokens.spacingHorizontalM
|
|
468
|
+
}
|
|
469
|
+
},
|
|
470
|
+
mediumVertical: {
|
|
471
|
+
'::after': {
|
|
472
|
+
bottom: tokens.spacingVerticalS,
|
|
473
|
+
left: 0,
|
|
474
|
+
top: tokens.spacingVerticalS,
|
|
475
|
+
width: tokens.strokeWidthThicker
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
largeHorizontal: {
|
|
479
|
+
'::after': {
|
|
480
|
+
bottom: 0,
|
|
481
|
+
height: tokens.strokeWidthThicker,
|
|
482
|
+
left: tokens.spacingHorizontalM,
|
|
483
|
+
right: tokens.spacingHorizontalM
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
largeVertical: {
|
|
487
|
+
'::after': {
|
|
488
|
+
bottom: tokens.spacingVerticalMNudge,
|
|
489
|
+
left: 0,
|
|
490
|
+
top: tokens.spacingVerticalMNudge,
|
|
491
|
+
width: tokens.strokeWidthThicker
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
/**
|
|
496
|
+
* Styles for the icon slot.
|
|
497
|
+
*/ const useIconStyles = makeStyles({
|
|
498
|
+
base: {
|
|
499
|
+
gridColumnStart: 1,
|
|
500
|
+
gridRowStart: 1,
|
|
501
|
+
alignItems: 'center',
|
|
502
|
+
display: 'inline-flex',
|
|
503
|
+
justifyContent: 'center',
|
|
504
|
+
overflow: 'hidden',
|
|
505
|
+
[`& .${iconClassNames.filled}`]: {
|
|
506
|
+
display: 'none'
|
|
507
|
+
},
|
|
508
|
+
[`& .${iconClassNames.regular}`]: {
|
|
509
|
+
display: 'inline'
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
// per design, the small and medium font sizes are the same.
|
|
513
|
+
// the size prop only affects spacing.
|
|
514
|
+
small: {
|
|
515
|
+
fontSize: '20px',
|
|
516
|
+
height: '20px',
|
|
517
|
+
width: '20px'
|
|
518
|
+
},
|
|
519
|
+
medium: {
|
|
520
|
+
fontSize: '20px',
|
|
521
|
+
height: '20px',
|
|
522
|
+
width: '20px'
|
|
523
|
+
},
|
|
524
|
+
large: {
|
|
525
|
+
fontSize: '24px',
|
|
526
|
+
height: '24px',
|
|
527
|
+
width: '24px'
|
|
528
|
+
},
|
|
529
|
+
selected: {
|
|
530
|
+
[`& .${iconClassNames.filled}`]: {
|
|
531
|
+
display: 'inline'
|
|
532
|
+
},
|
|
533
|
+
[`& .${iconClassNames.regular}`]: {
|
|
534
|
+
display: 'none'
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
/**
|
|
539
|
+
* Styles for the content slot (children)
|
|
540
|
+
*/ const useContentStyles = makeStyles({
|
|
541
|
+
base: {
|
|
542
|
+
...typographyStyles.body1,
|
|
543
|
+
overflow: 'hidden',
|
|
544
|
+
// content padding is the same for medium & small, horizontal & vertical
|
|
545
|
+
padding: `${tokens.spacingVerticalNone} ${tokens.spacingHorizontalXXS}`
|
|
546
|
+
},
|
|
547
|
+
selected: {
|
|
548
|
+
...typographyStyles.body1Strong
|
|
549
|
+
},
|
|
550
|
+
large: {
|
|
551
|
+
...typographyStyles.body2
|
|
552
|
+
},
|
|
553
|
+
largeSelected: {
|
|
554
|
+
...typographyStyles.subtitle2
|
|
555
|
+
},
|
|
556
|
+
noIconBefore: {
|
|
557
|
+
gridColumnStart: 1,
|
|
558
|
+
gridRowStart: 1
|
|
559
|
+
},
|
|
560
|
+
iconBefore: {
|
|
561
|
+
gridColumnStart: 2,
|
|
562
|
+
gridRowStart: 1
|
|
563
|
+
},
|
|
564
|
+
placeholder: {
|
|
565
|
+
visibility: 'hidden'
|
|
566
|
+
}
|
|
567
|
+
});
|
|
568
|
+
/**
|
|
569
|
+
* Apply styling to the Tab slots based on the state
|
|
570
|
+
*/ export const useTabStyles_unstable = (state)=>{
|
|
571
|
+
'use no memo';
|
|
572
|
+
useTabIndicatorStyles_unstable(state);
|
|
573
|
+
useTabButtonStyles_unstable(state, state.root);
|
|
574
|
+
useTabContentStyles_unstable(state);
|
|
575
|
+
return state;
|
|
576
|
+
};
|
|
577
|
+
/**
|
|
578
|
+
* Applies styles for the Tab indicator based on its current state.
|
|
579
|
+
*
|
|
580
|
+
* This hook is typically used internally by `useTabStyles_unstable`. You should
|
|
581
|
+
* only use it directly if you're creating a custom `Tab` component.
|
|
582
|
+
*
|
|
583
|
+
* @param state - The `Tab` component's current state
|
|
584
|
+
* @returns The state object with updated button styles
|
|
585
|
+
*/ export const useTabIndicatorStyles_unstable = (state)=>{
|
|
586
|
+
'use no memo';
|
|
587
|
+
const rootStyles = useRootStyles();
|
|
588
|
+
const pendingIndicatorStyles = usePendingIndicatorStyles();
|
|
589
|
+
const activeIndicatorStyles = useActiveIndicatorStyles();
|
|
590
|
+
const { appearance, disabled, selected, size, vertical } = state;
|
|
591
|
+
const classes = [
|
|
592
|
+
tabClassNames.root,
|
|
593
|
+
rootStyles.root
|
|
594
|
+
];
|
|
595
|
+
if (appearance !== 'subtle-circular' && appearance !== 'filled-circular') {
|
|
596
|
+
classes.push(// pending indicator (before pseudo element)
|
|
597
|
+
pendingIndicatorStyles.base, size === 'small' && (vertical ? pendingIndicatorStyles.smallVertical : pendingIndicatorStyles.smallHorizontal), size === 'medium' && (vertical ? pendingIndicatorStyles.mediumVertical : pendingIndicatorStyles.mediumHorizontal), size === 'large' && (vertical ? pendingIndicatorStyles.largeVertical : pendingIndicatorStyles.largeHorizontal), disabled && pendingIndicatorStyles.disabled, // active indicator (after pseudo element)
|
|
598
|
+
selected && activeIndicatorStyles.base, selected && !disabled && activeIndicatorStyles.selected, selected && size === 'small' && (vertical ? activeIndicatorStyles.smallVertical : activeIndicatorStyles.smallHorizontal), selected && size === 'medium' && (vertical ? activeIndicatorStyles.mediumVertical : activeIndicatorStyles.mediumHorizontal), selected && size === 'large' && (vertical ? activeIndicatorStyles.largeVertical : activeIndicatorStyles.largeHorizontal), selected && disabled && activeIndicatorStyles.disabled);
|
|
599
|
+
}
|
|
600
|
+
state.root.className = mergeClasses(...classes, state.root.className);
|
|
601
|
+
useTabAnimatedIndicatorStyles_unstable(state);
|
|
602
|
+
return state;
|
|
603
|
+
};
|
|
604
|
+
/**
|
|
605
|
+
* Applies styles to the Tab button slot based on its current state.
|
|
606
|
+
*
|
|
607
|
+
* This hook is typically used internally by `useTabStyles_unstable`. You should
|
|
608
|
+
* only use it directly if you're creating a custom `Tab` component.
|
|
609
|
+
*
|
|
610
|
+
* @param state - The Tab component's current state
|
|
611
|
+
* @param slot - The button slot of the Tab component
|
|
612
|
+
* @returns The state object with updated button styles
|
|
613
|
+
*/ export const useTabButtonStyles_unstable = (state, slot)=>{
|
|
614
|
+
'use no memo';
|
|
615
|
+
const rootStyles = useRootStyles();
|
|
616
|
+
const focusStyles = useFocusStyles();
|
|
617
|
+
const circularStyles = useCircularAppearanceStyles();
|
|
618
|
+
const { appearance, disabled, selected, size, vertical } = state;
|
|
619
|
+
const isSubtleCircular = appearance === 'subtle-circular';
|
|
620
|
+
const isFilledCircular = appearance === 'filled-circular';
|
|
621
|
+
const isCircular = isSubtleCircular || isFilledCircular;
|
|
622
|
+
const circularAppearance = [
|
|
623
|
+
circularStyles.base,
|
|
624
|
+
focusStyles.circular,
|
|
625
|
+
// sizes
|
|
626
|
+
size === 'medium' && circularStyles.medium,
|
|
627
|
+
// subtle-circular appearance
|
|
628
|
+
isSubtleCircular && circularStyles.subtle,
|
|
629
|
+
selected && isSubtleCircular && circularStyles.subtleSelected,
|
|
630
|
+
disabled && isSubtleCircular && circularStyles.subtleDisabled,
|
|
631
|
+
selected && disabled && isSubtleCircular && circularStyles.subtleDisabledSelected,
|
|
632
|
+
// filled-circular appearance
|
|
633
|
+
isFilledCircular && circularStyles.filled,
|
|
634
|
+
selected && isFilledCircular && circularStyles.filledSelected,
|
|
635
|
+
disabled && isFilledCircular && circularStyles.filledDisabled,
|
|
636
|
+
selected && disabled && isFilledCircular && circularStyles.filledDisabledSelected
|
|
637
|
+
];
|
|
638
|
+
const regularAppearance = [
|
|
639
|
+
focusStyles.base,
|
|
640
|
+
!disabled && appearance === 'subtle' && rootStyles.subtle,
|
|
641
|
+
!disabled && appearance === 'transparent' && rootStyles.transparent,
|
|
642
|
+
!disabled && selected && rootStyles.selected,
|
|
643
|
+
disabled && rootStyles.disabled
|
|
644
|
+
];
|
|
645
|
+
slot.className = mergeClasses(rootStyles.button, // orientation
|
|
646
|
+
vertical ? rootStyles.vertical : rootStyles.horizontal, // size
|
|
647
|
+
size === 'small' && (vertical ? rootStyles.smallVertical : rootStyles.smallHorizontal), size === 'medium' && (vertical ? rootStyles.mediumVertical : rootStyles.mediumHorizontal), size === 'large' && (vertical ? rootStyles.largeVertical : rootStyles.largeHorizontal), ...isCircular ? circularAppearance : regularAppearance, disabled && rootStyles.disabledCursor, slot.className);
|
|
648
|
+
return state;
|
|
649
|
+
};
|
|
650
|
+
/**
|
|
651
|
+
* Applies styles to the Tab content slot based on its current state.
|
|
652
|
+
*
|
|
653
|
+
* This hook is typically used internally by `useTabStyles_unstable`. You should
|
|
654
|
+
* only use it directly if you're creating a custom `Tab` component.
|
|
655
|
+
*
|
|
656
|
+
* @param state - The Tab component's current state
|
|
657
|
+
* @returns The state object with updated content styles
|
|
658
|
+
*/ export const useTabContentStyles_unstable = (state)=>{
|
|
659
|
+
'use no memo';
|
|
660
|
+
const iconStyles = useIconStyles();
|
|
661
|
+
const contentStyles = useContentStyles();
|
|
662
|
+
const { selected, size } = state;
|
|
663
|
+
if (state.icon) {
|
|
664
|
+
state.icon.className = mergeClasses(tabClassNames.icon, iconStyles.base, iconStyles[size], selected && iconStyles.selected, state.icon.className);
|
|
665
|
+
}
|
|
666
|
+
// This needs to be before state.content.className is updated
|
|
667
|
+
if (state.contentReservedSpace) {
|
|
668
|
+
state.contentReservedSpace.className = mergeClasses(reservedSpaceClassNames.content, contentStyles.base, size === 'large' ? contentStyles.largeSelected : contentStyles.selected, state.icon ? contentStyles.iconBefore : contentStyles.noIconBefore, contentStyles.placeholder, state.content.className);
|
|
669
|
+
// FIXME: this is a deprecated API
|
|
670
|
+
// should be removed in the next major version
|
|
671
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
672
|
+
state.contentReservedSpaceClassName = state.contentReservedSpace.className;
|
|
673
|
+
}
|
|
674
|
+
state.content.className = mergeClasses(tabClassNames.content, contentStyles.base, size === 'large' && contentStyles.large, selected && (size === 'large' ? contentStyles.largeSelected : contentStyles.selected), state.icon ? contentStyles.iconBefore : contentStyles.noIconBefore, state.content.className);
|
|
675
|
+
return state;
|
|
676
|
+
};
|