@@ -22,8 +22,8 @@ import {FormContext, useFormProps} from './Form';
22
22
import { ReactNode , useRef , forwardRef , RefObject , useContext } from 'react' ;
23
23
import { FocusableRef , LabelPosition , InputDOMProps , Alignment } from '@react-types/shared' ;
24
24
import { useFocusableRef } from '@react-spectrum/utils' ;
25
- import { style } from '../style/spectrum-theme' with { type : 'macro' } ;
26
- import { StyleProps , focusRing , field , getAllowedOverrides } from './style-utils' with { type : 'macro' } ;
25
+ import { style , size } from '../style/spectrum-theme' with { type : 'macro' } ;
26
+ import { StyleProps , focusRing , field , fieldInput , getAllowedOverrides } from './style-utils' with { type : 'macro' } ;
27
27
import { forwardRefType } from './types' ;
28
28
import { useNumberFormatter , useLocale } from '@react-aria/i18n' ;
29
29
import { clamp } from '@react-aria/utils' ;
@@ -38,19 +38,55 @@ export interface SliderBaseProps<T> extends Omit<AriaSliderProps<T>, 'children'>
38
38
labelPosition ?: LabelPosition
39
39
}
40
40
41
- export interface SliderProps < T > extends AriaSliderProps < T > , StyleProps {
41
+ export interface SliderProps < T > extends Omit < AriaSliderProps < T > , 'style' | 'className' | 'orientation' > , StyleProps {
42
+ /**
43
+ * The content to display as the label.
44
+ */
42
45
label ?: ReactNode ,
46
+ /**
47
+ * The label for the Slider's thumb.
48
+ */
43
49
thumbLabel ?: string ,
44
- labelAlign ?: Alignment ,
50
+ /**
51
+ * The size of the Slider.
52
+ *
53
+ * @default 'M'
54
+ */
45
55
size ?: 'S' | 'M' | 'L' | 'XL' ,
56
+ /**
57
+ * The label's horizontal alignment relative to the element it is labeling.
58
+ *
59
+ * @default 'start'
60
+ */
61
+ labelAlign ?: Alignment ,
62
+ /**
63
+ * The label's overall position relative to the element it is labeling.
64
+ *
65
+ * @default 'top'
66
+ */
46
67
labelPosition ?: LabelPosition ,
68
+ /**
69
+ * The offset from which to start the fill.
70
+ */
47
71
fillOffset ?: number ,
72
+ /**
73
+ * Whether the Slider should be displayed with an emphasized style.
74
+ */
48
75
isEmphasized ?: boolean ,
49
- isThick ?: boolean ,
50
- isPrecise ?: boolean
76
+ /**
77
+ * The style of the Slider's track.
78
+ *
79
+ * @default 'thin'
80
+ */
81
+ trackStyle ?: 'thin' | 'thick' , // TODO: add ramp
82
+ /**
83
+ * The style of the Slider's thumb.
84
+ *
85
+ * @default 'default'
86
+ */
87
+ thumbStyle ?: 'default' | 'precise'
51
88
// TODO
52
89
// isEditable?: boolean
53
- // isRamp?: boolean
54
90
}
55
91
56
92
const slider = style ( {
@@ -65,17 +101,6 @@ const slider = style({
65
101
default : 'neutral-subdued' ,
66
102
isDisabled : 'disabled'
67
103
} ,
68
- width : {
69
- default : {
70
- size : {
71
- S : 192 ,
72
- M : 208 ,
73
- L : 224 ,
74
- XL : 240
75
- }
76
- } ,
77
- isInForm : 'auto'
78
- } ,
79
104
columnGap : {
80
105
size : {
81
106
S : 16 ,
@@ -137,9 +162,9 @@ const output = style({
137
162
} ) ;
138
163
139
164
export let track = style ( {
165
+ ...fieldInput ( ) ,
140
166
gridArea : 'track' ,
141
167
position : 'relative' ,
142
- minWidth : 112 , // an arbitrary number, no tokens for minwidth, can adjust if needed
143
168
width : 'full' ,
144
169
height : {
145
170
size : {
@@ -151,13 +176,12 @@ export let track = style({
151
176
}
152
177
} ) ;
153
178
154
-
155
179
export let thumbContainer = style ( {
156
180
size : {
157
181
size : {
158
- S : '[18px]' ,
182
+ S : size ( 18 ) ,
159
183
M : 20 ,
160
- L : '[22px]' ,
184
+ L : size ( 22 ) ,
161
185
XL : 24
162
186
}
163
187
} ,
@@ -169,20 +193,22 @@ export let thumbContainer = style({
169
193
// if precision thumb should have a smaller hit area, then remove this
170
194
export let thumbHitArea = style ( {
171
195
size : {
172
- default : {
173
- size : {
174
- S : '[18px]' ,
175
- M : 20 ,
176
- L : '[22px]' ,
177
- XL : 24
178
- }
179
- } ,
180
- isPrecise : {
181
- size : {
182
- S : 20 ,
183
- M : '[22px]' ,
184
- L : 24 ,
185
- XL : '[26px]'
196
+ thumbStyle : {
197
+ default : {
198
+ size : {
199
+ S : size ( 18 ) ,
200
+ M : 20 ,
201
+ L : size ( 22 ) ,
202
+ XL : 24
203
+ }
204
+ } ,
205
+ precise : {
206
+ size : {
207
+ S : 20 ,
208
+ M : size ( 22 ) ,
209
+ L : 24 ,
210
+ XL : size ( 26 )
211
+ }
186
212
}
187
213
}
188
214
}
@@ -197,40 +223,41 @@ export let thumb = style({
197
223
left : '[50%]' ,
198
224
transform : 'translateY(-50%) translateX(-50%)' ,
199
225
width : {
200
- default : {
201
- size : {
202
- S : '[18px]' ,
203
- M : 20 ,
204
- L : '[22px]' ,
205
- XL : 24
206
- }
207
- } ,
208
- isPrecise : '[6px]'
226
+ thumbStyle : {
227
+ default : {
228
+ size : {
229
+ S : size ( 18 ) ,
230
+ M : 20 ,
231
+ L : size ( 22 ) ,
232
+ XL : 24
233
+ }
234
+ } ,
235
+ precise : size ( 6 )
236
+ }
209
237
} ,
210
238
height : {
211
- default : {
212
- size : {
213
- S : '[18px]' ,
214
- M : 20 ,
215
- L : '[22px]' ,
216
- XL : 24
217
- }
218
- } ,
219
- isPrecise : {
220
- size : {
221
- S : 20 ,
222
- M : '[22px]' ,
223
- L : 24 ,
224
- XL : '[26px]'
239
+ thumbStyle : {
240
+ default : {
241
+ size : {
242
+ S : size ( 18 ) ,
243
+ M : 20 ,
244
+ L : size ( 22 ) ,
245
+ XL : 24
246
+ }
247
+ } ,
248
+ precise : {
249
+ size : {
250
+ S : 20 ,
251
+ M : size ( 22 ) ,
252
+ L : 24 ,
253
+ XL : size ( 26 )
254
+ }
225
255
}
226
256
}
227
257
} ,
228
258
borderRadius : 'full' ,
229
259
borderStyle : 'solid' ,
230
- borderWidth : {
231
- default : '[2px]' ,
232
- isPrecise : '[2px]'
233
- } ,
260
+ borderWidth : '[2px]' ,
234
261
borderColor : {
235
262
default : 'gray-800' ,
236
263
isHovered : 'gray-900' ,
@@ -243,21 +270,29 @@ export let thumb = style({
243
270
backgroundColor : 'gray-25'
244
271
} ) ;
245
272
273
+ const trackStyling = {
274
+ height : {
275
+ trackStyle : {
276
+ thin : 4 ,
277
+ thick : 16
278
+ }
279
+ } ,
280
+ top : '[50%]' ,
281
+ borderRadius : {
282
+ trackStyle : {
283
+ thin : 'lg' ,
284
+ thick : 'sm'
285
+ }
286
+ }
287
+ } as const ;
288
+
246
289
export let upperTrack = style ( {
290
+ ...trackStyling ,
247
291
position : 'absolute' ,
248
292
backgroundColor : {
249
293
default : 'gray-300' ,
250
294
isDisabled : 'disabled'
251
295
} ,
252
- height : {
253
- default : 4 ,
254
- isThick : 16
255
- } ,
256
- top : '[50%]' ,
257
- borderRadius : {
258
- default : 'lg' ,
259
- isThick : 'sm'
260
- } ,
261
296
translateY : '[-50%]' ,
262
297
width : 'full' ,
263
298
boxSizing : 'border-box' ,
@@ -273,6 +308,7 @@ export let upperTrack = style({
273
308
} ) ;
274
309
275
310
export let filledTrack = style ( {
311
+ ...trackStyling ,
276
312
position : 'absolute' ,
277
313
backgroundColor : {
278
314
default : 'gray-700' ,
@@ -283,15 +319,6 @@ export let filledTrack = style({
283
319
isDisabled : 'GrayText'
284
320
}
285
321
} ,
286
- height : {
287
- default : 4 ,
288
- isThick : 16
289
- } ,
290
- top : '[50%]' ,
291
- borderRadius : {
292
- default : 'lg' ,
293
- isThick : 'sm'
294
- } ,
295
322
boxSizing : 'border-box' ,
296
323
borderStyle : 'solid' ,
297
324
borderWidth : '[.5px]' ,
@@ -382,8 +409,8 @@ function Slider<T extends number | number[]>(props: SliderProps<T>, ref: Focusab
382
409
size = 'M' ,
383
410
fillOffset,
384
411
isEmphasized,
385
- isThick ,
386
- isPrecise
412
+ trackStyle = 'thin' ,
413
+ thumbStyle = 'default'
387
414
} = props ;
388
415
let thumbRef = useRef ( null ) ;
389
416
let inputRef = useRef ( null ) ; // TODO: need to pass inputRef to SliderThumb when we release the next version of RAC 1.3.0
@@ -411,16 +438,16 @@ function Slider<T extends number | number[]>(props: SliderProps<T>, ref: Focusab
411
438
412
439
return (
413
440
< >
414
- < div className = { upperTrack ( { isDisabled, isThick } ) } />
415
- < div style = { { width : `${ Math . abs ( fillWidth ! ) * 100 } %` , [ cssDirection ] : `${ offset ! * 100 } %` } } className = { filledTrack ( { isDisabled, isEmphasized, isThick } ) } />
441
+ < div className = { upperTrack ( { isDisabled, trackStyle } ) } />
442
+ < div style = { { width : `${ Math . abs ( fillWidth ! ) * 100 } %` , [ cssDirection ] : `${ offset ! * 100 } %` } } className = { filledTrack ( { isDisabled, isEmphasized, trackStyle } ) } />
416
443
< SliderThumb className = { thumbContainer } index = { 0 } ref = { thumbRef } aria-label = { thumbLabel } style = { ( renderProps ) => pressScale ( thumbRef , { transform : 'translate(-50%, -50%)' } ) ( { ...renderProps , isPressed : renderProps . isDragging } ) } >
417
444
{ ( renderProps ) => (
418
445
< div className = { thumbHitArea ( { size} ) } >
419
446
< div
420
447
className = { thumb ( {
421
448
...renderProps ,
422
449
size,
423
- isPrecise
450
+ thumbStyle
424
451
} ) } />
425
452
</ div >
426
453
) }
0 commit comments