Changelog

Release notes

Every published version of @flatpay-dk/ui and @flatpay-dk/tailwind-preset — when each shipped and what changed. Hand-written, paired with each version's changeset.

@flatpay-dk/ui

  1. 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 below sm, 16 px at sm+) — 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. PageVariant is 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 below md, 32 px at md+, 48 px at lg+. Applied to both PageHeader variants (main + subpage), PageBody's outer vertical padding, and the inner horizontal column on both. PageHeader uses 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 own className still override via Tailwind's last-wins-on-conflict rule.
  2. 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 transparent Button variant — the borderless sibling of tertiary. 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 below md, centred modal at md+), and <Drawer> (explicit fixed-side panel, unchanged). Sheet handles its own responsive switch via window.matchMedia('(min-width: 48rem)') so consumers never write their own media-query logic. Modal sizes refined to align with the Tailwind scale: sm 360 → 400, md 512 → 560, lg unchanged at 720. New exports: Sheet, SheetHeader, SheetBody, SheetFooter, SheetProps, SheetSize.
    • <NavigationSideBar> gains a "responsive" mode and defaults to it. At lg+ the rail renders expanded; between md and lg it collapses to the mini icon-only variant; below md the 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 copy state to TextField (and a CopyField wrapper) 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. disabled wins over copy, and the state is a no-op at size="hero".

    Changed

    • <Table> column reduction is now driven by the viewport (sm / md / lg / xl / 2xl) instead of the table's own container (@container/table is gone). Below sm only the first and last columns remain — the canonical "mobile" 2-column layout. Tables with more than seven columns clamp at 2xl; consumers needing slot-relative collapse should wrap the table in their own @container query.
    • TextField now logs a dev-mode console.warn when the prefix slot'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 HTML disabled attribute, which triggered every variant's :disabled styles and wiped the foreground out from under the spinner. Loading now uses aria-disabled + aria-busy + data-loading and an internal onClick guard that short-circuits keyboard activation so a loading submit button still can't fire its form. Buttons that pass disabled={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 SearchField wrapper around TextField. The dedicated Search component (combobox with autocomplete listbox) is the canonical search input; for free-text queries that submit elsewhere, use a plain TextField with type="search" and showClearButton. The internal SearchIcon helper has also been removed. FilterSearchField is unrelated and unaffected.
  3. 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/ui to @flatpay-dk/ui. Published privately to GitHub Packages under the FLATPAY-DK org. Consumers need an .npmrc mapping @flatpay-dk:registry=https://npm.pkg.github.com and a read:packages-scoped GitHub PAT to install.
  4. 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 from React.useId() instead of an in-module uid counter. Consumer-supplied id props are unchanged; only the auto-generated default's shape changes (now flatpay-search-:r0: rather than flatpay-search-1).
  5. 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.js now declares interTight and martianMono with const instead of var. esbuild's bundler had been rewriting top-level export const to var for TDZ-safe circular-import behaviour, which Next.js's next/font/local plugin refuses on principle. tsup's onSuccess hook now post-processes the fonts entry to put the const back.
  6. 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/@3xl container-query thresholds. The synthetic chevron column appears whenever the table is reduced and disappears once every column fits. TableColumn.mobile becomes 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 in column.header carries 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.
  7. 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

    • Table mobile reduction is driven by @container/table instead of viewport md: 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.noWrap defaults to true. 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 via noWrap: false.
    • Pagination spans 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.
  8. 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 NavigationItems preset — "PAY" | "POS" | "Ecom" (default "POS") with an optional admin flag 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 NavigationPage shell. Required topBar and sideBar slots enforce that the bar and the rail are never used independently.
    • NavigationLocation gains a variant prop ("chip" | "secondary"). chip is the default desktop chrome; secondary renders as a filled bg-secondary surface used inside the mobile sheet.

    Changed

    • NavigationSideBar and NavigationTopBar now share the accent-neutral-subtler surface; the rail drops its border-r, the bar drops its border-b at lg+, so the chrome reads as one continuous L-tint against the white content column.

    Fixed

    • NavigationSubItem now matches the parent row's height (48 px) and base typography. Children no longer render at text-sm / h-9; nesting is carried by the 44 px left inset alone.
  9. 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-v3 entry mirrors the Tailwind v4 preset's @theme inline block; a new @flatpay-dk/ui/fonts/css entry registers Inter Tight + Martian Mono via plain @font-face for non-Next consumers. Existing Next.js consumers see no behavioural difference.
    • ./package.json is now in the exports map, so consumers can read the package's version at build time via import 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 with emphasis: 0 | 1 | 2 | 3 (the four-step neutral ramp) and an admin boolean for the staff-only yellow surface. The old surface prop and sectionVariants export 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 now h-full overflow-hidden and 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.
  10. 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-display chain.
    • Compiled-bundle distribution. The package ships dist/ (esbuild + tsup) — consumers no longer need transpilePackages in their Next config.

@flatpay-dk/tailwind-preset

  1. 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.
  2. 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.
  3. 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-preset to @flatpay-dk/tailwind-preset. Published privately to GitHub Packages under the FLATPAY-DK org. Peer dependency updated to @flatpay-dk/ui@workspace:*.
  4. 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.
  5. 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: uppercase and the 0.06–0.08em letter-spacing from both .eyebrow and .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.
  6. 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.
  7. 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.
  8. 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.
  9. 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.
  10. 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-subtlest token (and the bg-accent-neutral-subtlest Tailwind utility) for symmetry with subtler and subtle. Purely additive — no changes to existing utilities.

    Changed

    • Updated peer to @flatpay-dk/ui@1.0.1.
  11. 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 @theme namespace — bg-accent-blurple-subtlest, text-foreground, the brand status family.
    • .eyebrow and .eyebrow-lg utility 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.