feat: Textfield prefix followup#10014
Conversation
|
Build successful! 🎉 |
## API Changes
@react-spectrum/s2/@react-spectrum/s2:ColorField ColorField {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
channel?: ColorChannel
colorSpace?: ColorSpace
contextualHelp?: ReactNode
defaultValue?: T
description?: ReactNode
errorMessage?: ReactNode | (ValidationResult) => ReactNode
excludeFromTabOrder?: boolean
form?: string
id?: string
isDisabled?: boolean
isInvalid?: boolean
isReadOnly?: boolean
isRequired?: boolean
isWheelDisabled?: boolean
label?: ReactNode
labelAlign?: Alignment = 'start'
labelPosition?: LabelPosition = 'top'
name?: string
necessityIndicator?: NecessityIndicator = 'icon'
onBeforeInput?: FormEventHandler<T>
onBlur?: (FocusEvent<Target>) => void
onChange?: (Color | null) => void
onCompositionEnd?: CompositionEventHandler<T>
onCompositionStart?: CompositionEventHandler<T>
onCompositionUpdate?: CompositionEventHandler<T>
onCopy?: ClipboardEventHandler<T>
onCut?: ClipboardEventHandler<T>
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onInput?: FormEventHandler<T>
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onPaste?: ClipboardEventHandler<T>
onSelect?: ReactEventHandler<T>
placeholder?: string
+ prefix?: ReactNode
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesProp
validate?: (Color | null) => ValidationError | boolean | null | undefined
value?: T
}/@react-spectrum/s2:ComboBox ComboBox <T extends {}> {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
align?: 'start' | 'end' = 'start'
allowsCustomValue?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children: ReactNode | ({}) => ReactNode
contextualHelp?: ReactNode
defaultInputValue?: string
defaultItems?: Iterable<T>
defaultSelectedKey?: Key | null
dependencies?: ReadonlyArray<any>
description?: ReactNode
direction?: 'bottom' | 'top' = 'bottom'
disabledKeys?: Iterable<Key>
errorMessage?: ReactNode | (ValidationResult) => ReactNode
form?: string
formValue?: 'text' | 'key' = 'key'
id?: string
inputValue?: string
isDisabled?: boolean
isInvalid?: boolean
isReadOnly?: boolean
isRequired?: boolean
items?: Iterable<T>
label?: ReactNode
labelAlign?: Alignment = 'start'
labelPosition?: LabelPosition = 'top'
loadingState?: LoadingState
menuTrigger?: MenuTriggerAction = 'input'
menuWidth?: number
name?: string
necessityIndicator?: NecessityIndicator = 'icon'
onBlur?: (FocusEvent<HTMLInputElement>) => void
onFocus?: (FocusEvent<HTMLInputElement>) => void
onFocusChange?: (boolean) => void
onInputChange?: (string) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onLoadMore?: () => any
onOpenChange?: (boolean, MenuTriggerAction) => void
onSelectionChange?: (Key | null) => void
placeholder?: string
+ prefix?: ReactNode
selectedKey?: Key | null
shouldFlip?: boolean = true
shouldFocusWrap?: boolean
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
validate?: (ComboBoxValidationValue<SelectionMode>) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
}/@react-spectrum/s2:NumberField NumberField {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
commitBehavior?: 'snap' | 'validate' = 'snap'
contextualHelp?: ReactNode
decrementAriaLabel?: string
defaultValue?: number
description?: ReactNode
errorMessage?: ReactNode | (ValidationResult) => ReactNode
form?: string
formatOptions?: Intl.NumberFormatOptions
hideStepper?: boolean = false
id?: string
incrementAriaLabel?: string
isDisabled?: boolean
isInvalid?: boolean
isReadOnly?: boolean
isRequired?: boolean
isWheelDisabled?: boolean
label?: ReactNode
labelAlign?: Alignment = 'start'
labelPosition?: LabelPosition = 'top'
maxValue?: number
minValue?: number
name?: string
necessityIndicator?: NecessityIndicator = 'icon'
onBeforeInput?: FormEventHandler<T>
onBlur?: (FocusEvent<Target>) => void
onChange?: (T) => void
onCompositionEnd?: CompositionEventHandler<T>
onCompositionStart?: CompositionEventHandler<T>
onCompositionUpdate?: CompositionEventHandler<T>
onCopy?: ClipboardEventHandler<T>
onCut?: ClipboardEventHandler<T>
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onInput?: FormEventHandler<T>
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onPaste?: ClipboardEventHandler<T>
onSelect?: ReactEventHandler<T>
placeholder?: string
+ prefix?: ReactNode
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
step?: number
styles?: StylesProp
validationBehavior?: 'native' | 'aria' = 'native'
value?: number
}/@react-spectrum/s2:ColorFieldProps ColorFieldProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-errormessage?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
channel?: ColorChannel
colorSpace?: ColorSpace
contextualHelp?: ReactNode
defaultValue?: T
description?: ReactNode
errorMessage?: ReactNode | (ValidationResult) => ReactNode
excludeFromTabOrder?: boolean
form?: string
id?: string
isDisabled?: boolean
isInvalid?: boolean
isReadOnly?: boolean
isRequired?: boolean
isWheelDisabled?: boolean
label?: ReactNode
labelAlign?: Alignment = 'start'
labelPosition?: LabelPosition = 'top'
name?: string
necessityIndicator?: NecessityIndicator = 'icon'
onBeforeInput?: FormEventHandler<T>
onBlur?: (FocusEvent<Target>) => void
onChange?: (Color | null) => void
onCompositionEnd?: CompositionEventHandler<T>
onCompositionStart?: CompositionEventHandler<T>
onCompositionUpdate?: CompositionEventHandler<T>
onCopy?: ClipboardEventHandler<T>
onCut?: ClipboardEventHandler<T>
onFocus?: (FocusEvent<Target>) => void
onFocusChange?: (boolean) => void
onInput?: FormEventHandler<T>
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onPaste?: ClipboardEventHandler<T>
onSelect?: ReactEventHandler<T>
placeholder?: string
+ prefix?: ReactNode
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
slot?: string | null
styles?: StylesProp
validate?: (Color | null) => ValidationError | boolean | null | undefined
value?: T
}/@react-spectrum/s2:ComboBoxProps ComboBoxProps <T extends {}> {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
align?: 'start' | 'end' = 'start'
allowsCustomValue?: boolean
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
autoFocus?: boolean
children: ReactNode | ({}) => ReactNode
contextualHelp?: ReactNode
defaultInputValue?: string
defaultItems?: Iterable<T>
defaultSelectedKey?: Key | null
dependencies?: ReadonlyArray<any>
description?: ReactNode
direction?: 'bottom' | 'top' = 'bottom'
disabledKeys?: Iterable<Key>
errorMessage?: ReactNode | (ValidationResult) => ReactNode
form?: string
formValue?: 'text' | 'key' = 'key'
id?: string
inputValue?: string
isDisabled?: boolean
isInvalid?: boolean
isReadOnly?: boolean
isRequired?: boolean
items?: Iterable<T>
label?: ReactNode
labelAlign?: Alignment = 'start'
labelPosition?: LabelPosition = 'top'
loadingState?: LoadingState
menuTrigger?: MenuTriggerAction = 'input'
menuWidth?: number
name?: string
necessityIndicator?: NecessityIndicator = 'icon'
onBlur?: (FocusEvent<HTMLInputElement>) => void
onFocus?: (FocusEvent<HTMLInputElement>) => void
onFocusChange?: (boolean) => void
onInputChange?: (string) => void
onKeyDown?: (KeyboardEvent) => void
onKeyUp?: (KeyboardEvent) => void
onLoadMore?: () => any
onOpenChange?: (boolean, MenuTriggerAction) => void
onSelectionChange?: (Key | null) => void
placeholder?: string
+ prefix?: ReactNode
selectedKey?: Key | null
shouldFlip?: boolean = true
shouldFocusWrap?: boolean
size?: 'S' | 'M' | 'L' | 'XL' = 'M'
styles?: StylesProp
validate?: (ComboBoxValidationValue<SelectionMode>) => ValidationError | boolean | null | undefined
validationBehavior?: 'native' | 'aria' = 'native'
} |
| <Provider values={[[IconContext, {styles: style({size: fontRelative(20), '--iconPrimary': {type: 'fill', value: 'currentColor'}})}]]}> | ||
| <CenterBaseline id={prefixId} styles={style({minWidth: 20, color: 'gray-600', flexShrink: 0, marginEnd: 'text-to-visual'})}> |
There was a problem hiding this comment.
should the size scale with the tshirt size? Or is that completely up to the user to handle?
There was a problem hiding this comment.
I think you're asking about this from the description?
It center baselines everything automatically for alignment. Should it also set size on avatar and swatch? that's more things that each field has to pull in.
There was a problem hiding this comment.
right, sorry I should've been more specific. Avatar seems more troublesome since it doesn't map directly to the tshirt sizing but maybe we can make that mapping for the user. ColorSwatch does have tshirt sizing so it feels like we could automatically provide that via context. Alternatively, we could have prefix accept a render function or something so we could pass the size down via that, might be more flexible depending on just what exactly we wanna allow a user to put in the prefix slot (maybe overkill?)
There was a problem hiding this comment.
Yeah, I was unsure how far to carry it. It would mean that each of these components would need to import more code, so that seemed less ideal. Icons are pretty standard already.
LFDanLu
left a comment
There was a problem hiding this comment.
I'm ok with the current API since the user can still scale up the swatch/avatar/arbitrary element if they want to. We can add auto scaling for those later if need be
Closes
Team talked about supporting more things in the prefix slot today.
It center baselines everything automatically for alignment. Should it also set size on avatar and swatch? that's more things that each field has to pull in.
This also adds an id to associate with the input's aria-labelledby so it's announced when a user arrives in an input.
✅ Pull Request Checklist:
📝 Test Instructions:
🧢 Your Project: