@@ -23,20 +23,23 @@ import {
2323 type TextInputBorderRadius ,
2424} from "../styles/fields.js" ;
2525import {
26+ getBackgroundColor ,
2627 getFontColor ,
2728 type FontColorKey ,
2829 type ThemeOrColorKey ,
2930} from "../styles/themes.js" ;
3031import { applyTypography } from "../styles/typography.js" ;
3132import { z } from "../styles/z-index.js" ;
3233import type { ToReactNodesArgs } from "../utils/toReactNodes/toReactNodes.js" ;
34+ import { toReactNodes } from "../utils/toReactNodes/toReactNodes.js" ;
3335import { CheckboxContainer } from "./Checkbox.js" ;
3436import { Icon , IconContainer } from "./Icon/Icon.js" ;
3537import { type IconName } from "./Icon/types.js" ;
3638import { Loading } from "./Loading.js" ;
3739import { ToggleContainer } from "./Toggle.js" ;
3840import { Tooltip } from "./Tooltip.js" ;
3941import { UnstyledButton } from "./UnstyledButton.js" ;
42+ import { type TypographyPropsWithoutChildren } from "./typography/renderTypography.js" ;
4043import {
4144 type PartialSimpleTypographyProps ,
4245 type RequiredSimpleTypographyProps ,
@@ -53,6 +56,16 @@ export type IconWidth = (typeof iconWidths)[number];
5356export const iconStrokeWidths = [ 1 , 1.5 , 2 ] as const ;
5457export type IconStrokeWidth = ( typeof iconStrokeWidths ) [ number ] ;
5558
59+ export type TextLabelOptions = {
60+ backgroundColor ?: ThemeOrColorKey ;
61+ borderRadius ?: TextInputBorderRadius ;
62+ paddingX ?: number ;
63+ paddingY ?: number ;
64+ typography ?: TypographyPropsWithoutChildren ;
65+ position ?: "absolute" | "relative" ;
66+ marginBottom ?: number ;
67+ } ;
68+
5669export type TextInputProps = {
5770 disabled ?: boolean | undefined ;
5871 error ?: string | ToReactNodesArgs | undefined ;
@@ -101,6 +114,7 @@ export type TextInputProps = {
101114 hideNonErrorsIfBlurred ?: boolean | undefined ;
102115 hintTooltip ?: string | undefined ;
103116 label ?: string ;
117+ labelOptions ?: TextLabelOptions ;
104118 rightButtonText ?: string | undefined ;
105119 onRightButtonClick ?: ( e : React . MouseEvent < HTMLButtonElement > ) => void ;
106120 typography ?: PartialSimpleTypographyProps | undefined ;
@@ -342,7 +356,14 @@ export function TextInput(textInputProps: TextInputProps) {
342356 return (
343357 < StyledTextInput widthProp = { textInputWidth } marginTop = { props . marginTop } >
344358 { props . label ? (
345- < TextInputLabel hasError = { hasError } > { props . label } </ TextInputLabel >
359+ < TextInputLabel hasError = { hasError } labelOptions = { props . labelOptions } >
360+ { props . labelOptions ?. typography
361+ ? toReactNodes ( {
362+ text : props . label ,
363+ typography : props . labelOptions . typography ,
364+ } )
365+ : props . label }
366+ </ TextInputLabel >
346367 ) : null }
347368 { select && (
348369 < TextInputSelect
@@ -486,18 +507,46 @@ const RightButton = styled(UnstyledButton)`
486507 padding: 8px 10px;
487508` ;
488509
489- const TextInputLabel = styled . label < { hasError : boolean } > `
490- ${ standardBorderRadius ( 8 ) }
510+ const TextInputLabel = styled . label < {
511+ hasError : boolean ;
512+ labelOptions ?: TextLabelOptions | undefined ;
513+ } > `
514+ ${ ( { labelOptions } ) =>
515+ labelOptions ?. borderRadius
516+ ? `${ labelOptions . borderRadius } px`
517+ : standardBorderRadius ( 8 ) } ;
491518 font-size: 10px;
492- position: absolute;
519+ position: ${ ( { labelOptions } ) => labelOptions ?. position || " absolute" } ;
493520 z-index: ${ z . textInput + 1 } ;
494- background-color: ${ ( { theme } ) => theme . bg } ;
521+ background-color: ${ ( { theme, labelOptions } ) =>
522+ labelOptions ?. backgroundColor
523+ ? getBackgroundColor ( theme , labelOptions . backgroundColor )
524+ : theme . bg } ;
495525 color: ${ ( { theme, hasError } ) =>
496526 hasError ? theme . danger : theme . mcNeutral } ;
497527 font-weight: 600;
498- padding: 4px 6px;
499- left: 12px;
500- top: -10px;
528+ padding-left: ${ ( { labelOptions } ) =>
529+ labelOptions ?. paddingX === undefined
530+ ? "6px"
531+ : `${ labelOptions . paddingX } px` } ;
532+ padding-right: ${ ( { labelOptions } ) =>
533+ labelOptions ?. paddingX === undefined
534+ ? "6px"
535+ : `${ labelOptions . paddingX } px` } ;
536+ padding-top: ${ ( { labelOptions } ) =>
537+ labelOptions ?. paddingY === undefined
538+ ? "4px"
539+ : `${ labelOptions . paddingY } px` } ;
540+ padding-bottom: ${ ( { labelOptions } ) =>
541+ labelOptions ?. paddingY === undefined
542+ ? "4px"
543+ : `${ labelOptions . paddingY } px` } ;
544+ left: ${ ( { labelOptions } ) =>
545+ labelOptions ?. position === "relative" ? "0" : "12px" } ;
546+ top: ${ ( { labelOptions } ) =>
547+ labelOptions ?. position === "relative" ? "0" : "-10px" } ;
548+ margin-bottom: ${ ( { labelOptions } ) =>
549+ labelOptions ?. marginBottom ? `${ labelOptions . marginBottom } px` : "0" } ;
501550` ;
502551
503552export const TextInputHalfRow = styled . div `
@@ -514,6 +563,8 @@ const StyledTextInput = styled.div<{
514563 widthProp : string ;
515564 marginTop : number | undefined ;
516565} > `
566+ display: flex;
567+ flex-direction: column;
517568 width: ${ ( { widthProp } ) => widthProp } ;
518569 position: relative;
519570 /* Apply marginTop to every TextInput when specified */
0 commit comments