Changelog

Notable changes and bug fixes in Plex UI

This changelog documents significant updates, bug fixes, and improvements to components in the Plex UI design system. Entries follow the Keep a Changelog format.


0.7.92 — 2026-04-05

Added

  • FloatingLabelInput description (FloatingLabelInput)
    New description prop for helper text below the input. When both errorMessage and description are present, error appears first (closest to input), description below — rendered as a single tight block with margin-bottom only under the last element. Text is left-aligned with input content via padding-inline-start. Error uses plain text (no icon) with role="alert" for accessibility.


0.7.87 — 2026-04-03

Added

  • Form examples (Form Examples)
    New docs page with real-world form patterns: Field label vs section header hierarchy following Apple Settings strategy — SidebarGroupLabel for section headers, Field labels for individual controls.

Fixed

  • Field label-description gap
    Set gap between label and description to 0px for all Field sizes (align with Figma).

  • Switch label-description gap
    Removed 4px gap between Switch label and description (align with Figma).

  • Switch horizontal alignment
    Horizontal Switch fields now align to top instead of center.


0.7.82 — 2026-04-02

Added

  • FileCard (FileUpload)
    Extracted FileCard as a standalone component with optional delete button.

Fixed

  • Control border-radius
    Aligned control border-radius with Figma design tokens for sm, lg, and xl sizes.


0.7.76 — 2026-04-01

Added

  • FileUpload (FileUpload)
    New file upload component with drag-and-drop, multi-file support, middle-truncated filenames, and form integration. CSS pixel-perfect from Figma specs.

  • FloatingLabelInput multiline (FloatingLabelInput)
    New textarea mode with auto-resize, no resize handle, 2-row default, and exact padding match with input mode.

  • RadioGroup/Checkbox descriptions
    Added description examples to RadioGroup and Checkbox docs.

Fixed

  • FileUpload colors
    Icon color set to --input-text-color, filesize to --color-text-tertiary. All colors use CSS variables (no hardcoded values).

  • Textarea label position
    Matched textarea label position to input mode, accounting for border-box.


0.7.68 — 2026-03-30

Added

  • Horizontal menu (Menu)
    New horizontal menu layout with size prop (sm/md/lg), equal-width items, and Play icon.

  • Icon-only tabs (Tabs)
    New example showing icon-only tab items.

  • Icons: AlignCenterVertical, AlignStartVertical, AlignEndVertical, FoldHorizontal, UnfoldHorizontal, TextAlignCenter, TextAlignEnd, ArrowsMaximize, ArrowsMinimize, Play.


0.7.64 — 2026-03-28

Fixed

  • Field gap
    Synced Field gap with Figma (6px). Fixed desktop preview max-width.

  • Mobile previews
    Responsive mobile previews, OG image for Twitter, Product structured data.

  • MarkdownEditor
    Fixed placeholder visibility, default rows=1.


0.7.61 — 2026-03-28

Added

  • Markdown Editor (Markdown Editor)
    New compact WYSIWYG markdown editor embedded in a form field, powered by Tiptap. Supports bold, italic, ordered/unordered lists, and links. Markdown input/output format ([text](url)). Includes link dialog with URL + title fields and remove action. Toolbar buttons show active state and feature design-system tooltips. Works with Field wrapper and supports outline/soft variants.

  • Icons: Bold, Italic, List, ListNumbers.


0.7.51 — 2026-03-25

Added

  • Sidebar Filtered Tree example (Sidebar)
    New demo with type-based filtering via Filter / FilterBadge icons, expand mode toggle (row vs chevron), and search with soft Input variant.

  • Sidebar Action Tree example (Sidebar)
    Drag-and-drop sortable nested items using @dnd-kit/sortable. Hover-revealed action buttons (more, add, reorder). New GripVertical and Parallel icons.

  • Icons: Filter, FilterBadge, GripVertical, Parallel.

  • @plexui/mcp
    MCP server package for AI agents, docs page, and llms.txt.

Fixed

  • Sidebar menu item press effect on action hover
    Hovering action buttons no longer triggers scale/press animation on the parent menu item. Root cause: Tailwind scale property didn't override CSS module transform: scale().

  • Sidebar action tree DnD not working
    Extracted SortableNestedItem to module level (was re-created every render). Removed onPointerDownCapture stopPropagation on drag handle that blocked dnd-kit's onPointerDown listener.

  • Sidebar child item text centered instead of left-aligned
    <button> default text-align: center inherited by flex-1 text spans. Added text-left.

  • Hydration mismatch on sidebar page
    Added stable id prop to DndContext to prevent dnd-kit's auto-incrementing counter from diverging between SSR and client.

  • Dialog mobile buttons, Input line-height & sizing demo

0.7.45 — 2026-03-18

Added

  • DatePicker variants (DatePicker)
    DOB dropdown, time picker, masked date/datetime inputs.


0.7.44 — 2026-03-16

Added

  • Dialog component (Dialog)
    New modal dialog built on Radix Dialog. Compound components: Dialog.Content, Dialog.Trigger, Dialog.Header, Dialog.Title, Dialog.Description, Dialog.Footer, Dialog.Close. Supports 9-step size scale, scroll lock, and focus trapping.

  • Form Examples page (Form Examples)
    Dedicated page for complete authentication flow demos: About You, Sign up, Log in, Enter password, Verify email, Verify email (error), and Confirm phone. Each demo includes a dialog toggle to preview the form inside a modal shell.

  • OTP input mode toggle (Form Examples)
    Verify email and Confirm phone demos now toggle between per-digit OTPInput and standard FloatingLabelInput text field modes.

Changed

Fixed

  • Inline links in docs not distinguishable
    Prose links in documentation pages were rendered in the same color as body text, making them invisible as links. Now use --link-primary-text-color with hover state, matching the TextLink component.


0.7.40 — 2026-03-13

Added

  • StatCard component (Stat Card)
    New dashboard statistics card with 7 configurable features: size (sm/md/lg), tooltip, trendPosition (label/value), trendVariant (positive/negative/neutral), icon with accent colors, and invertTrend. Supports 8 accent color schemes. Icon layout uses align-self: stretch; aspect-ratio: 1 for equal padding. Includes 5 interactive demo components with live controls.

  • DataTable component (Table)
    New data table built on TanStack Table v8. Features: sorting, pagination, global filtering, column visibility, row click, row selection, and empty state handling. Includes DataTableColumnHeader for sortable headers and DataTablePagination with rows-per-page selector.

  • DataTable variant prop (Table)
    Added variant prop with "default" (borderless) and "bordered" (rounded border with tinted header background) options.

  • DataTable column helpers (Table)
    New helper functions for common cell patterns: idCell (monospace ID with CopyTooltip), dateTimeCell (formatted datetime via Intl.DateTimeFormat), statusCell (Badge with automatic status-to-color mapping), and tooltipHeader (header with dashed underline and tooltip).

  • DataTable meta.align (Table)
    Column definitions now support meta: { align: "right" } to align both header and cell content consistently. Extends TanStack Table's ColumnMeta type.

  • Fingerprint icon
    Added new Fingerprint icon to the icon library.

Changed

  • Table table-layout: fixed (Table)
    Table primitive now uses table-layout: fixed to prevent column widths from jumping when sorting changes row order.

  • DataTable pagination buttons (Table)
    Pagination prev/next buttons no longer use pill shape (pill={false}), using standard border-radius instead.


0.7.36 — 2026-03-05

Added

  • Menu.Label and Menu.Group (Menu)
    New compound components for organizing menu items into labeled groups. Menu.Group wraps related items, Menu.Label renders a non-interactive section heading.

  • FloatingLabelSelect component (Floating Label Input)
    New select variant with floating label animation matching FloatingLabelInput. Label floats above when an option is selected.

  • FloatingLabelInput endAdornment (Floating Label Input)
    Added endAdornment prop for placing icons or buttons at the end of the input. Includes password toggle, SSN mask, and birthday masked input demos.

  • FloatingLabelInput placeholder support (Floating Label Input)
    Added placeholder prop with focus-only visibility — placeholder text appears when the input is focused and the label has floated above.

  • Birthday masked input (Field)
    Composition demo for segmented birthday input with segment highlighting, cursor positioning through separators, and live validation. Includes both masked and segmented select variants.

  • Phone input and country selector (Select Control)
    Composition demo combining SelectControl with country flag icons and phone number formatting. Flag icons use lipis/flag-icons 4:3 SVGs via jsDelivr CDN.

  • Column configuration demo (Select)
    Composition demo for table column visibility toggles using Select with checkbox items.

  • Switch description prop (Switch)
    Added description prop to Switch for displaying secondary text below the label.

  • Tabs scrollable demo (Tabs)
    Added Scrollable example to Tabs documentation showing horizontal overflow behavior with auto-scroll to active tab. No extra prop needed — just constrain the container width.

Changed

  • Alert dismiss button (Alert)
    Replaced raw close icon with a soft Button component for the dismiss action. Consolidated Actions and Dismissible sections into single previews for cleaner documentation.

  • Indicator sizes unified (Indicators)
    Standardized all indicator sizes to 18px across LoadingIndicator, CircularProgress, and LoadingDots. Consolidated Indicator and Dismissible demo sections into single preview cards.

  • Checkbox alignment unified with RadioGroup (Checkbox)
    Aligned Checkbox indicator size (18×18px) and label gap with RadioGroup for visual consistency. Fixed label vertical alignment to match RadioGroup first-line behavior. Added combined Checkbox + RadioGroup alignment demo to both doc pages.

  • FloatingLabelInput focus tokens (Floating Label Input)
    Replaced hardcoded blue focus ring color with neutral design tokens for consistency with the rest of the system.

  • Birthday segment highlight token (Field)
    Uses primary/solid token for active segment highlight instead of hardcoded color.

  • Removed "New" badges from component index and sidebar
    Cleared all isNew badges from the components index page and sidebar — too many components were flagged, reducing the signal value.

Fixed

  • Birthday mask cursor positioning (Field)
    Fixed cursor advancing past separators on complete segment and handling backspace through separator characters in the masked birthday input.

  • Birthday inputs browser autocomplete (Field)
    Fixed segmented birthday inputs triggering unwanted browser autocomplete dropdown.

  • Flag icon aspect ratio (Select Control)
    Fixed flag icons rendering as squares instead of proper 4:3 rectangles. Switched to same-height CDN endpoints and fixed alignment in dropdown lists.

  • Input clear button styling (Input)
    Fixed clear button styling inconsistencies when used alongside FloatingLabelSelect demos.

  • Column config demo toggles (Select)
    Fixed broken toggle state and removed unnecessary separator in column configuration popover.

  • Button sizing demo height jump (Button)
    Fixed preview card height jumping when switching between button sizes.

  • FileDocument icon export (Menu)
    Fixed import using non-existent File icon export — replaced with FileDocument.


0.6.0 — 2026-02-01

Added

  • Sidebar component (Sidebar)
    New composable navigation sidebar for application layouts. Includes SidebarProvider for state management, SidebarLayout for layout structure, scrollable SidebarContent, sticky SidebarHeader/SidebarFooter, and organized navigation with SidebarGroup, SidebarMenu, SidebarMenuItem, and SidebarMenuButton. Supports three collapse modes: offcanvas (drawer on mobile, full collapse on desktop), icon (collapses to icon rail), and none (static). Includes keyboard shortcut Cmd+B/Ctrl+B for toggling.

  • Sidebar nested navigation (Sidebar)
    Collapsible nested menus with SidebarMenuSub and SidebarMenuSubButton. Animated chevron toggles via SidebarMenuChevron. Supports multi-level hierarchies for documentation and API reference navigation patterns.

  • Sidebar footer cards (Sidebar)
    SidebarCard component for promotional content, upgrade CTAs, or announcements in the sidebar footer. Includes SidebarCardTitleLink with dismissible close button, SidebarCardContent for description text, and SidebarCardFooter for action buttons. Cards animate in after sidebar expansion with delayed opacity transition.

  • Sidebar badges (Sidebar)
    SidebarMenuBadge container for displaying status indicators, counts, or labels alongside menu items. Pairs with the Badge component supporting all semantic colors (success, warning, danger, info, discovery, caution) and pill shape option.

  • Sidebar mobile menu (Sidebar)
    SidebarMobileMenuButton with animated hamburger icon that transforms to close icon. Mobile behavior is automatic via SidebarProvider with responsive breakpoint detection. Drawer slides in from left with backdrop overlay.

  • Skeleton component (Skeleton)
    New component for displaying loading placeholders. Supports rectangular and circular shapes via circle prop. Uses design tokens for background color and border-radius. Includes composition examples for avatars, cards, text blocks, forms, and tables.

  • Floating Label Input component (Floating Label Input)
    New input component with animated floating label that moves above the input on focus or when filled. Supports error states with errorMessage prop, built-in clear button via onClear, disabled and read-only modes, browser autofill detection with onAutofill callback, and password manager extension blocking with allowAutofillExtensions.

  • Progress Steps component (Progress Steps)
    New component for displaying progress through multi-step processes. Supports horizontal and vertical orientations, three sizes (sm, md, lg), solid and dashed connector styles, custom icons per step, and a minimal bar variant for compact layouts. Includes compound components: ProgressSteps.Step, ProgressSteps.Title, and ProgressSteps.Description. Color schemes include default and success variants.

  • ShimmerText component (ShimmerText)
    New component for animated shimmer effect on text content. Includes ShimmerText for simple shimmer animation and ShimmerableText for streaming-style text reveal with shimmer on the latest token. Supports customizable speed, shimmer width, and color via CSS custom properties.

  • Field component (Field)
    New form field wrapper that provides label, description, and error message with automatic accessibility linking. Generates htmlFor, aria-describedby, and aria-invalid attributes. Supports 9-step size scale, horizontal/vertical orientation, required indicator, and composition with Input, Textarea, Select, Slider, Checkbox, RadioGroup, and Switch controls via render prop pattern.

  • Field optical alignment (Field)
    New opticallyAlign prop on Field that forwards to child controls via cloneElement. Compensates for pill gutter padding in form layouts, aligning labels and error messages with the visual text edge of Input, Select, and Button controls.

  • Slider range mode (Slider)
    Slider now supports dual-thumb range selection via array value/defaultValue. Also added vertical orientation, disabled state, prefix/suffix units, and step markers with labels.

  • Icon and badge support (Tabs)
    Added icon and badge props to Tabs.Tab. Icons automatically size based on control size. Badges support semantic colors (secondary, success, danger, etc.), style variants (soft, solid), and pill shape option.

  • Tabs component (Tabs)
    Renamed and extended SegmentedControl into Tabs. Adds variant prop with "segmented" (default, existing behavior) and "underline" (animated line indicator with no background). Adds orientation prop with "horizontal" (default) and "vertical" support. Sub-components: Tabs.Tab (new canonical name) and Tabs.Option (backward-compat alias). The SegmentedControl import continues to work as a backward-compatible alias.

  • Tabs flush underline variant (Tabs)
    Added flush boolean prop for the underline variant. Removes tab padding so the indicator matches the text width exactly, uses gap-based spacing between tabs, removes the container bottom border, and renders a 1px indicator with no border-radius. Spacing scales with size prop.

  • RadioGroup orientation and block props (Radio Group)
    New orientation prop on RadioGroup.Item positions the radio indicator left (default) or right of the label. New block prop stretches the item to full width with justify-content: space-between for menu-style layouts. Documented with Orientation, With Field, Field error, Choice card, and Card selection examples.

Changed

  • Sidebar variants simplified (Sidebar)
    Removed unused sidebar variants (floating, inset, dual-tier) from type definitions, documentation, and CSS. The component now supports only sidebar (default) and docs variants.

  • Field horizontal orientation refactored (Field)
    Restructured HTML to use LabelGroup (label + description) and Content (control + error) containers for proper horizontal layout. Added fixed-width CSS variables --field-horizontal-label-width and --field-horizontal-control-width. Label vertical centering now uses calc((control-height - label-line-height) / 2) per size for pixel-perfect alignment.

  • Checkbox indicator aligned to Figma (Checkbox)
    Indicator size changed from hardcoded 20×20px to 18×18px using the --menu-checkbox-indicator-size token — matching the Menu CheckboxItem and Figma specification. Border colors changed from solid grays (var(--gray-200)) to alpha-based tokens (var(--alpha-16) default, var(--alpha-20) hover) for consistent rendering on any background.

  • Checkbox label layout (Checkbox)
    Label changed from display: flex; align-items: center to display: block for proper text flow in multi-line labels with descriptions. Gap tokens aligned with Menu CheckboxItem: spacing(2) (8px) for left orientation, spacing(3) (12px) for right orientation.

Fixed

  • Sidebar collapse animation stability (Sidebar)
    Fixed jitter and layout shifts during sidebar collapse/expand animations. Stabilized flexbox rendering for menu items, improved padding transitions, and ensured footer cards animate in only after sidebar fully expands.

  • Sidebar mobile menu label visibility (Sidebar)
    Labels in mobile menu were sometimes hidden due to incorrect collapsed state detection. Fixed to ensure labels are always visible in mobile drawer mode regardless of desktop sidebar state.

  • Month stepper sizing and alignment (Date Range Picker)
    Fixed multiple issues with the month stepper trigger: stepper buttons now properly scale with control size using CSS variable overrides with correct specificity; added vertical alignment for buttons; gap between buttons and text scales with control size; month text min-width now uses em units (9em) to scale with font size, preventing width jumps when switching between months with different name lengths (e.g., "May" vs "September"). Stepper buttons now inherit pill prop from parent, matching SelectControl's Clear button behavior. Added size and pill controls to Storybook docs for testing.

  • Clear button sizing and consistency (Input)
    Clear button overflow and border collision at various sizes. Refactored to use built-in onClear prop with dedicated sizing tokens matching SelectControl's clear-iso button. Updated gutter values and added per-size offsets for proper alignment in both standard and pill modes.

  • FieldError semantic color tokens (Field)
    Replaced hardcoded error colors with --color-text-danger-outline and --color-border-danger-outline semantic tokens. Removed margin-top: -0.1em hack from error icon, now relies on flex centering for alignment.

  • Pill overflow and text overlap (Tabs)
    In pill mode, narrow options (icons, single digits) could be narrower than the control height, causing circular hover highlights and the active thumb to overflow or clip. Added min-width to options in pill mode ensuring they're at least as wide as the control height. Also fixed a scrollable mode regression where text items overlapped, and corrected invalid white-space: wrap to white-space: normal.

  • Highlight overlay radius mismatch (Tabs)
    The hover/active overlay (::before) used the same border-radius as the option, but the overlay is inset by 1px. This caused the inner rounded shape to not nest correctly. Added calculated radius as option radius minus inset, so the overlay aligns flush with the container.

  • Pill gutter scaling with opticallyAlign (Select Control, Input, Button)
    When using opticallyAlign with pill={true}, the margin calculation used only the base gutter and ignored the pill scaling multiplier (1.33×). Controls with pills now correctly multiply the margin by --control-gutter-pill-scaling, aligning properly with Ghost controls.

  • Inconsistent gap between Options and Actions (Select)
    Options used gap: spacing(1) (4px) while Actions used --menu-item-gap (6px). Standardized both to use --menu-item-gap for consistency with the base Menu component.

  • Search input icon color (Select)
    The search icon had className="fill-secondary" but fill="currentColor" in the SVG path inherited color from the Input container, ignoring the class. Fixed by passing fill="var(--color-text-secondary)" as a prop with !important to override currentColor.

  • Missing caution color variant (Badge)
    Badge was missing the caution color option, inconsistent with Button and Alert. Added caution to BadgeProps, implemented CSS styles for all variants (soft, solid, outline), and added to the Colors example matrix.

  • Tabs pill variant radius (Tabs)
    Fixed incorrect border-radius in pill mode for both segmented and vertical orientations. The option radius now correctly uses --radius-full when pill is active.

  • Field label text selection (Field)
    Removed user-select: none from Field label, allowing users to select and copy label text.


Contributing

When adding entries to this changelog:

  1. Add new items under a new Unreleased section at the top
  2. Group by change type: Added, Changed, Deprecated, Removed, Fixed, Security
  3. Link to the affected component in parentheses after the fix title
  4. Describe the issue and the fix concisely
  5. When releasing, move items to a dated version section (e.g., ## 1.2.0 — 2026-01-26)