Skip to content

Latest commit

 

History

History
212 lines (173 loc) · 49 KB

File metadata and controls

212 lines (173 loc) · 49 KB

Changelog

All notable changes to the PremUI Design System are documented here.

Format follows Keep a Changelog.


[Unreleased]

2026-07-12 — 19:40 IST

Added

  • HeaderCard / SidebarHeader — real Placeholder brand data + a working workspace switcher — The logo, brand name, and description shown in the sidebar's header card now come from the project's existing Placeholder brand asset library (PlaceholderBrand + PLACEHOLDER_DATA, 9 real companies) instead of a static "Apex Financial" default. Clicking the header's expand button opens a real switcher panel — a fixed-position, click-outside-to-close dropdown listing every placeholder company (logo, brand name, category), built with the existing DropdownItem. The panel opens beside the header card (top-aligned to its right edge) rather than dropping down below it, so it doesn't get clipped by the sidebar's own overflow: hidden or cover the nav items underneath, and shows the full company list with no internal scrollbar. New company/defaultCompany/onCompanyChange/companies props support both controlled and uncontrolled usage; brand/description/leading remain available as manual overrides. SidebarNavigation's stories were updated to pass company through instead of hardcoded brand text, demonstrating the real data flow end to end.
  • TopbarItem + TopbarUserProfile + TopbarIconButton Components (Product Components > Navigation > Topbar Components) — Ported from Figma (Align UI Design System 2.0, nodes 3802:24588 + 3814:24667 + 3814:25156). TopbarItem is SidebarItem's horizontal counterpart — a nav tab with an optional leading icon, "New" badge, red notification-count badge, and trailing chevron; its active state recolors the icon to --primary-base and the label to --color-text-strong rather than an accent bar, per the fetched Active-state variable trace (no accent-bar token existed for this component). TopbarUserProfile is a compact avatar+name+verified chip whose chevron flips between down/up as it opens. TopbarIconButton is a 40px icon-only action button (its Figma node exported as a flattened raster with no decomposed layers, so its Default/Hover/Active colors were confirmed via get_variable_defs rather than the usual generated code) with an optional small red unread-notification dot.
  • TopbarNavigation Component (Product Components > Navigation) — Ported from Figma (Align UI Design System 2.0, node 3814:25274). The full top nav bar, composed entirely from the Topbar Components above plus the existing DropdownItem and PlaceholderBrand. Figma's rigid product: "HR Management" | "Finance & Banking" variant enum (two hardcoded nav configurations) was collapsed into plain items/moreItems props, matching the same pattern already used for SidebarNavigation's mainItems. The trailing "Others" chevron — purely decorative in the Figma source, with no defined destination — was made genuinely functional instead of left as a dead end: it's a real overflow dropdown (the same fixed-position + click-outside technique introduced for the HeaderCard switcher above) listing moreItems. Real controlled/uncontrolled active-tab state and a real search input, following the same conventions as SidebarNavigation.

2026-07-12 — 20:50 IST

Fixed

  • vitest.config.ts — module resolution errors — Resolved 7 TypeScript "Cannot find module" errors (node:path, node:url, vitest/config, @storybook/experimental-addon-test/vitest-plugin, @vitest/browser-playwright) that appeared in the IDE. Root causes: (1) @vitest/browser-playwright only exists starting from vitest v4 — the project uses v3, which ships the Playwright provider directly inside @vitest/browser/providers; replaced the non-existent v4-only import with the built-in 'playwright' string provider supported by @vitest/browser@3.x. (2) node:path/node:url were invisible to the TS compiler because @types/node was not installed — added @types/node to devDependencies and npm install --legacy-peer-deps to pick it up. (3) vitest.config.ts itself was excluded from compilation since the tsconfig.json include array only covered src/**/* — added vitest.config.ts and vitest.shims.d.ts to include so the compiler now processes them with the correct settings.
  • vitest.shims.d.ts — stale type reference — The file referenced /// <reference types="@vitest/browser-playwright" />, a package that does not exist for Vitest 3. Updated to /// <reference types="@vitest/browser/providers/playwright" /> (the correct path inside the installed @vitest/browser@3.2.7 package) and added /// <reference types="node" /> so node:* built-ins are available during config compilation.
  • tsconfig.json — invalid ignoreDeprecations value + deprecated baseUrl — The "ignoreDeprecations": "6.0" option was invalid; the only accepted value in TypeScript is "5.0". Since the project already runs TypeScript 6.0.2, the workaround was unnecessary — removed it entirely. Also removed the now-deprecated baseUrl: "." option; on TypeScript 6, paths mappings work independently of baseUrl, so the @premui/* alias continues to resolve correctly without it.
  • package.json — wrong browser-playwright peer — Replaced @vitest/browser-playwright@^4.1.10 (requires vitest@4, incompatible with this project's vitest@^3) with playwright@^1.49.0, which is the actual optional peer dependency declared by @vitest/browser@3.2.7 for the built-in Playwright provider.

2026-07-12 — 15:29 IST

Added

  • New "Product Components" top-level category — for higher-level, composed product UI assembled from the primitive components below, as opposed to 1:1 Figma atoms.
  • SidebarItem + HeaderCard + SidebarHeader + UserProfileCard + SidebarFooter + SidebarFeatureCard Components (Product Components > Navigation > Sidebar Components) — Ported from Figma (Align UI Design System 2.0, nodes 3741:45019 + 3802:10204 + 3789:3886 + 3802:11038 + 3789:5341 + 3789:3551). SidebarItem is the nav row (leading icon or ChartLegendDot indicator, optional badge/notification-count/keyboard-shortcut, an icon-only collapsed "rail" mode, and a primary accent bar for the persistent active state). HeaderCard/SidebarHeader and UserProfileCard/SidebarFooter are workspace-switcher and signed-in-user cards, each with a thin wrapper adding an optional divider and collapsed handling. SidebarFeatureCard collapses Figma's 24 variants (6 types — Daily Meeting/Progress Bar/Icon & Link/Left Icon/Support/Cloud Storage — × 4 styles — Stroke/Gray/Primary/Neutral) into one component with type/style props, reusing the existing Avatar, ProgressBar, LinkButton, and CompactButton components rather than re-implementing each combination; its progress percentages are real (driven by a percentage prop), not Figma's static 80%/90% demo. Fixed a follow-up visual bug during review: on the primary/neutral (dark) card styles, ProgressBar's default blue fill was indistinguishable from the primary-blue card background — added a scoped override (white fill, translucent track) matching the source's actual primary-darkest-track treatment.
  • SidebarNavigation Component (Product Components > Navigation) — Ported from Figma (Align UI Design System 2.0, node 3802:11759). The full sidebar shell, composed entirely from the Sidebar Components above (SidebarHeader, SidebarItem, SidebarFeatureCard, SidebarFooter) rather than re-implementing their internals — this component is pure composition plus real navigation state: a real controlled/uncontrolled active-item selection (click any item to select it) and a real search input, plus a collapsed prop that switches every child to its icon-only rail mode at once.

Fixed

  • Tooltip — Rebuilt the tail from scratch after re-verifying against the Figma source: it isn't a CSS trick, it's a real SVG (a rounded-tip triangle path stroked in the border color, plus an unstroked rect that locally masks the card's own border line at the seam), stacked as a plain flex sibling with no gap/overlap. Replaced the earlier CSS rotated-square hack — which had a visible seam and a thinner-looking stroke on the tail than the card (rotated borders anti-alias across the diagonal and read lighter) — with the exact SVG paths from Figma, fixing both issues at once. Also fixed a soft gray halo around the tail in dark mode: the card's box-shadow blur (up to 48px) was bleeding upward past the card's rectangle since box-shadow only follows a literal box, not the tail's silhouette — moved the outer shadow layers to filter: drop-shadow() on the whole tooltip so they trace the real tail+card union.
  • KeyIcon (used in Popover) / StatusModal status icon / PaymentIcon — These circular icon containers were rendering as ovals, not perfect circles, because their size was inferred from the icon glyph's content box (padding + font-size on an icon font) rather than an explicit width/height — icon-font line-height rarely equals its em-width. Fixed all three with explicit sizing; also corrected StatusModal's icon from a rounded-square radius to full radius per design review.
  • RatingBar — The right-edge border was being clipped by the container's overflow: hidden, because each row relied on summed per-item borders instead of one border owned by the container; flex sub-pixel rounding across 5 fractional-width items shaved the last item's border off. Moved the outer border onto the container itself, with items only contributing internal dividers.
  • Scroll / ScrollArea — Fixed a perceptible lag between scrolling and the custom thumb's visual update. The thumb's position was driven entirely through React state on every native scroll event (render-cycle delay on every tick), and a stray CSS transition: top animated each position change by 200ms on top of that. Switched to direct DOM mutation via a forwarded ref inside a requestAnimationFrame-throttled scroll handler — React state now only toggles the scrollbar's visibility, not its position — and removed the transition.
  • HintText icon/text misalignment (visible in CounterInput, Input, and every other component using HintText) — the icon wrapper's implicit height (from the icon font's own line-height) didn't match the adjacent text's explicit line-height: 16px, offsetting the icon vertically. Fixed by sizing the icon box explicitly to 16×16 with line-height: 1.
  • Storybook "Set object" crashes — Around 20 story files had ReactNode-typed props (or array props like items/members) with no explicit argTypes control override; Storybook inferred an "object" control for these, and clicking "Set object" reset the value to {}, which isn't a valid React child and crashed rendering. Added explicit control: 'text' or table: { disable: true } overrides across Button, LinkButton, FancyButton, SocialButton, Badge, StatusBadge, Tag, CheckboxLabel, CheckboxCard, CommandMenuItem, ButtonGroup, Breadcrumb, AvatarGroup, SegmentedControl, Table, and the whole TextInput family (Input, TagInput, CounterInput, InlineInput).
  • PinInput — Added a "Show value (demo)" Storybook toggle so the raw PIN debug caption can be hidden; it's a story-only helper, not part of the component itself.

Added

  • Badge Component — Ported from Figma (Align UI Design System, Badge [1.1] component set). 2 sizes (sm/16px, md/20px) × 4 styles (filled/light/lighter/stroke) × 10 colors (mapped to the 10 semantic state tokens) × basic/dot/left-icon/right-icon layouts, plus a fixed-width count mode for notification badges.
  • Banner Component — Ported from Figma (Align UI Design System, Banner [1.1] component set). Full-width top-of-page announcement bar, 4 styles × 5 statuses (error/warning/success/information/feature), optional action link and dismiss.
  • StatusBadge Component — Ported from Figma (Align UI Design System, Status Badge [1.1] component set). 2 styles (stroke/light) × 5 statuses (completed/pending/failed/information/disabled), with an icon or small colored-dot mode. Text is neutral in stroke style and state-colored in light style (disabled is always neutral).
  • Breadcrumb + BreadcrumbItem Components — Ported from Figma (Align UI Design System, Breadcrumbs Group [1.1] + Breadcrumb Items [1.1]). Navigation trail with arrow/slash/dot dividers; the last item renders as the non-interactive current page (aria-current="page").
  • SocialButton Component — Ported from Figma (Align UI Design System, Social Buttons [1.1] component set). 7 brands (Apple/X/Google/Facebook/LinkedIn/GitHub/Dropbox) × 2 styles (filled/stroke), icon-only mode. Uses RemixIcon's brand glyphs instead of the original multi-color Figma logo assets, per the project's Remix-Icon-only rule; per-brand hover overlay (white or black at 16%) and focus ring reuse existing shadow tokens.
  • CompactButton Component — Small square icon-only button (dismiss/close), 4 styles (stroke/ghost/modifiable/white) × 2 sizes (24px/20px) × 4 states (default/hover/active/disabled), rounded-square or full-circle radius. A state prop can force Default/Hover/Active/Disabled for design-QA galleries; real :hover/:active/:focus-visible/disabled drive normal interactive usage. First built from an AI Handoff visual pack while the Figma MCP was rate-limited, then verified and corrected directly against Figma MCP (Align UI Design System 2.0) once the user upgraded their plan — the trace corrected radius-off to --radius-6 (was guessed as radius-8), Active to a solid --color-bg-surface (#262626) background with a white icon (was guessed darker/lighter), and Modifiable's hover/active to a translucent --alpha-white-alpha-16 overlay with a white border ring on active (was guessed as opacity dimming).
  • FancyButton Component — Ported from Figma (Align UI Design System 2.0, Fancy Buttons [1.1] component set). High-emphasis button, 4 types (neutral/primary/destructive/basic) × 3 sizes (md/sm/xs) × 3 states (default/hover/disabled). Neutral/Primary/Destructive share a gradient-filled surface + 1px ring shadow (Primary reuses --primary-base so it re-colors with the theme-accent switcher); Basic is a plain white bordered surface. Neutral's label uses --color-text-white (dark-mode-aware) while Primary/Destructive use --color-static-white (always white), matching the same distinction already established in Button.css.
  • ButtonGroup + ButtonGroupItem Components — Ported from Figma (Align UI Design System 2.0, Button Group [1.1] + Button Group Items [1.1]). Segmented control, 3 sizes (sm/xs/2xs), with adjacent segment borders collapsed via margin-left: -1px (classic segmented-control technique). active is a persistent "selected segment" prop, not a :active press — the state prop only forces Default/Hover/Disabled for design-QA galleries.
  • Checkbox + CheckboxLabel + CheckboxCard Components — Ported from Figma (Align UI Design System 2.0, Checkbox [1.1] + Checkbox Label [1.1] + Checkbox Card [1.1]). Checkbox draws unchecked as a colored ring behind a smaller white inset box (matching Figma exactly) and checked/indeterminate as a solid filled square; Figma's "Focused" variant (which recolors the ring) was replaced with the system's standard :focus-visible ring for consistency. CheckboxLabel composes label/sublabel/badge/description/link, reusing the existing Badge and LinkButton components. CheckboxCard is a selectable bordered card; Figma's 6 rigid "type" variants (which bake in specific brand logos like Mastercard/Spotify) were replaced with one generic leading ReactNode slot. Fixed a nested-<button> hydration error by adding a decorative render mode to Checkbox (renders a <span> instead of <button> when embedded inside CheckboxCard's own button).
  • ColorPicker + ColorSpectrum + ColorSliders + ColorDots Components — Ported from Figma (Align UI Design System 2.0, Color Picker [1.1] + sub-components). A genuinely functional, pointer-draggable color picker: ColorSpectrum (2D saturation/brightness), ColorSliders (hue + opacity, checkerboard-backed), and ColorDots (10 preset swatches reusing the same color→state-token mapping as Badge). New colorUtils.ts implements HSV↔RGB↔hex conversion. Figma's Hex/RGB/HSB format-switcher dropdown was simplified to a static hex input.
  • ContentDivider Component — Ported from Figma (Align UI Design System 2.0, Content Divider [1.1] component set). 9 variants: line, spaced line, labeled line ("OR"), standalone label, solid-background label bar, and 4 button/button-group + line combinations. The button variants compose the existing FancyButton (type="basic" size="xs") and ButtonGroup components rather than re-implementing Figma's nested "Buttons [1.1]"/"Button Group [1.1]" instances from scratch.
  • CommandMenu + CommandMenuSearchInput + CommandMenuItem + CommandMenuFooter Components — Ported from Figma (Align UI Design System 2.0, Command Menu Search Input [1.1] + Command Menu Items [1.1] + Command Menu Footer [1.1]). CommandMenuSearchInput is a real controlled search field that swaps its trailing shortcut/info affordance for a clear button once text is entered. CommandMenuItem simplifies Figma's 6 rigid "type" variants (which bake in Spotify/Apex/US-flag images) into one generic leading ReactNode slot, and reuses Badge for its "NEW"-style tag. CommandMenuFooter reuses LinkButton for its "Help Center" link. CommandMenu composes all three into a bordered card.
  • DatePicker + DateRangePicker + DayCell + DayLabel + DateSelector + PeriodRangeItem Components — Ported from Figma (Align UI Design System 2.0, Day Label & Cells [1.1] + Date/Range Picker [1.1] + Period Range & Date Selector [1.1]). Genuinely functional calendars, not static mockups: dateUtils.ts generates real Monday-first, leap-year-correct month grids. DatePicker is a single month with a Cancel/Apply footer; DateRangePicker adds a preset sidebar (Today/Last 7 days/etc.) and two side-by-side months with click-to-select range logic (first click sets the start, second sets the end, clicking again starts a new range). Both reuse this project's existing CompactButton (month-nav arrows) and Button (footer actions). Fixed a CSS specificity bug caught during visual verification: :not(:disabled):hover had higher specificity than [data-selected], so hovering a selected day showed the gray hover fill instead of staying solid blue — changed to plain :hover (disabled cells already get pointer-events: none, so they never match :hover regardless).
  • Switch Component — New primitive (32×20 track, 16px thumb) built to match the existing --shadow-component-toggle-switch token; no standalone Figma frame existed for it, only an inline raster reference within DrawerFooter's Toggle type. Ships with a decorative render mode (renders a <span>, not <button>) for embedding inside another already-interactive row, following the same pattern as Checkbox.
  • DrawerHeader + DrawerFooter + StepperDots Components — Ported from Figma (Align UI Design System 2.0, Drawer Header [1.1] + Drawer Footer [1.1]). DrawerHeader supports Basic/Left-Icon types × Small/Large sizes, an optional count badge (reuses Badge's count mode), an optional Link Button (Small sizes only, per the source trace), a dismiss button, and a bottom divider. DrawerFooter covers 6 layouts (Stretch/Basic/Checkbox/Toggle/Stepper/Link Button), each pairing Cancel+Continue actions (Button type="neutral"/style="stroke" and type="primary"/style="filled" at size="sm", matching the precedent already set by DatePicker's footer); the Checkbox layout reuses CheckboxLabel, the Toggle layout uses the new Switch, and the Stepper layout uses a new small StepperDots indicator.
  • DropdownItem + DropdownMiscItem Components — Ported from Figma (Align UI Design System 2.0, Dropdown Items [1.1] + Dropdown Misc Items [1.1]). DropdownItem simplifies Figma's 6 rigid leading-visual "types" (Basic/Country/Avatar/Provider/Brand/Company) into one generic leading ReactNode slot, following the same pattern as CheckboxCard/CommandMenuItem; supports 4 states (default/hover/selected/disabled) × 2 sizes (sm-36/lg-56) with optional checkbox/badge/shortcut/toggle/button/right-icon slots — per the fetched Figma state trace, "Selected" keeps the same white background as "Default", with selection communicated only via the checkbox's checked fill. DropdownMiscItem covers the search input (with clear button once text is entered), the "Add Workspace" button row (reuses Button), and a static caption row.
  • FileFormatIcon + ProgressBar + FileUploadArea + FileUploadCard + ImageUpload Components — Ported from Figma (Align UI Design System 2.0, File Format Icons [1.1] + File Upload Area [1.1] + File Upload Cards [1.1] + Image Upload [1.1]). FileFormatIcon renders a colored file-type tag (9 colors × 2 sizes) using RemixIcon's file-2-line glyph for the page shape (already resembles the folded-corner page in the Figma raster) instead of importing raw Figma vectors, keeping the RemixIcon-only policy; color mapping matches Badge/ColorDots' state-token mapping. FileUploadArea is a real drag-and-drop dashed zone wired to a hidden file input. FileUploadCard covers uploading/success/error states with a ProgressBar, reuses CompactButton (dismiss) and LinkButton (Try Again, error style). ImageUpload covers Avatar/Company type × Vertical/Horizontal alignment × Empty/Uploaded state, reusing the existing Avatar component for the "avatar" type (the "company" type's Figma reference used a brand-specific logo asset, simplified to a generic building-icon placeholder plus a leading slot); title/description text only renders at alignment="vertical", matching the source trace exactly. Grouped into Components/FileUpload/ alongside the other file-upload pieces.
  • FilterBar + VerticalFilterItem + VerticalFilterHeader + VerticalFilterFooter Components — Ported from Figma (Align UI Design System 2.0, Horizontal Filter [1.1] + Vertical Filter Items [1.1] + Vertical Filter Header [1.1] + Vertical Filter Footer [1.1]). FilterBar covers the toolbar row (search input, Filter/Settings/Sort-by buttons) with a consumer-composed left slot, since Figma's Calendar type (date-preset ButtonGroup) and Table type (SegmentedControl tabs) differ too much to force into one rigid shape; the Table type composes the standalone SegmentedControl primitive. VerticalFilterItem covers the sidebar filter-category row (default/hover/active/disabled, active shows a primary-colored icon + trailing chevron). VerticalFilterFooter reuses DrawerFooter's "stretch" layout directly (same Cancel/Continue button pairing, relabeled Clear/Apply) instead of re-implementing an equivalent footer.
  • KeyIcon Component — Ported from Figma (Align UI Design System 2.0, Key Icons [1.1]). Reusable circular icon container, 9 colors x 5 sizes x 2 styles (stroke = white bordered surface, lighter = tinted surface). The Figma component set generated ~90 near-identical hardcoded variants (one branch per color/size/style combination); implemented generically via CSS data attributes instead. This same visual pattern had already appeared inline (uncomponentized) inside DrawerHeader's Left-Icon Large slot and the new ContentLabel/ContentCard Left-Icon type.
  • PaymentIcon Component — Ported from Figma (Align UI Design System 2.0, Payment Icons [1.1]). 8 fixed types (water/gas/electricity/donate/internet/phone/rent/tax), each with a semantically pinned icon+color pairing rather than independently configurable props.
  • ChartLegend + ChartLegendDot Components — Ported from Figma (Align UI Design System 2.0, Chart Legends [1.1] + Chart Legend Dots [1.1]). Colored dot + label for chart/data-viz legends; color mapping matches Badge/ColorDots' 10 state-token colors plus an 11th neutral "lightGray", and a disabled state.
  • Label + HintText + PasswordStrength Components — Ported from Figma (Align UI Design System 2.0, Label [1.1] + Hint Text [1.1] + Password Strength [1.1]). Label supports required (asterisk in --primary-base, not error-red, matching the source design), optional sublabel, info icon, and a "Help?" affordance. HintText covers default/error/disabled helper text. PasswordStrength is genuinely functional — it takes a real password string and computes uppercase/number/length requirements itself, rather than an enum matching Figma's 4 static demo states (whose per-condition icons didn't generalize into consistent real logic), following this project's precedent (DatePicker, ColorPicker) of favoring functional behavior over literal mockup replication.
  • ContentLabel + ContentCard Components — Ported from Figma (Align UI Design System 2.0, Content Label [1.1] + Content Card [1.1]). ContentLabel is an unbordered list row (md/lg sizes, optional "NEW" badge reusing Badge, optional Switch toggle); ContentCard is the bordered card variant with a dismiss button reusing CompactButton. Figma's 6 rigid leading-visual types (Basic/Left-Icon/Avatar/Provider/Brand/Company, plus Card-Provider for the card) were simplified to one generic leading ReactNode slot, following the established CheckboxCard/CommandMenuItem/DropdownItem pattern — pairs naturally with the new KeyIcon component for the Left-Icon type.
  • Modal + ModalOverlay + ModalHeader + ModalFooter + StatusModal Components — Ported from Figma (Align UI Design System 2.0, Modal Header [1.1] + Modal Footer [1.1] + Status Modals [1.1] + Modal Overlay [1.1]). Modal/ModalOverlay are genuinely functional — Escape key, overlay-click, and body-scroll lock while open — not static markup, matching this project's precedent (DatePicker, ColorPicker). ModalHeader covers Basic/Left-Icon/Error/Warning/Success/Information x Medium/Small, reusing the new KeyIcon component directly for its Medium-size icon circle (identical 40px/padding-10/icon-20 proportions). ModalFooter shares DrawerFooter's exact structure and button sizing plus an added "Information" type (Figma's custom info-custom-fill icon substituted with RemixIcon's information-fill, per the RemixIcon-only policy). StatusModal composes a full alert-dialog card (icon + title + description, Horizontal/Vertical alignment, 4 status types) with a ModalFooter built in.
  • NotificationHeader + NotificationTabMenu + NotificationItem + NotificationFooter Components — Ported from Figma (Align UI Design System 2.0, Notifications Header [1.1] + Notifications Tab Menu [1.1] + Notifications Items [1.1] + Notifications Footer [1.1]). NotificationTabMenu generalizes Figma's fixed "quantity" variants (hardcoded 2/3/4-tab layouts) into a data-driven tabs array with per-tab count badges and an underline active indicator. NotificationItem covers 4 types (Basic/File/Button/Message) with a hover-revealed "more" button, and a generic companyIcon slot in place of Figma's brand-specific Apex logo asset.
  • Pagination + PaginationCell Components — Ported from Figma (Align UI Design System 2.0, Pagination Cells [1.1] + Pagination Group [1.1]). Genuinely functional, not a static mockup: paginationUtils.ts's getPageRange computes the real first/last + sibling-window + ellipsis-collapsing range for any currentPage/totalPages, rather than reproducing Figma's fixed 1,2,3,4,5,...,16 demo example. Covers all 3 Figma variants (Basic, Group — shared borders like ButtonGroup, Full Radius) plus the optional "Page X of Y" label and a real native <select>-backed per-page control.
  • ProgressBar + ProgressBarLabel + CircularProgressBar Components — Ported from Figma (Align UI Design System 2.0, Progress Bar [1.1] + Progress Bar Label [1.1] + Circular Progress Bar [1.1]). ProgressBar was originally built inline inside FileUpload/ for FileUploadCard's upload progress; moved to its own Components/ProgressBar/ folder and generalized with a color prop (blue/red/orange/green) now that a standalone Progress Bar family was requested — FileUploadCard updated to import it from the new location. ProgressBarLabel adds title/percentage/description/Upgrade-link layouts (On Top/On Right). CircularProgressBar is a genuinely computed SVG ring (real stroke-dashoffset math from a continuous 0-100 percentage, 5 sizes), not snapped to Figma's discrete 25%-step raster demo variants; its center label never renders at size=48, matching the source design.
  • Popover + PopoverFooter Components — Ported from Figma (Align UI Design System 2.0, Popover [1.1] + Popover Footer [1.1]). Covers all 12 placement variants (top/bottom/left/right x start/center/end) via a single placement prop. The tail uses the classic CSS rotated-square technique (a bordered square rotated 45deg with two edges' borders removed) instead of importing Figma's raster "Tail" asset. The header icon reuses KeyIcon directly (size="lg" matches the 48px/padding-12/icon-24 proportions exactly). PopoverFooter covers Stretch/Stepper/Text-Stepper layouts, reusing StepperDots from the Drawer family.
  • Radio + RadioLabel + RadioCard Components — Ported from Figma (Align UI Design System 2.0, Radio [1.1] + Radio Label [1.1] + Radio Card [1.1]). Mirrors the Checkbox/CheckboxLabel/CheckboxCard architecture exactly, including the same decorative render-mode fix for embedding Radio inside RadioCard's own button (avoiding a nested-<button> HTML error), and the same generic leading slot simplifying Figma's 6 rigid RadioCard types (Basic/Left-Icon/Avatar/Card-Provider/Brand/Company). Figma's "Focused" variant recolors the ring to --primary-base/--primary-darkest depending on checked state — mapped to the standard :focus-visible pseudo-class instead of a separate outline, for consistency with Checkbox.
  • RatingIcon + Rating + RatingCell + RatingBar + RatingBarArea Components — Ported from Figma (Align UI Design System 2.0, Rating Items [1.1] + Rating Review [1.1] + Rating Cell [1.1] + Rating Bar Area [1.1] + Rating Bar [1.1] + Rating Bar Items [1.1]). RatingIcon uses RemixIcon's star-fill/star-line/star-half-fill directly; Heart has no half-heart glyph in RemixIcon, so its "half" state uses a clipped fill-over-line overlay instead. Rating's aggregate display genuinely computes full/half/empty icon counts from a continuous 0-5 value, not a fixed demo. RatingBar's "Emoji" type substitutes RemixIcon's emotion-sad/unhappy/normal/happy/laugh-line progression for Figma's raster emoji assets, per the RemixIcon-only policy, and is a real controlled 1-5 selector; RatingBarArea adds a genuine feedback <textarea>.
  • RichEditorToolbar + RichEditorItem + RichEditorDivider + RichEditorColorDot Components — Ported from Figma (Align UI Design System 2.0, Rich Editor [1.1] + Rich Editor Items [1.1] + Rich Editor Colors [1.1]). Figma defined 4 rigid toolbar variants, each a fixed subset/ordering of items; generalized into a composable RichEditorToolbar that accepts any combination of RichEditorItem/RichEditorDivider children instead, since real rich-text editors need arbitrary toolbar configurations — the Gallery story recreates all 4 Figma variants purely via composition. RichEditorItem covers Text/Dropdown/Icon/Color types with a chevron that flips direction when active. RichEditorColorDot's 10 colors match Badge/ColorDots' mapping exactly.
  • Scroll + ScrollArea Components — Ported from Figma (Align UI Design System 2.0, Scroll [1.1]). The Figma component was a static track+thumb visual with the thumb fixed at the vertical center; Scroll genuinely parameterizes thumb size/position via thumbRatio/thumbOffset props, and ScrollArea derives those from a real scroll container's metrics via a scroll listener + ResizeObserver — a working custom scrollbar, not a decorative fixed thumb, matching this project's precedent (DatePicker, Pagination, RatingBar).
  • Switch expanded: SwitchLabel + SwitchCard + IntegrationSwitchSwitch (previously a standalone primitive with no dedicated Figma frame) turned out to have more variants once Switch Label [1.1] (385:4580), Switch Card [1.1] (385:4733), and Integration Switch [1.1] (3678:14609) were fetched. Switch itself gained a state prop (default/hover/disabled) and real hover-darkening, matching the Radio/Checkbox convention. SwitchLabel/SwitchCard mirror CheckboxLabel/CheckboxCard and RadioLabel/RadioCard exactly (same generic leading slot simplifying 6 rigid Figma types). IntegrationSwitch covers a brand/integration row (title/badge/description, optional Manage button) in Horizontal/Vertical x Card/List layouts, with a generic leading slot replacing Figma's brand-specific Microsoft Office asset. All four now live together under Components/Switch/.
  • SegmentedControl Component — Ported from Figma (Align UI Design System 2.0, Segmented Control [1.1], nodes 2604:114 + 2603:2062). Promoted out of Filter/ into its own Components/SegmentedControl/ folder now that the fetched trace showed a full Default/Left-Icon/Only-Icon type × Default/Hover/Active/Disabled state matrix — a standalone reusable primitive beyond FilterBar's original Table-type usage, following the same promotion precedent as KeyIcon/PaymentIcon/ChartLegend. label is now optional (icon-only segments), icon accepts any RemixIcon name, and each item can be individually disabled. Hover is a real :hover rule that only shifts text color (--color-text-sub) with no background change — distinct from the active segment's white-bg + --shadow-component-toggle-switch treatment, matching the Figma trace exactly (Hover does not get the raised-white treatment, only Active does).
  • Tooltip Component — Ported from Figma (Align UI Design System 2.0, Tooltip [1.1], node 2604:269). Figma hardcoded 48 variants (8 placements × 3 sizes × 2 dark-mode states), each with its own raster "Tail" asset; reused the CSS rotated-square tail technique already established in Popover instead — same border-omit-per-edge approach, extended with a dark-mode background swap (uses the dedicated --shadow-component-tooltip token) and a size-driven corner offset (8px/12px/16px for sm/md/lg, matching the source trace's pl-8/pl-12/pl-16 values). The Large size's leading icon uses RemixIcon's global-line glyph and its dismiss button reuses CompactButton (style="ghost" size="md"), following the same pattern as Popover.
  • TimePickerItem + TimePickerDuration + TimePickerStatus Components — Ported from Figma (Align UI Design System 2.0, Time Picker Items [1.1] + Time Picker Select Duration [1.1] + Time Picker Select Status [1.1], nodes 165483:5687 + 165483:6046 + 165596:41348). Figma's Default/Disabled variants render as plain non-interactive <div>s while Hover/Active/Selected render as <button>s — a static-demo artifact; all three are implemented as genuine interactive buttons with real :hover, disabled, and a controlled active/selected prop, plus an optional state override for design-QA galleries, following the Checkbox/Radio/Switch precedent. TimePickerItem supports an optional second time group with a direction prop controlling whether the active check mark lands after both groups ("right") or between them ("center"). The Figma "Check" raster asset is substituted with RemixIcon's checkbox-circle-fill. TimePickerStatus's 4 color mappings (success/error/warning/faded) reuse the exact same state tokens as Badge/StatusBadge.
  • TextArea Component — Ported from Figma (Align UI Design System 2.0, Text Area [1.1] + Text Area Character Counter [1.1], nodes 435:5725 + 435:5712). Genuinely functional — a real controlled/uncontrolled <textarea> with a live character counter computed from the actual value length (not Figma's static "0/200" demo text), following this project's precedent (Pagination, ProgressBar, PasswordStrength) of favoring functional behavior. Composes the existing Label and HintText components directly rather than reimplementing them. Figma's "Filled" state is visually identical to "Default" in the source trace (same border/shadow, just with text present), so no separate CSS was needed. The counter's "Resize" icon is decorative — the textarea has real resize: vertical for native dragging — substituted with RemixIcon's expand-diagonal-2-line.
  • Tag Component — Ported from Figma (Align UI Design System 2.0, Tag [1.1], node 431:16147). Figma defined 6 rigid leading-visual "types" (Basic/Left-Icon/Avatar/Country/Brand/Company) × 2 styles × 4 states × optional dismiss — 96 variants total, several baking in placeholder assets (a flag, a person avatar, a brand logo); collapsed into one generic leading ReactNode slot, following the CheckboxCard/DropdownItem/CommandMenuItem pattern. active is a persistent "selected tag" prop (not a :active press), matching ButtonGroup's precedent — Figma's Active variant keeps a solid border + bold text rather than a transient press effect. Figma's Hover state drops the border entirely (converging Stroke and Gray styles to the same weak-bg look) regardless of starting style, reproduced via a plain :hover rule.
  • Table + TableCellContent + SortingIcon Components — Ported from Figma (Align UI Design System 2.0, Table Row Cell [1.1] + Table Header Cell [1.1] + Sorting Icons [1.1], nodes 553:22175 + 587:5793 + 581:2327). Figma's Table Row Cell defined 6 rigid leading-visual options (checkbox/radio/icon/avatar/brand/company/file-format), collapsed into one generic leading slot on the new TableCellContent, following the CheckboxCard/DropdownItem/CommandMenuItem pattern; its "misc" rich-content cell types (Button/ButtonGroup/Toggle/Rating/ProgressBar/StatusBadge/BadgeGroup/AvatarGroup) needed no dedicated wrapper — a column's render function can return any existing component directly. Rather than a static demo grid, Table is a real functional data table rendered as semantic <table>/<thead>/<tbody> markup: sortable columns genuinely re-sort the passed data (asc → desc → none, cycling on click), and row/select-all checkboxes maintain real controlled-or-uncontrolled selection state reusing the existing Checkbox component — following this project's precedent (Pagination, DatePicker, ColorPicker) of favoring functional behavior over literal mockup replication. Figma's header "Disabled"/"Empty" states were dropped since a real table's columns don't sensibly disable.
  • Input + TagInput + CounterInput + PinInput + InlineInput Components (Text Input family) — Ported from Figma (Align UI Design System 2.0, Text Input [1.1] + Tag Input [1.1] + Counter Input [1.1] + Digit Input [1.1] + Inline Input [1.1], nodes 266:5251 + 428:4860 + 428:5656 + 429:5172 + 429:5195). The core Text Input defined 12 rigid "types" (Basic/Email/Phone/Card/Website/Amount/Date/Search/Password/Button/Dropdown/Emoji) × 3 sizes × 6 states — 216+ variants, each type really only differing by its leading icon and an optional trailing affordance (a shortcut badge, a password eye-toggle, a copy-link button, an inline select); collapsed into one Input with generic leading/trailing slots plus named real behaviors (showPasswordToggle genuinely swaps type="password""text", clearable shows a real clear button once there's a value, action renders a separated trailing button in its own bordered cell for the copy-link pattern), following the same promotion pattern as CheckboxCard/DropdownItem/Tag/TableCellContent. TagInput, CounterInput, PinInput (Figma's "Digit Input" cell, assembled into a full multi-box control), and InlineInput were each separate Figma components sharing the same Label/HintText composition and 3-size/6-state scheme, so all five live together under Components/TextInput/. Every one is genuinely functional rather than a static demo, following this project's precedent (Pagination, DatePicker, ColorPicker, Table): TagInput actually adds tags on Enter/comma and removes them on click or Backspace (reusing the Tag component's dismiss button), CounterInput actually increments/decrements with min/max clamping, PinInput actually auto-advances focus per digit, moves back on Backspace/arrow keys, and fills every box from a single paste, and InlineInput actually toggles between a borderless display state and an editable state with real Cancel/Confirm actions.

Changed

  • Storybook organization:
    • Button, LinkButton, SocialButton, CompactButton, and FancyButton now live under one Components/Buttons/ group in the sidebar (previously Button was miscategorized under a separate Primitive/ group).
    • Badge and StatusBadge now live under one Components/Badges/ group in the sidebar.
    • ButtonGroup and ButtonGroupItem live under Components/ButtonGroup/.
    • Checkbox, CheckboxLabel, and CheckboxCard live under Components/Checkbox/.
    • ColorPicker, ColorSpectrum, ColorSliders, and ColorDots live under Components/ColorPicker/.
    • CommandMenu, CommandMenuSearchInput, CommandMenuItem, and CommandMenuFooter live under Components/CommandMenu/.
    • ContentDivider lives under Components/ContentDivider/.
    • DatePicker, DateRangePicker, DayCell, DayLabel, DateSelector, and PeriodRangeItem live under Components/DatePicker/.
    • DrawerHeader, DrawerFooter, and StepperDots live under Components/Drawer/.
    • DropdownItem and DropdownMiscItem live under Components/Dropdown/.
    • FileFormatIcon, ProgressBar, FileUploadArea, FileUploadCard, and ImageUpload live under Components/FileUpload/ (ImageUpload was initially given its own folder, then moved here since it's another image/file-upload widget).
    • FilterBar, VerticalFilterItem, VerticalFilterHeader, and VerticalFilterFooter live under Components/Filter/.
    • SegmentedControl lives under its own Components/SegmentedControl/.
    • KeyIcon lives under Components/KeyIcon/.
    • PaymentIcon lives under Components/PaymentIcon/.
    • ChartLegend and ChartLegendDot live under Components/ChartLegend/.
    • Label, HintText, and PasswordStrength live under Components/FormHelpers/.
    • ContentLabel and ContentCard live under Components/ContentItem/.
    • Modal, ModalOverlay, ModalHeader, ModalFooter, and StatusModal live under Components/Modal/.
    • NotificationHeader, NotificationTabMenu, NotificationItem, and NotificationFooter live under Components/NotificationFeed/.
    • Pagination and PaginationCell live under Components/Pagination/.
    • ProgressBar, ProgressBarLabel, and CircularProgressBar live under Components/ProgressBar/ (moved out of Components/FileUpload/, where ProgressBar originally lived).
    • Popover and PopoverFooter live under Components/Popover/.
    • Radio, RadioLabel, and RadioCard live under Components/Radio/.
    • RatingIcon, Rating, RatingCell, RatingBar, and RatingBarArea live under Components/Rating/.
    • RichEditorToolbar, RichEditorItem, RichEditorDivider, and RichEditorColorDot live under Components/RichEditor/.
    • Scroll and ScrollArea live under Components/Scroll/.
    • Switch, SwitchLabel, SwitchCard, and IntegrationSwitch live under Components/Switch/.

[0.3.0] — 2026-06-23

Added

  • Avatars Component — Added modular layout for user avatars, initials, and size scaling.
  • ActivityFeed Component — Added dynamic status feeds, custom dates, and action controls.
  • Storybook Deployment — Configured automated build and deploy pipeline using GitHub Actions to host Storybook live on GitHub Pages.
  • Architecture Specification — Created ARCHITECTURE.md detailing the design system's architecture, 3-tier token hierarchy, build setup, and custom accent themes.

Fixed

  • Testing Addon Compatibility — Resolved dependencies in package.json by updating @storybook/addon-vitest to @storybook/experimental-addon-test at version ^8.6.18 to fix incompatibilities with Storybook v8.
  • Node.js Environment — Upgraded Node.js runner in GitHub Actions to v22 to support dependencies requiring newer engine features.
  • Lockfile Synchronization — Changed deployment script to run npm install on the runner to resolve out-of-sync local package-lock definitions.

[0.1.0] — 2026-04-09

🎉 Initial Release — Figma to Code Migration

Complete migration of the PremUI Figma design system into a code-first, token-based architecture.

Added

Core Tokens (tokens/core/)

  • colors.json — 10 color palettes (gray, slate, blue, red, green, orange, yellow, purple, sky, pink, teal) with 11 shades each (50–950), plus neutral 0 (white). ~123 colors total.
  • alpha.json — Transparency overlay system for 13 color channels (slate, gray, blue, orange, red, green, yellow, purple, sky, pink, teal, white, black) at 24%, 16%, 10% opacity. Shadow-specific tints (gray, blue, purple, orange, green) at 8%, 6%, 4%, 2%, 0% opacity. ~65 tokens.
  • spacing.json — 13-step spacing scale: 0, 2, 4, 6, 8, 10, 12, 16, 24, 32, 40, 48.
  • radius.json — 12-step corner radius scale: 0, 2, 4, 6, 8, 10, 12, 16, 20, 24, 28, full (999px).
  • shadows.json — 30+ box-shadow tokens across 6 categories: regular, card, custom, colored (blue/green), component (switch/slider), gradient.
  • typography.json — Font primitives: families (Inter, Inter Display), weights (400–700), sizes (11–36px), line-heights.
  • motion.json — 5 duration steps (100–500ms), 4 easing curves (ease-out, ease-in-out, spring, bounce), 4 pre-composed transition shorthands.
  • layout.json — 12-column grid system (24px gutter, 32px margin), sidebar widths (272px default, 80px collapsed, 200px submenu).

Semantic Tokens (tokens/semantic/)

  • light.json — Light theme with 11 categories: static, bg (7 levels incl. weak-25), text (5 levels), stroke (4 levels), icon (5 levels), state (10 intents × 4 shades), theme (4 colors × 5 tiers), overlay (4 variants), social (7 brand colors), illustration (5 levels).
  • dark.json — Dark theme with inverted mappings for all light categories. State tokens use rgba alpha values for dark-mode transparency.
  • theme.json — Multi-mode primary accent system. Default: Blue. Alternatives: Purple, Orange, Green. Each with 5 solid shades (darkest→lighter), 3 alpha overlays (24/16/10%), 5 shadow tints (8→0%). Switch via [data-theme-color] attribute.
  • typography.json — 23 named text styles: Title (h1–h6), Label (xl–xs), Paragraph (xl–xs), Subheading (xl–2xs), Doc (h1–h4). Each with font-family, weight, size, line-height, letter-spacing, and text-transform.

Components (src/ui/)

  • button.css — Button component v1 using semantic intent tokens.
  • grid.css — 12-column CSS Grid + sidebar layout utilities consuming core layout tokens.

Infrastructure

  • sd.config.js — Style Dictionary configuration. Compiles JSON tokens into 5 CSS files: variables.css, dark-theme.css, theme-purple.css, theme-orange.css, theme-green.css.
  • package.json — Node.js project with remixicon and style-dictionary dependencies.
  • .cursorrules — AI agent constraints enforcing Remix Icon usage and forbidding Lucide/HeroIcons/FontAwesome.
  • registry/components.json — Component manifest tracking dependencies, token usage, and build status.

Visual Reference

  • premui.lib.pen — Pencil design file with all tokens synced as variables: ~250+ variables covering colors, alphas, semantics, spacing, radius, primary theme, shadow tints, states, overlays, social colors, and illustrations.

Figma Reference

  • 01-token/ — 12 screenshots of Figma 01-Tokens variable collection.
  • 06-foundations/ — 20 screenshots of Figma 06-Foundations variable collection.

Figma Collections Covered

Collection Variables Status
01-Tokens 137 ✅ Complete
02-Neutral 12 ✅ Complete
03-Theme 13 ✅ Complete
04-Radius 12 ✅ Complete
05-Spacing 13 ✅ Complete
06-Foundations 189 ✅ Complete

[0.2.0] — 2026-04-09

Added

Components

  • Accordion — High-fidelity implementation featuring:
    • Smart indentation (44px/74px) for automatic title/description alignment.
    • Full interactive states (Hover, Active, Open, Focus).
    • Grid-based height animations for smooth expansion.
    • String-based icon selection (RemixIcon) via Storybook controls.
    • Defensive rendering to prevent crashes with missing props.
  • AI Reference — Added AI_PREMUI_REFERENCE.md for consistent AI-assisted development.

Storybook & DX

  • Full-App Dark Mode — Documentation and Preview UI now stay perfectly in sync.
  • Default Dark Theme — Environment starts in Dark mode by default.
  • Build Pipeline — Stabilized Style Dictionary build with path-based filtering for multiple themes.
  • Barrel Exports — Unified component access in src/index.ts.

Changed

  • Refactored token build process to prevent variable collisions.
  • Optimized Storybook decorators for layout stability and background parity.

[0.1.0] — 2026-04-09