import { ClassValue } from 'clsx'; import { Theme } from '@material/material-color-utilities'; export { Theme, argbFromHex, hexFromArgb } from '@material/material-color-utilities'; import * as React$1 from 'react'; import React__default, { LabelHTMLAttributes, InputHTMLAttributes, HTMLAttributes, RefObject, ReactNode, ButtonHTMLAttributes, Key as Key$2, JSX as JSX$1, ReactElement } from 'react'; import * as class_variance_authority_types from 'class-variance-authority/types'; import { VariantProps } from 'class-variance-authority'; import { AriaButtonProps, AriaTextFieldProps, AriaCheckboxProps, AriaSwitchProps, AriaRadioProps, AriaRadioGroupProps, AriaTabProps, AriaTabPanelProps, Key as Key$1, AriaDialogProps, AriaLinkOptions, AriaProgressBarProps, PressEvent, AriaMenuTriggerProps, AriaMenuProps } from 'react-aria'; import { Key, SelectionMode, Selection, CalendarState, RangeCalendarState } from 'react-stately'; import { MenuItemProps as MenuItemProps$1, SeparatorProps } from 'react-aria-components'; import { DateValue, CalendarDate } from '@internationalized/date'; /** * Combines and merges Tailwind CSS classes efficiently. * * Uses `clsx` for conditional joining + extended `tailwind-merge` that is * aware of MD3 typography scale utilities (`text-body-large`, etc.) so they * are not incorrectly removed when merged alongside color utilities * (`text-on-surface`, `text-primary`, etc.). * * @example * ```tsx * cn('px-2 py-1', condition && 'bg-blue-500', { 'text-white': isActive }) * // => 'px-2 py-1 bg-blue-500 text-white' * ``` * * @example Merging conflicting classes (later wins) * ```tsx * cn('px-2', 'px-4') * // => 'px-4' * ``` * * @example MD3 typography + color (both kept — no false conflict) * ```tsx * cn('text-body-large', 'text-on-surface') * // => 'text-body-large text-on-surface' * ``` */ declare function cn(...inputs: ClassValue[]): string; /** * Color Utilities * * Utilities for working with Material Design 3 color system. * Provides functions for color manipulation, CSS variable extraction, * and integration with material-color-utilities. */ /** * Material Design 3 color roles */ type MD3ColorRole = "primary" | "on-primary" | "primary-container" | "on-primary-container" | "secondary" | "on-secondary" | "secondary-container" | "on-secondary-container" | "tertiary" | "on-tertiary" | "tertiary-container" | "on-tertiary-container" | "error" | "on-error" | "error-container" | "on-error-container" | "surface" | "on-surface" | "surface-variant" | "on-surface-variant" | "outline" | "outline-variant" | "background" | "on-background"; /** * Get the computed value of a CSS variable * * @param variable - CSS variable name (with or without `--` prefix) * @param element - Element to get computed style from (defaults to document root) * @returns The computed value of the CSS variable * * @example * ```ts * const primaryColor = getColorValue('--md-sys-color-primary'); * // Returns: '#6750a4' * * const primaryColor = getColorValue('md-sys-color-primary'); * // Also returns: '#6750a4' * ``` */ declare function getColorValue(variable: string, element?: HTMLElement): string; /** * Get a Material Design 3 color token value * * @param role - MD3 color role name * @returns The hex color value * * @example * ```ts * const primary = getMD3Color('primary'); * // Returns: '#6750a4' * * const onPrimary = getMD3Color('on-primary'); * // Returns: '#ffffff' * ``` */ declare function getMD3Color(role: MD3ColorRole): string; /** * Add opacity to a hex color * * @param color - Hex color string (with or without #) * @param opacity - Opacity value (0-1) * @returns Hex color with opacity (8-digit hex) * * @example * ```ts * withOpacity('#6750a4', 0.5); * // Returns: '#6750a480' * * withOpacity('6750a4', 0.12); * // Returns: '#6750a41f' * ``` */ declare function withOpacity(color: string, opacity: number): string; /** * Convert hex color to RGB object * * @param hex - Hex color string (with or without #) * @returns RGB object with r, g, b values (0-255) * * @example * ```ts * hexToRgb('#6750a4'); * // Returns: { r: 103, g: 80, b: 164 } * ``` */ declare function hexToRgb(hex: string): { r: number; g: number; b: number; }; /** * Convert RGB to hex color * * @param r - Red value (0-255) * @param g - Green value (0-255) * @param b - Blue value (0-255) * @returns Hex color string * * @example * ```ts * rgbToHex(103, 80, 164); * // Returns: '#6750a4' * ``` */ declare function rgbToHex(r: number, g: number, b: number): string; /** * Generate a complete Material Design 3 theme from a seed color * * @param seedColor - Hex color to generate theme from * @returns Material Color Utilities Theme object * * @example * ```ts * const theme = generateMD3Theme('#6750a4'); * * // Access light mode colors * const lightPrimary = hexFromArgb(theme.schemes.light.primary); * // Returns: '#6750a4' * * // Access dark mode colors * const darkPrimary = hexFromArgb(theme.schemes.dark.primary); * // Returns: '#d0bcff' * ``` */ declare function generateMD3Theme(seedColor: string): Theme; /** * State layer opacity values (Material Design 3 spec) * * These values are used for hover, focus, press, and drag states * in Material Design 3 components. * * @see https://m3.material.io/foundations/interaction/states/state-layers */ declare const STATE_LAYER_OPACITY: { readonly hover: 0.08; readonly focus: 0.12; readonly press: 0.12; readonly drag: 0.16; }; /** * Apply a state layer opacity to a color * * @param color - Base hex color * @param state - State type ('hover' | 'focus' | 'press' | 'drag') * @returns Color with state layer opacity applied * * @example * ```ts * applyStateLayer('#6750a4', 'hover'); * // Returns: '#6750a414' (8% opacity) * * applyStateLayer('#6750a4', 'focus'); * // Returns: '#6750a41f' (12% opacity) * ``` */ declare function applyStateLayer(color: string, state: keyof typeof STATE_LAYER_OPACITY): string; /** * Typography Utilities * * Utilities for working with Material Design 3 typography system. * Provides type-safe access to typography tokens and helper functions * for applying complete text styles. */ /** * Material Design 3 typography scales * * MD3 defines 5 categories of typography, each with 3 size variants. */ type MD3TypographyScale = "display" | "headline" | "title" | "body" | "label"; /** * Typography size variants */ type MD3TypographySize = "large" | "medium" | "small"; /** * Complete typography style name * Combination of scale and size (e.g., 'display-large', 'body-medium') */ type MD3TypographyStyle = "display-large" | "display-medium" | "display-small" | "headline-large" | "headline-medium" | "headline-small" | "title-large" | "title-medium" | "title-small" | "body-large" | "body-medium" | "body-small" | "label-large" | "label-medium" | "label-small"; /** * Typography token properties */ type TypographyProperty = "size" | "line-height" | "weight" | "tracking"; /** * Typography style object returned by getTypographyStyle() */ interface TypographyStyleObject { fontSize: string; lineHeight: string; fontWeight: string; letterSpacing: string; fontFamily?: string; } /** * Get a typography token value * * @param style - Typography style name (e.g., 'display-large', 'body-medium') * @param property - Property to retrieve ('size' | 'line-height' | 'weight' | 'tracking') * @returns The token value as a string * * @example * ```ts * getTypographyToken('display-large', 'size'); * // Returns: '3.5625rem' (57px) * * getTypographyToken('body-medium', 'weight'); * // Returns: '400' * ``` */ declare function getTypographyToken(style: MD3TypographyStyle, property: TypographyProperty): string; /** * Get a complete typography style object * * Returns a style object with all typography properties that can be * spread directly into a React component's style prop. * * @param style - Typography style name * @param includeFontFamily - Whether to include font-family (default: false) * @returns Typography style object for React inline styles * * @example * ```tsx * const displayStyle = getTypographyStyle('display-large'); * // Returns: { * // fontSize: '3.5625rem', * // lineHeight: '4rem', * // fontWeight: '400', * // letterSpacing: '-0.25px' * // } * *

Display Large Text

* ``` * * @example * ```tsx * // With font family * const bodyStyle = getTypographyStyle('body-medium', true); * // Returns: { * // fontSize: '0.875rem', * // lineHeight: '1.25rem', * // fontWeight: '400', * // letterSpacing: '0.25px', * // fontFamily: 'system-ui, -apple-system, ...' * // } * ``` */ declare function getTypographyStyle(style: MD3TypographyStyle, includeFontFamily?: boolean): TypographyStyleObject; /** * Get font family token value * * @param variant - Font family variant ('plain' | 'brand') * @returns Font family stack * * @example * ```ts * getFontFamily('plain'); * // Returns: 'system-ui, -apple-system, Segoe UI, Roboto, ...' * * getFontFamily('brand'); * // Returns: Same as plain (can be customized via CSS variables) * ``` */ declare function getFontFamily(variant?: "plain" | "brand"): string; /** * Typography scale recommendations for semantic HTML elements * * Maps HTML elements to recommended MD3 typography styles. * Based on Material Design 3 guidelines. */ declare const TYPOGRAPHY_ELEMENT_MAP: { readonly h1: "display-large"; readonly h2: "display-medium"; readonly h3: "headline-large"; readonly h4: "headline-medium"; readonly h5: "headline-small"; readonly h6: "title-large"; readonly p: "body-large"; readonly span: "body-medium"; readonly small: "body-small"; readonly button: "label-large"; readonly label: "label-medium"; readonly caption: "label-small"; }; /** * Get recommended typography style for an HTML element * * @param element - HTML element tag name * @returns Recommended MD3 typography style * * @example * ```ts * getTypographyForElement('h1'); * // Returns: 'display-large' * * getTypographyForElement('button'); * // Returns: 'label-large' * ``` */ declare function getTypographyForElement(element: keyof typeof TYPOGRAPHY_ELEMENT_MAP): MD3TypographyStyle; /** * Typography scale usage guidelines * * Provides semantic context for when to use each typography scale. */ declare const TYPOGRAPHY_USAGE: { readonly display: "Large, expressive text for hero sections and marketing"; readonly headline: "High-emphasis text for titles and important headings"; readonly title: "Medium-emphasis text for section headers and card titles"; readonly body: "Plain text for paragraphs, lists, and general content"; readonly label: "UI labels, buttons, tabs, and form elements"; }; /** * Create a typography CSS class name * * Generates a consistent class name for typography styles. * Useful for creating utility classes or component variants. * * @param style - Typography style name * @returns CSS class name string * * @example * ```ts * getTypographyClassName('display-large'); * // Returns: 'text-display-large' * * getTypographyClassName('body-medium'); * // Returns: 'text-body-medium' * ``` */ declare function getTypographyClassName(style: MD3TypographyStyle): string; /** * Responsive typography helper * * Creates a style object that adapts typography across breakpoints. * * @param mobile - Typography style for mobile screens * @param tablet - Typography style for tablet screens (optional) * @param desktop - Typography style for desktop screens (optional) * @returns Object with styles for different breakpoints * * @example * ```tsx * const responsiveTitle = getResponsiveTypography( * 'headline-small', * 'headline-medium', * 'headline-large' * ); * * // Use with CSS-in-JS or styled-components * const Title = styled.h2` * ${responsiveTitle.mobile} * * @media (min-width: 768px) { * ${responsiveTitle.tablet} * } * * @media (min-width: 1024px) { * ${responsiveTitle.desktop} * } * `; * ``` */ declare function getResponsiveTypography(mobile: MD3TypographyStyle, tablet?: MD3TypographyStyle, desktop?: MD3TypographyStyle): { mobile: TypographyStyleObject; tablet?: TypographyStyleObject; desktop?: TypographyStyleObject; }; /** * Convert rem to pixels (assuming 16px base) * * @param rem - Rem value (with or without 'rem' suffix) * @returns Pixel value * * @example * ```ts * remToPx('1.5rem'); * // Returns: 24 * * remToPx('3.5625rem'); * // Returns: 57 * ``` */ declare function remToPx(rem: string): number; /** * Convert pixels to rem (assuming 16px base) * * @param px - Pixel value (with or without 'px' suffix) * @returns Rem value as string * * @example * ```ts * pxToRem(24); * // Returns: '1.5rem' * * pxToRem('57px'); * // Returns: '3.5625rem' * ``` */ declare function pxToRem(px: number | string): string; /** * Truncate text with ellipsis * * Returns CSS properties for single or multi-line text truncation. * * @param lines - Number of lines before truncation (1 for single-line) * @returns CSS properties object * * @example * ```tsx * // Single line truncation * const singleLine = truncateText(1); *
Long text here...
* * // Multi-line truncation (3 lines) * const multiLine = truncateText(3); *

Long paragraph text here...

* ``` */ declare function truncateText(lines?: number): React.CSSProperties; /** * MD3 Top App Bar size variants * * Each variant differs in height, title alignment, and type scale. * - `small`: 64dp height, title left-aligned, title-large type scale * - `center-aligned`: 64dp height, title centered, title-large type scale * - `medium`: min 112dp height, title bottom-left, headline-medium type scale * - `large`: min 120dp height, title bottom-left, display-small type scale * * Medium and large grow vertically when a subtitle is present. * * @see https://m3.material.io/components/top-app-bar/specs */ type AppBarVariant = "small" | "center-aligned" | "medium" | "large"; /** * Material Design 3 Top App Bar Component Props * * Provides a top app bar with navigation icon, title, and trailing action icon slots. * Supports scroll-triggered elevation changes with both controlled and uncontrolled modes. * * **Usage:** * - Pass existing `` components into `navigationIcon` and `actions` slots * - No hardcoded slot components — fully composable API * * @example * ```tsx * // Small variant with navigation icon and actions * * * * } * actions={ * * * * } * /> * * // Center-aligned with controlled scroll state * * * // Large variant for hero/expanded layouts * * ``` */ interface AppBarProps { /** * Size variant of the Top App Bar * Controls height, title position, and type scale * @default 'small' */ variant?: AppBarVariant; /** * The title content. Accepts a string or any React node. * Typography scale is automatically applied based on `variant`. */ title: React__default.ReactNode; /** * Optional subtitle content rendered below the title. * Typography scale and color are automatically applied based on `variant`: * - `small` / `center-aligned`: title-medium, on-surface-variant * - `medium`: title-large, on-surface * - `large`: headline-small, on-surface * * @example * ```tsx * * ``` */ subtitle?: React__default.ReactNode; /** * Navigation icon slot (leading position, optional). * Expects a React node — typically an `` with `aria-label`. * * **Accessibility:** Per MD3 spec, focus should initially land on this element * since it is the first interactive element in the app bar. The `aria-label` * must clearly describe the action (e.g. "Open navigation menu", "Go back"). * * @example * ```tsx * navigationIcon={ * * * * } * ``` */ navigationIcon?: React__default.ReactNode; /** * Trailing action icon slots (up to 3, optional). * Expects one or more React nodes — typically `` components. * * @example * ```tsx * actions={ * <> * * * * } * ``` */ actions?: React__default.ReactNode; /** * Controlled scroll state. * When provided, the component operates in controlled mode — the consumer * is responsible for managing this value. * When `undefined`, internal scroll detection is used (uncontrolled mode). * * - `false` (default): flat surface — `bg-surface`, `shadow-elevation-0` * - `true`: on-scroll surface — `bg-surface-container`, `shadow-elevation-2` */ scrolled?: boolean; /** * Callback fired when the scroll elevation state changes. * In uncontrolled mode, this fires when the user scrolls past the threshold. * In controlled mode, this is an informational callback — the consumer * decides whether to update `scrolled`. * * @param scrolled - The new scroll state */ onScrollStateChange?: (scrolled: boolean) => void; /** * Additional CSS classes to merge onto the root `
` element. * Uses Tailwind CSS — conflicting classes are resolved by `cn()`. */ className?: string; } /** * AppBarHeadless Component Props * * Unstyled primitive for the Top App Bar. * Renders a `
` and manages scroll elevation state. * Use this for full visual control when the styled `AppBar` is not sufficient. * * Extends `React.HTMLAttributes` so all standard HTML attributes * (including `data-*` attributes) are forwarded to the underlying `
`. * * @example * ```tsx * *
My custom layout
*
* ``` */ interface AppBarHeadlessProps extends React__default.HTMLAttributes { /** * The content to render inside the header */ children: React__default.ReactNode; /** * Controlled scroll state. * When `undefined`, the component uses internal scroll detection. */ scrolled?: boolean; /** * Callback fired when scroll state changes */ onScrollStateChange?: (scrolled: boolean) => void; } /** * Material Design 3 Top App Bar Component (M3 Expressive Flexible) * * Provides context and actions for the current screen. Supports four size variants, * a navigation icon slot, title, optional subtitle, and trailing action icon slots. * Implements scroll-triggered elevation changes per MD3 specification. * * **Architecture:** * - Layer 3 (this file): MD3 styled, CVA slot variants, layout composition * - Layer 2: `AppBarHeadless` — `
`, scroll state * - Layer 1: React Aria via `` in consumer slots * * **Slot-based styling:** * All layout and state styling follows the Variants vs States pattern: * - `variant` prop drives design-time choices (height, type scale, alignment) * - Scroll elevation state is emitted as `data-scrolled=""` on the root and * consumed by `group-data-[scrolled]/appbar:*` selectors (presence-based) * - Subtitle presence is emitted as `data-with-subtitle=""` on the root and * used to grow medium/large bar heights (group-data-[with-subtitle]/appbar:*) * * **Key Features:** * - 4 MD3 variants: small, center-aligned, medium, large * - M3 Expressive flexible: medium and large grow vertically with a subtitle * (136dp / 152dp respectively), per the M3 Expressive flexible spec * - Composable API: pass `` nodes into navigation and action slots * - Scroll elevation: bg-surface at rest → bg-surface-container + shadow-elevation-2 * - Controlled and uncontrolled scroll state * - MD3 motion: background-color + box-shadow use standard effects spring pair * - WCAG 2.1 AA: `role="banner"` landmark, keyboard accessible slots * - Dark mode via existing token system * * **M3 Expressive Flexible subtitle type scales:** * - small / center-aligned: label-medium, on-surface-variant * - medium expanded: label-large, on-surface-variant * - large expanded: title-medium, on-surface-variant * * **MD3 Accessibility (m3.material.io/components/app-bars/accessibility):** * - Focus lands on the leading navigation button first (first interactive element in DOM) * - Tab navigates: leading icon → trailing action icons (left to right) * - Space / Enter activates the focused element * - All icon buttons MUST have descriptive `aria-label` attributes * - Title text is the accessibility label for the current page context * * @example * ```tsx * // Small variant (default) * * * * } * actions={ * * * * } * /> * * // Center-aligned with scroll elevation * * * // Medium with expanded title and subtitle (grows to 136dp with subtitle) * * * * } * /> * ``` */ declare const AppBar: React$1.ForwardRefExoticComponent>; /** * Headless AppBar Component (Layer 2) * * Unstyled Top App Bar primitive. Renders a `
` landmark * and manages scroll elevation state via the `useScrollElevation` hook. * * Features: * - Semantic `
` element with `role="banner"` ARIA landmark * - Controlled scroll state via `scrolled` prop * - Uncontrolled scroll state with internal `window` scroll detection * - `onScrollStateChange` callback for both modes * - Full ref forwarding to the header element * * Use this layer when you need full visual control beyond what the styled * `AppBar` provides. * * @example * ```tsx * // Uncontrolled (auto scroll detection) * *
My custom layout
*
* * // Controlled scroll state * *
My custom layout
*
* ``` */ declare const AppBarHeadless: React$1.ForwardRefExoticComponent>; /** * Material Design 3 Button Variants * * Architecture: Variants vs States * - CVA holds design-time structure only (no disabled/loading state variants). * - All interaction states are driven by data-* attributes on the root via * group-data-[x]/button Tailwind selectors in each slot's base classes. * - Content flags (data-with-icon, data-loading) are set explicitly by the component. * * Slot responsibilities: * buttonVariants — root * * // Outlined button (medium emphasis) * * * // Tonal button (secondary emphasis) * * * // With icon (MD3 spec: 18px × 18px) * * * // Loading state * * * // Disabled * * * // Headless version (custom styling) * Click me * ``` */ interface ButtonProps extends AriaButtonProps, Omit, keyof AriaButtonProps | "children"> { /** * Button variant (MD3 specification). * Determines visual emphasis and color roles. * @default 'filled' */ variant?: ButtonVariant; /** * Size variant. * MD3 heights: small=32dp, medium=40dp, large=56dp * @default 'medium' */ size?: ButtonSize; /** * Leading icon (before label text). * * MD3 Specification: Icons must be 18px × 18px. * * @example * ```tsx * * ``` */ icon?: React__default.ReactNode; /** * Trailing icon (after label text). * * MD3 Specification: Icons must be 18px × 18px. * * @example * ```tsx * * ``` */ trailingIcon?: React__default.ReactNode; /** * Button label content. */ children: React__default.ReactNode; /** * Full width button (spans container width). * @default false */ fullWidth?: boolean; /** * Loading state — shows spinner and disables interaction. * The button remains in the DOM as disabled while loading. * @default false */ loading?: boolean; /** * Disable the ripple effect on press. * @default false */ disableRipple?: boolean; /** * Additional Tailwind CSS classes applied to the root element. */ className?: string; /** * Tab index for keyboard navigation. * @default 0 */ tabIndex?: number; /** * Button type attribute. * @default 'button' */ type?: "button" | "submit" | "reset"; } /** * Material Design 3 Button Component (Layer 3: Styled) * * Built on React Aria for world-class accessibility. * Implements the Variants-vs-States architecture: all interaction states are * expressed as data-* attributes on the root and consumed by each slot via * group-data-[x]/button Tailwind selectors — no state variants in CVA. * * Features: * - ✅ 5 MD3 variants: filled, outlined, tonal, elevated, text * - ✅ 3 sizes: small (32dp), medium (40dp), large (56dp) * - ✅ Loading state with spinner * - ✅ Ripple effect (Material Design) * - ✅ Proper MD3 state layer (hover 8%, focus 10%, pressed 10%) * - ✅ Full keyboard accessibility (via React Aria) * - ✅ Screen reader support (via React Aria) * - ✅ Focus management (via React Aria) * - ✅ ButtonGroup-aware: applies connected corner radii and min-width when inside a group * * MD3 Specifications: * - Height: 40dp (medium), 32dp (small), 56dp (large) * - Typography: Label Large (medium), Label Medium (small), Title Medium (large) * - Icon size: 18px × 18px (per MD3 spec) * - State layers: 8% hover, 10% focus/pressed * - Elevation: Level 1 on hover (filled), Level 1 base → Level 2 hover (elevated) * * @example * ```tsx * // Basic usage * * * // With variant * * * // With icon (MD3 spec: icons are 18px × 18px) * * * // Loading state * * * // Disabled * * * // Full width * * * // Inside a connected ButtonGroup * * * * * * ``` */ declare const Button: React__default.ForwardRefExoticComponent & React__default.RefAttributes>; /** * ButtonGroup layout variant (Material Design 3) * * - `standard`: Buttons are separate, gap shrinks/grows with interaction * - `connected`: Buttons are visually joined with 2dp gap; used for toggle patterns */ type ButtonGroupVariant = "standard" | "connected"; /** * ButtonGroup size — inherited by child buttons * * Maps to MD3 button height tiers. Controls inner gap between buttons. */ type ButtonGroupSize = "extra-small" | "small" | "medium" | "large" | "extra-large"; /** * Corner shape applied to child buttons (Material Design 3) * * - `round`: Fully-rounded (pill) outer corners with smaller inner corners (connected variant) * - `square`: Uniform corner radius matching the size tier */ type ButtonGroupShape = "round" | "square"; /** * Selection mode for toggle-button groups * * - `single`: At most one button selected at a time (deselectable) * - `required`: Exactly one button must always be selected (non-deselectable) * - `multi`: Any number of buttons may be selected simultaneously */ type ButtonGroupSelectionMode = "single" | "multi" | "required"; /** * Value provided to child buttons via `ButtonGroupContext` */ interface ButtonGroupContextValue { /** * Layout variant inherited from the parent group */ variant: ButtonGroupVariant; /** * Size inherited from the parent group */ size: ButtonGroupSize; /** * Shape inherited from the parent group */ shape: ButtonGroupShape; /** * Selection mode inherited from the parent group. * `undefined` when the group is action-only (no selection). */ selectionMode: ButtonGroupSelectionMode | undefined; /** * Currently selected button values. * Empty set when nothing is selected. */ selectedValues: Set; /** * Callback invoked when a child button is pressed / toggled. * The child passes its own `value` string. */ onSelectionChange: (value: string) => void; /** * Whether the entire group is disabled. * When `true`, all child buttons should be non-interactive. * * @default false */ isDisabled: boolean; /** * Tailwind class for the inner (adjacent) corner radius in the connected variant. * Applied to all four corners of every button in a connected group. * * @example 'rounded-sm' // for extra-small/small/medium sizes * @example 'rounded-lg' // for large size */ connectedInnerRadius: string; /** * Tailwind class for the outer (exposed) corner radius in the connected variant. * Applied to the start-side of the first button and end-side of the last button. * * @example 'rounded-full' // for round shape * @example 'rounded-sm' // for square shape + extra-small/small/medium sizes */ connectedOuterRadius: string; /** * Whether child buttons should enforce a minimum width of `min-w-12` (48dp). * `true` only for `connected` variant at `extra-small` or `small` size — required by MD3 * to preserve the 48dp touch target at smaller sizes. * * @default false */ enforceMinWidth: boolean; } /** * Props for the `ButtonGroup` and `ButtonGroupHeadless` components. * * Material Design 3 Button Group — an invisible container that: * - Controls the gap between child buttons * - Optionally manages selection state across child toggle buttons * - Passes shape/variant information to children via React Context * * @example * ```tsx * // Standard icon-button group (no selection) * * * * * * // Connected size-picker (single selection required) * * * * * * * // Multi-select connected group (controlled) * * * * * ``` */ interface ButtonGroupProps extends Omit, "onChange"> { /** * Layout variant. * * - `standard`: floating buttons with larger gap; shape transitions on press * - `connected`: joined buttons with 2dp gap; only pressed button changes shape * * @default 'standard' */ variant?: ButtonGroupVariant; /** * Size tier shared across all child buttons. * Controls inner gap values per MD3 spec. * * @default 'medium' */ size?: ButtonGroupSize; /** * Corner shape for child buttons. * * - `round`: pill outer corners, smaller inner corners (connected variant) * - `square`: uniform corner radius matching the size tier * * @default 'round' */ shape?: ButtonGroupShape; /** * Selection mode. When omitted, the group is action-only (no toggle behaviour). * * - `single`: at most one selection, deselectable * - `required`: exactly one must always be selected * - `multi`: any number selected simultaneously * * @default undefined */ selectionMode?: ButtonGroupSelectionMode | undefined; /** * Controlled set of currently selected values. * Each child button should have a matching `value` prop. * Use together with `onSelectionChange` for controlled behaviour. * * @example * ```tsx * const [sel, setSel] = useState(new Set(['8oz'])); * setSel(v)} /> * ``` */ selectedValues?: Set | undefined; /** * Callback fired when the selection changes. * Receives the **new full Set** of selected values after the change. * * @example * ```tsx * console.log([...values])} /> * ``` */ onSelectionChange?: ((values: Set) => void) | undefined; /** * Default selected values for uncontrolled usage. * Ignored when `selectedValues` is provided. * * @default new Set() */ defaultValue?: string | string[] | undefined; /** * Whether the entire group and all child buttons are disabled. * When `true`, the group container receives `data-disabled` and * all children inherit the disabled state via context. * * @default false */ isDisabled?: boolean; /** * Child buttons (Button, IconButton, or any element with a `value` prop). */ children: React__default.ReactNode; /** * Additional Tailwind CSS classes applied to the container element. */ className?: string; } /** * Material Design 3 ButtonGroup Component (Layer 3: Styled) * * Built on the Variants-vs-States architecture: interaction/selection states * are expressed as data-* attributes on the root and consumed by child slots * via group-data-[x]/button-group Tailwind selectors. * * An invisible container that: * - Applies MD3-spec gap between child buttons with spatial spring transitions * - Manages selection state (single / multi / required) across toggle buttons * - Passes shape, size, variant, and disabled metadata to children via React Context * - Emits container-level state attributes for CSS targeting * * Container data attributes: * - `data-connected` — variant is "connected" * - `data-has-selection` — at least one child button is selected * - `data-selection-mode` — "single" | "required" | "multi" * - `data-disabled` — group is non-interactive (via getInteractionDataAttributes) * * Variants: * - `standard`: Buttons float independently. Gap is larger for xs/sm to preserve * 48dp touch targets. Shape morphs transiently on press/select. * - `connected`: Buttons are visually joined with a 2dp gap. Only the pressed * button's shape changes; adjacent buttons are unaffected. * * Selection modes: * - `single`: At most one button selected; deselectable. * - `required`: Exactly one always selected; pressing the active button is a no-op. * - `multi`: Any number of buttons selected simultaneously. * * Motion: * - Gap transitions use spring-standard-fast-spatial (350ms) for smooth layout changes * - Border-radius morphing on child buttons uses expressive-fast-spatial (350ms, overshoot) * - Color/opacity effects on children use spring-standard-fast-effects (150ms, no overshoot) * * @example * ```tsx * // Standard icon-button group (no selection management) * * * * * * // Connected size-picker — required single selection * * * * * * * // Disabled group * * * * * ``` */ declare const ButtonGroup: React__default.ForwardRefExoticComponent>; /** * Headless ButtonGroup Component (Layer 2) * * Unstyled group container using a `
` for semantic grouping. * Provides behavior only — bring your own styles via the styled `ButtonGroup` * or your own className. * * Responsibilities: * - Renders a non-focusable `
` (ARIA group landmark) * - Manages selection state (uncontrolled) or delegates to parent (controlled) * - Provides all group metadata to children via `ButtonGroupContext` * * @example * ```tsx * // Uncontrolled with default value * * Small * Medium * Large * * * // Controlled * * Bold * Italic * * ``` */ declare const ButtonGroupHeadless: React__default.ForwardRefExoticComponent>; /** * Material Design 3 ButtonGroup Variants * * Architecture: Variants vs States * - CVA holds design-time structure only (no interaction state variants). * - All interaction/selection states are driven by data-* attributes on the root * via group-data-[x]/button-group Tailwind selectors. * - Container-level state attributes: * data-connected — variant is "connected" * data-has-selection — at least one child button is selected * data-disabled — entire group is non-interactive * data-selection-mode — "single" | "required" | "multi" (when applicable) * * Slot responsibilities: * buttonGroupRootVariants — layout container; gap, alignment, motion, disabled state * * MD3 Spec (Inner Gap): * | Size | standard | connected | * |-------------|------------|-----------| * | extra-small | 18dp | 2dp | * | small | 12dp | 2dp | * | medium | 8dp | 2dp | * | large | 8dp | 2dp | * | extra-large | 8dp | 2dp | * * Motion: * Gap is a spatial property — uses spring-standard-fast-spatial (350ms, no overshoot * for gap since CSS gap cannot visually overshoot). This ensures smooth transitions * when the size prop changes or buttons are added/removed. * * Note: xs/sm standard gaps are intentionally large to preserve 48dp touch targets. * Connected gap is always 2dp (`gap-0.5`) regardless of size. */ /** * Root container element — carries `group/button-group` scope via the styled layer. * * Handles: * - Flexbox layout (inline-flex or flex) * - Gap between child buttons (per variant × size) * - Spatial motion for gap transitions * - Disabled state (opacity + pointer-events) */ declare const buttonGroupRootVariants: (props?: ({ variant?: "standard" | "connected" | null | undefined; size?: "small" | "large" | "medium" | "extra-small" | "extra-large" | null | undefined; } & class_variance_authority_types.ClassProp) | undefined) => string; /** * Focus ring overlay for the group container. * * Visible only when the group itself receives keyboard focus (rare — typically * focus goes to child buttons). Included for completeness and edge cases where * the group container might receive programmatic focus. * * Uses the same pattern as Switch/Button focus rings: * - Always in DOM (opacity-0) * - Transitions to opacity-100 on group-data-[focus-visible] */ declare const buttonGroupFocusRingVariants: (props?: class_variance_authority_types.ClassProp | undefined) => string; /** * @deprecated Use `buttonGroupRootVariants` instead. * Kept for backward compatibility during migration. */ declare const buttonGroupVariants: (props?: ({ variant?: "standard" | "connected" | null | undefined; size?: "small" | "large" | "medium" | "extra-small" | "extra-large" | null | undefined; } & class_variance_authority_types.ClassProp) | undefined) => string; type ButtonGroupRootVariants = VariantProps; type ButtonGroupFocusRingVariants = VariantProps; /** * Context that provides ButtonGroup state to all child buttons. * * Consumed via `useButtonGroup()` hook inside child components * (Button, IconButton, or any custom button primitive). * * @example * ```tsx * // Inside a child button component * const { variant, size, selectedValues, onSelectionChange } = useButtonGroup(); * ``` */ declare const ButtonGroupContext: React__default.Context; /** * Hook for consuming ButtonGroup context inside child button components. * * @throws When called outside of a `ButtonGroup` or `ButtonGroupHeadless` container. * * @example * ```tsx * const MyButton = ({ value, children }: { value: string; children: React.ReactNode }) => { * const { selectedValues, onSelectionChange, variant } = useButtonGroup(); * return ( * * ); * }; * ``` */ declare function useButtonGroup(): ButtonGroupContextValue; /** * Optional hook for consuming ButtonGroup context inside child button components. * * Unlike `useButtonGroup()`, this hook does **not** throw when called outside a group. * Use this inside `Button` and `IconButton` so they can read group metadata when * rendered inside a `ButtonGroup` but still work standalone. * * Returns `null` when called outside a `` or ``. * * @example * ```tsx * // Inside Button or IconButton * const groupCtx = useOptionalButtonGroup(); * const isConnected = groupCtx?.variant === 'connected'; * ``` */ declare function useOptionalButtonGroup(): ButtonGroupContextValue | null; /** * Returns the Tailwind class strings for connected-variant corner radius overrides. * * Call this inside `Button` or `IconButton` when `variant === 'connected'` is * detected from `useOptionalButtonGroup()`. The returned classes: * * 1. Override the button's default `rounded-full` with the correct inner radius * 2. Use `first:rounded-s-*` to restore outer corners on the first button * 3. Use `last:rounded-e-*` to restore outer corners on the last button * * Relies on CSS pseudo-class specificity — no React-level child enumeration needed. * * @example * ```tsx * const groupCtx = useOptionalButtonGroup(); * if (groupCtx?.variant === 'connected') { * const radiusClasses = getConnectedRadiusClasses(groupCtx); * // → ['rounded-sm', 'first:rounded-s-3xl', 'last:rounded-e-3xl'] * } * ``` */ declare function getConnectedRadiusClasses(ctx: ButtonGroupContextValue, value?: string): readonly string[]; /** * IconButton variant types (MD3 specification) */ type IconButtonVariant = "standard" | "filled" | "tonal" | "outlined"; /** * Color scheme (MD3 color roles) */ type IconButtonColor = "primary" | "secondary" | "tertiary" | "error"; /** * Icon button sizes — M3 Expressive 5-tier system. * * Container heights (dp → px): * - xsmall: 32dp * - small: 40dp * - medium: 56dp (default) * - large: 96dp * - xlarge: 136dp */ type IconButtonSize = "xsmall" | "small" | "medium" | "large" | "xlarge"; /** * Width variant — adjusts container width relative to height. * - narrow: narrower than height * - default: same width as height (square container) * - wide: wider than height */ type IconButtonWidth = "narrow" | "default" | "wide"; /** * Shape variant — controls corner rounding. * - round: fully circular (rounded-full) * - square: size-tiered corner radius (MD3 shape scale) */ type IconButtonShape = "round" | "square"; /** * Material Design 3 Expressive IconButton Component Props * * Icon-only button component following the M3 Expressive spec with: * - 5 sizes: xsmall, small, medium (default), large, xlarge * - 3 width options: narrow, default, wide * - 2 shapes: round (circular), square (corner-radius scale) * - Press shape-morph: corners tighten on press when `shape="round"` * - Toggle support: `selected` + `selectedIcon` * - 4 variants: standard, filled, tonal, outlined * - Mandatory `aria-label` for accessibility * * @example * ```tsx * // Standard icon button * * * * * // Filled with color * * * * * // Toggle button with selectedIcon * setIsFavorite(!isFavorite)} * selectedIcon={} * > * * * * // Large square shape * * * * * // Disabled * * * * ``` */ interface IconButtonProps extends AriaButtonProps { /** * Button variant * @default 'standard' */ variant?: IconButtonVariant; /** * Color scheme * @default 'primary' */ color?: IconButtonColor; /** * Size tier (M3 Expressive 5-tier system) * @default 'medium' */ size?: IconButtonSize; /** * Container width relative to height. * - `narrow`: slimmer than the container height * - `default`: square container (width = height) * - `wide`: wider than the container height * * @default 'default' */ width?: IconButtonWidth; /** * Corner shape. * - `round`: fully circular (pill-shaped) * - `square`: size-tiered corner radius from the MD3 shape scale * * Applies a press shape-morph (corners tighten on press, spring back on release). * * @default 'round' */ shape?: IconButtonShape; /** * Icon content. Recommended icon sizes per container size: * - xsmall: 20×20px * - small / medium: 24×24px * - large: 32×32px * - xlarge: 40×40px */ children: React__default.ReactNode; /** * Icon to display when `selected` is `true`. * When provided with a `selected` prop the button becomes a toggle button. * If omitted, `children` is shown in both states. */ selectedIcon?: React__default.ReactNode; /** * Toggle state. * When defined (even as `false`) the button behaves as a toggle button and * `aria-pressed` is set. * @default undefined */ selected?: boolean; /** * Disable ripple effect * @default false */ disableRipple?: boolean; /** * Additional CSS classes (Tailwind) */ className?: string; /** * Value string used by ButtonGroup context for selection tracking and * shape-morph logic in connected groups. Required when the IconButton is * inside a ``. */ value?: string; /** * HTML title attribute for tooltip. * Recommended for better UX on desktop. */ title?: string; /** * Mouse down handler (for ripple effect and custom handling) */ onMouseDown?: (e: React__default.MouseEvent) => void; /** * REQUIRED: Accessible label for screen readers. * Since IconButton has no visible text, this is mandatory. * * @example * aria-label="Delete item" * aria-label="Add to favorites" * aria-label="Close dialog" */ "aria-label": string; } /** * Material Design 3 Expressive — IconButton Component (Layer 3: Styled) * * Built on React Aria for world-class accessibility. Implements the * Variants-vs-States architecture: all interaction/selection states are * expressed as data-* attributes (emitted by IconButtonHeadless) and consumed * by each slot via group-data-[x]/icon-button Tailwind selectors — no state * variants in CVA. * * Features: * - ✅ M3 Expressive 5-tier sizes: xsmall, small, medium, large, xlarge * - ✅ 3 width options: narrow, default, wide * - ✅ 2 shapes: round (circular), square (MD3 corner scale) * - ✅ Press shape-morph (round shape springs into square corner on press) * - ✅ 4 variants: standard, filled, tonal, outlined * - ✅ 4 color roles: primary, secondary, tertiary, error * - ✅ Toggle support (selected + selectedIcon) * - ✅ MD3-correct state layer: per-variant color, opacity-8/10/10 * - ✅ MD3-correct disabled: content opacity-38 + container on-surface/12 * - ✅ Ripple effect on press * - ✅ ButtonGroup-aware: connected corner radii + min-width * - ✅ Mandatory aria-label for accessibility * * @example * ```tsx * // Standard icon button * * * * * // Filled with color, large * * * * * // Toggle button with selectedIcon * setSelected(!selected)} * selectedIcon={} * > * * * * // Square shape, wide width * * * * ``` */ declare const IconButton: React__default.ForwardRefExoticComponent>; /** * Headless IconButton Component (Layer 2) * * Unstyled icon button primitive using React Aria for accessibility. * Provides behavior AND emits MD3-compliant data-* interaction attributes * so the styled Layer 3 can drive all visual states through CSS alone. * * Emitted data attributes (via getInteractionDataAttributes): * - `data-hovered` — pointer is over the button * - `data-focus-visible` — keyboard/programmatic focus is visible * - `data-pressed` — button is being pressed * - `data-selected` — toggle button is in the ON state * - `data-disabled` — button is non-interactive * * Content flags (set explicitly): * - `data-toggle` — button is a toggle (selected prop is defined) * * Features: * - Full keyboard navigation (Enter, Space) * - Screen reader support (aria-pressed for toggle buttons) * - Touch/pointer event handling * - Focus management * - Hover detection (useHover — pointer-only, not keyboard) * - Disabled state handling * * @example * ```tsx * // Advanced custom styling * * * * ``` */ interface IconButtonHeadlessProps extends AriaButtonProps { /** Additional CSS classes */ className?: string; /** Icon content */ children: React.ReactNode; /** Tab index for keyboard navigation @default 0 */ tabIndex?: number; /** Mouse down handler (for ripple effect) */ onMouseDown?: (e: React.MouseEvent) => void; /** Button type attribute @default 'button' */ type?: "button" | "submit" | "reset"; /** * Toggle selected state. * When defined, sets aria-pressed and emits data-selected / data-toggle. */ isSelected?: boolean; /** * Whether this button behaves as a toggle (i.e. selected prop was passed). * Drives `data-toggle` attribute; determines whether aria-pressed is set. */ isToggle?: boolean; /** Whether the button is disabled */ isDisabled?: boolean; /** REQUIRED: Accessible label for screen readers */ "aria-label": string; /** HTML title attribute for tooltip */ title?: string; } declare const IconButtonHeadless: React$1.ForwardRefExoticComponent>; /** * Material Design 3 FAB Variants — Slot-based architecture * * Architecture: Variants vs States * - CVA holds design-time structure only (no disabled/loading state variants). * - All interaction states are driven by data-* attributes on the root via * group-data-[x]/fab Tailwind selectors in each slot's base classes. * - Content flags (data-with-icon, data-loading) are set explicitly by the component. * - Self-targeting data-[x]: selectors handle root-level disabled styling. * * Slot responsibilities: * fabVariants — root