All notable changes to the PremUI Design System are documented here.
Format follows Keep a Changelog.
- 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 existingDropdownItem. 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 ownoverflow: hiddenor cover the nav items underneath, and shows the full company list with no internal scrollbar. Newcompany/defaultCompany/onCompanyChange/companiesprops support both controlled and uncontrolled usage;brand/description/leadingremain available as manual overrides.SidebarNavigation's stories were updated to passcompanythrough 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).
TopbarItemis 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-baseand the label to--color-text-strongrather than an accent bar, per the fetched Active-state variable trace (no accent-bar token existed for this component).TopbarUserProfileis a compact avatar+name+verified chip whose chevron flips between down/up as it opens.TopbarIconButtonis 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 viaget_variable_defsrather 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
DropdownItemandPlaceholderBrand. Figma's rigidproduct: "HR Management" | "Finance & Banking"variant enum (two hardcoded nav configurations) was collapsed into plainitems/moreItemsprops, matching the same pattern already used forSidebarNavigation'smainItems. 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) listingmoreItems. Real controlled/uncontrolled active-tab state and a real search input, following the same conventions asSidebarNavigation.
- 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-playwrightonly 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:urlwere invisible to the TS compiler because@types/nodewas not installed — added@types/nodetodevDependenciesandnpm install --legacy-peer-depsto pick it up. (3)vitest.config.tsitself was excluded from compilation since thetsconfig.jsonincludearray only coveredsrc/**/*— addedvitest.config.tsandvitest.shims.d.tstoincludeso 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.7package) and added/// <reference types="node" />sonode:*built-ins are available during config compilation. - tsconfig.json — invalid
ignoreDeprecationsvalue + deprecatedbaseUrl— 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-deprecatedbaseUrl: "."option; on TypeScript 6,pathsmappings work independently ofbaseUrl, 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'svitest@^3) withplaywright@^1.49.0, which is the actual optional peer dependency declared by@vitest/browser@3.2.7for the built-in Playwright provider.
- 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).
SidebarItemis the nav row (leading icon orChartLegendDotindicator, optional badge/notification-count/keyboard-shortcut, an icon-only collapsed "rail" mode, and a primary accent bar for the persistent active state).HeaderCard/SidebarHeaderandUserProfileCard/SidebarFooterare workspace-switcher and signed-in-user cards, each with a thin wrapper adding an optional divider and collapsed handling.SidebarFeatureCardcollapses 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 withtype/styleprops, reusing the existingAvatar,ProgressBar,LinkButton, andCompactButtoncomponents rather than re-implementing each combination; its progress percentages are real (driven by apercentageprop), not Figma's static 80%/90% demo. Fixed a follow-up visual bug during review: on theprimary/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 acollapsedprop that switches every child to its icon-only rail mode at once.
- 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-shadowblur (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 tofilter: 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: topanimated each position change by 200ms on top of that. Switched to direct DOM mutation via a forwarded ref inside arequestAnimationFrame-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 usingHintText) — the icon wrapper's implicit height (from the icon font's own line-height) didn't match the adjacent text's explicitline-height: 16px, offsetting the icon vertically. Fixed by sizing the icon box explicitly to 16×16 withline-height: 1. - Storybook "Set object" crashes — Around 20 story files had
ReactNode-typed props (or array props likeitems/members) with no explicitargTypescontrol 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 explicitcontrol: 'text'ortable: { disable: true }overrides acrossButton,LinkButton,FancyButton,SocialButton,Badge,StatusBadge,Tag,CheckboxLabel,CheckboxCard,CommandMenuItem,ButtonGroup,Breadcrumb,AvatarGroup,SegmentedControl,Table, and the wholeTextInputfamily (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.
- 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-widthcountmode 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
stateprop can force Default/Hover/Active/Disabled for design-QA galleries; real:hover/:active/:focus-visible/disableddrive 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-16overlay 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-baseso 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 inButton.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 viamargin-left: -1px(classic segmented-control technique).activeis a persistent "selected segment" prop, not a:activepress — thestateprop 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]).Checkboxdraws 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-visiblering for consistency.CheckboxLabelcomposes label/sublabel/badge/description/link, reusing the existingBadgeandLinkButtoncomponents.CheckboxCardis a selectable bordered card; Figma's 6 rigid "type" variants (which bake in specific brand logos like Mastercard/Spotify) were replaced with one genericleadingReactNode slot. Fixed a nested-<button>hydration error by adding adecorativerender mode toCheckbox(renders a<span>instead of<button>when embedded insideCheckboxCard'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), andColorDots(10 preset swatches reusing the same color→state-token mapping asBadge). NewcolorUtils.tsimplements 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 existingFancyButton(type="basic" size="xs") andButtonGroupcomponents 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]).CommandMenuSearchInputis a real controlled search field that swaps its trailing shortcut/info affordance for a clear button once text is entered.CommandMenuItemsimplifies Figma's 6 rigid "type" variants (which bake in Spotify/Apex/US-flag images) into one genericleadingReactNode slot, and reusesBadgefor its "NEW"-style tag.CommandMenuFooterreusesLinkButtonfor its "Help Center" link.CommandMenucomposes 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.tsgenerates real Monday-first, leap-year-correct month grids.DatePickeris a single month with a Cancel/Apply footer;DateRangePickeradds 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 existingCompactButton(month-nav arrows) andButton(footer actions). Fixed a CSS specificity bug caught during visual verification::not(:disabled):hoverhad 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 getpointer-events: none, so they never match:hoverregardless). - Switch Component — New primitive (32×20 track, 16px thumb) built to match the existing
--shadow-component-toggle-switchtoken; no standalone Figma frame existed for it, only an inline raster reference withinDrawerFooter's Toggle type. Ships with adecorativerender mode (renders a<span>, not<button>) for embedding inside another already-interactive row, following the same pattern asCheckbox. - DrawerHeader + DrawerFooter + StepperDots Components — Ported from Figma (Align UI Design System 2.0,
Drawer Header [1.1]+Drawer Footer [1.1]).DrawerHeadersupports Basic/Left-Icon types × Small/Large sizes, an optional count badge (reusesBadge'scountmode), an optional Link Button (Small sizes only, per the source trace), a dismiss button, and a bottom divider.DrawerFootercovers 6 layouts (Stretch/Basic/Checkbox/Toggle/Stepper/Link Button), each pairing Cancel+Continue actions (Buttontype="neutral"/style="stroke" and type="primary"/style="filled" at size="sm", matching the precedent already set byDatePicker's footer); the Checkbox layout reusesCheckboxLabel, the Toggle layout uses the newSwitch, and the Stepper layout uses a new smallStepperDotsindicator. - DropdownItem + DropdownMiscItem Components — Ported from Figma (Align UI Design System 2.0,
Dropdown Items [1.1]+Dropdown Misc Items [1.1]).DropdownItemsimplifies Figma's 6 rigid leading-visual "types" (Basic/Country/Avatar/Provider/Brand/Company) into one genericleadingReactNode slot, following the same pattern asCheckboxCard/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.DropdownMiscItemcovers the search input (with clear button once text is entered), the "Add Workspace" button row (reusesButton), 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]).FileFormatIconrenders a colored file-type tag (9 colors × 2 sizes) using RemixIcon'sfile-2-lineglyph 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 matchesBadge/ColorDots' state-token mapping.FileUploadAreais a real drag-and-drop dashed zone wired to a hidden file input.FileUploadCardcovers uploading/success/error states with aProgressBar, reusesCompactButton(dismiss) andLinkButton(Try Again, error style).ImageUploadcovers Avatar/Company type × Vertical/Horizontal alignment × Empty/Uploaded state, reusing the existingAvatarcomponent for the "avatar" type (the "company" type's Figma reference used a brand-specific logo asset, simplified to a generic building-icon placeholder plus aleadingslot); title/description text only renders atalignment="vertical", matching the source trace exactly. Grouped intoComponents/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]).FilterBarcovers the toolbar row (search input, Filter/Settings/Sort-by buttons) with a consumer-composedleftslot, since Figma's Calendar type (date-presetButtonGroup) and Table type (SegmentedControltabs) differ too much to force into one rigid shape; the Table type composes the standaloneSegmentedControlprimitive.VerticalFilterItemcovers the sidebar filter-category row (default/hover/active/disabled, active shows a primary-colored icon + trailing chevron).VerticalFilterFooterreusesDrawerFooter'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) insideDrawerHeader's Left-Icon Large slot and the newContentLabel/ContentCardLeft-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 matchesBadge/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]).Labelsupports required (asterisk in--primary-base, not error-red, matching the source design), optional sublabel, info icon, and a "Help?" affordance.HintTextcovers default/error/disabled helper text.PasswordStrengthis genuinely functional — it takes a realpasswordstring 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]).ContentLabelis an unbordered list row (md/lg sizes, optional "NEW" badge reusingBadge, optionalSwitchtoggle);ContentCardis the bordered card variant with a dismiss button reusingCompactButton. Figma's 6 rigid leading-visual types (Basic/Left-Icon/Avatar/Provider/Brand/Company, plus Card-Provider for the card) were simplified to one genericleadingReactNode slot, following the establishedCheckboxCard/CommandMenuItem/DropdownItempattern — pairs naturally with the newKeyIconcomponent 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/ModalOverlayare genuinely functional — Escape key, overlay-click, and body-scroll lock while open — not static markup, matching this project's precedent (DatePicker,ColorPicker).ModalHeadercovers Basic/Left-Icon/Error/Warning/Success/Information x Medium/Small, reusing the newKeyIconcomponent directly for its Medium-size icon circle (identical 40px/padding-10/icon-20 proportions).ModalFootersharesDrawerFooter's exact structure and button sizing plus an added "Information" type (Figma's custominfo-custom-fillicon substituted with RemixIcon'sinformation-fill, per the RemixIcon-only policy).StatusModalcomposes a full alert-dialog card (icon + title + description, Horizontal/Vertical alignment, 4 status types) with aModalFooterbuilt 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]).NotificationTabMenugeneralizes Figma's fixed "quantity" variants (hardcoded 2/3/4-tab layouts) into a data-driventabsarray with per-tab count badges and an underline active indicator.NotificationItemcovers 4 types (Basic/File/Button/Message) with a hover-revealed "more" button, and a genericcompanyIconslot 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'sgetPageRangecomputes the real first/last + sibling-window + ellipsis-collapsing range for anycurrentPage/totalPages, rather than reproducing Figma's fixed 1,2,3,4,5,...,16 demo example. Covers all 3 Figma variants (Basic, Group — shared borders likeButtonGroup, 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]).ProgressBarwas originally built inline insideFileUpload/forFileUploadCard's upload progress; moved to its ownComponents/ProgressBar/folder and generalized with acolorprop (blue/red/orange/green) now that a standalone Progress Bar family was requested —FileUploadCardupdated to import it from the new location.ProgressBarLabeladds title/percentage/description/Upgrade-link layouts (On Top/On Right).CircularProgressBaris a genuinely computed SVG ring (real stroke-dashoffset math from a continuous 0-100percentage, 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 singleplacementprop. 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 reusesKeyIcondirectly (size="lg" matches the 48px/padding-12/icon-24 proportions exactly).PopoverFootercovers Stretch/Stepper/Text-Stepper layouts, reusingStepperDotsfrom 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 theCheckbox/CheckboxLabel/CheckboxCardarchitecture exactly, including the samedecorativerender-mode fix for embeddingRadioinsideRadioCard's own button (avoiding a nested-<button>HTML error), and the same genericleadingslot 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-darkestdepending on checked state — mapped to the standard:focus-visiblepseudo-class instead of a separate outline, for consistency withCheckbox. - 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]).RatingIconuses RemixIcon'sstar-fill/star-line/star-half-filldirectly; 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-5value, not a fixed demo.RatingBar's "Emoji" type substitutes RemixIcon'semotion-sad/unhappy/normal/happy/laugh-lineprogression for Figma's raster emoji assets, per the RemixIcon-only policy, and is a real controlled 1-5 selector;RatingBarAreaadds 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 composableRichEditorToolbarthat accepts any combination ofRichEditorItem/RichEditorDividerchildren instead, since real rich-text editors need arbitrary toolbar configurations — the Gallery story recreates all 4 Figma variants purely via composition.RichEditorItemcovers Text/Dropdown/Icon/Color types with a chevron that flips direction when active.RichEditorColorDot's 10 colors matchBadge/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;Scrollgenuinely parameterizes thumb size/position viathumbRatio/thumbOffsetprops, andScrollAreaderives 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 + IntegrationSwitch —
Switch(previously a standalone primitive with no dedicated Figma frame) turned out to have more variants onceSwitch Label [1.1](385:4580),Switch Card [1.1](385:4733), andIntegration Switch [1.1](3678:14609) were fetched.Switchitself gained astateprop (default/hover/disabled) and real hover-darkening, matching theRadio/Checkboxconvention.SwitchLabel/SwitchCardmirrorCheckboxLabel/CheckboxCardandRadioLabel/RadioCardexactly (same genericleadingslot simplifying 6 rigid Figma types).IntegrationSwitchcovers a brand/integration row (title/badge/description, optional Manage button) in Horizontal/Vertical x Card/List layouts, with a genericleadingslot replacing Figma's brand-specific Microsoft Office asset. All four now live together underComponents/Switch/. - SegmentedControl Component — Ported from Figma (Align UI Design System 2.0,
Segmented Control [1.1], nodes 2604:114 + 2603:2062). Promoted out ofFilter/into its ownComponents/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 beyondFilterBar's original Table-type usage, following the same promotion precedent asKeyIcon/PaymentIcon/ChartLegend.labelis now optional (icon-only segments),iconaccepts any RemixIcon name, and each item can be individuallydisabled. Hover is a real:hoverrule that only shifts text color (--color-text-sub) with no background change — distinct from the active segment's white-bg +--shadow-component-toggle-switchtreatment, 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 inPopoverinstead — same border-omit-per-edge approach, extended with a dark-mode background swap (uses the dedicated--shadow-component-tooltiptoken) 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'sglobal-lineglyph and its dismiss button reusesCompactButton(style="ghost" size="md"), following the same pattern asPopover. - 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 optionalstateoverride for design-QA galleries, following theCheckbox/Radio/Switchprecedent.TimePickerItemsupports an optional second time group with adirectionprop controlling whether the active check mark lands after both groups ("right") or between them ("center"). The Figma "Check" raster asset is substituted with RemixIcon'scheckbox-circle-fill.TimePickerStatus's 4 color mappings (success/error/warning/faded) reuse the exact same state tokens asBadge/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 existingLabelandHintTextcomponents 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 realresize: verticalfor native dragging — substituted with RemixIcon'sexpand-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 genericleadingReactNode slot, following theCheckboxCard/DropdownItem/CommandMenuItempattern.activeis a persistent "selected tag" prop (not a:activepress), matchingButtonGroup'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:hoverrule. - 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 genericleadingslot on the newTableCellContent, following theCheckboxCard/DropdownItem/CommandMenuItempattern; its "misc" rich-content cell types (Button/ButtonGroup/Toggle/Rating/ProgressBar/StatusBadge/BadgeGroup/AvatarGroup) needed no dedicated wrapper — a column'srenderfunction can return any existing component directly. Rather than a static demo grid,Tableis a real functional data table rendered as semantic<table>/<thead>/<tbody>markup: sortable columns genuinely re-sort the passeddata(asc → desc → none, cycling on click), and row/select-all checkboxes maintain real controlled-or-uncontrolled selection state reusing the existingCheckboxcomponent — 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 oneInputwith genericleading/trailingslots plus named real behaviors (showPasswordTogglegenuinely swapstype="password"↔"text",clearableshows a real clear button once there's a value,actionrenders a separated trailing button in its own bordered cell for the copy-link pattern), following the same promotion pattern asCheckboxCard/DropdownItem/Tag/TableCellContent.TagInput,CounterInput,PinInput(Figma's "Digit Input" cell, assembled into a full multi-box control), andInlineInputwere each separate Figma components sharing the sameLabel/HintTextcomposition and 3-size/6-state scheme, so all five live together underComponents/TextInput/. Every one is genuinely functional rather than a static demo, following this project's precedent (Pagination,DatePicker,ColorPicker,Table):TagInputactually adds tags on Enter/comma and removes them on click or Backspace (reusing theTagcomponent's dismiss button),CounterInputactually increments/decrements with min/max clamping,PinInputactually auto-advances focus per digit, moves back on Backspace/arrow keys, and fills every box from a single paste, andInlineInputactually toggles between a borderless display state and an editable state with real Cancel/Confirm actions.
- Storybook organization:
Button,LinkButton,SocialButton,CompactButton, andFancyButtonnow live under oneComponents/Buttons/group in the sidebar (previouslyButtonwas miscategorized under a separatePrimitive/group).BadgeandStatusBadgenow live under oneComponents/Badges/group in the sidebar.ButtonGroupandButtonGroupItemlive underComponents/ButtonGroup/.Checkbox,CheckboxLabel, andCheckboxCardlive underComponents/Checkbox/.ColorPicker,ColorSpectrum,ColorSliders, andColorDotslive underComponents/ColorPicker/.CommandMenu,CommandMenuSearchInput,CommandMenuItem, andCommandMenuFooterlive underComponents/CommandMenu/.ContentDividerlives underComponents/ContentDivider/.DatePicker,DateRangePicker,DayCell,DayLabel,DateSelector, andPeriodRangeItemlive underComponents/DatePicker/.DrawerHeader,DrawerFooter, andStepperDotslive underComponents/Drawer/.DropdownItemandDropdownMiscItemlive underComponents/Dropdown/.FileFormatIcon,ProgressBar,FileUploadArea,FileUploadCard, andImageUploadlive underComponents/FileUpload/(ImageUploadwas initially given its own folder, then moved here since it's another image/file-upload widget).FilterBar,VerticalFilterItem,VerticalFilterHeader, andVerticalFilterFooterlive underComponents/Filter/.SegmentedControllives under its ownComponents/SegmentedControl/.KeyIconlives underComponents/KeyIcon/.PaymentIconlives underComponents/PaymentIcon/.ChartLegendandChartLegendDotlive underComponents/ChartLegend/.Label,HintText, andPasswordStrengthlive underComponents/FormHelpers/.ContentLabelandContentCardlive underComponents/ContentItem/.Modal,ModalOverlay,ModalHeader,ModalFooter, andStatusModallive underComponents/Modal/.NotificationHeader,NotificationTabMenu,NotificationItem, andNotificationFooterlive underComponents/NotificationFeed/.PaginationandPaginationCelllive underComponents/Pagination/.ProgressBar,ProgressBarLabel, andCircularProgressBarlive underComponents/ProgressBar/(moved out ofComponents/FileUpload/, whereProgressBaroriginally lived).PopoverandPopoverFooterlive underComponents/Popover/.Radio,RadioLabel, andRadioCardlive underComponents/Radio/.RatingIcon,Rating,RatingCell,RatingBar, andRatingBarArealive underComponents/Rating/.RichEditorToolbar,RichEditorItem,RichEditorDivider, andRichEditorColorDotlive underComponents/RichEditor/.ScrollandScrollArealive underComponents/Scroll/.Switch,SwitchLabel,SwitchCard, andIntegrationSwitchlive underComponents/Switch/.
- 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.mddetailing the design system's architecture, 3-tier token hierarchy, build setup, and custom accent themes.
- Testing Addon Compatibility — Resolved dependencies in
package.jsonby updating@storybook/addon-vitestto@storybook/experimental-addon-testat version^8.6.18to 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 installon the runner to resolve out-of-sync local package-lock definitions.
Complete migration of the PremUI Figma design system into a code-first, token-based architecture.
- 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).
- 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.
- button.css — Button component v1 using semantic intent tokens.
- grid.css — 12-column CSS Grid + sidebar layout utilities consuming core layout tokens.
- 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
remixiconandstyle-dictionarydependencies. - .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.
- 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.
- 01-token/ — 12 screenshots of Figma 01-Tokens variable collection.
- 06-foundations/ — 20 screenshots of Figma 06-Foundations variable collection.
| 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 |
- 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.mdfor consistent AI-assisted development.
- 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.
- Refactored token build process to prevent variable collisions.
- Optimized Storybook decorators for layout stability and background parity.