UNPKG

@zag-js/radio-group

Version:

Core logic for the radio group widget implemented as a state machine

202 lines (199 loc) • 5.33 kB
import { Machine, EventObject, Service } from '@zag-js/core'; import { PropTypes, RequiredBy, DirectionProperty, CommonProperties, Rect } from '@zag-js/types'; interface ValueChangeDetails { value: string | null; } type ElementIds = Partial<{ root: string; label: string; indicator: string; item: (value: string) => string; itemLabel: (value: string) => string; itemControl: (value: string) => string; itemHiddenInput: (value: string) => string; }>; interface RadioGroupProps extends DirectionProperty, CommonProperties { /** * The ids of the elements in the radio. Useful for composition. */ ids?: ElementIds | undefined; /** * The controlled value of the radio group */ value?: string | null | undefined; /** * The initial value of the checked radio when rendered. * Use when you don't need to control the value of the radio group. */ defaultValue?: string | null | undefined; /** * The name of the input fields in the radio * (Useful for form submission). */ name?: string | undefined; /** * The associate form of the underlying input. */ form?: string | undefined; /** * If `true`, the radio group will be disabled */ disabled?: boolean | undefined; /** * If `true`, the radio group is marked as invalid. */ invalid?: boolean | undefined; /** * If `true`, the radio group is marked as required. */ required?: boolean | undefined; /** * Whether the radio group is read-only */ readOnly?: boolean | undefined; /** * Function called once a radio is checked */ onValueChange?: ((details: ValueChangeDetails) => void) | undefined; /** * Orientation of the radio group */ orientation?: "horizontal" | "vertical" | undefined; } interface PrivateContext { /** * The value of the checked radio */ value: string | null; /** * The id of the active radio */ activeValue: string | null; /** * The id of the focused radio */ focusedValue: string | null; /** * The id of the radio that has focus-visible */ focusVisibleValue: string | null; /** * The id of the hovered radio */ hoveredValue: string | null; /** * The active tab indicator's dom rect */ indicatorRect: Rect | null; /** * Whether indicator transitions should be animated */ animateIndicator: boolean; /** * Whether the radio group's fieldset is disabled */ fieldsetDisabled: boolean; /** * Whether the radio group is in server-side rendering */ ssr: boolean; } type PropsWithDefault = "orientation"; type ComputedContext = Readonly<{ /** * Whether the radio group is disabled */ isDisabled: boolean; }>; interface Refs { /** * Function to clean up the observer for the active tab's rect */ indicatorCleanup: VoidFunction | null; /** * Previous selected value, used to detect real value transitions */ prevValue: string | null; } interface RadioGroupSchema { state: "idle"; props: RequiredBy<RadioGroupProps, PropsWithDefault>; context: PrivateContext; computed: ComputedContext; refs: Refs; event: EventObject; action: string; effect: string; guard: string; } type RadioGroupService = Service<RadioGroupSchema>; type RadioGroupMachine = Machine<RadioGroupSchema>; interface ItemProps { value: string; disabled?: boolean | undefined; invalid?: boolean | undefined; } interface ItemState { /** * The value of the item */ value: string; /** * Whether the item is invalid */ invalid: boolean; /** * Whether the item is disabled */ disabled: boolean; /** * Whether the item is checked */ checked: boolean; /** * Whether the item is focused */ focused: boolean; /** * Whether the item is focused and the focus is visible */ focusVisible: boolean; /** * Whether the item is hovered */ hovered: boolean; /** * Whether the item is active or pressed */ active: boolean; } interface RadioGroupApi<T extends PropTypes = PropTypes> { /** * The current value of the radio group */ value: string | null; /** * Function to set the value of the radio group */ setValue: (value: string) => void; /** * Function to clear the value of the radio group */ clearValue: VoidFunction; /** * Function to focus the radio group */ focus: VoidFunction; /** * Returns the state details of a radio input */ getItemState: (props: ItemProps) => ItemState; getRootProps: () => T["element"]; getLabelProps: () => T["element"]; getItemProps: (props: ItemProps) => T["label"]; getItemTextProps: (props: ItemProps) => T["element"]; getItemControlProps: (props: ItemProps) => T["element"]; getItemHiddenInputProps: (props: ItemProps) => T["input"]; getIndicatorProps: () => T["element"]; } export type { ElementIds, ItemProps, ItemState, RadioGroupApi, RadioGroupMachine, RadioGroupProps, RadioGroupSchema, RadioGroupService, ValueChangeDetails };