/** * DynamicToggle type definitions (v2 API). * * CSS-animated toggle where one option expands into sub-options. * Uses hidden radios + `:has(:checked)` for zero-JS animation. * Optional gooey morph via `GooeyCanvas` or `MorphPath` primitives. * * @module @mks2508/mks-ui/react/ui/DynamicToggle */ import type { SlotOverrides, IBaseConfig } from '../../../core/types'; import type { DynamicToggleSlot, DynamicToggleVariantProps } from './DynamicToggle.styles'; /** How the group appears when collapsed (standalone option active). */ export type DynamicToggleCollapsedMode = 'title' | 'opts' | 'title-opts'; /** * Bubble position relative to the pill. * - `top` — bubble grows above the pill (default) * - `bottom` — bubble grows below the pill * - `none` — no bubble, no gooey canvas, label-only pill with indicator */ export type DynamicToggleBubblePosition = 'top' | 'bottom' | 'none'; /** * Animation and behavior configuration for DynamicToggle. * * Controls timing, easing, and indicator behavior. * The `morph` rendering mode is a root-level variant prop, NOT in config. * * @example * ```tsx * * ... * * ``` */ export interface IDynamicToggleConfig extends IBaseConfig { /** CSS transition duration in seconds (default: 0.22) */ duration?: number; /** Indicator slide duration in seconds (default: 0.3) */ indicatorDuration?: number; /** Indicator slide easing (default: material standard cubic-bezier) */ indicatorEasing?: string; /** Force translate-based indicator instead of CSS Anchor (debug/compat) */ forceTranslateIndicator?: boolean; } /** Structured payload for group registration via context. */ export type DynamicToggleGroupRegistration = { label: string; values: string[]; bubblePosition: DynamicToggleBubblePosition; collapsedMode: DynamicToggleCollapsedMode; bubble?: React.ReactNode; }; /** * Context shared between DynamicToggle root and its children. */ export type DynamicToggleContextType = { /** Current selected value */ value: string; /** Update selected value */ setValue: (value: string) => void; /** Auto-generated radio group name */ groupName: string; /** Whether a group child is active */ groupActive: boolean; /** Whether the toggle is disabled */ disabled: boolean; /** Effective morph mode after variant resolution */ morph: 'none' | 'filter' | 'path'; /** Register group info (called by DynamicToggleGroup on mount) */ registerGroup: (info: DynamicToggleGroupRegistration) => void; }; /** * Props for the DynamicToggle root container. * * Supports exactly one `DynamicToggleOption` + one `DynamicToggleGroup`. * The group expands into sub-options when one of its children is active. * * @example * ```tsx * * Tree * * Flat * Grouped * * * ``` */ export interface IDynamicToggleProps extends DynamicToggleVariantProps, Omit, 'defaultValue' | 'children'> { /** Controlled value */ value?: string; /** Uncontrolled default value */ defaultValue?: string; /** Change callback */ onValueChange?: (value: string) => void; /** Disable the entire toggle */ disabled?: boolean; /** Slot class overrides */ slots?: SlotOverrides; /** Animation/behavior configuration */ config?: IDynamicToggleConfig; /** DynamicToggleOption and DynamicToggleGroup children */ children: React.ReactNode; } /** * Props for a single toggle option (top-level or inside a group). * * @example * ```tsx * Tree * ``` */ export interface IDynamicToggleOptionProps { /** Value this option represents */ value: string; /** Label content */ children: React.ReactNode; /** Additional class */ className?: string; } /** * Props for an expandable group of options. * * `bubblePosition` is the single prop that controls whether a bubble * label appears and where it is positioned. * * When none of the group's options are active, shows collapsed content * based on `collapsedMode`: * - `'title'` — only the group label * - `'opts'` — only the combined sub-option text ("Solo · Team") * - `'title-opts'` — WIP: currently falls back to 'title' behavior * * @example * ```tsx * // With bubble above * * Solo * Team * * * // No bubble — simple pill toggle * * A * B * * ``` */ export interface IDynamicToggleGroupProps { /** Label shown as group title / collapsed text */ label: string; /** Custom content for the bubble label (overrides label text when provided) */ bubble?: React.ReactNode; /** * Bubble position relative to the pill. * `'none'` = no bubble, no gooey — label-only pill with indicator. * @default 'top' */ bubblePosition?: DynamicToggleBubblePosition; /** How the group appears when collapsed (default: 'title') */ collapsedMode?: DynamicToggleCollapsedMode; /** Sub-option children */ children: React.ReactNode; /** Additional class */ className?: string; } //# sourceMappingURL=DynamicToggle.types.d.ts.map