import * as stylex from "@stylexjs/stylex"; import { type PropsWithChildren, memo } from "react"; import { a11y, interaction, reset } from "./mixins"; import { controlColor } from "./theme.stylex"; import { font, fontSize, size } from "./tokens.stylex"; export type SelectProps = | UncontrolledMultipleSelectProps | UncontrolledSingleSelectProps | ControlledSingleSelectProps | ControlledMultipleSelectProps; /** * @remarks Intentionally uses a native . */ export interface BaseSelectProps extends PropsWithChildren { name?: string; size?: "small" | "medium" | "large"; required?: boolean; disabled?: boolean; autoComplete?: string; autoFocus?: boolean; } export interface UncontrolledSingleSelectProps extends BaseSelectProps { multiple?: false | undefined; defaultValue?: string; } export interface UncontrolledMultipleSelectProps extends BaseSelectProps { multiple: true; defaultValue?: string[]; } export interface ControlledSingleSelectProps extends UncontrolledSingleSelectProps { value: string; onChange: (value: string) => void; } export interface ControlledMultipleSelectProps extends UncontrolledMultipleSelectProps { value: string[]; onChange: (value: readonly string[]) => void; } const styles = stylex.create({ select: { // ask the browser to render it in its native dark mode. We hope that this sets the dropdown style to dark mode. colorScheme: "dark", background: { default: controlColor.inputBackground, ":focus": controlColor.inputActiveBackground, ":disabled": controlColor.inputDisabledBackground, }, borderWidth: "1px", borderStyle: "solid", borderColor: { default: controlColor.inputBorder, ":focus": controlColor.inputActiveBorder, // https://web.dev/articles/user-valid-and-user-invalid-pseudo-classes ":user-invalid": controlColor.inputInvalidBorder, ":disabled": controlColor.inputDisabledBorder, }, borderRadius: 0, color: { default: controlColor.inputColor, ":focus": controlColor.inputActiveColor, ":disabled": controlColor.inputDisabledColor, }, width: "100%", fontFamily: font.main, "::placeholder": { color: controlColor.inputPlaceholderColor, }, outline: { ":focus": "none", }, cursor: { ":disabled": "not-allowed", }, }, }); const sizeVariants = stylex.create({ small: { padding: `${size.rem1} ${size.rem2}`, fontSize: fontSize.body, }, medium: { padding: `${size.px2} ${size.px3}`, fontSize: size.rem4, fontWeight: 400, }, large: { padding: `${size.rem1} ${size.rem2}`, fontSize: size.rem6, // TODO: ASK-UX:So we have small/large text fields? }, }); export const Select = memo(function Select(props: SelectProps) { return ( ); }); export interface SelectOptionGroupProps extends PropsWithChildren { label: string; disabled?: boolean; } export const SelectOptionGroup = memo(function SelectOptionGroup( props: SelectOptionGroupProps, ) { return ; }); export interface SelectOptionProps extends PropsWithChildren { value: string; disabled?: boolean; } export const SelectOption = memo(function SelectOption( props: SelectOptionProps, ) { return