Lynx/Modules/HeroUI/API reference
@sigx/lynx-heroui · Beta · Component library

API reference#

Every export of @sigx/lynx-heroui v0.4.9. Components render real native views on iOS and Android.

@sigx/lynx-heroui is a HeroUI-flavored design system built on @sigx/lynx-zero (pilot scope, signalxjs/lynx#219). All components and types in this reference come from the main barrel unless noted. The Tailwind preset and the stylesheet are subpath-only exports — import them from @sigx/lynx-heroui/preset and @sigx/lynx-heroui/styles, not the barrel.

Any JS import of the package entry point auto-seeds the hero-light and hero-dark themes into the shared @sigx/lynx-zero registry at module load (via registerTheme). The CSS-only @sigx/lynx-heroui/styles subpath does not execute JS, so an app must import both: the JS barrel (to seed themes and pull in components) and /styles (for the CSS).

The engine and neutral layout primitives are re-exported verbatim from @sigx/lynx-zero, so a hero app keeps a single import source. Switching an app between @sigx/lynx-daisyui and @sigx/lynx-heroui is mostly an import swap.

Entry points#

TypeScript
import { /* components, theme API, types */ } from '@sigx/lynx-heroui';
import { herouiPreset } from '@sigx/lynx-heroui/preset';
import '@sigx/lynx-heroui/styles';
TSX
import { ThemeProvider } from '@sigx/lynx-heroui';
import '@sigx/lynx-heroui/styles';

defineApp(() => () => (
    <ThemeProvider>
        <App />
    </ThemeProvider>
));

Shared component contract#

  • color is the semantic color — ColorVariant from zero (primaryerror); some components exclude neutral.
  • variant is the HeroUI fill style (solid / bordered / flat / ghost, subset per component).
  • size is the sm / md / lg subset of zero's SizeScale.
  • Interactive components also accept disabled and follow the sigx onPress / emitted-event conventions.
  • Button, Toggle, Checkbox, Radio.Item and Select spread WithAccessibility (accessibility-element / -label / -role / -trait / -status passthrough to the host).

Components#

Button#

TypeScript
const Button: Component<ButtonProps>;

Pressable action button. Composes a semantic color (default neutral) with a fill variant, size, plus block, disabled and loading. Wraps @sigx/lynx-gestures' Pressable with PRESSED_SCALE / PRESSED_OPACITY feedback. Emits a press event, suppressed while disabled or loading. accessibility-* props are forwarded to the host. Platform: iOS and Android.

Text#

TypeScript
const Text: Component<TextProps>;

Themed typography. size defaults to base. Supports weight, color and selectable (maps to text-selection with flatten=false). Renders a native <text> with hero-text-* / hero-font-* classes reading the shared --text-* tokens. Platform: iOS and Android.

Heading#

TypeScript
const Heading: Component<HeadingProps>;

Heading. level 1–6 (default 2) maps to text-size/weight utilities and is always hero-text-base-content. Renders a native <text>. Platform: iOS and Android.

Card#

TypeScript
const Card: Compound<Component<CardProps>, {
    Body: Component<{ class?: string }>;
}>;

Surface container (hero-card, optional hero-card-bordered). Compound with Card.Body, which renders the hero-card-body region (takes class plus a default slot). Platform: iOS and Android.

Input#

TypeScript
const Input: Component<InputProps>;

Single-line text input with two-way model binding via model. variant is flat (default) or bordered; type defaults to text. Resolves the base-content text color and the placeholder color to literal hex at runtime, because native text widgets cannot read CSS variables (signalxjs/lynx#225). Platform: iOS and Android.

Textarea#

TypeScript
const Textarea: Component<TextareaProps>;

Multi-line text input with model binding. rows defaults to 3 and computes the height; variant is flat or bordered. Like Input, text and placeholder colors are resolved to literal hex. Platform: iOS and Android.

Toggle#

TypeScript
const Toggle: Component<ToggleProps>;

Switch toggle. Controlled via checked; emits change with the next boolean. The thumb's translateX animates per size. Wraps Pressable. Platform: iOS and Android.

Checkbox#

TypeScript
const Checkbox: Component<CheckboxProps>;

Checkbox that renders a checkmark when checked. Controlled via checked; emits change with the next boolean. Wraps Pressable. Platform: iOS and Android.

Radio#

TypeScript
const Radio: Compound<Component<RadioGroupProps>, {
    Item: Component<RadioItemProps>;
}>;

Radio group, compound with Radio.Item. The group provides a headless selection (value / color / size / select) to its items and emits change with the selected value. Radio.Item emits select, and its per-item value / color / size override the group; an item is checked when its explicit checked prop is set, otherwise when the group's value equals the item's value. Platform: iOS and Android.

Select#

TypeScript
const Select: Component<SelectProps>;

Dropdown select. Renders an absolute-positioned dropdown of pressable options and emits change with the chosen value. Controlled via value; placeholder (default Select…) shows when no value matches. variant is flat or bordered. Platform: iOS and Android.

FormField#

TypeScript
const FormField: Component<FormFieldProps>;

Labelled form-control wrapper. Renders an optional label (with a trailing * when required), the default-slot control, and an optional error line. Classes: hero-form-field / -label / -error. Platform: iOS and Android.

Divider#

TypeScript
const Divider: Component<DividerProps>;

Horizontal (default) or vertical divider. With default-slot content it renders the line·label·line composition; otherwise a plain hero-divider / hero-divider-vertical line. margin is a number. Platform: iOS and Android.

TypeScript
const Modal: Compound<Component<ModalProps>, {
    Header: Component<{ class?: string }>;
    Body: Component<{ class?: string }>;
    Actions: Component<{ class?: string }>;
}>;

Overlay modal. Compound with Modal.Header, Modal.Body and Modal.Actions. Closed state fully unmounts its content and renders a zero-size absolute placeholder (not display:none, which avoids Lynx text-paint leaks). A tap on the overlay calls onClose, while a tap on the inner box stops propagation. onClose is a callback prop, not an emitted event. Platform: iOS and Android.

Tabs#

TypeScript
const Tabs: Compound<Component<TabsProps>, {
    Tab: Component<TabProps>;
}>;

Tab container, compound with Tabs.Tab. The container provides headless selection via zero's provideTabsSelection(activeTab, onChange); each Tabs.Tab reads it via useTabsSelection. Tabs.Tab requires value; an explicit active overrides the container, and onPress fires in addition to onChange. Active tabs add hero-tab-active; tabs wrap Pressable. Platform: iOS and Android.

Theme engine (re-exported)#

These are re-exported verbatim from @sigx/lynx-zero; their signatures and implementations live there.

ThemeProvider#

TypeScript
const ThemeProvider: Component<ThemeProviderProps>;

Theme engine provider. Wraps the app and applies the active theme class to its host view. Mount once at the app root. Platform: iOS and Android.

StatusBarSync#

TypeScript
const StatusBarSync: Component<StatusBarSyncProps>;

Side-effect-only component that syncs the native status-bar appearance to the active theme. Renders nothing; mount once inside ThemeProvider. Platform: iOS and Android.

useTheme#

TypeScript
function useTheme(): ThemeController;

Returns the active theme controller (the nearest ThemeProvider, or the global singleton).

themeController#

TypeScript
const themeController: ThemeController;

The module-level global theme singleton — read or set the theme headlessly without a mounted provider.

listThemes#

TypeScript
function listThemes(): readonly Theme[];

All registered themes (includes the seeded hero-light / hero-dark).

registerTheme#

TypeScript
function registerTheme(theme: Theme): void;

Registers or replaces a theme in the shared registry. Also used internally to seed HERO_BUILTIN_THEMES at module load.

extendTheme#

TypeScript
function extendTheme(/* base, patch */): Theme;

Derives a new full Theme from a registered base. Pass the result to registerTheme.

pickThemeFor#

TypeScript
function pickThemeFor(/* variant */): string;

Selects an appropriate registered theme for a given variant / condition.

pairOf#

TypeScript
function pairOf(/* name */): string;

Resolves the paired (light/dark) theme of a theme.

variantOf#

TypeScript
function variantOf(/* name */): ThemeVariant | undefined;

Returns the variant (light / dark) of a registered theme.

colorsOf#

TypeScript
function colorsOf(/* name */): ThemePalette | undefined;

Returns the color palette of a registered theme.

radiusOf#

TypeScript
function radiusOf(/* name */): ThemeRadius | undefined;

Returns the radius config of a registered theme.

sizesOf#

TypeScript
function sizesOf(/* name */): ThemeSizes | undefined;

Returns the sizes config of a registered theme.

resolveColorToken#

TypeScript
function resolveColorToken(/* token */): string;

Resolves a semantic ColorToken to a concrete color value against the active palette.

Layout primitives (re-exported)#

These are re-exported unchanged from @sigx/lynx-zero.

Row#

TypeScript
const Row: Component<RowProps>;

Flex-row layout primitive. Platform: iOS and Android.

Col#

TypeScript
const Col: Component<ColProps>;

Flex-column layout primitive; same prop surface as Row. Platform: iOS and Android.

Center#

TypeScript
const Center: Component<CenterProps>;

Centers its children on both axes. Platform: iOS and Android.

Spacer#

TypeScript
const Spacer: Component<SpacerProps>;

Flexible / fixed spacer primitive. Platform: iOS and Android.

ScrollView#

TypeScript
const ScrollView: Component<ScrollViewProps>;

Scrollable container primitive. Platform: iOS and Android.

Constants#

HERO_BUILTIN_THEMES#

TypeScript
const HERO_BUILTIN_THEMES: readonly Theme[];

The two built-in themes (hero-light, hero-dark), produced by mapping HeroUI's default light/dark palettes through completeTheme. A for-loop calls registerTheme on each at module load. Both carry staticCss: true, softMix: 0.2, and a radius of { selector: 12px, field: 12px, box: 14px }.

HeroLynxPreset#

TypeScript
// from '@sigx/lynx-heroui/preset'
const HeroLynxPreset: Partial<Config>;

The HeroUI Lynx Tailwind preset. Currently equals @sigx/lynx-zero/preset (zeroPreset) re-composed — the place hero-specific Tailwind extensions would land. Subpath export only — exported from src/preset/index.ts, not the main barrel.

herouiPreset#

TypeScript
// from '@sigx/lynx-heroui/preset'
const herouiPreset = HeroLynxPreset;

The preferred consumer-facing alias for HeroLynxPreset. Subpath export only.

Types#

HeroTheme#

TypeScript
type HeroTheme = 'hero-light' | 'hero-dark' | (string & {});

Theme name applied to the provider host. The two built-ins autocomplete; arbitrary strings are accepted for custom registered themes.

ButtonProps#

TypeScript
type ButtonProps =
    & Define.Prop<'color', ButtonColor, false>
    & Define.Prop<'variant', ButtonVariant, false>
    & Define.Prop<'size', ButtonSize, false>
    & Define.Prop<'disabled', boolean, false>
    & Define.Prop<'loading', boolean, false>
    & Define.Prop<'block', boolean, false>
    & Define.Prop<'class', string, false>
    & WithAccessibility
    & Define.Slot<'default'>
    & Define.Event<'press', void>;

Button props. press is suppressed while disabled or loading.

ButtonColor#

TypeScript
type ButtonColor = ColorVariant;

Semantic color for Button.

ButtonVariant#

TypeScript
type ButtonVariant = 'solid' | 'bordered' | 'flat' | 'ghost';

Fill style for Button; composes with color.

ButtonSize#

TypeScript
type ButtonSize = Extract<SizeScale, 'sm' | 'md' | 'lg'>;

Button size on the shared scale (sm / md / lg).

TextProps#

TypeScript
type TextProps =
    & Define.Prop<'size', TextSize, false>
    & Define.Prop<'weight', TextWeight, false>
    & Define.Prop<'color', TextColor, false>
    & Define.Prop<'class', string, false>
    & Define.Prop<'selectable', boolean, false>
    & Define.Slot<'default'>;

Text props. size defaults to base.

TextSize#

TypeScript
type TextSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl';

TextWeight#

TypeScript
type TextWeight = 'light' | 'normal' | 'medium' | 'semibold' | 'bold';

TextColor#

TypeScript
type TextColor = 'base-content' | Exclude<ColorVariant, 'neutral'>;

HeadingProps#

TypeScript
type HeadingProps =
    & Define.Prop<'level', HeadingLevel, false>
    & Define.Prop<'class', string, false>
    & Define.Slot<'default'>;

Heading props. level defaults to 2.

HeadingLevel#

TypeScript
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;

CardProps#

TypeScript
type CardProps =
    & Define.Prop<'bordered', boolean, false>
    & Define.Prop<'class', string, false>
    & Define.Slot<'default'>;

Card props.

InputProps#

TypeScript
type InputProps =
    & Define.Prop<'placeholder', string, false>
    & Define.Prop<'size', InputSize, false>
    & Define.Prop<'variant', InputVariant, false>
    & Define.Prop<'color', InputColor, false>
    & Define.Prop<'disabled', boolean, false>
    & Define.Prop<'type', 'text' | 'number' | 'password', false>
    & Define.Prop<'class', string, false>
    & Define.Model<string>;

Input props. Define.Model<string> enables two-way binding via model; type defaults to text.

InputSize#

TypeScript
type InputSize = Extract<SizeScale, 'sm' | 'md' | 'lg'>;

InputVariant#

TypeScript
type InputVariant = 'flat' | 'bordered';

InputColor#

TypeScript
type InputColor = Exclude<ColorVariant, 'neutral'>;

TextareaProps#

TypeScript
type TextareaProps =
    & Define.Prop<'placeholder', string, false>
    & Define.Prop<'rows', number, false>
    & Define.Prop<'size', TextareaSize, false>
    & Define.Prop<'variant', TextareaVariant, false>
    & Define.Prop<'color', TextareaColor, false>
    & Define.Prop<'disabled', boolean, false>
    & Define.Prop<'class', string, false>
    & Define.Model<string>;

Textarea props. rows defaults to 3.

TextareaSize#

TypeScript
type TextareaSize = Extract<SizeScale, 'sm' | 'md' | 'lg'>;

TextareaVariant#

TypeScript
type TextareaVariant = 'flat' | 'bordered';

TextareaColor#

TypeScript
type TextareaColor = Exclude<ColorVariant, 'neutral'>;

ToggleProps#

TypeScript
type ToggleProps =
    & Define.Prop<'checked', boolean, false>
    & Define.Prop<'color', ToggleColor, false>
    & Define.Prop<'size', ToggleSize, false>
    & Define.Prop<'disabled', boolean, false>
    & Define.Prop<'class', string, false>
    & WithAccessibility
    & Define.Event<'change', boolean>;

Toggle props; emits change(nextChecked).

ToggleColor#

TypeScript
type ToggleColor = Exclude<ColorVariant, 'neutral'>;

ToggleSize#

TypeScript
type ToggleSize = Extract<SizeScale, 'sm' | 'md' | 'lg'>;

CheckboxProps#

TypeScript
type CheckboxProps =
    & Define.Prop<'checked', boolean, false>
    & Define.Prop<'color', CheckboxColor, false>
    & Define.Prop<'size', CheckboxSize, false>
    & Define.Prop<'disabled', boolean, false>
    & Define.Prop<'class', string, false>
    & WithAccessibility
    & Define.Event<'change', boolean>;

Checkbox props; emits change(nextChecked).

CheckboxColor#

TypeScript
type CheckboxColor = Exclude<ColorVariant, 'neutral'>;

CheckboxSize#

TypeScript
type CheckboxSize = Extract<SizeScale, 'sm' | 'md' | 'lg'>;

RadioGroupProps#

TypeScript
type RadioGroupProps =
    & Define.Prop<'value', string, false>
    & Define.Prop<'color', RadioColor, false>
    & Define.Prop<'size', RadioSize, false>
    & Define.Prop<'class', string, false>
    & Define.Slot<'default'>
    & Define.Event<'change', string>;

Radio group props; emits change(selectedValue). Provides value / color / size to its items.

RadioItemProps#

TypeScript
type RadioItemProps =
    & Define.Prop<'value', string, false>
    & Define.Prop<'label', string, false>
    & Define.Prop<'disabled', boolean, false>
    & Define.Prop<'checked', boolean, false>
    & Define.Prop<'color', RadioColor, false>
    & Define.Prop<'size', RadioSize, false>
    & Define.Prop<'class', string, false>
    & WithAccessibility
    & Define.Event<'select', string>;

Radio.Item props. Per-item value / color / size override the group; checked falls back to the group's selected value. Emits select(value).

RadioColor#

TypeScript
type RadioColor = Exclude<ColorVariant, 'neutral'>;

RadioSize#

TypeScript
type RadioSize = Extract<SizeScale, 'sm' | 'md' | 'lg'>;

SelectProps#

TypeScript
type SelectProps =
    & Define.Prop<'options', SelectOption[], false>
    & Define.Prop<'value', string, false>
    & Define.Prop<'placeholder', string, false>
    & Define.Prop<'size', SelectSize, false>
    & Define.Prop<'variant', SelectVariant, false>
    & Define.Prop<'color', SelectColor, false>
    & Define.Prop<'disabled', boolean, false>
    & Define.Prop<'class', string, false>
    & WithAccessibility
    & Define.Event<'change', string>;

Select props. placeholder defaults to Select…; emits change(value).

SelectOption#

TypeScript
interface SelectOption {
    label: string;
    value: string;
}

A single option for Select.

SelectSize#

TypeScript
type SelectSize = Extract<SizeScale, 'sm' | 'md' | 'lg'>;

SelectVariant#

TypeScript
type SelectVariant = 'flat' | 'bordered';

SelectColor#

TypeScript
type SelectColor = Exclude<ColorVariant, 'neutral'>;

FormFieldProps#

TypeScript
type FormFieldProps =
    & Define.Prop<'label', string, false>
    & Define.Prop<'error', string, false>
    & Define.Prop<'required', boolean, false>
    & Define.Prop<'class', string, false>
    & Define.Slot<'default'>;

FormField props.

DividerProps#

TypeScript
type DividerProps =
    & Define.Prop<'vertical', boolean, false>
    & Define.Prop<'margin', number, false>
    & Define.Prop<'class', string, false>
    & Define.Slot<'default'>;

Divider props. margin is a number.

ModalProps#

TypeScript
type ModalProps =
    & Define.Prop<'open', boolean, false>
    & Define.Prop<'onClose', () => void, false>
    & Define.Prop<'class', string, false>
    & Define.Slot<'default'>;

Modal props. onClose is a callback prop, not an emitted event.

TabsProps#

TypeScript
type TabsProps =
    & Define.Prop<'activeTab', string, false>
    & Define.Prop<'onChange', (value: string) => void, false>
    & Define.Prop<'class', string, false>
    & Define.Slot<'default'>;

Tabs container props.

TabProps#

TypeScript
type TabProps =
    & Define.Prop<'value', string, true>
    & Define.Prop<'active', boolean, false>
    & Define.Prop<'label', string, false>
    & Define.Prop<'onPress', () => void, false>
    & Define.Prop<'class', string, false>
    & Define.Slot<'default'>;

Tabs.Tab props; value is required. active overrides the container's activeTab; onPress fires in addition to onChange.

Re-exported types#

These are re-exported verbatim from @sigx/lynx-zero; they are defined there, not in heroui.

  • ThemeName, ThemeController, ThemeProviderProps, Theme, ThemePalette, ThemeRadius, ThemeSizes, ThemeVariant, StatusBarSyncProps — theme engine types.
  • RowProps, ColProps, CenterProps, SpacerProps, ScrollViewProps — layout primitive prop types.
  • SizeScale, ColorVariant, ColorToken, BackgroundValue — shared design-system contract types.

See the @sigx/lynx-zero API reference for their full definitions.

See also#