Headless API
Headless API
Section titled “Headless API”All hooks live in @truongdq01/headless. @truongdq01/ui re-exports everything, so you only need one install.
ThemeProvider
Section titled “ThemeProvider”import { ThemeProvider } from "@truongdq01/ui";
<ThemeProvider colorScheme="system" // "light" | "dark" | "system" override={{ light: { ... }, dark: { ... } }}> <App /></ThemeProvider>Theme hooks
Section titled “Theme hooks”const { tokens, components, colorScheme, setColorScheme } = useTheme();const tokens = useTokens(); // semantic tokens onlyconst { button, input } = useComponentTokens(); // component recipesconst isDark = useIsDark(); // booleanusePressable
Section titled “usePressable”const { gesture, animatedStyle, accessibilityProps, isPressed } = usePressable({ onPress, onLongPress, longPressMinDuration: 500, disabled: false, feedbackMode: 'scale', // "scale" | "scaleSubtle" | "opacity" | "none" accessibilityLabel: 'Button', accessibilityHint: 'Saves changes', accessibilityRole: 'button', haptic: true, hitSlop: 8, // auto-expands touch target to min 44px});useTable
Section titled “useTable”const { page, rowsPerPage, sort, selected, paginatedData, totalPages, setPage, handleSort, toggleSelect,} = useTable({ data: myData, rowsPerPage: 10, initialSort: { key: 'name', direction: 'asc' },});useAlert
Section titled “useAlert”const { isOpen, close, getAlertProps, getCloseButtonProps } = useAlert({ defaultOpen: true, onClose: () => console.log('Closed'),});useOTPInput
Section titled “useOTPInput”const { inputRef, isFocused, getOtpProps, handlePress } = useOTPInput({ length: 6, value: otp, onChange: setOtp, onComplete: (val) => verify(val),});useSegmentedControl
Section titled “useSegmentedControl”const { value, isSelected, getTabProps } = useSegmentedControl({ value: activeIndex, onChange: (i) => setActiveIndex(i),});useBottomNavigation
Section titled “useBottomNavigation”const { value, isSelected, getItemProps } = useBottomNavigation({ value: currentRoute, onChange: (val) => router.push(val),});useMenu
Section titled “useMenu”const { isOpen, open, close, getTriggerProps, getItemProps } = useMenu({ onClose: () => console.log('Menu closed'),});useDisclosure
Section titled “useDisclosure”const { isOpen, open, close, toggle, triggerProps, contentProps } = useDisclosure({ defaultOpen: false, isOpen: controlled, // optional controlled value onOpen: () => {}, onClose: () => {}, });useField
Section titled “useField”const { value, error, touched, isValidating, onChange, onBlur, reset, setError, inputProps,} = useField({ defaultValue: '', validate: async (v) => (v.length < 3 ? 'Too short' : undefined), validateOnChange: false,});useCheckbox
Section titled “useCheckbox”const { isChecked, isIndeterminate, isDisabled, toggle, accessibilityProps } = useCheckbox({ defaultChecked: false, checked: controlled, onChange: (v) => {}, disabled: false, indeterminate: false, });useSwitch
Section titled “useSwitch”const { isOn, isDisabled, toggle, accessibilityProps } = useSwitch({ defaultOn: false, on: controlled, onChange: (v) => {}, disabled: false,});useSelect
Section titled “useSelect”const { selected, isOpen, open, close, toggle, selectOption, clearSelection, isSelected, displayLabel, triggerProps } = useSelect({ options: [{ label: "A", value: "a" }, ...], defaultValue: "a", value: controlled, onChange: (v) => {}, multiple: false, disabled: false, placeholder: "Select…", });useRadioGroup
Section titled “useRadioGroup”const { selectedValue, select, isSelected, isDisabled, getItemProps } = useRadioGroup({ defaultValue: 'a', value: controlled, onChange: (v) => {}, disabled: false, });
// Use getItemProps to wire up each radio item:const { onPress, accessibilityRole, accessibilityState } = getItemProps('a');useSlider
Section titled “useSlider”const { currentValue, thumbAnimatedStyle, fillAnimatedStyle, trackAnimatedStyle, panGesture, onTrackLayout, percentage,} = useSlider({ min: 0, max: 100, step: 1, defaultValue: 50, value: controlled, onChange: (v) => {}, onChangeEnd: (v) => {}, disabled: false,});useListItem
Section titled “useListItem”const { itemAnimatedStyle, trailingActionsStyle, leadingActionsStyle, gesture, accessibilityProps, isRevealed, close,} = useListItem({ onPress, onLongPress, trailingActions: [ { label: 'Delete', color: '#ef4444', onPress: handleDelete }, ], leadingActions: [{ label: 'Star', color: '#f59e0b', onPress: handleStar }], disabled: false,});useToast
Section titled “useToast”const { toasts, show, dismiss, dismissAll, success, error, warning, info } = useToast();
// Imperative (works outside React):import { showToast, dismissToast, dismissAllToasts,} from '@truongdq01/headless';showToast({ message: 'Saved!', variant: 'success', duration: 3500 });useBottomSheet
Section titled “useBottomSheet”const { isOpen, open, close, snapTo, currentSnapIndex, sheetAnimatedStyle, backdropAnimatedStyle, panGesture, backdropTapGesture,} = useBottomSheet({ snapPoints: ['50%', '90%'], initialSnapIndex: 0, onClose: () => {}, onSnapChange: (i) => {}, enableDismissOnSwipe: true, enableBackdrop: true,});