@molecule/app-ui

Core interface · ui · App (browser) · v1.3.6 · Apache-2.0

Styled component library with ClassMap

npm install @molecule/app-ui

npm · Source on GitHub

How it works

@molecule/app-ui is the ui core interface on the app (browser) side: the API your app calls, with no vendor inside.

Choose the implementation by bonding one of its 9 providers: @molecule/app-ui-angular, @molecule/app-ui-nativewind, @molecule/app-ui-react, @molecule/app-ui-react-native, @molecule/app-ui-solid, @molecule/app-ui-svelte, @molecule/app-ui-tailwind, @molecule/app-ui-tailwind-glass, @molecule/app-ui-vue.

import { getClassMap, molIdProps } from '@molecule/app-ui'
const cm = getClassMap()

<button
  className={cm.cn(cm.surface, cm.textSize('sm'))} // resolved classes — never a raw "px-3 text-sm"
  {...molIdProps('save-button')} // data-mol-id for agents/tests
>…</button>

Providers (9): @molecule/app-ui-angular, @molecule/app-ui-nativewind, @molecule/app-ui-react, @molecule/app-ui-react-native, @molecule/app-ui-solid, @molecule/app-ui-svelte, @molecule/app-ui-tailwind, @molecule/app-ui-tailwind-glass, @molecule/app-ui-vue

Works with: @molecule/app-bond, @molecule/app-i18n

Reference

UI component interfaces for molecule.dev.

Provides standardized prop interfaces for common UI components that can be implemented by different UI libraries (styled-components, Tailwind, Ionic, etc.).

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Quick Start

import { getClassMap, molIdProps } from '@molecule/app-ui'
const cm = getClassMap()

<button
  className={cm.cn(cm.surface, cm.textSize('sm'))} // resolved classes — never a raw "px-3 text-sm"
  {...molIdProps('save-button')} // data-mol-id for agents/tests
>…</button>

Type

core

Installation

npm install @molecule/app-ui @molecule/app-bond @molecule/app-i18n

API

Interfaces

UIProvider

Identifies the bonded UI styling library. Providers set name to indicate which library is active (e.g. "tailwind", "bootstrap").

interface UIProvider {
  /**
   * Identifier for the styling library (e.g. `"tailwind"`, `"ionic"`).
   */
  name: string
}

MoleculeSpinnerTimings

The mark's timings, in CSS duration strings. Swap cycle → glint cycle.

interface MoleculeSpinnerTimings {
  /** One full 3-phase atom-swap cycle (also drives bond fades + glints). */
  dur: string
  /** Whole-figure rotation. Keep at two swap cycles for the intended feel. */
  spin: string
  /** Bond gradient flow period (one full translate across the figure). */
  flow: string
}

MoleculeSpinnerColors

Gradient-mode colors. Any CSS color string, including var() forms.

interface MoleculeSpinnerColors {
  /** Bond base / glint tail color. */
  blue?: string
  /** Flow highlight / glint head color at rest. */
  light?: string
  /** Glint ignition color while an atom is in flight. */
  peach?: string
}

MoleculeSpinnerMarkOptions

Options for moleculeSpinnerMarkSvg.

interface MoleculeSpinnerMarkOptions {
  /** Motion timings; defaults to the shipped design (2.5s / 5s / 3s). */
  timings?: Partial<MoleculeSpinnerTimings>
  /** `gradient` (default) or `mono` — plain `currentColor` outline, no defs. */
  paint?: 'gradient' | 'mono'
  /** Gradient-mode colors; default the `var(--mol-spin-*, fallback)` set. */
  colors?: MoleculeSpinnerColors
  /**
   * Gradient id for url() references. Must be unique per rendered instance
   * on a page. Defaults to `mol-spinner-gradient`.
   */
  gradientId?: string
  /** Pixel size baked into width/height; omit when CSS sizes the svg. */
  size?: number
  /** Class attribute for the svg element. */
  className?: string
  /** Inline style attribute (already serialized, e.g. `color:re$d`). */
  style?: string
  /** Announce as `role="status"` with this label; omit for `aria-hidden`. */
  ariaLabel?: string
}

CSSProperties

Framework-agnostic CSS properties. Mirrors React.CSSProperties but without React dependency.

interface CSSProperties {
  [key: string]: string | number | undefined
}

BaseProps

Base props shared by all components.

interface BaseProps {
  /**
   * Additional CSS class name(s).
   */
  className?: string

  /**
   * Inline styles.
   */
  style?: CSSProperties

  /**
   * Test ID for automated testing.
   */
  testId?: string

  /**
   * Automation ID for AI agents and E2E tests. Maps to the `data-mol-id`
   * HTML attribute. Use `molId()` from `./automation.js` to generate
   * semantic IDs. (Tooling only — screen readers do not expose `data-*`
   * attributes; accessible names come from labels/`aria-*`.)
   */
  automationId?: string

  /**
   * Whether the component is disabled.
   */
  disabled?: boolean
}

HTMLElementProps

Base props for HTML elements. Framework bindings should extend this with framework-specific attributes.

interface HTMLElementProps extends BaseProps {
  id?: string
  title?: string
  tabIndex?: number
  role?: string
  'aria-label'?: string
  'aria-labelledby'?: string
  'aria-describedby'?: string
  'aria-hidden'?: boolean
  'aria-disabled'?: boolean
  'aria-expanded'?: boolean
  'aria-selected'?: boolean
  'aria-checked'?: boolean | 'mixed'
  'aria-pressed'?: boolean | 'mixed'
  'aria-invalid'?: boolean
  'aria-required'?: boolean
  'aria-readonly'?: boolean
  'aria-busy'?: boolean
  'aria-live'?: 'off' | 'polite' | 'assertive'
  onClick?: MouseEventHandler
  onDoubleClick?: MouseEventHandler
  onMouseEnter?: MouseEventHandler
  onMouseLeave?: MouseEventHandler
  onFocus?: FocusEventHandler
  onBlur?: FocusEventHandler
  onKeyDown?: KeyboardEventHandler
  onKeyUp?: KeyboardEventHandler
  onKeyPress?: KeyboardEventHandler
}

InputElementProps

Base props for input elements.

interface InputElementProps extends HTMLElementProps {
  name?: string
  value?: string | number | readonly string[]
  defaultValue?: string | number | readonly string[]
  placeholder?: string
  required?: boolean
  readOnly?: boolean
  autoFocus?: boolean
  autoComplete?: string
  maxLength?: number
  minLength?: number
  pattern?: string
  onChange?: ChangeEventHandler
  onInput?: FormEventHandler
}

ButtonElementProps

Base props for button elements.

interface ButtonElementProps extends HTMLElementProps {
  /**
   * Defaults to `'button'` in every framework binding, so a button never submits a
   * form by accident. A form's primary action must set `type="submit"`: Enter then
   * submits the form, and tests that select `button[type="submit"]` find it.
   */
  type?: 'button' | 'submit' | 'reset'
  name?: string
  value?: string
  form?: string
}

TextareaElementProps

Base props for textarea elements.

interface TextareaElementProps extends HTMLElementProps {
  name?: string
  value?: string
  defaultValue?: string
  placeholder?: string
  required?: boolean
  readOnly?: boolean
  autoFocus?: boolean
  rows?: number
  cols?: number
  maxLength?: number
  minLength?: number
  wrap?: 'hard' | 'soft' | 'off'
  onChange?: ChangeEventHandler
  onInput?: FormEventHandler
}

SelectElementProps

Base props for select elements.

interface SelectElementProps extends HTMLElementProps {
  name?: string
  required?: boolean
  autoFocus?: boolean
  multiple?: boolean
  onChange?: ChangeEventHandler
}

FormElementProps

Base props for form elements.

interface FormElementProps extends HTMLElementProps {
  action?: string
  method?: 'get' | 'post'
  encType?: string
  target?: string
  noValidate?: boolean
  autoComplete?: 'on' | 'off'
  onSubmit?: FormEventHandler
  onReset?: FormEventHandler
}

ButtonProps

Props for the Button component.

interface ButtonProps extends ButtonElementProps {
  /**
   * Button content.
   */
  children?: Children

  /**
   * Visual variant.
   */
  variant?: ButtonVariant

  /**
   * Color scheme.
   */
  color?: ColorVariant

  /**
   * Button size.
   */
  size?: ButtonSize

  /**
   * Whether the button is in a loading state.
   */
  loading?: boolean

  /**
   * Loading text to display.
   */
  loadingText?: string

  /**
   * Whether the button takes full width.
   */
  fullWidth?: boolean

  /**
   * Icon to display before the label.
   */
  leftIcon?: Children

  /**
   * Icon to display after the label.
   */
  rightIcon?: Children
}

InputProps

Props for the Input component (text field, email, password, etc.).

interface InputProps extends InputElementProps {
  /**
   * Input type.
   */
  type?: InputType

  /**
   * Input size.
   */
  size?: Size

  /**
   * Horizontal text alignment inside the input (see
   * `InputClassOptions.align`). Defaults to the bond's own style.
   */
  align?: 'left' | 'center'

  /**
   * Label text.
   */
  label?: string

  /**
   * Error message.
   */
  error?: string

  /**
   * Hint/help text.
   */
  hint?: string

  /**
   * Element to display on the left.
   */
  leftElement?: Children

  /**
   * Element to display on the right.
   */
  rightElement?: Children

  /**
   * Whether to show a clear button.
   */
  clearable?: boolean

  /**
   * Called when the clear button is clicked.
   */
  onClear?: () => void

  /**
   * Accessible label for the clear button.
   * @default 'Clear'
   */
  clearLabel?: string
}

TextareaProps

Props for the Textarea component.

interface TextareaProps extends TextareaElementProps {
  /**
   * Text size tier (see `TextareaClassOptions.size`) — pass the same
   * `size` as a neighboring Input for identical font sizes.
   */
  size?: Size

  /**
   * Label text.
   */
  label?: string

  /**
   * Error message.
   */
  error?: string

  /**
   * Hint/help text.
   */
  hint?: string

  /**
   * Whether the textarea auto-resizes.
   */
  autoResize?: boolean

  /**
   * Minimum number of rows.
   */
  minRows?: number

  /**
   * Maximum number of rows.
   */
  maxRows?: number
}

SelectOption

A single option in a Select dropdown.

interface SelectOption<T = string> {
  /**
   * Option value.
   */
  value: T

  /**
   * Display label.
   */
  label: string

  /**
   * Whether the option is disabled.
   */
  disabled?: boolean

  /**
   * Option group (for grouped selects).
   */
  group?: string
}

SelectProps

Props for the Select dropdown component (single or multi-select).

interface SelectProps<T = string> extends SelectElementProps {
  /**
   * Select options.
   */
  options: SelectOption<T>[]

  /**
   * Current value.
   */
  value?: T

  /**
   * Change handler (with typed value).
   */
  onValueChange?: (value: T) => void

  /**
   * Select size.
   */
  size?: Size

  /**
   * Label text.
   */
  label?: string

  /**
   * Placeholder text.
   */
  placeholder?: string

  /**
   * Error message.
   */
  error?: string

  /**
   * Hint/help text.
   */
  hint?: string

  /**
   * Whether to allow clearing the selection.
   */
  clearable?: boolean
}

CheckboxProps

Props for the Checkbox component.

interface CheckboxProps extends InputElementProps {
  /**
   * Checkbox label.
   */
  label?: Children

  /**
   * Whether the checkbox is checked.
   */
  checked?: boolean

  /**
   * Whether the checkbox is in an indeterminate state.
   */
  indeterminate?: boolean

  /**
   * Checkbox size.
   */
  size?: Size

  /**
   * Error message.
   */
  error?: string
}

RadioOption

A single option in a RadioGroup.

interface RadioOption<T = string> {
  /**
   * Option value.
   */
  value: T

  /**
   * Display label.
   */
  label: Children

  /**
   * Whether the option is disabled.
   */
  disabled?: boolean
}

RadioGroupProps

Props for the RadioGroup component.

interface RadioGroupProps<T = string> extends BaseProps {
  /**
   * Radio options.
   */
  options: RadioOption<T>[]

  /**
   * Current value.
   */
  value?: T

  /**
   * Change handler.
   */
  onChange?: (value: T) => void

  /**
   * Radio size.
   */
  size?: Size

  /**
   * Group label.
   */
  label?: string

  /**
   * Shared `name` attribute for the group's radio inputs (used for native
   * form submission). When omitted, a unique per-instance name is generated
   * so separate groups never merge — the visible `label` is deliberately
   * NOT used as the name, because two groups with the same label (e.g. two
   * "Size" pickers) would otherwise form ONE native radio group and
   * deselect each other.
   */
  name?: string

  /**
   * Layout direction.
   */
  direction?: 'horizontal' | 'vertical'

  /**
   * Error message.
   */
  error?: string
}

SwitchProps

Props for the Switch/Toggle component.

interface SwitchProps extends InputElementProps {
  /**
   * Switch label.
   */
  label?: Children

  /**
   * Whether the switch is on.
   */
  checked?: boolean

  /**
   * Switch size.
   */
  size?: Size

  /**
   * Color when on.
   */
  color?: ColorVariant
}

ModalProps

Props for the Modal/Dialog component.

interface ModalProps extends HTMLElementProps {
  /**
   * Whether the modal is open.
   */
  open: boolean

  /**
   * Called when the modal should close.
   */
  onClose: () => void

  /**
   * Modal title.
   */
  title?: string

  /**
   * Modal content.
   */
  children?: Children

  /**
   * Modal size.
   */
  size?: ModalSize

  /**
   * Whether to show a close button.
   */
  showCloseButton?: boolean

  /**
   * Whether clicking the overlay closes the modal.
   */
  closeOnOverlayClick?: boolean

  /**
   * Whether pressing Escape closes the modal.
   */
  closeOnEscape?: boolean

  /**
   * Footer content (typically action buttons).
   */
  footer?: Children

  /**
   * Whether the modal is centered vertically.
   */
  centered?: boolean

  /**
   * Whether to prevent body scroll when open.
   */
  preventScroll?: boolean

  /**
   * Accessible label for the close button.
   * @default 'Close'
   */
  closeLabel?: string
}

SpinnerProps

Props for the Spinner/loading indicator component.

interface SpinnerProps extends BaseProps {
  /**
   * Spinner size.
   */
  size?: Size

  /**
   * Spinner color.
   */
  color?: ColorVariant | string

  /**
   * Loading label (for accessibility).
   */
  label?: string

  /**
   * Spinner thickness.
   */
  thickness?: number
}

AvatarProps

Props for the Avatar component.

interface AvatarProps extends HTMLElementProps {
  /**
   * Image source URL.
   */
  src?: string

  /**
   * Alt text for the image.
   */
  alt?: string

  /**
   * Name for fallback initials.
   */
  name?: string

  /**
   * Avatar size.
   */
  size?: Size | number

  /**
   * Whether the avatar is rounded.
   */
  rounded?: boolean

  /**
   * Fallback element when no image.
   */
  fallback?: Children
}

BadgeProps

Props for the Badge component (status labels, counts, tags).

interface BadgeProps extends HTMLElementProps {
  /**
   * Badge content.
   */
  children?: Children

  /**
   * Badge color.
   */
  color?: ColorVariant

  /**
   * Badge variant.
   */
  variant?: 'solid' | 'outline' | 'subtle'

  /**
   * Badge size.
   */
  size?: Size

  /**
   * Whether the badge is rounded.
   */
  rounded?: boolean
}

TooltipProps

Props for the Tooltip component (hover/focus popover with informational text).

interface TooltipProps extends HTMLElementProps {
  /**
   * Tooltip content.
   */
  content: Children

  /**
   * Element that triggers the tooltip.
   */
  children: Children

  /**
   * Tooltip placement.
   */
  placement?: TooltipPlacement

  /**
   * Delay before showing (ms).
   */
  delay?: number

  /**
   * Whether the tooltip has an arrow.
   */
  hasArrow?: boolean
}

CardProps

Props for the Card container component (elevated, outlined, or filled surface).

interface CardProps extends HTMLElementProps {
  /**
   * Card content.
   */
  children?: Children

  /**
   * Card variant.
   */
  variant?: 'elevated' | 'outlined' | 'filled'

  /**
   * Whether the card is interactive (clickable).
   */
  interactive?: boolean

  /**
   * Padding size.
   */
  padding?: Size | 'none'
}

ContainerProps

Props for the Container layout component.

interface ContainerProps extends HTMLElementProps {
  /**
   * Container content.
   */
  children?: Children

  /**
   * Maximum width.
   */
  maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full' | string

  /**
   * Whether to center the container.
   */
  centered?: boolean

  /**
   * Horizontal padding.
   */
  paddingX?: Size | string
}

FlexProps

Flex container props.

interface FlexProps extends HTMLElementProps {
  /**
   * Flex content.
   */
  children?: Children

  /**
   * Flex direction.
   */
  direction?: 'row' | 'column' | 'row-reverse' | 'column-reverse'

  /**
   * Justify content.
   */
  justify?: 'start' | 'end' | 'center' | 'between' | 'around' | 'evenly'

  /**
   * Align items.
   */
  align?: 'start' | 'end' | 'center' | 'baseline' | 'stretch'

  /**
   * Flex wrap.
   */
  wrap?: 'wrap' | 'nowrap' | 'wrap-reverse'

  /**
   * Gap between items.
   */
  gap?: Size | string | number
}

GridProps

Grid container props.

interface GridProps extends HTMLElementProps {
  /**
   * Grid content.
   */
  children?: Children

  /**
   * Number of columns.
   */
  columns?: number | string

  /**
   * Number of rows.
   */
  rows?: number | string

  /**
   * Gap between items.
   */
  gap?: Size | string | number

  /**
   * Column gap.
   */
  columnGap?: Size | string | number

  /**
   * Row gap.
   */
  rowGap?: Size | string | number
}

SpacerProps

Props for the Spacer layout component (adds whitespace between elements).

interface SpacerProps extends BaseProps {
  /**
   * Space size.
   */
  size?: Size | string | number

  /**
   * Whether the spacer is horizontal.
   */
  horizontal?: boolean
}

FormProps

Props for the Form component (wraps inputs with submission handling and validation).

interface FormProps extends FormElementProps {
  /**
   * Form content.
   */
  children?: Children

  /**
   * Submit handler with form data.
   */
  onFormSubmit?: (data: Record<string, unknown>) => void | Promise<void>

  /**
   * Whether the form is submitting.
   */
  submitting?: boolean
}

FormFieldProps

Form field wrapper props.

interface FormFieldProps extends HTMLElementProps {
  /**
   * Field content.
   */
  children?: Children

  /**
   * Field label.
   */
  label?: string

  /**
   * Field name.
   */
  name?: string

  /**
   * Error message.
   */
  error?: string

  /**
   * Hint/help text.
   */
  hint?: string

  /**
   * Whether the field is required.
   */
  required?: boolean
}

AlertProps

Props for the Alert component.

interface AlertProps extends HTMLElementProps {
  /**
   * Alert content.
   */
  children?: Children

  /**
   * Alert title.
   */
  title?: string

  /**
   * Alert status/type.
   */
  status?: ColorVariant

  /**
   * Alert variant.
   */
  variant?: 'solid' | 'subtle' | 'outline' | 'left-accent'

  /**
   * Whether the alert is dismissible.
   */
  dismissible?: boolean

  /**
   * Called when dismissed.
   */
  onDismiss?: () => void

  /**
   * Icon to display.
   */
  icon?: Children

  /**
   * Accessible label for the dismiss button.
   * @default 'Dismiss'
   */
  dismissLabel?: string
}

ToastProps

Props for the Toast/notification component.

interface ToastProps extends HTMLElementProps {
  /**
   * Toast content.
   */
  children?: Children

  /**
   * Toast title.
   */
  title?: string

  /**
   * Toast description.
   */
  description?: string

  /**
   * Toast status/type.
   */
  status?: ColorVariant

  /**
   * Duration in milliseconds (0 for persistent).
   */
  duration?: number

  /**
   * Whether the toast is dismissible.
   */
  dismissible?: boolean

  /**
   * Called when dismissed.
   */
  onDismiss?: () => void

  /**
   * Toast position.
   */
  position?: 'top' | 'top-right' | 'top-left' | 'bottom' | 'bottom-right' | 'bottom-left'

  /**
   * Accessible label for the close button.
   * @default 'Close'
   */
  closeLabel?: string
}

TabItem

A single tab in a Tabs component.

interface TabItem<T = string> {
  /**
   * Tab value/id.
   */
  value: T

  /**
   * Tab label.
   */
  label: Children

  /**
   * Tab content.
   */
  content?: Children

  /**
   * Whether the tab is disabled.
   */
  disabled?: boolean

  /**
   * Icon to display.
   */
  icon?: Children
}

TabsProps

Props for the Tabs component (switchable tabbed content panels).

interface TabsProps<T = string> extends BaseProps {
  /**
   * Tab items.
   */
  items: TabItem<T>[]

  /**
   * Current active tab.
   */
  value?: T

  /**
   * Default active tab.
   */
  defaultValue?: T

  /**
   * Change handler.
   */
  onChange?: (value: T) => void

  /**
   * Tab variant.
   */
  variant?: 'line' | 'enclosed' | 'soft-rounded' | 'solid-rounded'

  /**
   * Tab size.
   */
  size?: Size

  /**
   * Whether tabs are fitted (take full width).
   */
  fitted?: boolean
}

AccordionItem

A single item in an Accordion component.

interface AccordionItem<T = string> {
  /**
   * Item value/id.
   */
  value: T

  /**
   * Item header/trigger.
   */
  header: Children

  /**
   * Item content.
   */
  content: Children

  /**
   * Whether the item is disabled.
   */
  disabled?: boolean
}

AccordionProps

Props for the Accordion component.

interface AccordionProps<T = string> extends BaseProps {
  /**
   * Accordion items.
   */
  items: AccordionItem<T>[]

  /**
   * Expanded item(s).
   */
  value?: T | T[]

  /**
   * Default expanded item(s).
   */
  defaultValue?: T | T[]

  /**
   * Change handler.
   */
  onChange?: (value: T | T[]) => void

  /**
   * Whether multiple items can be expanded.
   */
  multiple?: boolean

  /**
   * Whether items can be collapsed.
   */
  collapsible?: boolean
}

TableColumn

Table column definition.

interface TableColumn<T> {
  /**
   * Column key (data property).
   */
  key: keyof T | string

  /**
   * Column header.
   */
  header: Children

  /**
   * Custom cell renderer.
   */
  render?: (value: unknown, row: T, index: number) => Children

  /**
   * Column width.
   */
  width?: string | number

  /**
   * Whether the column is sortable.
   */
  sortable?: boolean

  /**
   * Text alignment.
   */
  align?: 'left' | 'center' | 'right'
}

TableProps

Props for the Table component.

interface TableProps<T> extends HTMLElementProps {
  /**
   * Table data.
   */
  data: T[]

  /**
   * Column definitions.
   */
  columns: TableColumn<T>[]

  /**
   * Row key extractor.
   */
  rowKey?: keyof T | ((row: T) => string | number)

  /**
   * Whether to show borders.
   */
  bordered?: boolean

  /**
   * Whether rows are striped.
   */
  striped?: boolean

  /**
   * Whether rows are hoverable.
   */
  hoverable?: boolean

  /**
   * Table size.
   */
  size?: Size

  /**
   * Empty state content.
   */
  emptyContent?: Children

  /**
   * Loading state.
   */
  loading?: boolean

  /**
   * Sort configuration.
   */
  sort?: { key: string; direction: 'asc' | 'desc' }

  /**
   * Sort change handler.
   */
  onSort?: (key: string, direction: 'asc' | 'desc') => void

  /**
   * Row click handler.
   */
  onRowClick?: (row: T, index: number) => void
}

PaginationProps

Props for the Pagination component (page navigation with current page, total, page size, and change callbacks).

interface PaginationProps extends BaseProps {
  /**
   * Current page (1-indexed).
   */
  page: number

  /**
   * Total number of pages.
   */
  totalPages: number

  /**
   * Page change handler.
   */
  onChange: (page: number) => void

  /**
   * Number of sibling pages to show.
   */
  siblings?: number

  /**
   * Number of boundary pages to show.
   */
  boundaries?: number

  /**
   * Pagination size.
   */
  size?: Size

  /**
   * Whether to show first/last buttons.
   */
  showFirstLast?: boolean

  /**
   * Whether to show previous/next buttons.
   */
  showPrevNext?: boolean

  /**
   * Accessible labels for pagination controls.
   */
  labels?: {
    nav?: string
    first?: string
    previous?: string
    next?: string
    last?: string
    goToPage?: (page: number) => string
  }
}

SkeletonProps

Props for the Skeleton loading placeholder component.

interface SkeletonProps extends BaseProps {
  /**
   * Skeleton width.
   */
  width?: string | number

  /**
   * Skeleton height.
   */
  height?: string | number

  /**
   * Whether the skeleton is circular.
   */
  circle?: boolean

  /**
   * Border radius.
   */
  borderRadius?: string | number

  /**
   * Animation type.
   */
  animation?: 'pulse' | 'wave' | 'none'
}

SeparatorProps

Props for the Separator/Divider component.

interface SeparatorProps extends BaseProps {
  /**
   * Separator orientation.
   */
  orientation?: 'horizontal' | 'vertical'

  /**
   * Whether the separator is decorative only.
   */
  decorative?: boolean
}

Dropdown menu item.

interface DropdownItem<T = string> {
  /**
   * Item value/id.
   */
  value: T

  /**
   * Display label.
   */
  label: Children

  /**
   * Whether the item is disabled.
   */
  disabled?: boolean

  /**
   * Icon to display.
   */
  icon?: Children

  /**
   * Keyboard shortcut display.
   */
  shortcut?: string

  /**
   * Whether this is a separator.
   */
  separator?: boolean

  /**
   * Nested items (for submenus).
   */
  items?: DropdownItem<T>[]
}

Props for the Dropdown menu component.

interface DropdownProps<T = string> extends BaseProps {
  /**
   * Dropdown trigger element.
   */
  trigger: Children

  /**
   * Dropdown items.
   */
  items: DropdownItem<T>[]

  /**
   * Called when an item is selected.
   */
  onSelect?: (value: T) => void

  /**
   * Dropdown placement.
   */
  placement?:
    'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'right'

  /**
   * Whether the dropdown is open (controlled).
   */
  open?: boolean

  /**
   * Called when open state changes.
   */
  onOpenChange?: (open: boolean) => void

  /**
   * Menu alignment.
   */
  align?: 'start' | 'center' | 'end'

  /**
   * Menu width.
   */
  width?: 'trigger' | 'auto' | number | string
}

PageShellProps

Props for the PageShell component — authenticated page wrapper with navigation.

interface PageShellProps extends BaseProps {
  /** Sidebar content (navigation links). */
  sidebar?: Children
  /** Top bar content (breadcrumbs, user menu). */
  topbar?: Children
  /** Whether the sidebar is collapsed. */
  sidebarCollapsed?: boolean
  /** Callback when sidebar toggle is clicked. */
  onSidebarToggle?: () => void
  /** Main content. */
  children?: Children
}

EmptyStateProps

Props for the EmptyState component — shown when a list or section has no data.

interface EmptyStateProps extends BaseProps {
  /** Icon or illustration to display. */
  icon?: Children
  /** Main heading text. */
  title: string
  /** Description text. */
  description?: string
  /** Primary action button (e.g., "Create first item"). */
  action?: Children
}

PageHeaderProps

Props for the PageHeader component — consistent page title area.

interface PageHeaderProps extends BaseProps {
  /** Page title. */
  title: string
  /** Page description. */
  description?: string
  /** Action buttons (e.g., "Create", "Export"). */
  actions?: Children
  /** Breadcrumb trail. */
  breadcrumbs?: Array<{ label: string; href?: string }>
}

ButtonClassOptions

Options for resolving button CSS classes via UIClassMap.

interface ButtonClassOptions {
  variant?: ButtonVariant
  color?: ColorVariant
  size?: ButtonSize
  fullWidth?: boolean
}

InputClassOptions

Options for resolving input CSS classes via UIClassMap.

interface InputClassOptions {
  error?: boolean
  size?: Size
  /**
   * Horizontal text alignment inside the input. Bonds may default to a
   * centered aesthetic (e.g. the Tailwind bond's floating-label style);
   * `'left'` opts a specific field out — e.g. a form field sitting next to
   * left-aligned textareas.
   */
  align?: 'left' | 'center'
}

TextareaClassOptions

Options for textarea class resolution.

interface TextareaClassOptions {
  error?: boolean
  /**
   * Text size tier, matching `InputClassOptions.size` — a same-`size`
   * input + textarea pair renders identical font sizes. Bonds default to
   * their historic textarea size when omitted.
   */
  size?: Size
}

SelectClassOptions

Options for resolving select CSS classes via UIClassMap.

interface SelectClassOptions {
  error?: boolean
  size?: Size
}

CheckboxClassOptions

Options for resolving checkbox CSS classes via UIClassMap.

interface CheckboxClassOptions {
  error?: boolean
}

RadioClassOptions

Options for resolving radio CSS classes via UIClassMap.

interface RadioClassOptions {
  error?: boolean
}

SwitchClassOptions

Options for switch class resolution.

interface SwitchClassOptions {
  size?: Size
  /**
   * Color used for the checked/on track. Reuses the same semantic color
   * scale as `ButtonClassOptions.color`/`BadgeClassOptions.variant`.
   * @default 'primary'
   */
  color?: ColorVariant
}

LabelClassOptions

Options for label class resolution.

interface LabelClassOptions {
  required?: boolean
}

CardClassOptions

Options for resolving card CSS classes via UIClassMap.

interface CardClassOptions {
  variant?: 'default' | 'elevated' | 'outline' | 'ghost'
}

BadgeClassOptions

Options for resolving badge CSS classes via UIClassMap.

interface BadgeClassOptions {
  variant?: ColorVariant
  size?: Size
}

AlertClassOptions

Options for resolving alert CSS classes via UIClassMap.

interface AlertClassOptions {
  variant?: 'default' | 'info' | 'success' | 'warning' | 'error'
}

AvatarClassOptions

Options for resolving avatar CSS classes via UIClassMap.

interface AvatarClassOptions {
  size?: Size
}

ModalClassOptions

Options for resolving modal/dialog CSS classes via UIClassMap.

interface ModalClassOptions {
  size?: ModalSize
}

SpinnerClassOptions

Options for resolving spinner CSS classes via UIClassMap.

interface SpinnerClassOptions {
  size?: Size
}

ToastClassOptions

Options for toast class resolution.

interface ToastClassOptions {
  variant?: 'default' | 'success' | 'warning' | 'error' | 'info'
}

SeparatorClassOptions

Options for resolving separator CSS classes via UIClassMap.

interface SeparatorClassOptions {
  orientation?: 'horizontal' | 'vertical'
}

AccordionClassOptions

Options for resolving accordion CSS classes via UIClassMap.

interface AccordionClassOptions {
  variant?: string
}

TabsClassOptions

Options for resolving tabs (tabsList/tabsTrigger/tabsContent) CSS classes via UIClassMap. Active vs inactive trigger styling is NOT one of these options — it is expressed as data-[state=active] CSS attribute selectors baked into the returned class string, driven by the data-state="active"|"inactive" attribute the framework binding already sets on the trigger element (see @molecule/app-ui-react's Tabs).

interface TabsClassOptions {
  /**
   * Visual style: underline indicator, bordered/filled boxes, a soft-bg
   * pill, or a solid-bg pill.
   */
  variant?: 'line' | 'enclosed' | 'soft-rounded' | 'solid-rounded'
  size?: Size
}

PaginationClassOptions

Options for pagination item class resolution.

interface PaginationClassOptions {
  active?: boolean
  size?: Size
}

ContainerClassOptions

Options for container class resolution.

interface ContainerClassOptions {
  size?: Size | '2xl' | 'full'
}

FlexClassOptions

Options for flex class resolution.

interface FlexClassOptions {
  direction?: 'row' | 'col' | 'row-reverse' | 'col-reverse'
  align?: 'start' | 'center' | 'end' | 'stretch' | 'baseline'
  justify?: 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'
  wrap?: 'wrap' | 'nowrap' | 'wrap-reverse'
  /** Named tokens or Tailwind spacing scale index (e.g. `3` → `gap-3`). */
  gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number
}

GridClassOptions

Options for grid class resolution.

interface GridClassOptions {
  cols?: number
  /** Named tokens or Tailwind spacing scale index (e.g. `10` → `gap-10`). */
  gap?: 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | number
  /**
   * Mobile-first responsive collapse. When omitted (the default), a grid of
   * `cols >= 2` starts at a single column on small screens and steps up to
   * `cols` at larger breakpoints, so cards don't overflow on mobile. Pass
   * `false` for a FIXED `cols`-column grid at every viewport width. Ignored
   * for `cols <= 1` (always single-column) and by ClassMap bonds without a
   * breakpoint system (e.g. NativeWind).
   */
  responsive?: boolean
}

UIClassMap

UIClassMap interface — the contract for styling-agnostic class resolution.

Each styling library (Tailwind, Bootstrap, etc.) provides its own UIClassMap implementation. Component resolvers accept GENERIC variant names from @molecule/app-ui types and map to library-specific classes internally.

Framework UI packages (@molecule/app-ui-react, etc.) call getClassMap() at render time to resolve classes without knowing which styling library is active.

interface UIClassMap {
  /**
   * Merges class names with library-specific conflict resolution
   * (e.g. tailwind-merge for Tailwind).
   */
  cn(...classes: ClassMapValue[]): string

  // ---- Component resolvers (functions) ----

  button(opts?: ButtonClassOptions): string
  input(opts?: InputClassOptions): string
  textarea(opts?: TextareaClassOptions): string
  select(opts?: SelectClassOptions): string
  checkbox(opts?: CheckboxClassOptions): string
  radio(opts?: RadioClassOptions): string
  switchBase(opts?: SwitchClassOptions): string
  switchThumb(opts?: SwitchClassOptions): string
  label(opts?: LabelClassOptions): string
  card(opts?: CardClassOptions): string
  badge(opts?: BadgeClassOptions): string
  alert(opts?: AlertClassOptions): string
  avatar(opts?: AvatarClassOptions): string
  modal(opts?: ModalClassOptions): string
  spinner(opts?: SpinnerClassOptions): string
  toast(opts?: ToastClassOptions): string
  separator(opts?: SeparatorClassOptions): string
  accordion(opts?: AccordionClassOptions): string
  pagination(opts?: PaginationClassOptions): string
  tabsList(opts?: TabsClassOptions): string
  tabsTrigger(opts?: TabsClassOptions): string
  tabsContent(opts?: TabsClassOptions): string
  tooltip(): string
  progress(): string
  progressBar(): string
  skeleton(): string
  container(opts?: ContainerClassOptions): string
  flex(opts?: FlexClassOptions): string
  grid(opts?: GridClassOptions): string

  // ---- Variant resolvers (parameterized sub-component classes) ----

  /**
   * Returns card padding class for the given size ('none' removes padding).
   */
  cardPadding(size?: Size | 'none'): string
  /**
   * Returns progress bar height class for the given size.
   */
  progressHeight(size?: Size): string
  /**
   * Returns progress bar fill color class for the given color variant.
   */
  progressColor(color?: ColorVariant): string
  /**
   * Returns toast container positioning class for the given position.
   */
  toastContainer(opts?: { position?: ToastPosition }): string
  /**
   * Returns radio group layout class for horizontal or vertical direction.
   */
  radioGroupLayout(direction?: 'horizontal' | 'vertical'): string
  /**
   * Returns spacer element class (block or inline with configurable size).
   */
  spacer(opts?: { size?: Size; horizontal?: boolean }): string

  // ---- Static class strings (sub-components without variants) ----

  formError: string
  formHint: string
  cardHeader: string
  cardTitle: string
  cardDescription: string
  cardContent: string
  cardFooter: string
  /**
   * Left-accent strip classes for Alert variant="left-accent", keyed by the
   * alert's status (Alert calls `cm.alertLeftAccent({ variant })`). Renders
   * the same inset bar as `UIClassMap.accentCard`.
   */
  alertLeftAccent(opts?: { variant?: 'default' | 'info' | 'success' | 'warning' | 'error' }): string
  /**
   * A block with a colored bar down its leading edge: the bar sits INSIDE the
   * block (inset from the edge, clear of rounded corners, rounded ends) rather
   * than as a hard border-left. The block's own padding, background and border
   * come from the caller (a card, a list row, a note). `tone: 'custom'` reads
   * the color from the `--mol-accent` CSS variable the caller sets inline, for
   * data-driven colors (a chart series, a provider). Pair the heading with
   * `UIClassMap.accentCardLabel` in the same tone so it matches the bar.
   */
  accentCard(opts?: { tone?: AccentTone }): string
  /**
   * The small uppercase heading of an `UIClassMap.accentCard` block, in
   * the bar's color. Same tones as the card.
   */
  accentCardLabel(opts?: { tone?: AccentTone }): string
  alertTitle: string
  alertDescription: string
  avatarImage: string
  avatarFallback: string
  dialogOverlay: string
  dialogHeader: string
  dialogFooter: string
  dialogTitle: string
  dialogDescription: string
  dialogClose: string
  /**
   * Floating close button for title-less dialogs: overlays the top-right
   * corner of the dialog box instead of occupying a full-width header row
   * that pushes the body down.
   */
  dialogCloseFloating: string
  /** Modal centering wrapper: fixed full-screen flex container for centering content. */
  dialogWrapper: string
  /** Modal scrollable body area with padding. */
  dialogBody: string
  /** Bottom-anchored sheet panel for pickers and action menus (mobile pattern). */
  actionSheet: string
  /** Header section of an action sheet with bottom border. */
  actionSheetHeader: string
  dropdownContent: string
  dropdownItem: string
  dropdownSeparator: string
  dropdownLabel: string
  table: string
  tableHeader: string
  tableBody: string
  tableFooter: string
  tableRow: string
  tableHead: string
  tableCell: string
  tableCaption: string
  tooltipContent: string
  toastViewport: string
  toastTitle: string
  toastDescription: string
  toastClose: string
  toastAction: string
  accordionRoot: string
  accordionItem: string
  accordionContent: string
  accordionContentInner: string
  paginationRoot: string
  paginationContent: string
  paginationLink: string
  paginationPrevious: string
  paginationNext: string
  paginationEllipsis: string
  center: string
  srOnly: string
  notSrOnly: string

  // ---- Icon size tokens ----

  /** Extra-small icon (e.g. 12×12). */
  iconXs: string
  /** Small icon (e.g. 16×16). Used for close buttons, sort indicators. */
  iconSm: string
  /** Medium icon (e.g. 20×20). Used for status icons, alerts, toasts. */
  iconMd: string

  // ---- Button sub-element tokens ----

  /** Left icon spacing inside buttons. */
  buttonIconLeft: string
  /** Right icon spacing inside buttons. */
  buttonIconRight: string
  /** Inline spinner inside loading buttons. */
  buttonSpinner: string

  // ---- Card sub-element tokens ----

  /** Interactive card hover/cursor behavior. */
  cardInteractive: string

  // ---- Alert sub-element tokens ----

  /** Alert icon wrapper (prevents shrinking). */
  alertIconWrapper: string
  /** Alert content area (fills remaining space). */
  alertContent: string
  /** Alert dismiss button styling. */
  alertDismiss: string

  // ---- Theme toggle tokens ----

  /** Theme toggle button (icon-only, transparent). */
  themeToggleButton: string

  // ---- OAuth tokens ----

  /** OAuth section "or continue with" divider container. */
  oauthDivider: string
  /** OAuth divider horizontal line. */
  oauthDividerLine: string
  /** OAuth divider text span (with background to mask line). */
  oauthDividerText: string
  /** OAuth button group (flex wrap container). */
  oauthButtonGroup: string
  /** Individual OAuth provider button. */
  oauthButton: string
  /** OAuth button icon wrapper (opacity transition). */
  oauthButtonIcon: string

  // ---- Auth page tokens ----

  /** Auth form error message. */
  authFormError: string
  /** Forgot password link button. */
  forgotPasswordLink: string

  // ---- Floating input sub-element tokens ----

  /** Floating input wrapper (relative inline-block). */
  floatingInputWrapper: string
  /** Floating input field class (sibling-selector hook for floating label). */
  floatingInput: string
  /** Floating input label/placeholder (absolute positioned). */
  floatingLabel: string

  // ---- Input sub-element tokens ----

  /** Input outer wrapper (full-width block). */
  inputWrapper: string
  /** Input inner wrapper (relative positioning for icons). */
  inputInner: string
  /** Left icon/element container inside input. */
  inputLeftElement: string
  /** Right icon/element container inside input. */
  inputRightElement: string
  /** Clear button inside input. */
  inputClearButton: string
  /** Input left padding when left element is present. */
  inputPadLeft: string
  /** Input right padding when right element is present. */
  inputPadRight: string

  // ---- Select sub-element tokens ----

  /** Native select arrow area. */
  selectNative: string
// … truncated — the full declaration is in node_modules/@molecule/app-ui/dist/types.d.ts

Types

Children

Framework-agnostic child content. Use unknown to allow any framework's node type (ReactNode, VNode, etc.).

type Children = unknown

EventHandler

Framework-agnostic event handler.

type EventHandler<E = Event> = (event: E) => void
  • event — The DOM event object.

MouseEventHandler

Framework-agnostic mouse event handler.

type MouseEventHandler = EventHandler<MouseEvent>

KeyboardEventHandler

Framework-agnostic keyboard event handler.

type KeyboardEventHandler = EventHandler<KeyboardEvent>

FocusEventHandler

Framework-agnostic focus event handler.

type FocusEventHandler = EventHandler<FocusEvent>

ChangeEventHandler

Framework-agnostic change event handler.

type ChangeEventHandler = EventHandler<Event>

FormEventHandler

Framework-agnostic form event handler.

type FormEventHandler = EventHandler<Event>

Size

Standard size scale used across all molecule UI components (buttons, inputs, badges, etc.).

type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'

ButtonSize

Button size variants (extends Size with 'icon' for square icon-only buttons).

type ButtonSize = Size | 'icon'

ColorVariant

Semantic color variants used across components for status indication.

type ColorVariant = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info'

ButtonVariant

Button visual variant styles.

type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'link'

InputType

Allowed HTML input type attribute values for the Input component.

type InputType =
  | 'text'
  | 'email'
  | 'password'
  | 'number'
  | 'tel'
  | 'url'
  | 'search'
  | 'date'
  | 'time'
  | 'datetime-local'

ModalSize

Modal size variants including full-screen.

type ModalSize = 'sm' | 'md' | 'lg' | 'xl' | 'full'

TooltipPlacement

Position where a tooltip renders relative to its trigger element (top, bottom, left, right, and corner variants).

type TooltipPlacement =
  'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end'

ClassMapValue

Class value types accepted by the UIClassMap cn() function. Supports strings, booleans, arrays, and conditional objects.

type ClassMapValue =
  | string
  | number
  | boolean
  | undefined
  | null
  | ClassMapValue[]
  | Record<string, boolean | undefined | null>

SpacingScale

Abstract spacing scale. Each styling library maps these to its own units. For Tailwind: 0 → 0, 1 → 0.25rem, 4 → 1rem, 8 → 2rem, etc.

type SpacingScale = 0 | 0.5 | 1 | 1.5 | 2 | 2.5 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16 | 20 | 24

TailwindArbitraryBracket

Tailwind arbitrary value in bracket notation (e.g. [440px], [65%]).

type TailwindArbitraryBracket = `[${string}]`

SpacingProperty

CSS spacing property shorthand (padding/margin with direction).

type SpacingProperty =
  'p' | 'px' | 'py' | 'pt' | 'pb' | 'pl' | 'pr' | 'm' | 'mx' | 'my' | 'mt' | 'mb' | 'ml' | 'mr'

SpacingOverrides

Compound spacing specification for conflict-free overrides.

Pass to sp() to get a style object (for use on the style prop). More specific properties override less specific ones: pr overrides px overrides p (same cascade as CSS shorthand).

Returns Record<string, string> so it is compatible with any framework's inline style API without requiring a React-specific import.

type SpacingOverrides = Partial<Record<SpacingProperty, SpacingScale>>

ResponsiveBreakpoint

Viewport breakpoints for responsive visibility (hiddenBelow/hiddenFrom): sm ≈ 640px, md ≈ 768px, lg ≈ 1024px, xl ≈ 1280px (each ClassMap bond maps them to its own breakpoints).

type ResponsiveBreakpoint = 'sm' | 'md' | 'lg' | 'xl'

TextScale

Text size scale from extra-small to 4xl.

type TextScale = 'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl'

FontWeightScale

Font weight scale.

type FontWeightScale = 'normal' | 'medium' | 'semibold' | 'bold' | 'extrabold'

MaxWidthScale

Max-width scale for constraining content.

type MaxWidthScale =
  | 'none'
  | 'xs'
  | 'sm'
  | 'md'
  | 'lg'
  | 'xl'
  | '2xl'
  | '3xl'
  | '4xl'
  | '5xl'
  | '6xl'
  | '7xl'
  | 'full'
  | 'screen-2xl'
  | TailwindArbitraryBracket

WidthValue

Width value — fractional, keyword, or numeric (mapped to spacing scale).

type WidthValue =
  | 'full'
  | '1/2'
  | '1/3'
  | '2/3'
  | '1/4'
  | '3/4'
  | 'auto'
  | 'screen'
  | 'fit'
  | TailwindArbitraryBracket

HeightValue

Height value — fractional, keyword, or numeric (mapped to spacing scale).

type HeightValue =
  'full' | 'screen' | 'auto' | '1/2' | '1/3' | '2/3' | '1/4' | '3/4' | TailwindArbitraryBracket

ToastPosition

Toast position values for screen placement.

type ToastPosition = 'top' | 'top-right' | 'top-left' | 'bottom' | 'bottom-right' | 'bottom-left'

AccentTone

Tones of an accent bar: the semantic colors, the brand primary, or custom (the --mol-accent variable).

type AccentTone = 'default' | 'primary' | 'info' | 'success' | 'warning' | 'error' | 'custom'

ClassMapOverrides

Overrides for extending a UIClassMap.

Can be a partial map of token replacements, or a function that receives the base ClassMap and returns overrides (useful for extending resolver functions while preserving the base behavior).

type ClassMapOverrides = Partial<UIClassMap> | ((base: UIClassMap) => Partial<UIClassMap>)

Functions

molId(component, context, qualifier)

Generate a semantic automation ID for a component.

function molId(component: string, context: string, qualifier?: string): string
  • component — Component type (e.g., 'button', 'input', 'card')
  • context — Context within the page (e.g., 'login', 'product', 'settings')
  • qualifier — Optional qualifier (e.g., 'submit', 'cancel', item ID)

Returns: The joined automation ID string.

molIdProps(id)

Generate the props object for spreading onto an element.

function molIdProps(id: string): Record<string, string>
  • id — The automation ID string.

Returns: An object with the data-mol-id attribute set.

molSelector(id)

Playwright/testing selector for finding elements by automation ID.

function molSelector(id: string): string
  • id — The automation ID to find.

Returns: A CSS attribute selector string.

molSelectorPrefix(prefix)

Playwright/testing selector for finding elements by partial automation ID. Useful for finding all elements of a type: molSelectorPrefix('button-login')

function molSelectorPrefix(prefix: string): string
  • prefix — The automation ID prefix to match.

Returns: A CSS attribute prefix selector string.

setProvider(provider)

Registers a UI provider as the active singleton.

function setProvider(provider: UIProvider): void
  • provider — The UI provider implementation to bond.

getProvider()

Retrieves the bonded UI provider, or undefined if none is configured.

function getProvider(): UIProvider | undefined

Returns: The bonded UI provider, or undefined.

hasProvider()

Checks whether a UI provider is currently bonded.

function hasProvider(): boolean

Returns: true if a UI provider is bonded.

setClassMap(classMap)

Registers a UIClassMap as the active styling resolver. Called at app startup to wire a styling library (e.g. Tailwind, Bootstrap).

function setClassMap(classMap: UIClassMap): void
  • classMap — The UIClassMap implementation to bond.

getClassMap()

Retrieves the bonded UIClassMap, throwing if none is configured. Use this to resolve styling-agnostic class names in components.

function getClassMap(): UIClassMap

Returns: The bonded UIClassMap implementation.

hasClassMap()

Checks whether a UIClassMap is currently bonded.

function hasClassMap(): boolean

Returns: true if a UIClassMap is bonded.

moleculeSpinnerMarkSvg(options)

The molecule spinner mark as a complete SVG element string (SMIL-animated, framework-agnostic). See the module docblock for usage and gotchas.

function moleculeSpinnerMarkSvg(options?: MoleculeSpinnerMarkOptions): string
  • options — Paint, timings, size, gradient id and a11y shape.

Returns: A <svg>…</svg> markup string.

extendClassMap(base, overrides)

Creates a new UIClassMap by extending a base ClassMap with overrides.

Overrides can be a plain object (for replacing specific tokens/resolvers) or a function that receives the base map (for extending resolvers while preserving base behavior).

function extendClassMap(base: UIClassMap, overrides: ClassMapOverrides): UIClassMap
  • base — The base UIClassMap to extend
  • overrides — Token overrides (object or function returning object)

Returns: A new UIClassMap with overrides applied

Constants

MOL_ID_ATTR

The HTML attribute name for automation IDs.

const MOL_ID_ATTR: 'data-mol-id'

Available Providers

ProviderPackage
Angular UI@molecule/app-ui-angular
NativeWind@molecule/app-ui-nativewind
React UI@molecule/app-ui-react
React Native UI@molecule/app-ui-react-native
Solid UI@molecule/app-ui-solid
Svelte UI@molecule/app-ui-svelte
Tailwind UI@molecule/app-ui-tailwind
Tailwind Glass@molecule/app-ui-tailwind-glass
Vue UI@molecule/app-ui-vue

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-bond ^1.0.1
  • @molecule/app-i18n ^1.0.1

Runtime Dependencies

  • @molecule/app-bond
  • @molecule/app-i18n

Style through getClassMap — NEVER write raw CSS/Tailwind class names in a component. const cm = getClassMap() returns the resolver; use its helpers (cm.flex, cm.surface, cm.textSize(size), the component helpers like cm.button/cm.card, and cm.cn(...) to compose) and pass the result to className. Class-name STRINGS live only in the ClassMap bond (@molecule/app-ui-tailwind), so swapping the styling library touches only the bond — a literal "flex p-4" in a component defeats that and is the #1 styling mistake.

  • Button defaults to type="button". A form's primary action needs type="submit", or Enter does nothing and tests that select button[type="submit"] miss it (X1 RealWorld runs failed 15 browser tests on one Settings button).
  • Inline styles must not fight ClassMap. An inline style has higher specificity and SILENTLY overrides the class controlling the same property (e.g. style={{ background }} kills cm.surface). Use inline only for what ClassMap can't express (a specific pixel width, an SVG attribute, a one-off accent color).
  • Check what a class resolves to before using it — read the bond definition, don't guess a helper name or option value; an invalid cm.* value is a type error or a silent no-op.
  • Every interactive element needs a stable data-mol-id — spread molIdProps (or set MOL_ID_ATTR via molId) so AI agents and tests can target it.
  • tabsList/tabsTrigger/tabsContent are resolver functions, not static strings — call cm.tabsList(opts)/cm.tabsTrigger(opts)/cm.tabsContent(opts) with an optional TabsClassOptions (variant/size). Active-tab styling stays a data-state attribute selector the caller sets, not one of these options. cm.switchBase(opts) also accepts a color (SwitchClassOptions) alongside size.

Translations

Translation strings are provided by @molecule/app-locales-ui.