@flatpay-dk/ui
- v2.1.0
`<Page>` learns a new shape. The header and body content area now scale their gutters with the viewport (16 / 32 / 48 px at sm / md / lg), and a new `<PageHero>` slot lets a page lead with a `<Hero>` block instead of a `<PageHeader>` title row — landing pages, product introductions, onboarding. No breaking changes; everything is additive or default-only visual.
Added
- New
<PageHero>slot for hero-led main pages. Used in place of<PageHeader>when the page leads with editorial content. Wraps a configured<Hero>and provides a tight uniform gutter (8 px belowsm, 16 px atsm+) — distinct from the header/body scale because the Hero brings its own visual weight and accent surface. Don't render<PageHeader>and<PageHero>in the same page.PageVariantis unchanged; the "main with hero" variant is implicit in slot composition. New exports:PageHero,PageHeroProps.
Changed
<Page>content-area margins now scale with the viewport — 16 px belowmd, 32 px atmd+, 48 px atlg+. Applied to bothPageHeadervariants (main + subpage),PageBody's outer vertical padding, and the inner horizontal column on both.PageHeaderuses top-only padding so the body's matching top padding provides the single gap between title and content (rather than additive header-bottom + body-top).PageStickyFooter's padding is unchanged. No API change; consumers passing their ownclassNamestill override via Tailwind's last-wins-on-conflict rule.
- New
- v2.0.0
A wave of responsive work. `SearchField` retires (use `TextField` with `type="search"`). New `<Sheet>` splits dialog into intent-named exports; new `transparent` Button variant; `<NavigationSideBar>` collapses automatically below `lg`; `<Table>` columns now reduce on viewport, not slot. `<TextField>` gains a `copy` state. Plus a Button loading-state visual fix and tighter TextField label rendering.
Added
- New
transparentButton variant — the borderless sibling oftertiary. No fill and no border at rest; hover and active reuse the existing--background-interactive-tertiary-*tokens. Ships the full six-state set and the same three sizes / four icon configurations as the other variants. - New
<Sheet>component splits the dialog surface into three intent-named exports:<Modal>(confirmation, centred everywhere),<Sheet>(content; bottom drawer belowmd, centred modal atmd+), and<Drawer>(explicit fixed-side panel, unchanged). Sheet handles its own responsive switch viawindow.matchMedia('(min-width: 48rem)')so consumers never write their own media-query logic. Modal sizes refined to align with the Tailwind scale:sm360 → 400,md512 → 560,lgunchanged at 720. New exports:Sheet,SheetHeader,SheetBody,SheetFooter,SheetProps,SheetSize. <NavigationSideBar>gains a"responsive"mode and defaults to it. Atlg+ the rail renders expanded; betweenmdandlgit collapses to the mini icon-only variant; belowmdthe rail hides and the consumer renders<NavigationMobileToggle>in the top bar to open a<NavigationMobileDrawer>with the same items. Forced"expanded"/"mini"modes still override. New exports:NavigationMobileToggle,NavigationMobileDrawer,NavigationContext(for advanced consumers wrapping subtrees in a forced rail mode without rendering a full<NavigationSideBar>).- Add a
copystate toTextField(and aCopyFieldwrapper) for lifting a value out of the form. The field surface drops to the disabled bg + border tokens while value text stays primary; a 24 px copy button sits at the trailing edge. Clicking anywhere on the field copies the value, the icon flips to a check for ~1.5 s, then reverts.disabledwins overcopy, and the state is a no-op atsize="hero".
Changed
<Table>column reduction is now driven by the viewport (sm/md/lg/xl/2xl) instead of the table's own container (@container/tableis gone). Belowsmonly the first and last columns remain — the canonical "mobile" 2-column layout. Tables with more than seven columns clamp at2xl; consumers needing slot-relative collapse should wrap the table in their own@containerquery.TextFieldnow logs a dev-modeconsole.warnwhen theprefixslot's text exceeds 3 characters — the slot is sized for currency symbols and short unit prefixes; longer content collides with the value text.
Fixed
<Button loading>no longer renders as visually disabled. Previously it set the HTMLdisabledattribute, which triggered every variant's:disabledstyles and wiped the foreground out from under the spinner. Loading now usesaria-disabled+aria-busy+data-loadingand an internalonClickguard that short-circuits keyboard activation so a loading submit button still can't fire its form. Buttons that passdisabled={true}are unchanged.- Fix
TextField's empty-state label: previously the resting-state label rendered with a heavier optical weight than the filled-state label. Both states now share the same Inter Tight 13/16 weight 500 baseline.
Removed
- **Breaking:** removed the
SearchFieldwrapper aroundTextField. The dedicatedSearchcomponent (combobox with autocomplete listbox) is the canonical search input; for free-text queries that submit elsewhere, use a plainTextFieldwithtype="search"andshowClearButton. The internalSearchIconhelper has also been removed.FilterSearchFieldis unrelated and unaffected.
- New
- v1.0.7
First release on GitHub Packages. The package moves from public npm (`@flatpay-lab/ui`) to the private FLATPAY-DK org on `npm.pkg.github.com` (`@flatpay-dk/ui`). No runtime changes — same components, same tokens, same exports.
Changed
- Renamed from
@flatpay-lab/uito@flatpay-dk/ui. Published privately to GitHub Packages under the FLATPAY-DK org. Consumers need an.npmrcmapping@flatpay-dk:registry=https://npm.pkg.github.comand aread:packages-scoped GitHub PAT to install.
- Renamed from
- v1.0.6
Fix SSR hydration mismatch in `<Search>`. The component generated default ids from a module-scoped counter, so the server and client could disagree on the id whenever two Search instances co-existed or a streaming revalidation re-rendered one. Switched to `React.useId()` — stable across the SSR boundary, no module state.
Fixed
<Search>now defaults its element id fromReact.useId()instead of an in-moduleuidcounter. Consumer-suppliedidprops are unchanged; only the auto-generated default's shape changes (nowflatpay-search-:r0:rather thanflatpay-search-1).
- v1.0.5
Hot-fix: every Next.js consumer of `@flatpay-dk/ui/fonts` errored out on 1.0.4 with `Font loader calls must be assigned to a const`. The published bundle now declares the loaders correctly.
Fixed
dist/fonts/index.jsnow declaresinterTightandmartianMonowithconstinstead ofvar. esbuild's bundler had been rewriting top-levelexport consttovarfor TDZ-safe circular-import behaviour, which Next.js'snext/font/localplugin refuses on principle. tsup's onSuccess hook now post-processes the fonts entry to put theconstback.
- v1.0.4
Two Table polishes. Column reduction is now progressive — the table preserves as many columns as fit in its own container instead of switching from desktop to a two-column mobile layout. And the header row writes in sentence case ("End date", not "END DATE").
Changed
- Table column reduction is progressive. The first column and last column always show; middle columns drop right-to-left as the container narrows, mapped to the Tailwind v4
@sm/@md/@lg/@xl/@2xl/@3xlcontainer-query thresholds. The synthetic chevron column appears whenever the table is reduced and disappears once every column fits.TableColumn.mobilebecomes an "always show this column" override — most consumers don't need it. - Table header rows render in sentence case. Drops
uppercase+ 0.06em tracking from the<th>so the source text incolumn.headercarries the casing. Visual hierarchy still comes from the weight (semibold) and the muted tint; size bumps from 11 px to 13 px to read cleanly in mixed case. The eyebrow + uppercase treatment is reserved for actual section labels, not data-table chrome.
- Table column reduction is progressive. The first column and last column always show; middle columns drop right-to-left as the container narrows, mapped to the Tailwind v4
- v1.0.3
Three Table polishes that ride together. Mobile reduction now responds to the table's own container width (so a table inside a narrow drawer or sidebar collapses the same way a phone does). Cells default to no-wrap so a date column never breaks "Jan" onto its own line. Pagination spans the full width of the table beneath it.
Changed
Tablemobile reduction is driven by@container/tableinstead of viewportmd:queries. Threshold stays at 768 px; the trigger is now the Table's own width so a narrow drawer collapses the same way a phone does. Tables that already sit at full page width are unaffected.TableColumn.noWrapdefaults totrue. Currencies, dates, IDs, status pills, and short labels never break across lines — the right default for almost every column in an operational table. Long free-text columns opt out vianoWrap: false.Paginationspans its container's full width by default. The indicator span grows to fill the middle so First/Previous anchors to the left edge and Next/Last anchors to the right — the bar matches the width of the table or list it sits beneath.
- v1.0.2
Navigation grows up. The sidebar and topbar now share a continuous tint, the merchant rail ships as a typed preset (`PAY` / `POS` / `Ecom`, with optional admin block on top), and a new `NavigationPage` shell prevents the bar and the rail from drifting apart.
Added
- New
NavigationItemspreset —"PAY" | "POS" | "Ecom"(default"POS") with an optionaladminflag that prepends the back-office block (Admin · Customer search · Bookings · Sales · Onboarding · Installations · Callbacks · divider) above the merchant items. Inlines authentic Material Outlined fill paths, so the package keeps zero icon dependencies. - New
NavigationPageshell. RequiredtopBarandsideBarslots enforce that the bar and the rail are never used independently. NavigationLocationgains avariantprop ("chip" | "secondary").chipis the default desktop chrome;secondaryrenders as a filledbg-secondarysurface used inside the mobile sheet.
Changed
NavigationSideBarandNavigationTopBarnow share theaccent-neutral-subtlersurface; the rail drops itsborder-r, the bar drops itsborder-batlg+, so the chrome reads as one continuous L-tint against the white content column.
Fixed
NavigationSubItemnow matches the parent row's height (48 px) and base typography. Children no longer render attext-sm/h-9; nesting is carried by the 44 px left inset alone.
- New
- v1.0.1
Two structural fixes plus first-class support for Vite + React 18 + Tailwind v3 stacks. `<Section>` is now intentionally neutral — categorical hues moved to Hero and editorial components. `<Page>` no longer lets its sticky footer scroll up out of view. And the package gains a `tailwind-v3` preset, a CSS-only fonts entry, and a loosened React peer.
Added
- First-class Vite + React 18 + Tailwind v3 support. The React peer dependency loosens to
^18.0.0 || ^19.0.0; a new@flatpay-dk/ui/tailwind-v3entry mirrors the Tailwind v4 preset's@theme inlineblock; a new@flatpay-dk/ui/fonts/cssentry registers Inter Tight + Martian Mono via plain@font-facefor non-Next consumers. Existing Next.js consumers see no behavioural difference. ./package.jsonis now in theexportsmap, so consumers can read the package's version at build time viaimport uiPkg from "@flatpay-dk/ui/package.json". Purely additive.
Changed
<Section>is now neutral by default. The 12-surface accent palette is gone — categorical hues belong on Hero and editorial components, not on the structural primitive. Replaced withemphasis: 0 | 1 | 2 | 3(the four-step neutral ramp) and anadminboolean for the staff-only yellow surface. The oldsurfaceprop andsectionVariantsexport are removed; see CHANGELOG for the migration table.
Fixed
<Page>no longer lets<PageStickyFooter>scroll up out of the bottom of the page area on long subpages. The Page is now a bounded flex column that owns its own scroll: the body scrolls internally; the header and the sticky footer flank it. Page is nowh-full overflow-hiddenand expects a bounded-height parent — every Flatpay app shell already does this. Window-scroll listeners that previously depended on document scroll should now target the PageBody node.
- First-class Vite + React 18 + Tailwind v3 support. The React peer dependency loosens to
- v1.0.0
First public release. The full component set, the canonical token CSS, and the next/font/local wrapper for the system's open-licensed brand fonts.
Added
- Every component documented on this site — Button, Banner, Toast, Card, Chip / ChipGroup, Avatar, Badge, Combobox, Select, Search, DatePicker / DateRangePicker, Drawer, Modal, Menu (with MenuItemCheckbox / MenuItemRadio / MenuTrigger / MenuContent), Section, Page, StickyFooter, Chart, and more.
- The canonical token CSS at
@flatpay-dk/ui/styles— every colour, surface, border, and text token, with full dark-mode re-themeing under[data-theme="dark"]. useFlatpayFonts()from@flatpay-dk/ui/fonts— Inter Tight (--font-sans) + Martian Mono (--font-mono). Founders Grotesk X is licensed and intentionally not included; headings fall back to Inter Tight via the preset's--font-displaychain.- Compiled-bundle distribution. The package ships
dist/(esbuild + tsup) — consumers no longer needtranspilePackagesin their Next config.
@flatpay-dk/tailwind-preset
- v3.0.0
Transitive bump for `@flatpay-dk/ui@2.1.0`. The preset itself is unchanged — same `@theme` block, same status family, same eyebrow utilities. The major bump tracks the previous major-tracking pattern set in `2.0.0`; the underlying `@flatpay-dk/ui` change is a minor (additive `<PageHero>` slot + a responsive-margin tweak) and consumers don't need to update preset usage.
Changed
- Updated peer to
@flatpay-dk/ui@2.1.0.
- Updated peer to
- v2.0.0
Transitive bump for `@flatpay-dk/ui@2.0.0`. The preset itself is unchanged — same `@theme` block, same status family, same eyebrow utilities. The major version follows the peer-dependency range so consumers that lock against the preset's major don't accidentally pull a UI package with the `SearchField` removal.
Changed
- Updated peer to
@flatpay-dk/ui@2.0.0.
- Updated peer to
- v1.0.8
First release on GitHub Packages. The preset moves from public npm (`@flatpay-lab/tailwind-preset`) to the private FLATPAY-DK org on `npm.pkg.github.com` (`@flatpay-dk/tailwind-preset`). No CSS changes — same `@theme` block, same status family, same eyebrow utilities.
Changed
- Renamed from
@flatpay-lab/tailwind-presetto@flatpay-dk/tailwind-preset. Published privately to GitHub Packages under the FLATPAY-DK org. Peer dependency updated to@flatpay-dk/ui@workspace:*.
- Renamed from
- v1.0.7
Transitive bump for the @flatpay-dk/ui 1.0.6 Search hydration fix. The preset itself is unchanged.
Changed
- Updated peer to
@flatpay-dk/ui@1.0.6.
- Updated peer to
- v1.0.6
`.eyebrow` and `.eyebrow-lg` are now sentence case. The utility no longer forces `text-transform: uppercase` — the source text carries the casing. Pairs with the sentence-case Table header rule shipped in `@flatpay-dk/ui@1.0.4`.
Changed
- Drop
text-transform: uppercaseand the 0.06–0.08em letter-spacing from both.eyebrowand.eyebrow-lg. Write "Foundations · Color", not "FOUNDATIONS · COLOR". Acronyms stay capitalised in source ("API", "POS", "ID"). Founders Grotesk H1 is the only place ALL CAPS still applies.
- Drop
- v1.0.5
Transitive bump for the @flatpay-dk/ui 1.0.5 fonts hot-fix. The preset itself is unchanged.
Changed
- Updated peer to
@flatpay-dk/ui@1.0.5.
- Updated peer to
- v1.0.4
Transitive bump for the @flatpay-dk/ui 1.0.4 Table polishes (progressive reduction + sentence-case headers). The preset itself is unchanged.
Changed
- Updated peer to
@flatpay-dk/ui@1.0.4.
- Updated peer to
- v1.0.3
Transitive bump for the @flatpay-dk/ui 1.0.3 Table polish (container-query reduction, no-wrap default, full-width Pagination). The preset itself is unchanged.
Changed
- Updated peer to
@flatpay-dk/ui@1.0.3.
- Updated peer to
- v1.0.2
Transitive bump for the @flatpay-dk/ui 1.0.2 Navigation expansion. The preset itself is unchanged.
Changed
- Updated peer to
@flatpay-dk/ui@1.0.2.
- Updated peer to
- v1.0.1
The preset side of the @flatpay-dk/ui 1.0.1 `<Section>` neutralisation: a new `--color-accent-neutral-subtlest` token (and `bg-accent-neutral-subtlest` Tailwind utility) for symmetry with the existing `subtler` and `subtle` tokens.
Added
--color-accent-neutral-subtlesttoken (and thebg-accent-neutral-subtlestTailwind utility) for symmetry withsubtlerandsubtle. Purely additive — no changes to existing utilities.
Changed
- Updated peer to
@flatpay-dk/ui@1.0.1.
- v1.0.0
First public release of the Tailwind v4 preset. One `@import` lines up the system's tokens, status family, and eyebrow utility against your project's Tailwind setup.
Added
@import "@flatpay-dk/tailwind-preset";re-exports the canonical token CSS and maps every semantic var onto Tailwind's@themenamespace —bg-accent-blurple-subtlest,text-foreground, the brand status family..eyebrowand.eyebrow-lgutility classes for the system's ALL-CAPS section labels.--font-display: var(--font-display, var(--font-sans))fallback chain — apps without a licensed display font render headings in Inter Tight automatically.
Where this comes from
Hand-written, version-by-version
Every entry on this page — version, publish date, summary, and change bullets — lives in apps/docs/lib/docs/release-notes.ts and is paired with the version’s changeset when a release goes out. The packages themselves are published privately to GitHub Packages under the FLATPAY-DK org, so the page is built from the in-repo source of truth rather than a registry fetch.