@@ -39,6 +39,19 @@ const Mode = {
39
39
40
40
type Mode = typeof Mode [ keyof typeof Mode ] ;
41
41
42
+ export const SizeVariant = {
43
+ XSmall : 'xsmall' ,
44
+ Small : 'small' ,
45
+ Default : 'default' ,
46
+ Large : 'large' ,
47
+ } as const ;
48
+
49
+ export type SizeVariant = typeof SizeVariant [ keyof typeof SizeVariant ] ;
50
+
51
+ export const BaseFontSize = 14 | 16 ;
52
+
53
+ export type BaseFontSize = typeof BaseFontSize ;
54
+
42
55
interface TextInputProps extends HTMLElementProps < 'input' , HTMLInputElement > {
43
56
/**
44
57
* id associated with the TextInput component.
@@ -107,6 +120,18 @@ interface TextInputProps extends HTMLElementProps<'input', HTMLInputElement> {
107
120
handleValidation ?: ( value : string ) => void ;
108
121
109
122
[ 'aria-labelledby' ] ?: string ;
123
+
124
+ /**
125
+ * determines the font size and padding.
126
+ */
127
+
128
+ sizeVariant ?: SizeVariant ;
129
+
130
+ /**
131
+ * determines the base font size if sizeVariant is set to default.
132
+ */
133
+
134
+ baseFontSize ?: BaseFontSize ;
110
135
}
111
136
112
137
type AriaLabels = 'label' | 'aria-labelledby' ;
@@ -229,16 +254,26 @@ const interactionRingColor: Record<Mode, Record<'valid' | 'error', string>> = {
229
254
} ,
230
255
} ;
231
256
257
+ interface SizeSet {
258
+ inputHeight : number ;
259
+ inputText : number ;
260
+ text : number ;
261
+ lineHeight : number ;
262
+ padding : number ;
263
+ }
264
+
232
265
function getStatefulInputStyles ( {
233
266
state,
234
267
optional,
235
268
mode,
236
269
disabled,
270
+ sizeSet,
237
271
} : {
238
272
state : State ;
239
273
optional : boolean ;
240
274
mode : Mode ;
241
275
disabled : boolean ;
276
+ sizeSet : SizeSet ;
242
277
} ) {
243
278
switch ( state ) {
244
279
case State . Valid : {
@@ -264,13 +299,47 @@ function getStatefulInputStyles({
264
299
265
300
default : {
266
301
return css `
267
- padding-right : ${ optional ? 60 : 12 } px;
302
+ padding-right : ${ optional ? 60 : sizeSet . padding } px;
268
303
border-color : ${ colorSets [ mode ] . defaultBorder } ;
269
304
` ;
270
305
}
271
306
}
272
307
}
273
308
309
+ function getSizeSets ( baseFontSize : BaseFontSize , sizeVariant : SizeVariant ) {
310
+ const sizeSets : Record < SizeVariant , SizeSet > = {
311
+ [ SizeVariant . XSmall ] : {
312
+ inputHeight : 22 ,
313
+ inputText : 12 ,
314
+ text : 14 ,
315
+ lineHeight : 20 ,
316
+ padding : 10 ,
317
+ } ,
318
+ [ SizeVariant . Small ] : {
319
+ inputHeight : 28 ,
320
+ inputText : 14 ,
321
+ text : 14 ,
322
+ lineHeight : 20 ,
323
+ padding : 10 ,
324
+ } ,
325
+ [ SizeVariant . Default ] : {
326
+ inputHeight : 36 ,
327
+ inputText : baseFontSize ,
328
+ text : baseFontSize ,
329
+ lineHeight : 20 ,
330
+ padding : 12 ,
331
+ } ,
332
+ [ SizeVariant . Large ] : {
333
+ inputHeight : 48 ,
334
+ inputText : 18 ,
335
+ text : 18 ,
336
+ lineHeight : 22 ,
337
+ padding : 16 ,
338
+ } ,
339
+ } ;
340
+ return sizeSets [ sizeVariant ] ;
341
+ }
342
+
274
343
/**
275
344
* # TextInput
276
345
*
@@ -291,6 +360,7 @@ function getStatefulInputStyles({
291
360
* @param props.value The current value of the input field. If a value is passed to this prop, component will be controlled by consumer.
292
361
* @param props.className className supplied to the TextInput container.
293
362
* @param props.darkMode determines whether or not the component appears in dark mode.
363
+ * @param props.sizeVariant determines the size of the text and the height of the input.
294
364
*/
295
365
const TextInput : React . ComponentType <
296
366
React . PropsWithRef < AccessibleTextInputProps >
@@ -310,8 +380,10 @@ const TextInput: React.ComponentType<
310
380
value : controlledValue ,
311
381
className,
312
382
darkMode = false ,
383
+ sizeVariant = SizeVariant . Default ,
313
384
'aria-labelledby' : ariaLabelledby ,
314
385
handleValidation,
386
+ baseFontSize = 14 ,
315
387
...rest
316
388
} : AccessibleTextInputProps ,
317
389
forwardRef : React . Ref < HTMLInputElement > ,
@@ -321,6 +393,7 @@ const TextInput: React.ComponentType<
321
393
const [ uncontrolledValue , setValue ] = useState ( '' ) ;
322
394
const value = isControlled ? controlledValue : uncontrolledValue ;
323
395
const id = useIdAllocator ( { prefix : 'textinput' , id : propsId } ) ;
396
+ const sizeSet = getSizeSets ( baseFontSize , sizeVariant ) ;
324
397
325
398
// Validation
326
399
const validation = useValidation < HTMLInputElement > ( handleValidation ) ;
@@ -356,12 +429,27 @@ const TextInput: React.ComponentType<
356
429
return (
357
430
< div className = { cx ( textInputStyle , className ) } >
358
431
{ label && (
359
- < Label darkMode = { darkMode } htmlFor = { id } disabled = { disabled } >
432
+ < Label
433
+ darkMode = { darkMode }
434
+ htmlFor = { id }
435
+ disabled = { disabled }
436
+ className = { cx ( css `
437
+ font-size : ${ sizeSet . text } px;
438
+ ` ) }
439
+ >
360
440
{ label }
361
441
</ Label >
362
442
) }
363
443
{ description && (
364
- < Description darkMode = { darkMode } > { description } </ Description >
444
+ < Description
445
+ darkMode = { darkMode }
446
+ className = { cx ( css `
447
+ font-size : ${ sizeSet . text } px;
448
+ line-height : ${ sizeSet . lineHeight } px;
449
+ ` ) }
450
+ >
451
+ { description }
452
+ </ Description >
365
453
) }
366
454
< div className = { inputContainerStyle } >
367
455
< InteractionRing
@@ -386,6 +474,9 @@ const TextInput: React.ComponentType<
386
474
css `
387
475
color : ${ colorSets [ mode ] . inputColor } ;
388
476
background-color : ${ colorSets [ mode ] . inputBackgroundColor } ;
477
+ font-size : ${ sizeSet . inputText } px;
478
+ height : ${ sizeSet . inputHeight } px;
479
+ padding-left : ${ sizeSet . padding } px;
389
480
390
481
& : focus {
391
482
border : 1px solid ${ colorSets [ mode ] . inputBackgroundColor } ;
@@ -410,7 +501,13 @@ const TextInput: React.ComponentType<
410
501
}
411
502
}
412
503
` ,
413
- getStatefulInputStyles ( { state, optional, mode, disabled } ) ,
504
+ getStatefulInputStyles ( {
505
+ state,
506
+ optional,
507
+ mode,
508
+ disabled,
509
+ sizeSet,
510
+ } ) ,
414
511
) }
415
512
value = { value }
416
513
required = { ! optional }
@@ -462,6 +559,8 @@ const TextInput: React.ComponentType<
462
559
errorMessageStyle ,
463
560
css `
464
561
color : ${ colorSets [ mode ] . errorMessage } ;
562
+ font-size : ${ sizeSet . text } px;
563
+ line-height : ${ sizeSet . lineHeight } px;
465
564
` ,
466
565
) }
467
566
>
@@ -487,6 +586,8 @@ TextInput.propTypes = {
487
586
state : PropTypes . oneOf ( Object . values ( State ) ) ,
488
587
value : PropTypes . string ,
489
588
className : PropTypes . string ,
589
+ sizeVariant : PropTypes . oneOf ( Object . values ( SizeVariant ) ) ,
590
+ baseFontSize : PropTypes . oneOf ( [ 14 , 16 ] ) ,
490
591
} ;
491
592
492
593
export default TextInput ;
0 commit comments