@marigold/components
18.1.0 (Released on Aug 27, 2026)
Minor Changes
-
1dfe461: feat(DST-1489): add non-form interactive list component
Adds
<ListView>and<ListView.Item>, a non-form list built on React Aria'sGridList/GridListItemfor rows the user operates in place — dismissing with a<Button>, opening a per-row<ActionMenu>, or following a link — without leaving the page. Unlike<SelectList>/<Select>/<ListBox>,<ListView>has no selection, no hidden input, and never becomes a submitted form value.A row is a named-area grid —
'label actions' 'description actions'— so every region names the cell it wants instead of counting columns and rows. Row content is authored with Marigold's slot-aware components (<TextValue>,<Description>,<Title>), and each of them claims its cell through slot context, so text still lands correctly when it's wrapped in a fragment, behindmemo(), or inside a consumer's own component. A bare string child is wrapped as the row's text value; to emphasise part of a line, nest<Text as="span">inside<TextValue>/<Description>. A row carries one<Description>— it takes inline markup, so several facts go on one line.Trailing controls claim their cell through Marigold's
ButtonContextand inherit the row'sghostcascade, the same mechanism<Panel.Header>and<SelectList.Option>use. A row with more than one control must wrap them in a<ButtonGroup>: each control reads the same context and would otherwise be placed in the same cell. A dev-only warning catches that at authoring time. The trailing cell takes Button-family controls only; trailing badges, pills or timestamps have no slot yet.<ListView.Item>forces any nested<Title>to render as a<span>instead of a real heading, so a list of rows never emits one document heading per row.The list is flat (divider lines only) and draws no surface of its own, the way
<Table>does — a framed list nested in a container that already draws a surface is a ring inside a ring. A standalone framed list is<Card><ListView /></Card>.This closes the gap between
<List>(presentational, no roles),<ListBox>(selection only — forbids focusable controls inside a row),<SelectList>/<Select>(form fields),<Table>(tabular), and<Menu>(commands that close on activation). The motivating consumer is the Popover notifications panel (DST-1485), and the docs cover a second must-support scenario: a resource list with a per-row action menu.v1 is intentionally minimal: no selection, no bulk-action bar, no async loading, no drag-and-drop, and no leading media. Leading icons and images need slot-aware icon/image components so placement doesn't depend on authoring order, which is tracked separately along with the rest of the follow-ups (selection ships together with a bulk-action bar, building on DST-1487).
Documentation
New
/components/collection/listviewdocs page: anatomy, appearance, a "which list?" decision guide, the must-support demos, accessibility notes (including the<Title>-as-span caveat), and cross-links to<List>,<ListBox>,<SelectList>,<Table>, and<Menu>. -
1dfe461: feat(DST-1489):
ListViewis flat, and aligns likeTableandAccordioninside a bled container.What changed:
- The list ships one variant.
defaultis the flat list (divider lines only) and there is no framed variant — the oldvariant="plain"is gone, since it is whatdefaultnow does. - Row padding is sourced from
--bleed-px(via--listview-item-px) on the base rather than per variant. That is the custom property a bledPanel.Content/Panel.CollapsibleContent/Drawer.Contentpublishes; it falls back to the standalone row padding (--spacing-stretch-regular-x) when unset.
Why:
A framed list was what a consumer got without asking, and it collides with anything that draws its own surface — a
Card, aPanel, a docs preview — as a ring inside a ring 8px apart. EveryListViewin the repo lives inside such a container, so the frame had no consumer of its own;Tableanswers the same shape by drawing no frame at all and leaving the surface to its container. A standalone framed list is<Card><ListView /></Card>.Binding the bleed to a variant had the same problem from the other side:
<Table>and<Accordion>adopt--bleed-pxunconditionally, so both align inside a bledPanelwith no opt-in, while<ListView>needed two knobs to do the same thing. - The list ships one variant.
-
ce2720e: feat(Table): expandable rows for grouped records
<Table>can now nest rows, so records that belong together (a settlement run and its individual clearings, an order and its line items) share one table instead of being faked with a button and a menu. SettreeColumnto theidof the column that carries the hierarchy and nest<Table.Row>inside<Table.Row>; use the new<Table.ExpandableRows>when the nested rows come from data, and mark a rowexpandablewhen they are fetched only once it is opened. Nested rows stay real table rows, so their values line up under the same headers and each one carries its own actions.The tree column renders the expand control itself, reusing the caret and morph animation from
<Accordion>. The caret starts where the column's values start: its hit target is wider than the caret and hangs back into the cell's edge padding (--tree-caret-inset), so the ghost button's own whitespace is the gutter rather than something added to it. Behind it every row reserves that gutter, so a group row and a childless row at the same level start their value at the same x whether or not there is a control to show. Levels below the root indent by one gutter (--tree-indent), so a nested row's caret starts where its parent's value starts, and the column's own header label takes the same gutter, so it sits above the values it heads. Containment is carried by the children rather than the parent: nested rows share a filled band across the full row, so what belongs to a group is legible in the leading drag and selection columns too, which don't indent. Expansion is collapsed by default and can be controlled withexpandedKeys/defaultExpandedKeys/onExpandedChange.Drop indicators are level-aware: the insertion line starts at the x of the level the row would land at, so a reorder inside an expanded group reads as landing in that group, while a root-level drop still spans the row. Moving a row from one level to another is not supported.
The 32px control keeps that hit target without setting row height: a negative block margin cancels the surplus over the line box, so a group row is exactly as tall as a leaf row and the
sizevariant's cell padding stays the only thing that decides — 33 / 41 / 53px forcompact/default/spacious.New theme keys
treeIndentandexpandButton. The band isforeground/8, which holds ~1.17:1 whether the rows sit onsurface, onbackgroundor inside amutedtable, and yields to the hover wash so hovering still reads.adminandmasterrows keep their access colour at every level — who may see a row outranks where it sits in the tree.Inline editing composes with it:
Table.EditableCellrenders the tree column's gutter too, so a row keeps its expand control even when that cell is the editable one. When the edited value lives outside the row items, passdependenciestoTable.ExpandableRowsas well as toTable.Body. Selection checkboxes, drag handles and thecompact/default/spaciouspaddings all keep working alongside the tree column, and the tree column still takes its edge padding from aPanel's bleed contract.Selection works on grouped rows but does not cascade: each row selects on its own, and a group row shows no partial state while only some of its children are selected. Cascading selection is not part of this release.
Potentially breaking for opted-in tables: setting
treeColumnchanges the table's accessibility role fromgridtotreegrid, which is what makes screen readers announce expanded state and nesting level. Tests assertinggetByRole('grid')on such a table need to becomegetByRole('treegrid'). Tables that don't settreeColumnare unaffected.Collapsed child rows are deliberately not rendered, so searching or deep-linking to a nested row means expanding its ancestors first. Moving focus to a specific row is not supported yet, which is tracked in DST-1713. Sorting doesn't reorder levels for you either, so sort each level in your own data, and there is no expand all control, so set
expandedKeysto every group's key when you need one.
Patch Changes
-
17f9158: fix(DST-1675): treat
collapsedas axis-less when resolving inset paddingresolveInsetAxesappended an axis suffix to every non-numeric inset token, includingcollapsed— the one token where an axis split is meaningless, since it means "no spacing" on both axes. So<Panel p="collapsed">resolved tovar(--spacing-collapsed-x)rather thanvar(--spacing-collapsed).That variable went undeclared until it was added to
@marigold/theme-rui, so the declaration was invalid at computed-value time andpaddingfell back to its initial value of0— the right answer for the wrong reason. The cost was that every theme implementing this API had to ship three variables that all mean0(--spacing-collapsed,-x,-y) to make one documented prop value work, with nothing to tell it so.collapsedis now recognised as axis-less and passed through unsuffixed, so a theme declares--spacing-collapsedonly. The same guard is applied to the deliberately-divergent copy of the axis logic inSelectList, which had the identical bug on itspprop. A newisAxislessTokenpredicate is exported from@marigold/systemso the concept has one home instead of being inlined at both call sites.isScaleis unchanged:collapsedstays non-numeric there, becausecreateWidthVar,createHeightVarandcreateSpacingVardepend on that classification.Theme:
--spacing-collapsed-xand--spacing-collapsed-yare removed from@marigold/theme-rui. They shipped intheme-rui6.0.0 stable but existed only to satisfy the suffix that is no longer generated — nothing else referenced them, and the documented token has always beencollapsed. -
148ef97: fix(DST-1740): give
CheckboxandSwitchlabels a containing block for their hidden inputReact Aria renders the real
<input>inside the control's<label>wrapped inVisuallyHidden, which isposition: absolutewith no offsets. The label wasposition: static, so the input anchored to whatever positioned ancestor the consumer happened to have. In a list inside a dialog that is the dialog itself, a dozen static elements up.An absolutely positioned box laid out against an ancestor outside a scroll container is not part of that container's scrolled content, so the input stopped travelling with the row it belongs to. Clicking a row far down the list focused an input the browser believed was over a thousand pixels away, and it scrolled the dialog to reveal it. In the reported case the dialog also set
overflow: hidden, so there was no scrollbar to get back and it ended up blank.Both labels are now
relative. React Aria's own docs name this as a precondition ofVisuallyHidden("it must have aposition: relativeorposition: absoluteancestor"), citing stray scrollbars — the focus jump is the sharper consequence, which is probably why it went unnoticed.Radioalready positioned its label and is unchanged.Switchlooked like it did too, but itsrelativesat on a wrapper around the track, a sibling of the input rather than an ancestor, so it never reached it. That wrapper is gone and the track is now a direct child of the label, which carries therelative.Checkbox.GrouprendersCheckboxchildren and needs no change of its own.Consumers who worked around this by setting
position: relativeon their own scroll containers can drop it, though leaving it in place is harmless. -
1fd3f85: fix(DST-1729): take
useLocalefromreact-aria-components, not@react-aria/i18n.Calendar's preset resolution read the locale through the@react-aria/i18nshell. RAC pins itsreact-ariainternals exactly while the shells keep caret ranges, so a consumer's lockfile can legitimately resolve tworeact-ariacopies — two module instances, two distinctI18nContexts. The hook then reads a context that<I18nProvider>never wrote, and presets silently fall back to the default locale. Nothing errors, and our own dedupe hides it locally, so it only ever appears in a consumer's app.Same failure class as DSTSUP-261 and DST-1505. A check now fails CI if
packages/componentstakesI18nProvider,useLocaleorisRTLfrom the shell again. -
4a18a38: fix(Tray): don't dismiss the tray on gestures that start in its content
A vertical swipe inside
<Tray.Content>was read as drag-to-dismiss, so scrolling a list or swiping over a calendar closed the tray instead of scrolling it, including the trays thatDatePickerandDateRangePickeropen on mobile. The gesture now only starts on the tray's chrome (drag handle, title, actions), and motion no longer setstouch-action: pan-xon the tray, so content can pan vertically on touch. As a result, text inside the tray is selectable again — suppressing selection and touch panning is now scoped to the chrome. No opt-in required; nothing to change in consumer code. -
e41e633: style(DST-1711): give the undo toast's action button a visible weight.
addUndoToastrendered its Undo button asvariant="ghost", which has no fill and no border until it is hovered. It is now the defaultsecondarybutton, so the way back out of a deletion is visible at a glance.Review feedback on the Destructive Actions pattern found the button easy to overlook: the toast arrives far from the control that triggered it and leaves again after five seconds, which is the worst case for an affordance that only appears on hover. It is deliberately not a
destructivebutton — undo is the safe action, and red beside a completed deletion reads as a second delete. -
Updated dependencies [17f9158]
- @marigold/system@18.1.0
18.0.0 (Released on Aug 11, 2026)
Major Changes
-
b7122c0: feat(DST-1545): replace
ActionBar.Buttonwith a plain<Button>via aButtonContextcascade.ActionBarnow provides aghost/defaultcascade to its toolbar, so authors place a standard<Button>inside the bar and it adapts to the toolbar look automatically, with the full Button API available (disabled,loading,slot,size="icon"). This mirrors the pattern already used byPanel.HeaderandButtonGroup.Breaking:
ActionBar.Buttonis removed. Replace<ActionBar.Button>…</ActionBar.Button>with<Button>…</Button>. For icon-only actions use<Button size="icon" aria-label="…">, which also fixes an accessibility defect where the old wrapper silently droppedaria-label, shipping unlabeled icon buttons. The duplicatedactionButtontheme style is gone (it hand-mirrored Button'sghostvariant at the default size, minus the press and loading affordances a real<Button>now brings).// Before <ActionBar selectedItemCount={3} onClearSelection={clear}> <ActionBar.Button onPress={edit}> <Pencil /> Edit </ActionBar.Button> </ActionBar> // After <ActionBar selectedItemCount={3} onClearSelection={clear}> <Button onPress={edit}> <Pencil /> Edit </Button> </ActionBar> -
b7122c0: feat(AppLayout): switch to page-level scroll
AppLayoutno longer owns an interior scroll container. The document (<html>/<body>) scrolls the whole page; the sidebar sticks viaposition: stickyand the top header stays pinned throughTopNavigation's own sticky positioning.Why page-level scroll
- Mobile URL bar collapses on scroll. With interior scroll, Safari and Chrome mobile keep the URL bar expanded forever, wasting ~8% of the screen. Only document scroll lets the browser hide it.
- Pull-to-refresh works. Interior scroll disables it.
- Browser scroll restoration on back/forward only works reliably for the document, not interior containers. Interior scroll produces subtle "lost scroll position" bugs.
Cmd+Ffind-in-page scrolls the document, not an interior container, so matches outside the viewport scroll into view correctly.- Anchor links (
#section), iOS status-bar tap (scroll-to-top) and native keyboard nav (PgUp/PgDn/Space/Home/End) all behave predictably. IntersectionObserverwith default root, scroll-snap, sticky elements,scroll-margin-top— all simpler when there is one scroll container.
Breaking changes
- Code reading
mainRef.current.scrollTop(or similar) will no longer see user scroll. Readwindow.scrollY/document.documentElement.scrollTopinstead. - Styles assuming a fixed-height main region (
height: 100%on direct children of<AppLayout.Main>, for example) will no longer be bounded by the viewport. Usemin-h-dvhor remove the constraint.
Known trade-offs
- Pure app-shell look via
position: stickycan flicker on iOS Safari momentum scroll. Cosmetic, usually acceptable. - Sticky elements may show a brief re-paint when overlays close. Not a correctness bug.
-
b7122c0: feat([DST-1407]):
Drawerenforces one open at a time.Opening a sibling
<Drawer>while one is already open dismisses the first. Applies to desktop and mobile. The dismissed Drawer'sonOpenChange(false)is invoked so controlled-state consumers stay in sync.A
<Drawer.Trigger>nested inside an already-open Drawer is treated as a sub-flow: the nested Drawer opens over its parent and the parent stays mounted. Dismissing the parent in that situation would also unmount the nested trigger and tear down the new Drawer.Migration: No API change. If a flow relied on multiple simultaneous sibling drawers, refactor to a single drawer with switchable content, or use
<Modal>for layered interactions. -
b7122c0: chore(DST-1164): remove the unused
Breakoutcomponent and the now-deadalignAPI fromContainer.Breakouthad 0% usage across all scanned production repositories, so it is removed entirely (component, stories, tests, and docs).Container'salignprop, together with its internalgridColumn/gridColsAligngrid setup, only ever took effect via a[data-breakout]child, so it became dead code onceBreakoutwas gone and is removed as well.Migration: remove any
alignprop from<Container>usages. ThecontentLength,alignItems, andspaceprops are unchanged. -
b7122c0: refa([DST-1324]): Breaking change: Rename Inset's
space/spaceX/spaceYprops top/px/pyThe padding props on
Insetare renamed to align withPanel's existing API, so that across the design systemspacealways means gap between children andp/px/pyalways mean inner padding. Previously,spacecarried two different meanings depending on the component, which was a source of confusion.Migration:
Before After <Inset space="…" /><Inset p="…" /><Inset spaceX="…" spaceY="…" /><Inset px="…" py="…" />The discriminated union shape is unchanged:
pis mutually exclusive withpx/py. Token vocabularies are unchanged (InsetSpacingTokensforp,PaddingSpacingTokensforpx/py). -
b7122c0: feat(DST-1360): introduce
AppShell,Page,Page.Header, andPage.Content; removeAppLayoutRenames
AppLayouttoAppShelland removes its three pass-through subcomponents (AppLayout.Sidebar,AppLayout.Header,AppLayout.Main) —<Sidebar>,<TopNavigation>, and<Page>now sit directly inside<AppShell>(each owns its grid area, so child order does not matter).AppShellabsorbsSidebar.Providervia thedefaultSidebarOpenprop; render your own<Sidebar.Provider>around<AppShell>for controlled state,variant, orsizeand it is detected and used instead of the internal one.Adds
<Page>— the<main>landmark with page padding (p, orpx/py; defaultsquare-relaxed) and vertical rhythm between sections (space; defaultgroup). The page's<main>is named by its<h1>viaaria-labelledby; when there is no<Title>, passaria-label(or your ownaria-labelledby) instead. With none of these,<Page>warns in development so the landmark is never silently unnamed. Like<Panel>,<Page>forwards standard HTML attributes (id,data-*, event handlers) and arefto its<main>.Adds
<Page.Header>— a slot-based title/description/actions header that mirrorsPanel.Header— and an optional<Page.Content>(with its ownspace) for when the rhythm between sections should differ from the header-to-content gap. The page heading outline now falls out of the defaults:<Title>inPage.Headeris anh1,<Title>inPanel.Headeranh2,<Title>inPanel.Collapsibleanh3(override per<Page>withheadingLevel).Migration:
-<Sidebar.Provider defaultOpen> - <AppLayout> - <AppLayout.Sidebar>…</AppLayout.Sidebar> - <AppLayout.Header>…</AppLayout.Header> - <AppLayout.Main>{content}</AppLayout.Main> - </AppLayout> -</Sidebar.Provider> +<AppShell defaultSidebarOpen> + <Sidebar>…</Sidebar> + <TopNavigation>…</TopNavigation> + <Page> + <Page.Header> + <Title>Billing</Title> + <Description>Manage your plan and invoices.</Description> + <Button variant="primary">Upgrade plan</Button> + </Page.Header> + {content} + </Page> +</AppShell> -
b7122c0: refactor(DST-1548): rename
Card.BodytoCard.ContentAligns the Card body sub-component with
Panel.ContentandPage.Contentso all three container primitives expose the main body region under one name.Breaking change:
Card.Body(CardBody) is removed. Rename usages toCard.Content:- <Card.Body>...</Card.Body> + <Card.Content>...</Card.Content>The
bleedprop and padding behavior are unchanged. The internaldata-card-bodyattribute has been removed to matchPanel.Content.The
Cardtheme slot key is renamed frombodytocontentin the@marigold/systemThemetype and in@marigold/theme-rui. Theme authors overriding this slot must rename their key accordingly. -
b7122c0: refa([DST-1549]): Breaking change: Rename compound member
Tabs.TabPanel→Tabs.PanelTabsnow exposes.List,.Item, and.Panel, so every compound member follows one predictable naming rule.<Tabs.TabPanel>is removed (hard rename, no deprecated alias).Migration:
Before After <Tabs.TabPanel id="…"><Tabs.Panel id="…"> -
b7122c0: fix(DST-1559): remove dead and mis-named props from
TextField,FileTrigger, andLoader.TextField: drop themin/maxprops. They were never forwarded to the underlying<input>(react-aria filters them out of both the input and wrapper props), so they had no effect. Numeric constraints belong onNumberField.FileTrigger: remove the mis-named singularacceptedFileTypeprop. Its key did not match react-aria'sacceptedFileTypes, so file-type filtering silently never applied. Use the inheritedacceptedFileTypesinstead.Loader: fix theloaderTypeJSDoc, which documented a non-existentcyclevalue. The accepted values arexloaderandcircle(defaultcircle).
-
b7122c0: refactor([DST-1283]): Breaking Change — Remove
<Multiselect>(and thereact-selectdependency) from@marigold/components.Use
<TagField>instead. -
b7122c0: fix(DST-1353): remove
width="fit"from Select, ComboBox, and AutocompleteBREAKING CHANGE: The
fitvalue for thewidthprop is no longer accepted onSelect,ComboBox, andAutocomplete. These components use a popover with virtualized rendering, where the react-aria Virtualizer controls item sizing and ignores CSS layout. This caused dropdown content to be clipped whenwidth="fit"was used. Affected usages should switch to an explicit width value instead. -
b7122c0: fix(DST-1556): rename SectionMessage's controlled visibility prop from
closetoopen<SectionMessage>'s controlled visibility prop was namedclosebut its truthiness meant visible ,close={true}showed the message andclose={false}hid it, the opposite of what the name and docs implied. It's nowopen, matching the polarity used by<Dialog>,<Drawer>,<Tray>, and<Sidebar>.Before After close={isVisible}(truthy = visible)open={isVisible}(truthy = visible)close={!isDismissed}open={!isDismissed}onCloseChange={setX}(receives current value)onOpenChange={(open) => ...}(receivesfalseon dismiss)A new
defaultOpenprop (defaulttrue) sets the initial visibility in uncontrolled mode. The uncontrolled default behavior (visible, self-dismisses via the close button) is unchanged. -
b7122c0: feat(DST-1246): update Switch component layout and sizing to align with Checkbox and Radio
The Switch component previously rendered its label on the left and toggle on the right, which was inconsistent with Checkbox and Radio where the control sits on the left. When used together in forms, this created a visually misaligned layout.
Layout: Toggle now renders before the label (control on the left, label on the right), matching Checkbox and Radio. This ensures consistent visual alignment when Switch is used alongside other boolean controls in form layouts.
Sizing: Reduced the default track size from 24x40px to 16x28px and thumb from 20px to 12px. This brings the Switch closer in visual weight to Checkbox/Radio (16px), making it fit better in the flow of forms.
Settings variant: A new
variant="settings"mirrors the default layout — label and description on the left, toggle on the far right. This is the common pattern used on settings/preferences pages. The variant is propagated toBooleanFieldso that grid columns and description placement adjust accordingly.Description support: Switch now accepts a
descriptionprop (help text rendered below the control), matching Checkbox's existing support. The description text aligns with the label text using CSS grid + subgrid, automatically adapting to any control size without hardcoded padding. Properly wired witharia-describedbyfor accessibility.Form support: The
nameprop passes through to the underlying input for HTML form submission.Shared BooleanField: Extracted a reusable
BooleanFieldwrapper used by both Checkbox and Switch for consistent description rendering andaria-describedbywiring. Uses CSS grid with subgrid to align description text with label text across both components.Breaking changes
Restoring the old Switch behavior
The default Switch layout has changed: the toggle is now on the left and the label on the right (previously reversed). If you need the old layout (label left, toggle right), use the new
variant="settings":- <Switch label="Wi-Fi" /> + <Switch label="Wi-Fi" variant="settings" />The
size="large"prop has been removed. The default size is now smaller (16x28px track). There is no built-in way to get the old large dimensions (24x40px track) — if needed, create a custom size variant in your theme'sSwitch.styles.ts.Custom theme migration
This release introduces a new required theme component
BooleanFieldand changes the layout model of theCheckboxandSwitchcontainer slots from flexbox to CSS grid. Custom themes must be updated or Checkbox/Switch will throw a runtime error.1. Add
BooleanFieldto your theme (required)BooleanFieldis a new multi-slot theme component used internally by bothCheckboxandSwitchto render descriptions. If your theme does not include it, anyCheckboxorSwitchwith adescriptionprop will throw:Error: Component "BooleanField" is missing styles in the current theme.Add the following to your theme's component styles:
import { cva } from '@marigold/system'; export const BooleanField = { container: cva({ base: 'grid gap-x-2', variants: { variant: { default: 'grid-cols-[auto_1fr]', settings: 'grid-cols-[1fr_auto]', }, }, defaultVariants: { variant: 'default' }, }), description: cva({ base: 'mt-0.5', variants: { variant: { default: 'col-start-2', settings: 'col-start-1', }, }, defaultVariants: { variant: 'default' }, }), };container: Defines the 2-column grid layout wrapping the control and its description. Thedefaultvariant usesgrid-cols-[auto_1fr](control left, label right). Thesettingsvariant usesgrid-cols-[1fr_auto](label left, control right).description: Styles the description text wrapper. Placed under the label column viacol-start-2(default) orcol-start-1(settings).mt-0.5adds vertical spacing between the label row and description.
Then export it from your theme's component index file:
export { BooleanField } from './BooleanField.styles';2. Update
Checkboxcontainer slot (required if customized)The
Checkboxcontainer slot changed from flexbox to CSS grid with conditional subgrid support:Before:
container: cva({ base: 'cursor-pointer read-only:cursor-default gap-2' }),After:
container: cva({ base: [ 'grid grid-cols-[auto_1fr] gap-x-2 items-center', 'cursor-pointer read-only:cursor-default', 'group-data-[booleanfield]/booleanfield:grid-cols-subgrid group-data-[booleanfield]/booleanfield:col-span-full', ], }),Key changes:
gap-2changed togap-x-2(column gap only, since row gap is now handled byBooleanField.description)grid grid-cols-[auto_1fr] items-centerreplaces theflex items-centerthat was previously hardcoded in the componentgroup-data-[booleanfield]/booleanfield:grid-cols-subgridandgroup-data-[booleanfield]/booleanfield:col-span-fullenable subgrid when inside aBooleanFieldwrapper, so the description aligns with the label
3. Update
Switchcontainer slot (required if customized)The
Switchcontainer slot also changed from minimal styles to CSS grid with subgrid:Before:
container: cva({ base: 'disabled:cursor-not-allowed disabled:text-disabled-foreground', }),After:
container: cva({ base: [ 'grid gap-x-2 items-center', 'disabled:cursor-not-allowed disabled:text-disabled-foreground', 'group-data-booleanfield/booleanfield:grid-cols-subgrid group-data-booleanfield/booleanfield:col-span-full', ], variants: { variant: { default: 'grid-cols-[auto_1fr]', settings: 'grid-cols-[1fr_auto]', }, }, defaultVariants: { variant: 'default' }, }),Key changes:
- Added
grid gap-x-2 items-center(replacesflex items-center gap-2that was previously hardcoded in the component) - Grid columns moved to
variantto support both default and settings layouts - Added subgrid support for BooleanField integration
-
b7122c0: refa([DST-1162]): Breaking changes: The
Cardcomponent has been refactored into a compound component pattern.What changed:
- The previous prop-based API (
padding,space, etc.) has been removed. - Content must now be composed using explicit sub-components:
Card.Header,Card.Body,Card.Footer, andCard.Preview. - A
CardContextis now required — sub-components will throw an error if used outside of a<Card>.
Migration:
// Before <Card> <SomeContent /> </Card> // After <Card> <Card.Header>Title</Card.Header> <Card.Body><SomeContent /></Card.Body> <Card.Footer>Actions</Card.Footer> </Card> - The previous prop-based API (
-
b7122c0: refa([DST-1281]): Breaking change:
<Tooltip>no longer acceptsopen. Controlled visibility is only supported on<Tooltip.Trigger>(open/onOpenChange). Removes the internal React context that previously forwardedopenfrom<Tooltip>to the trigger.
Minor Changes
-
b7122c0: feat(DST-1381): add
master/adminaccess variants toLinkandMenuItemthat mark actions requiring elevated access rights with an icon (lock = master, key = admin).Badgerenders itsmaster/adminvariants with the same icons.The components render the icon as a decorative
<svg>colored by the theme's access foreground tokens (which also keeps it visible in forced-colors mode). OnLinkandMenuItemthe restriction is exposed to assistive technology through a visually hidden "Master"/"Admin" text label rendered after the visible label, so restricted links and menu items carry the access level in their accessible name.Badgerenders no extra label because its visible text already is the access level, which rules out double announcements by design.Note that
variantis a single axis: an access variant cannot be combined with another variant (e.g.destructiveonMenuItem). For destructive actions that are access-restricted, the access variant takes precedence (variant="master"), with the destructive nature conveyed by the action's label and confirmation flow. See the Admin & Master Mark pattern docs. -
b7122c0: feat(DST-1460): animated open/close caret in
Accordion.HeaderAccordion.Headernow uses the newMorphCareticon, which smoothly animates between the closed (down) and open (up) states by morphing its SVGdpath. Respectsprefers-reduced-motion. The unusedChevronDownicon has been removed. -
b7122c0: feat(DST-1551): add
DateRangePickercomponentNew
<DateRangePicker>lets users enter or select a start–end date range through a single field, mirroring<DatePicker>'s API and behaviour. Two date inputs (start/end) sit in one field group with a calendar button that opens a<RangeCalendar>in a popover on desktop and a tray on small screens. Supports per-input paste (ISO/EU/US formats),granularity(inline time segments),visibleDuration(up to three months), and the usual Marigold field props (disabled,readOnly,required,error,errorMessage,description,minValue,maxValue,dateUnavailable,width,variant,size). Adds a matchingDateRangePickertheme entry totheme-rui. -
b7122c0: feat([DST-1134]): add
<RangeCalendar>component (alpha)Adds a new
<RangeCalendar>for selecting a contiguous or non-contiguous date range, built on react-aria's<RangeCalendar>with Marigold conventions (disabled,readOnly,error,dateUnavailable,allowsNonContiguousRanges). Supports up to three side-by-side months viavisibleDuration, stacking vertically below thesmbreakpoint; the same responsive stacking now applies to multi-month<Calendar>for parity.descriptionanderrorMessageroute through<FieldBase>so the help/error UI matches the rest of the form-component family (TriangleAlert icon + HelpText container). Ships as an alpha component with a stub docs page under the form section. -
b7122c0: feat(DST-765): add
<SegmentedControl>componentAdds a new
<SegmentedControl>for compact, single-select view switching and quick filters. It is built on react-aria'sRadioGroup/RadioField/RadioButtonwith aSelectionIndicator, so it is a real form field:value/defaultValue/onChange, thenameattribute (submits like a radio group),required,error+errorMessage,description,readOnly, and validation all work exactly like the other Marigold form components (label/description/error route through<FieldBase>). The selected segment is marked by an animated indicator that slides between options.Options are declared via the compound API
SegmentedControl.Option(also exported asSegmentedControlOption), each with avalue:<SegmentedControl label="View" defaultValue="list"> <SegmentedControl.Option value="list">List</SegmentedControl.Option> <SegmentedControl.Option value="grid">Grid</SegmentedControl.Option> </SegmentedControl>Two variants —
default(abg-controltrack with a raisedui-surfacethumb, mirroring theSwitch) andghost(track-less, with a translucent ghost-Button-style indicator for dense toolbars) — at a singledefaultsize (matching theh-controlInput height). Hover and focus reuse the sharedui-*utilities (ui-state-focus,ui-state-hover-ghost); the indicator slides between options (ease-out-quint) and respectsprefers-reduced-motion.To make segments divide the available width equally, use the standard
widthprop — e.g.width="full". There is no separatefullWidthprop.When the options exceed the available width the control scrolls horizontally instead of compressing the segments, keeping the selected option scrolled into view (reduced-motion aware). A scroll-driven edge fade signals there is more to scroll where supported, falling back to a native scrollbar otherwise.
ToggleButtonGroupnow logs a dev-only warning when used withselectionMode, steering single-select use cases towardsSegmentedControl(it remains for independent on/off actions in toolbars). -
b7122c0: feat([DST-1429]):
Cardnow exposes aPanel-aligned padding API.What changed:
Cardacceptsp/px/pyprops (mutually exclusivepvspx+py), resolving to CSS custom properties--card-pxand--card-pyon the container. Defaults tosquare-regular.- A new
spaceprop controls the gap between slots, resolving to--card-gap. Defaults toregular. Card.BodyandCard.Footeraccept an opt-inbleedprop to skip horizontal padding for tables, media, or full-width action bars.- Internally,
Cardswitched from CSS grid withgrid-template-areasto a flex column withgap-y. JSX order now determines visual order — placeCard.Previewfirst when used. - Slot theme styles (
header,body,footer) no longer hardcodepx-4/py-*; padding lives in the component layer and is driven by the CSS variables above. Card.Previewautomatically escapes the container's vertical padding when used as the first or last child via negative margins.
Why:
Cards previously had no consumer-controllable padding API and no default padding on the container — content rendered as direct children of
<Card>was visually broken. The new API mirrorsPanel's padding model so the two surfaces behave consistently.Migration:
- Wrap bare children in
<Card.Body>. Bare children inside<Card>are no longer rendered with horizontal padding; this matchesPanel's composition contract. - If you used
Card.Previewfor media at the top, keep doing so — it stays edge-to-edge. - No changes needed for the canonical composition (
Preview+Header+Body+Footer).
-
b7122c0: feat(DST-1373): adopt the slot-configuration pattern in
CardCard.Headeris now a slot provider: drop a<Title>and an optional<Description>directly inside it and the header wires up the heading level, id, accessible name, and theme classes automatically. A bare<Title>placed directly inside<Card>(noCard.Headerwrapper) is also picked up by the root, so title-only cards can skip the header and still get the right padding andaria-labelledbywiring.<Card>itself now renders an<article>landmark and is automatically labelled by its<Title>viaaria-labelledby, or by an explicitaria-label. A newheadingLevelprop (default3) controls the underlying heading tag for the document outline.The theme
Cardslot map gainstitleanddescriptionentries — the typography previously carried on theheaderslot has moved totitle. Variant text color now flows through a new--card-accentCSS custom property, somasterandadmincards pick up the matching accent automatically. Raw<Stack>/<Headline>composition insideCard.Headerstill renders but does not pick up the slot wiring; prefer<Title>/<Description>going forward. -
b7122c0: feat(DST-876): add Card usage guidelines
Renames the
Card.Previewslot toCard.Mediaacross components, theme, and docs. This is a breaking change: consumers using<Card.Preview>, thedata-card-previewselector, or thepreviewtheme slot key must migrate toCard.Media,data-card-media, and themediaslot key respectively.Adds a "Usage" section to the Card docs covering when to use cards, media slot guidance.
-
0e2c676: fix(DST-1680): keep the mobile
ComboBox/Autocompletetray in the accessibility tree.On small screens both components render a
Trayinstead of RAC'sPopover. When the listbox opened,useComboBoxcalledariaHideOutside([inputRef.current, popoverRef.current].filter(el => el != null))— and because nothing claimedPopoverContextand the tray (with its input) portals in a later commit, both refs werenull.ariaHideOutsidehides everything outside the elements it is given, so an empty list hid the whole document, including the tray itself: screen readers could not reach the tray's dialog, search input or options at all.popoverRefnow points at the tray — the dialog element while open, and the container the tray portals into while closed — so the hide pass keeps the tray visible. Background isolation is unchanged; it comes from the tray's ownModal, which runsariaHideOutside(..., { shouldUseInert: true }). As a side effectuseComboBox's blur handling works again, since it checks whether focus moved intopopoverRef.currentbefore closing.Traynow also accepts arefto its dialog element. -
a9fdcff: feat(DST-944): add
addUndoToast, gateFileFieldremovals withonBeforeRemove, and make destructive confirmations settle reliably.useToastgainsaddUndoToast({ title, onUndo, onCommit }), which reports a destructive action as done and sends the real request only if the user does not take it back. It owns the parts that are easy to get wrong, so a caller cannot lose a deletion to a drifting timer, an unguarded commit, or a toast that never closes. The Destructive Actions pattern explains each one.addToastnow acceptsonClose, called when the toast closes for any reason: its timeout ran out, it was dismissed, it was closed throughremoveToast, or the queue was cleared. It also acceptscloseButton: false, which a toast that never auto-dismisses (warning,error,timeout: 0) ignores, since that would leave no way out of it.<FileField>acceptsonBeforeRemove, called with the file a remove button is about to drop. Returnfalse, or a promise resolving tofalse, to keep it, which is what puts a confirmation in front of the built-in remove buttons. A handler that throws keeps the file.Each
FileFieldremove button is now named after its file ("Remove agb-2026-08-01.pdf") instead of all announcing "Remove file", so the rows of a document list are distinguishable to a screen reader.FileField.ItemtakesremoveLabelto set that name when you compose items yourself.Dialog.Triggerno longer blocks Escape by default. An unsetkeyboardDismissablewas inverted into "keyboard dismiss disabled", so every dialog opened from a trigger trapped the keyboard unless the prop was passed explicitly, contradicting both the documentation and the default inTrayandDrawer. PasskeyboardDismissable={false}to opt out. This is a behaviour change for anyone who relied on the previous default.ConfirmationDialoganduseConfirmationgain four fixes around the same flow:- Closing a confirmation without pressing a button (Escape) now resolves
useConfirmationascancelled. Previously the promise never settled, so anawait confirm(...)silently stalled and its continuation never ran. ConfirmationDialogfocuses the cancel button by default whenvariant="destructive", so a reflexive Enter takes the safe path. PassautoFocusButton: 'action'to focus the confirm button instead.ConfirmationProvidernow forwards theautoFocusButtonfrom aconfirm()config, which it accepted but dropped, and its confirm button falls back to the localizedconfirmmessage rather than a hardcoded "Confirm" next to a translated "Cancel".ConfirmationDialogProps['variant']is typed as'destructive' | (string & {})so the variant that drives this behaviour is discoverable, rather than an untyped string.
The action buttons call their handler before closing the dialog so that an owner watching
onOpenChangesees the decision before it sees the close. This is a behaviour change for anyone relying on the previous ordering. They are still called with no arguments.See the new Destructive Actions pattern for when to confirm and when to offer undo.
- Closing a confirmation without pressing a button (Escape) now resolves
-
b7122c0: feat(DST-1369): adopt the slot-configuration pattern in
Dialog,Drawer, andTrayThe three overlay components now follow the same slot-configuration pattern as
PanelandCard. Each publishes the slot contexts at its root, so the title, description, and action primitives pick up the overlay's theme classes wherever they are dropped:Dialog.Title/Drawer.Title/Tray.Titleare thin wrappers over<Title slot="title">.- New
Dialog.Description/Drawer.Description/Tray.Descriptionwrap<Description slot="description">. - New
Dialog.Header/Drawer.Header/Tray.Headerare optional layout wrappers that group a title and description. A bare<Title slot="title">(or<*.Title>) without a header is a first-class, accessible authoring form —aria-labelledbyresolves to it automatically.
The compound-component API is unchanged. The
<header>element that previously wrapped the title is gone; the title now carries the header chrome directly, with no change to the rendered visuals. -
b7122c0: feat(DST-1635): add a
bleedprop toDrawer.Contentso edge-aware children can span the full Drawer width.What changed:
<Drawer.Content bleed>drops the Drawer's horizontal content padding and publishes a--bleed-pxcustom property, mirroringPanel.Content'sbleed.- The horizontal padding shared by the sectioned overlay surfaces (
ui-panel-header/ui-panel-content/ui-panel-actions) now comes from a single--ui-panel-pxtoken, and a bledDrawer.Contentre-publishes that exact token as--bleed-pxso the two can't drift. - Edge-aware children stay aligned with the Drawer title while their dividers/backgrounds reach the Drawer edges:
Accordionreads--bleed-pxdirectly, andTable's edge-cell padding now falls back to--bleed-px(after the Panel-only--panel-px), so it aligns inside a bled Drawer too.
Why:
Placing an
<Accordion>(orTable) inside<Drawer.Content>previously trapped it inside the content padding, so item dividers and hover/selection backgrounds could not reach the Drawer edges.bleedgives the same full-width alignmentPanel.Content bleedalready offered.Impact:
- Default behavior is unchanged: without
bleed,Drawer.Contentkeeps the paddedui-panel-contentand--bleed-pxstays unset (children resolve their inset to0px). The--ui-panel-pxtoken resolves to the same24pxthe surfaces used before, so Dialog/Drawer/Tray are visually identical.
-
b7122c0: feat(DST-1282): scroll the Tabs row horizontally when it overflows
When more tabs are rendered than fit the available width,
Tabs.Listnow scrolls horizontally instead of wrapping onto multiple lines or pushing the page wide. Tabs keep their natural width (shrink-0) and snap gently into place (proximity) as you scroll, with the adjacent tab kept peeking past the edge so the scrollability stays discoverable. A vertical mouse wheel scrolls the row horizontally (pointer users without a trackpad), without hijacking normal page scroll. Horizontal overscroll is contained so it does not trigger browser back/forward gestures, and scrolling is smooth for users who allow motion. On browsers that support scroll-driven animations the overflowing edges fade out (ui-scroll-mask-x); elsewhere it falls back to a plain scroll container. When all tabs fit, nothing changes visually.The sliding selection indicator stays correct while react-aria scrolls an off-screen tab into view (the scroll container is a
layoutScrollmotion element). No runtime API change.Breaking change (
@marigold/system): theTabsthemeRecordgains a new requiredtabsListScrollslot. It is deliberately required so a theme cannot shiptabsList(whosew-maxtriggers the overflow) without the scroll container that makes it behave. Custom themes that define aTabsblock must add atabsListScrollentry to type-check. -
b7122c0: feat(DST-1480): forward arbitrary HTML attributes on
<Panel><Panel>now extendsHTMLAttributes<HTMLElement>(minusclassName/style) and spreads the remaining props onto its root<section>, matching the<Card>API. Consumers can now passid,data-*, event handlers, and other standard attributes directly to a Panel.A consumer-supplied
aria-labelledbyis preserved instead of being overwritten withundefinedwhen no<Title>is present — the slot-ownedtitleIdstill wins when a<Title>renders. This mirrors the fallback adopted byCardin DST-1373. -
b7122c0: feat(DST-1483): remove ActionButton in favor of a slot-aware Button (rename ActionGroup → ButtonGroup)
The beta-only
<ActionButton>is removed.<Button>is now slot-aware: it adapts automatically inside a button container, so you write<Button>everywhere instead of learning a second button component.<ActionButton>is removed. Use<Button>; it adapts inside<ButtonGroup>and<Panel.Header>. Opt a button out of the cascade withslot={null}.<ActionGroup>is renamed to<ButtonGroup>, mirroring the existingToggleButtonGroup → ToggleButtonContext → ToggleButtontrio.- A single Marigold-owned
ButtonContextdrives the cascade (replacesActionButtonContext+ActionGroupContext). RAC's ownButtonContext(close/increment/decrementslots) is untouched. - Uniform precedence: a local prop (
variant,size,disabled) always wins over the container. This drops the formerActionGroupsize-group-wins outlier. <ButtonGroup>cascadesvariant: 'secondary'when unset, the same baseline as a standalone<Button>. Slot-aware parents override it where they want lower emphasis:<Panel.Header>cascadesvariant: 'ghost'+size: 'small', so a labelled header action stays readable. An icon-only action (a bare-icon<Button>, an<ActionMenu>kebab) setssize="icon"to render as a square.<ButtonGroup>now owns a structuralflex gap-1layout (orientation-aware), so a standalone cluster is spaced correctly —<ActionGroup>had no layout of its own. A container's positional className (e.g. Panel's[grid-area:actions]) still rides along and positions the group.- Overlays (
Popover,Modal,Tray,Drawer) resetButtonContextat their content root, so a header/group cascade can't leak through the portal into an overlay'sslot="close"orDialog.Actionsbuttons. <SelectList.Option>cascadesvariant: 'ghost'to a nested<Button>,<LinkButton>, or<ActionMenu>, so a trailing in-row action reads as low-emphasis chrome without an explicitvariant.
Migration
<ActionButton>→<Button>(itsdefaultvariant maps tovariant="ghost").<ActionGroup>→<ButtonGroup>.ActionButtonContext/ActionGroupContext→ButtonContext.<ActionMenu>keeps its public name. Its trigger is now a slot-aware<Button>that inherits the cascade instead of hardcoding a variant: it renderssecondaryon its own (the standalone<Button>baseline, matching the pre-unification look) andghostinside<Panel.Header>,<SelectList.Option>, or a<ButtonGroup>. Avariantset on the<ActionMenu>still wins.
-
b7122c0: feat(DST-1492): add
usePageFocusto move focus to the page<h1>on route changeOn client-side navigation focus lingers on the clicked link or falls back to
<body>, so screen-reader and keyboard users get no signal that the screen changed.usePageFocusimplements the standard SPA fix: given the current route key (typically the pathname), it makes the page<h1>programmatically focusable (tabIndex={-1}) and focuses it on each change.The first render is skipped so the initial load never steals focus, and it is a no-op on a page with no
<h1>(anaria-label-only<Page>).<Page>stays router-agnostic: the route signal comes from the app router (RouterProvider). Call the hook from a component that persists across navigations (the layout / shell level), since the skip-first-render guard is per mount.import { Page, usePageFocus } from '@marigold/components'; const PageFocus = ({ pathname }: { pathname: string }) => { usePageFocus(pathname); return null; }; <Page> <PageFocus pathname={location.pathname} /> <Page.Header> <Title>Billing</Title> </Page.Header> {/* … */} </Page>; -
b7122c0: feat(DST-1509): add
collapseAttoTag.GroupTag.Groupnow accepts acollapseAt={n}prop: the firstntags render as usual, and the rest collapse behind a "Show N more" / "Show N less" toggle, matching the behavior already available onCheckbox.GroupandRadio.Group.Unlike those groups,
Tag.Group's tags are a RAC collection (selection, removal, keyboard navigation), so collapsed tags stay mounted inside the<TagList>and are hidden via the nativehiddenattribute rather than being pulled out into a separate<Collapsible>. This keepsonRemove,removeAll, andemptyStateworking unchanged, and the collapsed count automatically shrinks as tags are removed. If a hidden tag is part of the initial selection, the group expands automatically.collapseAtonly applies to static children; dynamic collections (items+ a render function) are unaffected.When both
collapseAtandremoveAllare used together, "Show N more" bottom-aligns next to the last visible tag, while "Remove all" stays in its own trailing column so it never mixes into the tag wrap. -
b7122c0: Add relative date presets to
Calendar,RangeCalendar,DatePicker, andDateRangePickervia a newpresetsprop. On desktop the presets render as a quick-selection list beside the calendar. On small screens the grid renders first with a "Quick selection" row: inline calendars open the preset list in a bottom sheet, while the pickers switch their existing sheet to the list in place. Ships built-in localized presets (today,yesterday,tomorrow,this-week,next-7-days,next-30-days,last-7-days,last-30-days,this-month,this-quarter), supports custom presets with value resolvers, and exportsuseDatePresets/useDateRangePresetsfor userland compositions. -
b7122c0: feat(DST-1533): add
Table.FootercomponentNew
<Table.Footer>renders a semantic<tfoot>after<Table.Body>for summary rows like totals, counts, or averages, composed from<Table.Row>and<Table.Cell>just like the body. Supports astickyprop that pins the footer to the bottom of the viewport while scrolling, mirroring sticky table headers. Adds a matchingfootertheme entry totheme-rui. -
b7122c0: feat(DST-1568): add
erroranderrorMessagesupport toSwitchandCheckboxWhen
erroris set, the field is marked invalid and theerrorMessageis shown in place of thedescription, wired to the input viaaria-describedby. When both are unset, rendering is unchanged.Internally,
SwitchandCheckboxnow render theirHelpTextinside the RAC field (SwitchField/CheckboxField), relying on RAC's nativearia-describedbyandFieldErrorContextwiring instead of re-plumbing it by hand. No other public API change. -
b7122c0: feat(DST-1609): two-level sidebar navigation with
Sidebar.RailandSidebar.RailItemAdds a two-level navigation mode to the sidebar: a persistent rail of icon-first top-level destinations next to a panel showing the active section's sub-navigation. A
Sidebar.RailItemwrapping aSidebar.Navis a section that shows a panel. One with only anhrefis a direct link, and one insideSidebar.Footerpins to the bottom of the rail. Itsactiveprop overrides href matching for pages the URL can't identify. Collapsing (toggle or Cmd/Ctrl+B) hides the panel while the rail narrows to an icon strip, so top-level navigation always stays available. On small screens the rail renders as the same single-column drawer as the plain sidebar: sections drill in (opened at the active section) and links close the drawer.<AppShell>switches to a full-width top bar automatically when a rail is present (pure CSS via:has()), so the brand never moves when the panel collapses.Sidebar.Togglegainsvariant="rail"for its top-bar placement between the brand and the breadcrumbs.- New theme tokens:
--spacing-topbar(the shell's shared vertical datum for the top bar height, sidebar brand row, and rail sticky offset), the rail column widths--spacing-rail/--spacing-rail-collapsed/--spacing-rail-panel, and--spacing-touch-target(44px minimum row height on small screens, shared by the drawer's nav rows and the existing Tray-mode ListBox/Menu options). - Idle single-column nav labels darken a step (new
--color-secondary-boldtoken, charcoal-700) so they clearly out-rank the quiet group-label captions. - Keyboard: the rail supports arrow-key (and Home/End) movement on top of its flat tab order, and the section panel's tab stop re-syncs to the current page when the route changes, so Tab re-enters at the active item.
- The
TopNavigationbottom edge is now an always-on border. The non-reusableui-scroll-edgeandui-sidebar-seam-headerutilities are removed, so the sticky bar and the sidebar header carry a plain border instead. - The
AppShellheader row is now sizedauto(was a fixed3.5rem), so a shell without aTopNavigationno longer reserves an empty header band, so the row collapses to the height of its content. - The shell's viewport-height claims (
AppShellgrid, sidebar and rail asides) read the new--ui-viewport-heightcustom property with a100dvhfallback. Set it on a wrapper to render the shell inside a bounded container (embedded previews, demos) instead of the browser viewport. Nothing changes when it is unset.
-
b7122c0: fix(DST-1621): keep
AccordionstickyHeaderpinned when the header has actionsAccordion.Headernow accepts anactionsprop for content shown next to the title, such as buttons. Previously actions were added by wrappingAccordion.Headerin a layout component, which shrank the sticky header's containing block to the header row sostickyHeadercould no longer pin the header while scrolling. Passing actions throughactionskeeps the sticky wrapper a direct child of the item, so the header stays pinned together with its actions. -
b7122c0: feat(DST-1634): standardize
Inputtrailing-action alignment and makesize="icon"a publicButtonAPI.The
Inputleading icon is clamped to 16px so it no longer overlaps the placeholder. Every trailing action (clear button, chevron, loading spinner, or a custom icon button) now sits in a control-sized centered box flush to the edge, so its icon aligns at the same inset as the leading icon acrossInput,SearchField,ComboBox,Autocomplete,TagField, andDatePicker.Button'ssize="icon"is now public and documented as the way to build an icon button, composing with anyvariant(for examplevariant="ghost" size="icon").Migration:
variant="icon"was never a real Button variant. It silently rendered a default button, so any usage from older docs should switch tosize="icon"(with a variant, for examplevariant="ghost" size="icon"). -
b7122c0: feat(DST-1643): add a
fullscreensize toDialog<Dialog size="fullscreen">fills the viewport (minus a small margin) at every breakpoint, giving content-heavy picks room for search, filters, and a long scrollable list while the title and actions stay fixed. The existingxsmall/small/medium/largesizes are unchanged. -
b7122c0: feat([DST-901]): styleProps for
width,maxWidth,height,space,spaceX,spaceY,pr,pl,pt,pbnow accept both numeric scale values (4) and their string equivalents ("4"). The public types are now declarative (Scale | Fraction | WidthKeyword, etc.) instead of being derived from the internal class-name maps.Components that previously resolved
width,maxWidth, andheightvia class-name lookup (Form, Calendar, legacy Table column header / select-all cell, Slider, Scrollable, Switch, Grid) now resolve them through CSS custom properties (createWidthVar/createHeightVar) targeting--width,--max-width,--height. Those variables — along with--container-widthand--field-widthalready used byFieldBase— are registered as non-inheriting (@property … inherits: false) in the RUI theme so they cannot leak into descendants.createWidthVargained support for the previously missing keywords (svh,lvh,dvh,px,container), and a newcreateHeightVarhelper was added. Both share a common factory and a base keyword set, so they remain trivially in sync.The runtime class-name maps
width,maxWidth,height,gapSpace,paddingSpace,paddingSpaceX,paddingSpaceY,paddingRight,paddingLeft,paddingTop,paddingBottomare no longer exported from@marigold/system. These were internal utilities consumed only by@marigold/components. Use the prop types (WidthProp,HeightProp, …) and the CSS-var helpers (createWidthVar,createHeightVar,createSpacingVar) instead. The corresponding TypeScript prop types are unchanged. -
b7122c0: feat(DST-990): enrich
<Menu>with selection visuals, keyboard shortcuts, and dividers<Menu>gains richer building blocks for advanced menus:- Selected-item visuals. In
selectionMode="single"or"multiple", items show a leading checkmark and a highlighted row, aligned like<ListBox>. Command menus (noselectionMode) render exactly as before. - Keyboard-shortcut hints via a new shared
<Keyboard>primitive (a sibling to<TextValue>and<Description>). It renders a<kbd>key-cap on its own and adapts to its container, so inside aMenu.Itemit becomes a muted, right-aligned hint wired to react-aria'saria-describedby. - Dividers. Drop the shared
<Divider>between<Menu.Item>s to separate groups with arole="separator"line.
Breaking (
@marigold/system): theMenurecord in theThemetype now requires akeyboardkey. Custom themes implementingMenumust add it to keep compiling. All@marigold/componentsadditions are backward compatible. - Selected-item visuals. In
-
b7122c0: refa([DST-1298]): Refactor Divider component: API, styling, and docs
We fixed the vertical orientation of the divider, which previously didn't work. Added new Divider stories and updated the Divider docs.
-
b7122c0: feat(DST-1641): add
ErrorState, the error sibling ofEmptyState: same anatomy (title,description,action,headingLevel), plus typed DOM passthrough (role,tabIndex,ref) for error-boundary fallbacks. -
b7122c0: feat([DST-761]): export
useLandmarkfrom@marigold/components.Marigold now re-exports React Aria's
useLandmarkhook (and itsAriaLandmarkRole/AriaLandmarkPropstypes) so consumers can register custom regions as ARIA landmarks without adding@react-aria/landmarkas a direct dependency.import { useRef } from 'react'; import { useLandmark } from '@marigold/components'; const ref = useRef<HTMLElement>(null); const { landmarkProps } = useLandmark( { role: 'search', 'aria-label': 'Site search' }, ref );A new accessibility guide on landmarks and a dedicated
useLandmarkreference page have been added to the documentation. -
b7122c0: feat(DST-1587): share wheel-to-horizontal-scroll between
TabsandSegmentedControlThe wheel handler that lets pointer users without a trackpad reach overflowing
Tabsis now a shareduseWheelScrollXhook, andSegmentedControladopts it too. Wheeling vertically over an overflowingSegmentedControltrack now scrolls it horizontally, matchingTabs. No public API change on either component. -
b7122c0: fix([DST-1363]): make
<TagGroup>errorMessagerender and bridge it to form validation<TagGroup>acceptederrorMessagevia<FieldBase>but never rendered it because RAC'sTagGroupdoes not populateFieldErrorContext. The internal<HelpText>short-circuits on a missing context, so the error path was a silent no-op and<Form>-level validation never reached the user.Bridges
<TagGroup>to validation the same way<SelectList>does:useFormValidationState+useFormValidationon a hidden<select>(replacing the previous<input type="checkbox">shim), with<FormContext>inheritance forvalidationBehavior. The shared hidden control lives atHiddenSelection/and is now consumed by both<SelectList>and<TagGroup>so future fixes only happen once.New props on
<TagGroup>:error,required,disabled,validate,validationBehavior,form. Public API normalised to Marigold's convention —isInvalid/isRequired/isDisabledare removed andonSelectionChangeis renamed toonChange.selectionModenow defaults to'multiple'.disablednow propagates to each<Tag>via context so interaction is blocked alongside the form-disabled state. -
b7122c0: feat(DST-1257): add universal
nonespacing token- Introduce
NoSpacingToken = 'none'shared across all spacing token families - Add
'none'toSpacingTokens,PaddingSpacingTokens, andInsetSpacingTokens - Add
--spacing-none: --spacing(0)CSS custom property to the theme
'none'now works wherever a spacing token is accepted:Stack/Inlinegap (space="none"),Insetaxis padding (spaceX="none"/spaceY="none"), andInsetrecipes (space="none") — useful for wrappers that should render without adding any spacing (e.g. an edge-to-edgeTableinside a containing component). - Introduce
-
b7122c0: feat(DST-1646): add
OverflowRegion, a single-row layout primitive that hides trailing items instead of wrapping when horizontal space runs out, and restores them as space returns. Hidden items stay mounted (state preserved) but are removed from paint, tab order, and the accessibility tree. Like the other layout primitives it has no theme layer: space its items with thespaceprop (inherited from a parentInline/Stackwhen unset, likeInline), label it with the forwarded region props (role,aria-label, ...), and pair it with theindicatorrender prop or theonOverflowChangecallback so hidden items stay reachable through another surface, e.g. quick filters demoting into a filter panel. -
b7122c0: fix(DST-1573): default
<Page>and<Page.Content>spacing toregularThe
spaceprop on<Page>and<Page.Content>— which controls the vertical rhythm between a page's children (the<Page.Header>and the<Panel>s/sections below it) — now defaults toregular(spacing(6), 24px) instead ofgroup(spacing(12), 48px). The previous default produced too much whitespace between sections. Consumers can opt back into the larger gap withspace="group". -
b7122c0: feat(DST-1326): introduce
Panel.CollapsibleHeader,Panel.CollapsibleTitle, andPanel.CollapsibleDescription. The collapsible mirrorsPanel.Header— a header wrapper with a title plus an optional description — and the whole visual surface is a single click target: title and description render as spans inside the trigger<button>, with the accessible name wired viaaria-labelledbyand the description viaaria-describedby. The chevron icon uses a reusableMorphCaretthat animates via SVG path morphing (honoursprefers-reduced-motion). -
bb23186: feat(DST-1700):
--bleed-pxis the documented way to align content with a container's padding, and the overlay surface anatomy no longer borrows Panel's name.What changed:
- The
ui-panel-header/ui-panel-content/ui-panel-actionsutilities and their--ui-panel-pxtoken are nowui-surface-header/ui-surface-content/ui-surface-actionsand--ui-surface-px. They style the shared anatomy of sectioned overlay surfaces (Dialog,Drawer,Tray,Sidebar) — never thePanelcomponent, which has its own per-instance--panel-px. They are now named afterui-surface, the role those containers already wear. Tablederives its edge cell padding from--bleed-pxalone:var(--bleed-px, var(--cell-x-padding)). It previously readvar(--panel-px, var(--bleed-px, var(--cell-x-padding))).- A bled
Card.ContentandCard.Footernow publish--bleed-px(set to the Card's--card-px), which they never did. - Every non-bled content area (
Panel.Content,Panel.CollapsibleContent,Card.Content,Card.Footer,Drawer.Content) clears--bleed-pxwithinitial. Custom properties inherit through the whole subtree, so without the reset a container nested inside a bled one would read the outer container's padding and inset its edge-aware children twice. --panel-px/--panel-py/--panel-gap, their--card-*and--page-*counterparts, and--bleed-pxare documented as read-only public API under Reading container spacing.
Why:
--panel-pxis set on thePanelroot, so it inherits into the whole subtree whether content is bled or not. Reading it first meant the chain always resolved at step one inside a Panel and the remaining branches were unreachable: aTablein a non-bledPanel.Contentwas inset by the Panel's padding on top of the content area's own padding, putting its edge cells 12px from the border while the Panel title sat at 12px — offset twice. Every bleedable container already publishes--bleed-px, and because that is declared on the bled element rather than on a container root — and cleared again on every non-bled one — it is only in effect where edge alignment actually applies.Impact:
- A
Tablein a bledPanel.Content,Panel.CollapsibleContentorDrawer.Contentis unchanged. - A
Tablein a non-bledPanel.Contentnow uses the ordinary cell padding for its first and last cell instead of the Panel's horizontal padding. Docs steer tables tobleed, so most tables are unaffected. TableandAccordioninside a bledCard.ContentorCard.Footernow align with the container title, where previously they got no edge alignment at all.- A
TableorAccordionin a non-bled container nested inside a bled one no longer picks up the outer container's padding. Dialog,Drawer,TrayandSidebarare visually unchanged. If you override--ui-panel-pxor apply theui-panel-*utilities directly, rename them; the token was undocumented, so nothing else in the public API moves. It also only ever existed in18.0.0-rc.*, never in a stable release, so only prerelease consumers are affected.
- The
-
b7122c0: feat([DST-753]):
SectionMessageexposes anannounceprop and uses react-aria'sLiveAnnouncerto notify assistive technology.What changed (DST-753):
<SectionMessage>accepts a newannounce?: booleanprop. When set, the message text is sent to a shared, always-mounted live region maintained by@react-aria/live-announcer. Priority ispoliteforinfo/success/warningandassertiveforerror.announcedefaults totrueforvariant="error"andfalsefor all other variants, preserving today's behavior for the common error case while letting consumers opt in for confirmations and informational updates.- The wrapper element no longer carries
role="alert"for the error variant. Announcements are now delegated to the singleton live announcer instead. - Re-announcing the same message uses the React
keypattern: pass a changingkeyto force a remount.
Why:
The previous implementation only announced the
errorvariant, and it did so by addingrole="alert"to a conditionally rendered element. Per the WAI-ARIA spec and MDN guidance,role="alert"should be on an element that already exists in the DOM before its content is injected, and it should not contain interactive elements. Marigold'sSectionMessageviolated both constraints (the alert was mounted together with its content, and it can contain close buttons and action links), making announcements unreliable on some screen reader / browser combinations.The new implementation uses
@react-aria/live-announcer, which maintains persistent polite and assertive live regions at the document root. This is the same mechanism used across React Spectrum and avoids the conditional-rendering and interactive-content pitfalls of inlinerole="alert". It also unifies the API: opt in to announcement for any variant with a single prop.Additional cleanup bundled with this release (beyond DST-753):
- Close button now matches the rest of the system. The previous theme defined a
closeslot forSectionMessagewith bespoke overrides (size-8,[&_svg]:size-6,text-foreground, negative margins) that produced a visibly larger close button than every other close button in the design system. The component now renders the shared<CloseButton>with no overrides, so it gets the same 16px icon, focus ring, hover-opacity, and rounded-full styling as Dialog, Drawer, etc. Thecloseslot has been removed from theSectionMessagetheme type. - Component cleanup. Dropped a stale
useButton(props, buttonRef)call that was applying div-level props to a button, the unusedbuttonRef, and the{...buttonProps}spread on<CloseButton>. TheButtoninsideCloseButtonalready provides all keyboard/press semantics. - Theme variant order normalized.
info(the default) is now listed first across thecontainer,content, andiconslots intheme-rui, matching the variant table in the docs and the existingdefaultVariantssetting.
Docs:
- New anatomy SVG matching the Card / Sidebar / SelectList style; title and close button marked as optional, with content rules (no period in title, don't repeat title in body).
- Two realistic announcement demos: a bulk-archive form (polite, with RAC
validateand thekeyre-announce pattern) and a server-availability save error (assertive). - Added focus-management guidance for dynamic appearance and post-dismiss.
- Added form-summary placement rule pairing
<SectionMessage>with field-level validation. - Added action constraints (one primary action, verb+noun labels, descriptive link text).
- Added two-line body rule with a link-out overflow pattern for longer content.
- Folded the previous Position subsection into Usage; removed redundant Do/Don't tiles; renamed subsections to Dismissal / Actions / Announcements.
- Drive-by: typo fix in the
feedback-messagespattern doc.
Migration:
- Code relying on
getByRole('alert')or[role="alert"]selectors to find renderedSectionMessageerror nodes needs to be updated. The message text itself is still rendered as before; only the wrapper role is gone. - Consumers who previously wrapped a dynamic
<SectionMessage>in their own<div role="status">or<div aria-live="polite">can replace that wrapper with<SectionMessage announce>. - Custom themes that defined a
SectionMessage.closeslot will now see a type error. Remove the slot. Close button styling now flows entirely from theCloseButtontheme. - The SectionMessage's close button is visually smaller after this release (matches every other close button in Marigold). If you previously relied on the larger size, that was an inconsistency, not a feature.
-
b7122c0: feat(SelectList): standardized API, item layout, and visual distinction from ListBox (DST-1076)
<SelectList>has been refined into a first-class form field for picking one or many items from a visible list of rich two-line rows. This release contains breaking renames and a tightened type surface.Breaking changes
SelectList.Item→SelectList.Option. The option semantic matchesSelect.Optionand the HTML<option>mental model. Update any<SelectList.Item>usage to<SelectList.Option>.SelectList.Actionhas been removed. Drop your<ActionMenu>or<IconButton>directly inside<SelectList.Option>— the component positions, sizes, and styles the nested control automatically viaButtonContext. Limit: one action per option (multi-button groups will arrive with a futureActionGroup).- Leading-image slot has been removed. Compose images inside
<Text slot="label">(or anywhere in children) as you see fit. selectionMode="none"is no longer accepted.SelectListis a form field; the default is now"single".onChangeis strictly typed perselectionMode:(key: Key | null) => voidfor single,(keys: Key[]) => voidfor multiple. The shape matchesSelect<T, M>. PassingsetStatedirectly may require adapting the callback.
Other changes
- Selection indicator — single-select rows render a visible radio circle; multi-select renders a checkbox.
- Label & description slots — use
<Text slot="label">and<Text slot="description">inside<SelectList.Option>. The row skeleton isselection · label + description · action (optional). - Dev-mode warning when
textValueis missing on an option whose children aren't a plain string. - Own theme entry —
SelectListships a dedicated theme component. The theme exposes first-classlabel,description, andactionentries; slot styling no longer uses descendant selectors. Consumers with custom themes must add or update aSelectListentry.
Documentation
The SelectList docs page is rewritten around the new API. Adds an anatomy diagram, a decision table for choosing between
<SelectList>and lighter controls (<Radio.Group>,<Checkbox.Group>,<Select>,<Combobox>,<TagField>), and dedicated sections for multi-selection, per-row actions (decision-help and configuration patterns), horizontal orientation, and empty state. Replaces selected prose with Do/Don't tiles. Tightens the accessibility section to what's specific to SelectList (keyboard model, label requirement,textValuefor rich rows).Migration
- <SelectList selectionMode="none"> - <SelectList.Item id="free"> - <SelectList.Action> - <IconButton aria-label="Info"><Info /></IconButton> - </SelectList.Action> - Free - </SelectList.Item> - </SelectList> + <SelectList selectionMode="single"> + <SelectList.Option id="free"> + Free + <IconButton aria-label="Info"><Info /></IconButton> + </SelectList.Option> + </SelectList> -
b7122c0: feat(DST-1513):
<Select>'srenderValuenow receives a seconddetailsargument with the selectioncount, and works when options are provided as static<Select.Option>children (previously it was silently skipped unless the options came from theitemsprop).This makes it easy to summarise a multi-select trigger instead of listing every value, e.g.
renderValue={(items, { count }) => `${count} selected`}. The default trigger rendering is unchanged: withoutrenderValue, a multi-select still lists the selected values. -
b7122c0: feat(DST-1404): add
renderValueprop to<Select>for custom trigger rendering. When provided, the callback receives the selected items and replaces the default trigger render. Useful when the trigger should look different from the option (e.g. avatar plus name in the trigger, avatar plus name plus role in the dropdown). The placeholder still renders when nothing is selected. -
b7122c0: feat(DST-1322): add
currentprop toSidebar.Navfor automatic active item detectionSidebar.Navnow accepts acurrentprop that resolves the active leaf automatically — pass the current pathname (string) for smart segment-aware matching, or a predicate(href, key) => booleanfor full control. Removes the per-itemactive={pathname === '/...'}boilerplate. The per-itemactiveprop onSidebar.Itemstill works as a local override. -
b7122c0: feat(DST-1370): migrate
ContextualHelp,SectionMessage, andEmptyStateto the slot-configuration pattern-
SectionMessage.Titlenow renders a semantic heading (<h3>by default) instead of a<div>, fixing an a11y gap. The level is configurable via the newheadingLevelprop on<SectionMessage>. When a title is present, the container becomes arole="group"labelled by the title viaaria-labelledby. -
New
<SectionMessage.Description>sub-component for a short summary between title and content. -
ContextualHelp.Titlenow usesslot="title", so the popover dialog gets a properaria-labelledby. The title tag changes from<h3>to<h2>(same asDialog.Title); visual appearance is unchanged. -
New
<ContextualHelp.Description>sub-component. -
The
Themetype now requires adescriptionkey on theSectionMessageandContextualHelpstyle records; themes defining styles for these components must add it. -
EmptyState'stitlenow renders as a semantic heading (<h3>by default, configurable via the newheadingLevelprop), and itsdescriptionrenders through the<Description>primitive (same DOM as before, now sitting 4px below the title to match the description rhythm of the other components). The flat-props API is unchanged. -
All three roots now also publish a
ButtonContext, completing the slot-configuration set. It scopes action buttons (e.g. those placed inSectionMessage.Content, theEmptyStateaction, orContextualHelpcontent) to a clean baseline so they never inherit a surrounding container's button cascade (such as aPanel.Header's ghost/small look). No variant or positioning is imposed, so existing usage renders unchanged.
-
-
b7122c0: feat(DST-1098): persistent idle sort indicator on sortable columns
Table.ColumnwithallowsSortingnow shows a Lucidearrow-down-upicon when the column is sortable but not currently the active sort column. The active ascending/descending icons (SortAscending/SortDescending) are unchanged.
Patch Changes
-
b7122c0: feat(DST-1461):
Accordionaligns likeTableinside a bledPanel.What changed:
- A bled
Panel.Content/Panel.CollapsibleContentnow publishes a--bleed-pxcustom property (set to the Panel's--panel-px). Non-bled content is unchanged and does not set it. - The
defaultAccordionheaderandcontentinset themselves by--bleed-px(via--accordion-x-padding, which falls back to0px). So inside a bled Panel the item dividers span edge-to-edge while the header/content align with the Panel title. - In a bled Panel the full-width header (and its focus ring) is inset off the Panel border by one spacing step, matching
Panel.Collapsible.
Why:
Dropping an
<Accordion>into<Panel.Content bleed>now gives full-width item dividers and header/content aligned with the Panel title — the same behaviorTablealready had, with no new Accordion prop or variant.Impact:
- Standalone Accordions are unchanged (
--bleed-pxis only set by a bled Panel container, so the inset resolves to0px). - Accordions inside a non-bled
Panel.Contentare also unchanged — the inset stays0px, so header/content keep aligning with the dividers as before (no double indent). - Only Accordions inside a bled Panel gain the inset. The
cardvariant is unaffected; it keeps its ownpx-4.
- A bled
-
85e9a45: Fix
Autocomplete's publiconSubmittype, which declared(value, key)while the implementation, JSDoc, and both docs demos all used(key, value). The type now matches the actual(key, value)signature — no runtime behavior changes. -
b7122c0: style(DST-1586): scale breadcrumb separators with the size variant and emphasize the current page
The chevron separator now scales with the breadcrumb size (
small/default/large) instead of rendering at a fixed 16px, so it stays a quiet mark between crumbs; gaps tighten onsmallaccordingly. The current page reads a tier above the trail — medium weight in theforegroundink — matching how the sidebar marks the active item.The
<Breadcrumbs>chevrons drop their hardcodedsize={16}prop: the theme'sBreadcrumbsitemslot now owns the separator size ([&_svg]:size-*, which wins over the SVG's width/height), so the number in the component was dead and misleading. Themes that don't set a separator size fall back to the icon's default size. -
b7122c0: fix(DST-1659): draw the
Checkboxbox from theme tokens instead of raw Tailwind literalsThe checkbox icon painted itself with
bg-whiteandborder-black. Both now come from the token layer:bg-surfacefor the fill andborder-control-borderfor the affordance edge, matching how every other control draws its boundary.@marigold/theme-ruialready overrides both slots inCheckbox.styles.ts, so the rendered markup and the visual result are unchanged there. The literals only leaked in custom themes, where a consumer could not recolor the box edge or fill without fighting a hardcoded value. This was the last raw color in the component layer. -
b7122c0: feat([DST-1395]): SelectList horizontal layouts now automatically flip to a vertical stack when the wrapping container is narrower than
40rem(~640px). -
b7122c0: feat(DST-1286): Panel renders a
data-panelattribute on its rootThe root
<section>rendered by<Panel>now carries a valuelessdata-panelattribute. External stylesheets and host pages can use it as a stable selector (e.g.:not(:has([data-panel]))) to detect whether a Panel is present without depending on Tailwind utility classes. -
b7122c0: fix([DST-1295]): replace
gapbetweenCheckboxGroupandRadioGroupitems with per-item padding so the full space between items is clickable. Vertical items now meet the 24px target-size minimum; horizontal spacing keeps visual parity. StandaloneCheckboxis unaffected.Also align the label and icon: switched the inner row layout from
items-centertoitems-startso the icon stays on the first line when the label wraps.Radiolabels now useleading-4to matchCheckbox, andRadio's icon-to-label gap moves from an inlinegap-[1ch]to the theme-drivengap-x-2for parity withCheckbox. -
b7122c0: feat([DST-1339]): FileField gains a
size="small"compact layout renders as a single-row input-height control (upload button + file list) instead of the full drop-zone, suited for space-constrained forms. -
b7122c0: refactor(DST-1367): Panel adopts the slot-configuration pattern
Panel.Headeris now a single<Provider>that configuresHeadingContext,TextContext,ActionButtonContext, andActionGroupContextfor everything nested inside it. Consumers drop slot-aware primitives directly into the header —<Title>,<Description>, and any of<ActionButton>,<ActionGroup>,<ActionMenu>,<LinkButton>— and the Panel injects level, ids, ref wiring, grid-area positioning, and the action cascade via context.The compound sub-components that paired with
Panel.Headerare removed because slot-aware role primitives subsume their responsibilities:<Panel.Title>→ use<Title>.<Panel.Description>→ use<Description>.<Panel.HeaderActions>→ drop the wrapper; the action primitives themselves (<ActionButton>,<ActionGroup>,<ActionMenu>,<LinkButton>) land in the actions grid cell via the context className thatPanel.Headerpublishes.
Multiple actions belong inside an
<ActionGroup>— the cluster claims one cell and renders as a toolbar. A raw<Button>insidePanel.Headeris intentionally not slot-aware: it stays as a footgun so the action primitives are the obvious choice for header chrome.Panel.CollapsibleHeaderadopts the same shape:<Panel.CollapsibleTitle>/<Panel.CollapsibleDescription>are removed in favour of plain<Title>and<Description>inside the header.Panel.CollapsibleHeaderpublishes slot-keyedHeadingContextandTextContextinside its disclosure trigger so the primitives render as spans (matching the heading-inside-button constraint), while the structural<hN>semantics come fromPanel.CollapsibleHeaderitself.<Description>now honourselementTypefrom its surroundingTextContextslot config.Panel.HeaderdeliverselementType: 'p'so the description renders as a paragraph;Panel.CollapsibleHeaderdeliverselementType: 'span'so it nests cleanly inside the disclosure trigger button. Elsewhere,<Description>continues to render as RAC's default<span>.<Headline>now defaults to opting out of any surroundingHeadingContextslot config (slotdefaults to the no-slot opt-out instead ofundefined). This avoids "A slot prop is required" runtime crashes when a bare<Headline>is rendered inside a container that publishes a slot-keyedHeadingContext— such as a<Panel>that publishes itstitleslot at the root. An explicitslotprop on<Headline>still overrides the default. -
b7122c0: refactor(DST-1374): use
<TextValue>and<Description>for selection-container itemsConsumer-facing JSX in component stories and documentation demos for
<Select>,<SelectList>,<ListBox>,<Menu>,<ComboBox>, and<Autocomplete>now composes item content with the<TextValue>and<Description>primitives instead of hand-written<Text slot="label">/<Text slot="description">. The primitives are drop-in replacements that render the same RAC<Text>with the same default slot values, so rendering,aria-describedbywiring, and accessibility are identical.<Menu.Item>gains first-classlabelanddescriptiontheme slots, mirroring<SelectList.Option>.MenuItemmerges the Marigold theme classNames into RAC'sTextContextso nested<TextValue>/<Description>pick up Menu styling without losing RAC's slot wiring. Menu items adopt a two-column grid layout (icon column + content column) so descriptions render below labels; existing plain-text and icon+text menu items are unaffected.The
Menutheme type in@marigold/systemis extended with requiredlabelanddescriptionslot keys. Consumers maintaining a custom theme that overridesMenuwill need to add these two slots to satisfy the type.@marigold/theme-ruiis updated accordingly in this release.No public API change on
Select.Option,SelectList.Option,ListBox.Item,Menu.Item,ComboBox.Option, orAutocomplete.Option. -
b7122c0: fix([DST-1410]): restore RangeCalendar build by using
createWidthVarfor the width prop. The component still imported thewidthruntime map from@marigold/system, which DST-901 removed when it migrated dimension props to CSS variables. This brokemainfor everyone — typecheck, unit tests, and Storybook tests all failed on every open PR. Apply the same migration pattern Calendar already uses:w-(--width)className plusstyle={createWidthVar('width', width)}. -
2b9df4c: docs(DST-1427): promote
EmptyStatefrom beta to stableEmptyStatehas been in beta since January. v18 is where its surface settled, with the title becoming a semantic heading behind a configurableheadingLeveland the description moving onto the sharedDescriptionprimitive, so the badge comes off now that the API being frozen is the one 18.0.0 ships.title,description,actionandheadingLevelare covered by the usual semver guarantees from here on.variantandsizestay open ended, as they do on every themed component:theme-ruidefines no values for either today, and anything it adds later widens the accepted set rather than narrowing it. No code changes. -
b7122c0: feat(DST-1439): give
SectionMessagea neutral surface with a muted variant borderSectionMessageno longer fills its background with a per-variant tint (bg-info,bg-success,bg-warning,bg-destructive). It now sits on a neutralui-surfacewith neutral title and body text. The severity is carried by a muted per-variant colored border (the accent mixed halfway into the neutral border) plus the colored icon.This is a visible design change for every variant. Because the surface stays neutral, standard
<Button>and<Link>actions placed inside read correctly instead of floating on a colored fill. On the old tint the default<Button>(variantsecondary, which has its ownui-surfacefill) rendered as a foreign chip on the colored container for every variant except error. The muted border sits at the container edge, away from the content, so it signals the variant without touching the actions. The border color is set throughui-surface's--ui-border-colorhook, which is registered as a non-inheriting custom property, so it stays scoped to the container and does not leak into nested action borders.Variants stay distinguishable without relying on color alone through the colored border, the distinct icon shape and color, and the title. The bordered, in-flow treatment keeps an inline message visually distinct from the floating, shadowed
<Toast>. No API changes. -
b7122c0: fix(DST-1467): make
MorphCaretSSR-safeThe shared
reducedMotionconstant inutils/reducedMotion.tssampledwindow.matchMediaat module evaluation, so the server bundle always resolved tofalsewhile a client withprefers-reduced-motion: reduceresolved totrue— producing a React 19 hydration mismatch (silently absorbed in production, logged as an error in dev).MorphCaretnow reads the preference viauseReducedMotion()frommotion/react, matchingSidebarToggleIconandTrayModal. The obsoleteutils/reducedMotion.tshas been removed. -
b7122c0: fix(DST-1480): only set
aria-labelledbyon Panel when a Title is present<Panel>previously renderedaria-labelledby={titleId}whenever noaria-labelwas given, even if no<Title>was present. That left the<section>landmark pointing at an id no element carried, producing a broken/empty accessible name.The guard now also checks
hasTitle, soaria-labelledbyis only applied when a<Title>actually renders. This mirrors the stricter guard adopted byCardin DST-1373. -
b7122c0: fix(DST-1501):
<Panel p={number}>now applies paddingA numeric
p(e.g.p={4}) silently produced no padding: the value was suffixed with-x/-yand resolved to a non-existentvar(--spacing-4-x). A scale value is now applied directly (calc(var(--spacing) * 4)) on both axes, matchingpx/pyand<Page>. Named inset tokens are unchanged. -
b7122c0: Extract
resolveInsetAxeshelper to centralise inset-padding axis resolution.The
p→px/pyresolution logic (branching on whether the value is a numeric scale or a named token) was copy-pasted acrossPage,Panel, andCard. This duplication caused the<Card p={number}>silent bug (resolving to a non-existentvar(--spacing-4-x)), the same class of bug that had already been fixed independently inPanel(DST-1501) andPage(DST-1360).- Adds
resolveInsetAxes({ p, px, py, defaultInset })to@marigold/systemalongsidecreateSpacingVar. - Adopts the helper in
Card,Panel, andPage, fixing the live<Card p={number}>bug as part of the refactor. - Fixes the same numeric-
pbug inSelectList(inline, since its conditional-axis pattern differs).
- Adds
-
b7122c0: chore(DST-1503): Migrate
Checkbox,Switch, andRadiooff the deprecated react-aria-components single-element exports (Checkbox/Switch/Radio) to the*Field+*Buttoncomposition introduced inreact-aria-components@1.18.0. This removes thets(6385)deprecation warnings with no change to the public API, behavior, or visual output. -
b7122c0: chore(DST-1517): HelpText renders the shared Description component
HelpTextnow renders the description through the sharedDescriptioncomponent instead of react-aria's raw<Text slot="description">.Descriptionis just<Text slot="description">, so the rendered output andaria-describedbywiring are unchanged. The win is a singleDescriptionbuilding block shared by both the slot-configuration containers and the form fields, so the two cannot drift apart. No names, output, or behaviour change. -
b7122c0: refactor(DST-1534): build the
Calendaryear dropdown on react-aria'sCalendarYearPickerThe year dropdown now consumes react-aria's
CalendarYearPickerrender-prop (mirroring how the month dropdown already usesCalendarMonthPicker), replacing the hand-rolled year list and its localizedaria-labelworkaround. This was unblocked by react-aria's June 2026 fix that makesmaxValueinclusive, so the boundary year is reachable. Unbounded calendars keep the ±20-year window and bounded ranges stay fully reachable at both ends. When only one bound is set, the open side now widens to keep that bound reachable instead of staying at a fixed ±20 years. -
b7122c0: refactor(DST-1546): replace the bespoke TagGroup "Remove all" wrapper with a plain
<Button>via aButtonContextcascadeTagGroupnow provides alink/smallButtonContextaround its internalRemoveAllrender, so the "Remove all" action is a bare Marigold<Button>instead of the raw react-ariaButtonwith hand-rolled link styling. This mirrors the cascade pattern already used byActionBarandPanel.Header.The change is internal-only.
TagGroupRemoveAllis not part of the public API (TagGrouprenders it itself), the authoring API (removeAll/onRemove) is unchanged, and there is no behavioral or accessibility change.The redundant
removeAlltheme style is removed fromTag.styles.ts(thelinkvariant atsize="small"reproduces it), and the now-unusedremoveAllkey is dropped from theTagtheme type. -
b7122c0: chore(DST-1547): move z-index classes out of theme style files into component implementations
Per the z-index management rule (
CLAUDE.md),z-*utilities belong in component implementations, never in theme*.styles.tsfiles. The local focus/drop/sticky stacking classes forCalendar/RangeCalendar,LegacyTable,ListBox,Table,ToggleButtonandSegmentedControlhave been moved from theirtheme-ruistyles into the matching componentclassName(viacn()), preserving the exact modifiers and important flag. No visual or stacking change. -
b7122c0: fix(DST-1553): drop the dead
'small' | 'medium' | 'large'literals fromTabssizeThe
sizeandvariantprops onTabsresolved to nothing after the RUI theme size variants were removed (2025-03-04).sizenow accepts a plainstring(matchingLabelandHelpText) instead of advertising specific values that no theme backs. The props stay in place as theme hooks, so a consumer theme can define its ownsize/variantvariants without the misleading built-in union. -
b7122c0: fix(DST-1565): stop the DatePicker and DateRangePicker popover from stretching to the trigger width
The shared
Popoverforces its width to at least the trigger's viamin-w-(--trigger-width). That is right for field dropdowns (Select, ComboBox) whose list should line up with the field, but wrong for a calendar, whose width is its own. A newmatchTriggerWidthprop (defaulttrue, so every existing popover is unchanged) lets DatePicker and DateRangePicker opt out, so the calendar sizes to its content instead of the full field width. -
b7122c0: refactor(DST-1585): drive SegmentedControl's reduced-motion scroll from CSS
SegmentedControl now gates its selection-reveal scroll animation with the same CSS approach as Tabs: the scroll container carries
motion-safe:scroll-smoothand the component'sscrollTousesbehavior: 'auto', which follows that CSS — animating when motion is allowed and jumping instantly under reduced motion. This replaces the previous JSwindow.matchMedia('(prefers-reduced-motion)')check. Behavior is unchanged; the initial mount reveal stays instant. No API change. -
b7122c0: style(DST-1602): drop the removed elevation shadow from SelectionIndicator
SelectList'sSelectionIndicatorno longer appliesshadow-elevation-border, which is removed fromtheme-ruiin the accompanying change. The indicator keeps itsborderand surface fill. -
68122ff: refactor(DST-1627): extract a shared
CalendarBodyfor theCalendar/RangeCalendargrid layoutThe multi-month and single-month layout markup was duplicated verbatim in
CalendarandRangeCalendar, so every layout tweak had to be made twice and the copies could silently drift. Both components now render that markup through one internal<CalendarBody>, which reads the theme classes, visible months, min/max value, disabled state and a newisRangeflag off the existingCalendarContext, keeping the touch pointerup guard (DSTSUP-257) range-only. Pure refactor: the rendered DOM, the styling and the behavior are unchanged. -
b7122c0: fix(DST-1629): apply a
SelectListitem'sactionslot styling to a trailing MarigoldButton,LinkButton, orActionMenuso the action spans both rows and stays centered. The action slot className was only provided on RAC'sButtonContext, which Marigold'sButtonignores, so the action auto-placed into the title row and stretched it, pushing the description down. The className now flows through the MarigoldButtonContextthat these components read. -
b7122c0: fix(DST-1630): match the Panel collapsible header caret to the Accordion chevron. It rendered at the default 24px in the foreground color, while Accordion uses a 16px
text-secondarycaret, so the two collapsible patterns looked inconsistent. The Panel caret now renders at 16px and its color is driven by a new themeablecollapsibleIconslot (defaulting totext-secondaryin the RUI theme). -
b7122c0: fix(DST-1632): center the section
Loadertogether with its label and give theTabledrag handle edge spacing.The section
Loadersized its container to a fixed square, so a labelled loader overflowed the box and the section wrapper centered the box instead of the spinner-and-label group. The spinner now carries the fixed size and the container is content-sized, so the whole group centers as one. TheTabledrag cell had no padding, leaving the grip flush against the row edge. It now uses the shared cell edge padding and its column matches the checkbox column width, so the grip lines up with its header and the first cell. -
b7122c0: fix(DST-1645): align preset quick-selection rows with the tray nav row on small screens. The preset listbox rows reuse the shared
ListBoxp-1focus-ring gutter, which insets them narrower than the full-width nav row. On small screens the list now negates that gutter (-mx-1) so rows span the tray edge-to-edge and line up with the nav row, while the gutter still keeps each row's focus outline from being clipped by the list's overflow. -
e0f9c05: fix(DST-1647): honor the router's
useHrefin sidebar linksSidebar.ItemandSidebar.RailItemrendered the rawhrefprop straight onto their anchor, which shadowed the value produced byRouterProvider's optionaluseHref. Applications served from a prefix, such as a Next.jsbasePath, ended up with sidebar markup pointing at an unprefixed URL, so middle click and "copy link address" resolved to the wrong page. Both components now render the transformed href and keep handing the unprefixed path tonavigate, matching how React Aria's ownuseLinkbehaves. Consumers that do not passuseHrefsee no change, because the default leaves the href untouched.The
RouterProviderdocs now coveruseHrefnext tonavigate, and the component gained a matching Storybook story and prop description. -
b7122c0: fix(DSTSUP-256): show
cursor-not-allowedon disabled TagFieldThe hidden trigger button inside TagField had
cursor-pointerhardcoded, so hovering a disabled TagField showed the text/caret cursor instead ofnot-allowed— inconsistent with Select and ComboBox. Addeddisabled:cursor-not-allowedto the trigger button so the cursor now matches the rest of the form components. -
b7122c0: fix(DST-1354): restore collapsing
Table.EditableCelledit triggerThe overlay/ring affordance introduced in #5250 (DST-1275) did not read as editable in user testing: sighted users did not associate the hover ring with inline editing, and there was no discoverable trigger for keyboard or touch. This change reverts that approach and restores the explicit pencil edit button.
The trigger collapses to zero layout space at rest (
w-0 overflow-hidden) and expands on row hover or keyboard focus, so static layout remains clean while the affordance is discoverable the moment the user interacts with the row. When expanded, the wrapper switches tooverflow-visibleso the button's focus outline is not clipped. The cell itself stays clickable as a touch target. Enabled editable cells always truncate their content to stay aligned with column headers and match the single-line editing controls; disabled cells behave like a regularTable.Cell. -
b7122c0: fix(FieldBase): forward
isInvalid,isRequired, andisDisabledto RAC components passed viaasWhen
FieldBaserenders through a React Aria Components element (e.g.as={RACComponent}), validation props are now forwarded so the underlying RAC element receives them. Plain DOM elements continue to skip these props to avoid unknown attribute warnings. -
b7122c0: fix(Radio): apply width via CSS variable instead of raw class name
Radiobuilt itswidthclass name from the raw token directly (e.g.cn(width || groupWidth || 'w-full'), wherewidthcould be a literal"1/2"), which Tailwind can't statically detect at build time, so no CSS was ever generated — settingwidthhad no visible effect.Radionow follows the same pattern already used byFieldBase/TextField/NumberField: a staticw-(--field-width)class with the actual value injected viacreateWidthVar. IndividualRadioitems inside a sizedRadio.Groupnow inherit the group's already-computed width instead of recomputing it, which previously caused a double-shrink (e.g.width="1/2"rendering at 1/4 instead of 1/2). -
b7122c0: fix(DST-1352): use correct outline for focus + error state in compound fields
-
b7122c0: fix: stop exposing
styleonLabelLabelonly removedclassNamefrom its react-aria props, leavingstylein the public interface. It now omits both, matching theclassName/styleremoval convention used across the design system (e.g.Description,TextValue). Theme the label viavariant/sizeinstead. -
b7122c0: chore(DST-1364): migrate
ListBoxitem label/description styling off descendant selectorsListBoxnow exposeslabelanddescriptionas first-class theme entries, andListBox.Iteminjects their classNames into react-aria'sTextContext(merging rather than replacing, so RAC'saria-describedbywiring is preserved) instead of styling[slot=description]via a descendant selector onitem. This also benefitsSelect.Option,ComboBox.Option, andAutocomplete.Option, which re-exportListBox.Item.The
Themetype in@marigold/systemnow requireslabelanddescriptionkeys on theListBoxrecord, so custom themes implementingListBoxmust add these entries. No public API change in@marigold/components; visually identical exceptdescriptionnow explicitly setsfont-normal(parity withSelectList). -
b7122c0: fix(DST-1660): keep a loading
Button's accessible nameA
<Button loading>previously had no accessible name at all. The label is kept mounted so the button doesn't change width when the spinner is overlaid, but it was hidden withinvisible(visibility: hidden), which removes a subtree from the accessibility tree — not just from the screen. The spinner's ownaria-labeldid not substitute, because that is a child widget's name rather than text content the button can take its name from.The effect: a screen reader announced "Delete, button" before the press and roughly "dimmed, button" the moment the action started, so the user lost the identity of the operation they were waiting on. That is a WCAG 2.1 §4.1.2 (Name, Role, Value) failure at Level A, and it was worse than a plain
disabledbutton, which keeps its name.The label is now hidden with
opacity-0. It reserves the exact same layout box, so nothing moves — verified by comparinggetBoundingClientRect()for every button across all three surface grounds, withdisplay: noneas a control to confirm the measurement detects real shifts. Rendering is unchanged; this is purely a fix to what assistive technology reports. -
b7122c0: chore: extract shared
useMergedTextSlotshelper for RACTextContextslot stylingListBox.ItemandSelectList.Optionboth mergedlabel/descriptiontheme classNames into react-aria'sTextContext(spreading the parent slot first to preserve RAC'saria-describedbyid). That accessibility-critical logic — and itsSlottedContextValuetype — now lives in a singleuseMergedTextSlotshook that both consume. No public API or visual change. -
b7122c0:
Panel.Titlemay now be used as a direct child ofPanelwhen the Panel has only a title (no description, no actions) —Panel.Headeris the layout wrapper for title + description + actions, but a title-only Panel doesn't need it. Accessibility (aria-labelledby) and horizontal panel padding still resolve correctly.Panel.DescriptionandPanel.HeaderActionscontinue to require aPanel.Headerwrapper. No change to existing usages. -
b7122c0: test(DST-1329): add comprehensive unit and play-test coverage for
Paneland its sub-components (Header, Title, Description, HeaderActions, Content, Footer, Collapsible, CollapsibleHeader, CollapsibleTitle, CollapsibleDescription, CollapsibleContent, Context). No runtime changes. -
b7122c0: fix(DST-1622):
ProgressCircleandLoaderrespect a consumer-providedaria-label/aria-labelledby.What changed:
ProgressCircleno longer overwrites a caller's accessible name. The built-in localized "loading" message is now only a fallback, applied solely when the consumer provides neitheraria-labelnoraria-labelledby.Loader(BaseLoader) uses the same fallback: the localized message is applied only when there is noaria-label,aria-labelledby, or visiblechildrenlabel — and it no longer emits a redundantaria-labelnext to a consumer'saria-labelledby.- A fullscreen
Loadernow stays reliably named: when the consumer supplies their ownaria-labelledby, the overlayDialogreferences that element directly instead of the intermediate loader node (the accessible-name spec does not follow a secondaria-labelledbyhop, which otherwise left the modal unnamed).
Why:
Previously the
aria-labelwas set after{...props}was spread, so a caller passingaria-label(oraria-labelledby) had no effect and every progress circle announced the same generic "Loading…" string. This prevented labelling a spinner for its context (e.g. "Sending reminders" in a bulk-action flow).Impact:
- Callers that pass no label (e.g. the spinners inside
Button,ComboBox,SearchInput) are unchanged — they still get the localized fallback. - Callers that pass
aria-label/aria-labelledbynow get their own accessible name.
-
b7122c0: fix(ProgressCircle): resolve named
sizetokens to a numeric SVG dimensionA named
sizetoken (default|large|fit) was forwarded unchanged to the underlying<SVG>element, which renderswidth/heightas`${size}px`— producing invalid attribute values likewidth="defaultpx"and emitting console errors. The SVG now resolves named tokens to the pixel dimension of their themesize-*class (default→ 80,large→ 144) for itswidth/heightattributes and stroke-width math, so the stroke stays proportionate and the rendered output is unchanged.fitis content-sized and has no intrinsic dimension, so it falls back to the<SVG>default of24.The stroke-width comparison also switched from a string compare (
size <= '24') to a numeric one, which additionally fixes multi-digit sizes that were previously mis-classified (e.g.size="100"computed astrokeWidthof2instead of4). -
b7122c0: docs: improve
AutoTypeTableprop renderingCentralizes the display of design-system aliases in the component docs' prop tables. Props whose types reference aliases from
@marigold/systemor@marigold/types(e.g.SpacingTokens,Scale,WidthProp,NonZeroPercentage) now render with a meaningful summary in the main cell and the full list of resolvable literal values on row expand — instead of a wall of literals in the cell and a redundant alias name on expand.Before:
- Cell:
SpacingTokens<Tokens>(a fabricated generic, inconsistent across components) - Expand:
SpacingTokens | Scale | undefined(same alias names, no new info)
After:
- Cell:
SpacingTokens | Scale(accurate, derived from the real type) - Expand:
"96" | "80" | ... | "tight" | "related" | 0(every concrete value)
Under the hood this replaces 27 per-prop
@remarks \TypeName`JSDoc overrides with a single fumadocs-typescript transform in the docs site, so future components pick up the same behavior automatically. A@remarks` tag on a prop still wins as an escape hatch.Multiselect.widthandComboBox.widthnow useWidthProp['width']directly instead ofFieldBaseProps<'label'>['width']— structurally identical, no runtime change. - Cell:
-
0e2c676: chore(DST-1680): update React Aria to the 1.20.0 line.
What changed:
react-aria-components1.19.0 → 1.20.0, which pinsreact-aria3.51.0 andreact-stately3.49.0.@internationalized/date→ 3.12.3 and@react-types/shared→ 3.36.1. Both are required rather than cosmetic: RAC 1.20.0 declares^3.12.3/^3.36.1, and pnpm will not move an in-range dependency unless the specifier changes, so leaving the old floors keeps a second (runtime-bearing)@internationalized/datecopy in the tree.- The remaining declared floors now match the versions actually installed, which are also the latest published ones:
@react-aria/form→^3.2.1,@react-aria/live-announcer→^3.5.1,@react-stately/form→^3.3.1. Every other@react-aria/*and@react-stately/*entry was already current.
Impact:
No API change in Marigold components. Consumers pick up the upstream 1.20.0 fixes, including Table focus restoration,
FocusScoperestore-without-scrolling, and DatePicker focus handling in Firefox.One upstream behaviour change did need handling on our side: RAC 1.20.0 exposed a latent problem in the mobile
ComboBox/Autocompletetray, which lost its place in the accessibility tree. See the separate entry for that fix.@react-types/{button,checkbox,grid,table}deliberately stay on their type-only lines. All four latest minors pull@react-spectrum/provider— three as a direct dependency andgrid3.4.0 as a peer dependency — which drags in@adobe/react-spectrumand splits the i18n and overlay contexts. See the hold rule in.github/renovate.json. -
f331a41: chore: remove the leftover
react-selectdependency<Multiselect>was removed in v18 and it was the only thing importingreact-select, but the dependency itself was never dropped. It is now gone from@marigold/componentsand from the root workspace, along with theexternalentry intsdown.config.tsand theoptimizeDepspre-bundle entry invitest.config.shared.tsthat only existed for it. Nothing imports it anymore, so this is install-size only — no runtime change. -
b7122c0: fix(DST-1464): keep wide content inside
<AppLayout.Main>from overflowing the viewport. The shell grid usesgrid-cols-[auto_1fr]and the main grid item defaulted tomin-width: auto, so any content wider than the available track (most visibly a<Select selectionMode="multiple">with several long selected items) pushed the main column past the viewport and added a horizontal scrollbar. Addingmin-w-0toAppLayoutMainlets the1frtrack actually shrink, and children liketruncateon the Select trigger can now clip at the right place. -
04e22ab: fix(DST-1679): stop
SelectListfrom advertising two props it silently ignores, and stopSelectList.Optionfrom double-warning about a missingtextValue.What changed:
layoutandkeyboardNavigationBehaviorare no longer part ofSelectListProps. Both were publicly typed but discarded at runtime: the list hardcodeslayout="grid"after spreading consumer props, and RAC deriveskeyboardNavigationBehavior: 'tab'from that grid layout. They now sit inRemovePropsalongsideselectionMode, which is the correct pairing for a prop the component owns.SelectList.Optionno longer warns about a missingtextValue. RAC'sGridListalready warns on exactly that condition and its warning can't be suppressed, so one authoring mistake produced two console lines. ThetextValuefallback for plain-string children is unchanged.
Why:
layoutwas a prop that lied — the docs props table even published it as"stack" | "grid"defaulting to'stack'while the component always rendered a grid. Passing it type-checked and did nothing, and it couldn't be removed later without a breaking change.The duplicate warning was also a false positive in one case: RAC accepts an
aria-labelin place of atextValue, so an option named that way is perfectly accessible, but the local warning fired on it anyway while RAC stayed silent.Impact:
No runtime behavior change.
layoutandkeyboardNavigationBehaviorwere already no-ops, so code passing them keeps working identically — it just no longer type-checks, which is the point.layout="grid"stays hardcoded because it is load-bearing: it gives the list arrow-key navigation on both axes, so a horizontal list moves with Left/Right and still moves with Up/Down after the container-query flip to a vertical stack. Under RAC's"stack"default a row captures Left/Right to walk its own focusable children and horizontal navigation stops working; a new test now guards that. -
b7122c0: feat([DST-1396]): mobile-optimized pagination layout
Paginationnow hides the numbered page buttons on small viewports (max-sm) and spreads the previous/next navigation buttons across the full width usingjustify-between. This produces a cleaner, touch-friendly pagination on mobile while preserving the full layout on larger screens. -
b7122c0: style(DST-1586): remove the overshoot from the sidebar toggle icon animation
The sidebar toggle icon's panel/chevron animation eased with a spring-like overshoot bezier. It now settles on
ease-out-quint, matching the theme's motion register — fast start, smooth stop, no bounce. -
b7122c0: fix(DST-1642): keep the Slider thumb from being clipped at the track ends
The Slider thumb is centered on the track position, so at its min/max values it overhangs the track ends by half its width. Inside a scroll container such as
Drawer.Content— whoseoverflow-y: autopromotesoverflow-xto a clipping value — the overhang was sliced off, leaving a half-circle thumb (and it will be clipped unconditionally onceDrawer.Contentgains ableedprop with no horizontal padding). The track is now inset by half the thumb width so the thumb always stays within the Slider's own box, independent of any ancestor padding. -
6cfcea4: fix(DST-1686): make
controla ground-adaptive track fill, and give theSliderrail the same token asSwitchandSegmentedControlThe Slider rail was the wrong token, painted twice. It used
bg-border— the token for structural lines (dividers, grid lines, table rules) — where theSwitchgroove and theSegmentedControltrack both usebg-control. On top of that,Sliderapplied itstrackstyle to two exactly-overlapping elements (theSliderTrackand an inner raildiv), so the translucentbg-bordercomposited with itself and the rail rendered at ~0.26 effective alpha instead of 0.14 — measuring#c0bfbeon white where the token specifies#dddddc. The redundant inner element is gone; theSliderTrackitself is the rail. Geometry is unchanged (both wereh-2at the same position) andtouch-none,select-noneand the disabled cursor stay on the interactive track element.controlis now translucent (charcoal-950 / 16%, was the opaquecharcoal-300). A track is not painted on one known background — it appears on a white Card, the gray page ground, amutedfill, and inside a hovered Table or ListBox row — and a fixed palette step drifts across those. charcoal-300 measured 1.53:1 on white but only 1.21:1 inside a hovered row, where the groove half-dissolved into the row it sits in. At 16% the four grounds land within 0.02 of each other (1.41–1.43:1), so a track weighs the same wherever it goes. Same rationale asborderin DST-1672.The three tracks (
Switch,SegmentedControl,Slider) read a touch lighter on white surfaces as a result:#d8d8d7rather than#d4d0ce. The trade-off is that the white Switch thumb and SegmentedControl indicator now vary against the track by ground (1.43:1 on white, 1.79:1 on a hovered row) where the opaque step held a flat 1.53:1 — track-vs-ground and thumb-vs-track cannot both be constant while the thumb is opaque, and ground legibility wins because it decides whether the control reads as a control at all.The
SegmentedControlindicator is larger. The frame around the selected thumb went from 4px to 3px (inset-y-[3px]on the indicator,p-[3px]on the list), so the thumb is 30px tall instead of 28px. Since the thumb's own 1px rim occupies the innermost pixel of that frame, 2px of bare track is what you see.The
SegmentedControlthumb's focus ring is now the sharedui-state-focus. It previously hand-rolled only the outline, so it missed the other half of that utility — firming--ui-border-colorto the opaque ring colour — and read noticeably lighter than every other focused control. A focused thumb and a focusedInputnow resolve identically: 3pxoutline-ring/50atoutline-offset-0, plus a 1px opaqueoklch(0.52 0.008 54)rim. The ring stays outside the thumb, and 3px is the minimum frame that clears it: the list is a scroll container clipping at its padding box, so that padding is the only room an outset ring can grow into. Below 3px the first and last thumbs get a visibly shaved ring.The
SegmentedControltrack's corners are now concentric with the indicator's. Both used the sharedrounded-surface, but two rounded rectangles nested with a gap only look like parallel arcs when the outer radius is the inner radius plus that gap. With the thumb at 8px and 3px of frame around it, the track needs 11px; at 8px its corner read visibly tighter than the arc it frames. The track is nowcalc(var(--radius-surface) + 3px)— derived from the token, so it stays concentric if the radius is retuned. This is a deliberate exception to usingrounded-surfaceeverywhere.The
SegmentedControlindicator's resting rim is re-derived from the track.ui-framedraws its rim as an outset ring, so the indicator's rim lands on the track and composites overbg-control— it reads denser than the samecontrol-bordertoken does on a field. The old compensation subtracted a flat 0.08, hand-tuned against the previous opaquecharcoal-300track, which left the rim at an effective 0.31 against a field's 0.26. It is now derived from the track's own alpha (--control-alpha, newly exposed on the token), so a resting indicator rim and a restingInputedge render the same on every ground, and retuning the track cannot silently detune the rim.If you use
bg-controlin your own code, note that it is now translucent: two stacked elements that both carry it composite into a darker track than the token specifies, and anything that paints a translucent edge over a track has to account for the track underneath it. -
b7122c0: feat(DST-1366): introduce slot-configurable primitives
Adds three text-bearing role primitives —
Title,Description,TextValue— and three action primitives —ActionButton,ActionGroup,ActionMenu— that participate in slot-keyed context. Text/heading slots use React Aria'sHeadingContext/TextContextdirectly; action slots use Marigold-owned contexts (ActionButtonContext,ActionGroupContext,ActionMenuContext) consumed viauseContextProps.Titlewraps RAC's<Heading>withslot="title"andlevel={2}as defaults, both overridable byHeadingContext. Thelevelprecedence is default ← context ← local, so a container can publish{ level: 4 }and drive a stretch of nested<Title>s to<h4>without each call site setting it.DescriptionandTextValueforward straight to RAC's<Text>withslot="description"andslot="label"defaults respectively, letting<Text>consumeTextContexton its own. None of the three carry typography props. Styling cascades from the surrounding container (or selection item) viaHeadingContext/TextContext. Consumers drop these into containers without anyslotwiring. The container provides level, layout (e.g. a grid area), size, variant, color, and any other styling through a singleProvider.ActionGroupis its own top-level component (own folder, own docs page, own Storybook entry) — there is noActionButton.Groupcompound. It cascadessize,variant, anddisabledto nested<ActionButton>,<LinkButton>, and<ActionMenu>triggers viaActionGroupContext, with explicit per-prop precedence:size: group wins (visual uniformity within a cluster).variant: local wins (so a single destructive action can sit inside an otherwise uniform group).disabled: local wins; the group provides the default. Writingdisabled={false}on a child re-enables it inside an otherwise-disabled group.
ActionMenuis rebuilt to compose its ownMenuTrigger+<ActionButton>+Popover/Tray+ RACMenurather than delegating to Marigold'sMenu. The trigger uses<ActionButton>so an outerActionButtonContextcascades to it. Marigold'sMenuis untouched.LinkButtonis now slot-aware: it picks upActionButtonContextandActionGroupContextso a navigating action can sit alongside<ActionButton>inside an<ActionGroup>and inherit the same cascade. Adestructive-ghostvariant is added to match<ActionButton>. Context is consumed read-only (viauseSlottedContext) to sidestep the anchor/button ref-type mismatch thatuseContextPropswould have created. The read-only consumption now also absorbsclassNamefromActionButtonContext(mirroring<ActionButton>'suseContextProps-driven className merge) so positional classes published by a parent container — e.g. a grid-area class injected viaActionButtonContext— reach the rendered anchor. This lets<LinkButton>participate in container-driven layouts the same way<ActionButton>does.The container-driven layout pattern this enables comes with a corresponding convention: positional
classNameflows through slot contexts and is absorbed at the first layout boundary.<ActionGroup>enforces the convention at its own boundary by scrubbingActionButtonContextfor its descendants — it republishes an empty value so nested<ActionButton>s and<LinkButton>s do not individually re-claim a positional class that was meant for the group as a whole. Cascading props (size,variant,disabled) still reach the children viaActionGroupContext, which they read independently. This convention scales to every future container that adopts the slot-configuration pattern.<ActionBar>'s legacy top-levelActionButtonslot is internalized and re-exposed asActionBar.Button. Existing consumers that already use<ActionBar.Button>are unaffected.Typography prep:
HeadlineexportsHeadlineSize,TextexportsTextSizeandTextVariant. The aliases aren't yet consumed by other primitives, but exposing them now lets a future typography-token PR replace runtime classes without rewriting consumer-facing prop types. -
b7122c0: fix: apply
alignXfromTable.Columnto first column cellsTableCellContentused a truthy check oncolumnIndex, causing it to skip thealignXlookup whencolumnIndexwas0(first column). Replaced with a nullish check so all columns correctly inherit their alignment. -
b7122c0:
Titlelevelnow accepts the string form (level="2") in addition to a number, matchingHeadline. The two heading primitives now share oneleveltype. Non-breaking: existing numericlevel={2}usage is unaffected. -
b7122c0: fix: make Select and Menu overlay appear above Drawer on small screens
On small screens,
SelectandMenurender their options in aTray(bottom sheet). TheTrayoverlay hadz-40in the theme while theDraweroverlay usesz-50, so the tray rendered behind an open drawer and was unreachable.Moved the
z-indexfrom the theme style file into theTrayModalcomponent implementation (matching the project's z-index architecture rule), and raised it toz-50. Both theDrawerandTrayportal todocument.body; at equal z-index, DOM order determines stacking. TheTrayis always mounted after theDrawer, so it correctly appears on top. -
b7122c0: chore(deps): update
react-aria-components,@react-aria/*,@react-stately/*,@react-types/*, and@internationalized/*packages to their latest versions. -
b7122c0: fix(DST-1355): widen
variantandsizeprop types onLoaderandProgressCircleto accept arbitrary strings via| (string & {}). Matches the pattern already used byButton,Panel, and other components, and lets consumer themes register their own variant/size tokens without TypeScript errors while preserving IDE autocomplete for the built-in RUI values. -
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
- @marigold/system@18.0.0
18.0.0-rc.5
Minor Changes
-
0e2c676: fix(DST-1680): keep the mobile
ComboBox/Autocompletetray in the accessibility tree.On small screens both components render a
Trayinstead of RAC'sPopover. When the listbox opened,useComboBoxcalledariaHideOutside([inputRef.current, popoverRef.current].filter(el => el != null))— and because nothing claimedPopoverContextand the tray (with its input) portals in a later commit, both refs werenull.ariaHideOutsidehides everything outside the elements it is given, so an empty list hid the whole document, including the tray itself: screen readers could not reach the tray's dialog, search input or options at all.popoverRefnow points at the tray — the dialog element while open, and the container the tray portals into while closed — so the hide pass keeps the tray visible. Background isolation is unchanged; it comes from the tray's ownModal, which runsariaHideOutside(..., { shouldUseInert: true }). As a side effectuseComboBox's blur handling works again, since it checks whether focus moved intopopoverRef.currentbefore closing.Traynow also accepts arefto its dialog element. -
b7122c0: feat(DST-1492): add
usePageFocusto move focus to the page<h1>on route changeOn client-side navigation focus lingers on the clicked link or falls back to
<body>, so screen-reader and keyboard users get no signal that the screen changed.usePageFocusimplements the standard SPA fix: given the current route key (typically the pathname), it makes the page<h1>programmatically focusable (tabIndex={-1}) and focuses it on each change.The first render is skipped so the initial load never steals focus, and it is a no-op on a page with no
<h1>(anaria-label-only<Page>).<Page>stays router-agnostic: the route signal comes from the app router (RouterProvider). Call the hook from a component that persists across navigations (the layout / shell level), since the skip-first-render guard is per mount.import { Page, usePageFocus } from '@marigold/components'; const PageFocus = ({ pathname }: { pathname: string }) => { usePageFocus(pathname); return null; }; <Page> <PageFocus pathname={location.pathname} /> <Page.Header> <Title>Billing</Title> </Page.Header> {/* … */} </Page>; -
b7122c0: feat(DST-1609): two-level sidebar navigation with
Sidebar.RailandSidebar.RailItemAdds a two-level navigation mode to the sidebar: a persistent rail of icon-first top-level destinations next to a panel showing the active section's sub-navigation. A
Sidebar.RailItemwrapping aSidebar.Navis a section that shows a panel. One with only anhrefis a direct link, and one insideSidebar.Footerpins to the bottom of the rail. Itsactiveprop overrides href matching for pages the URL can't identify. Collapsing (toggle or Cmd/Ctrl+B) hides the panel while the rail narrows to an icon strip, so top-level navigation always stays available. On small screens the rail renders as the same single-column drawer as the plain sidebar: sections drill in (opened at the active section) and links close the drawer.<AppShell>switches to a full-width top bar automatically when a rail is present (pure CSS via:has()), so the brand never moves when the panel collapses.Sidebar.Togglegainsvariant="rail"for its top-bar placement between the brand and the breadcrumbs.- New theme tokens:
--spacing-topbar(the shell's shared vertical datum for the top bar height, sidebar brand row, and rail sticky offset), the rail column widths--spacing-rail/--spacing-rail-collapsed/--spacing-rail-panel, and--spacing-touch-target(44px minimum row height on small screens, shared by the drawer's nav rows and the existing Tray-mode ListBox/Menu options). - Idle single-column nav labels darken a step (new
--color-secondary-boldtoken, charcoal-700) so they clearly out-rank the quiet group-label captions. - Keyboard: the rail supports arrow-key (and Home/End) movement on top of its flat tab order, and the section panel's tab stop re-syncs to the current page when the route changes, so Tab re-enters at the active item.
- The
TopNavigationbottom edge is now an always-on border. The non-reusableui-scroll-edgeandui-sidebar-seam-headerutilities are removed, so the sticky bar and the sidebar header carry a plain border instead. - The
AppShellheader row is now sizedauto(was a fixed3.5rem), so a shell without aTopNavigationno longer reserves an empty header band, so the row collapses to the height of its content. - The shell's viewport-height claims (
AppShellgrid, sidebar and rail asides) read the new--ui-viewport-heightcustom property with a100dvhfallback. Set it on a wrapper to render the shell inside a bounded container (embedded previews, demos) instead of the browser viewport. Nothing changes when it is unset.
-
b7122c0: feat(DST-1641): add
ErrorState, the error sibling ofEmptyState: same anatomy (title,description,action,headingLevel), plus typed DOM passthrough (role,tabIndex,ref) for error-boundary fallbacks. -
b7122c0: feat(DST-1646): add
OverflowRegion, a single-row layout primitive that hides trailing items instead of wrapping when horizontal space runs out, and restores them as space returns. Hidden items stay mounted (state preserved) but are removed from paint, tab order, and the accessibility tree. Like the other layout primitives it has no theme layer: space its items with thespaceprop (inherited from a parentInline/Stackwhen unset, likeInline), label it with the forwarded region props (role,aria-label, ...), and pair it with theindicatorrender prop or theonOverflowChangecallback so hidden items stay reachable through another surface, e.g. quick filters demoting into a filter panel.
Patch Changes
-
85e9a45: Fix
Autocomplete's publiconSubmittype, which declared(value, key)while the implementation, JSDoc, and both docs demos all used(key, value). The type now matches the actual(key, value)signature — no runtime behavior changes. -
b7122c0: fix(DST-1659): draw the
Checkboxbox from theme tokens instead of raw Tailwind literalsThe checkbox icon painted itself with
bg-whiteandborder-black. Both now come from the token layer:bg-surfacefor the fill andborder-control-borderfor the affordance edge, matching how every other control draws its boundary.@marigold/theme-ruialready overrides both slots inCheckbox.styles.ts, so the rendered markup and the visual result are unchanged there. The literals only leaked in custom themes, where a consumer could not recolor the box edge or fill without fighting a hardcoded value. This was the last raw color in the component layer. -
68122ff: refactor(DST-1627): extract a shared
CalendarBodyfor theCalendar/RangeCalendargrid layoutThe multi-month and single-month layout markup was duplicated verbatim in
CalendarandRangeCalendar, so every layout tweak had to be made twice and the copies could silently drift. Both components now render that markup through one internal<CalendarBody>, which reads the theme classes, visible months, min/max value, disabled state and a newisRangeflag off the existingCalendarContext, keeping the touch pointerup guard (DSTSUP-257) range-only. Pure refactor: the rendered DOM, the styling and the behavior are unchanged. -
e0f9c05: fix(DST-1647): honor the router's
useHrefin sidebar linksSidebar.ItemandSidebar.RailItemrendered the rawhrefprop straight onto their anchor, which shadowed the value produced byRouterProvider's optionaluseHref. Applications served from a prefix, such as a Next.jsbasePath, ended up with sidebar markup pointing at an unprefixed URL, so middle click and "copy link address" resolved to the wrong page. Both components now render the transformed href and keep handing the unprefixed path tonavigate, matching how React Aria's ownuseLinkbehaves. Consumers that do not passuseHrefsee no change, because the default leaves the href untouched.The
RouterProviderdocs now coveruseHrefnext tonavigate, and the component gained a matching Storybook story and prop description. -
b7122c0: fix(Radio): apply width via CSS variable instead of raw class name
Radiobuilt itswidthclass name from the raw token directly (e.g.cn(width || groupWidth || 'w-full'), wherewidthcould be a literal"1/2"), which Tailwind can't statically detect at build time, so no CSS was ever generated — settingwidthhad no visible effect.Radionow follows the same pattern already used byFieldBase/TextField/NumberField: a staticw-(--field-width)class with the actual value injected viacreateWidthVar. IndividualRadioitems inside a sizedRadio.Groupnow inherit the group's already-computed width instead of recomputing it, which previously caused a double-shrink (e.g.width="1/2"rendering at 1/4 instead of 1/2). -
b7122c0: fix(DST-1660): keep a loading
Button's accessible nameA
<Button loading>previously had no accessible name at all. The label is kept mounted so the button doesn't change width when the spinner is overlaid, but it was hidden withinvisible(visibility: hidden), which removes a subtree from the accessibility tree — not just from the screen. The spinner's ownaria-labeldid not substitute, because that is a child widget's name rather than text content the button can take its name from.The effect: a screen reader announced "Delete, button" before the press and roughly "dimmed, button" the moment the action started, so the user lost the identity of the operation they were waiting on. That is a WCAG 2.1 §4.1.2 (Name, Role, Value) failure at Level A, and it was worse than a plain
disabledbutton, which keeps its name.The label is now hidden with
opacity-0. It reserves the exact same layout box, so nothing moves — verified by comparinggetBoundingClientRect()for every button across all three surface grounds, withdisplay: noneas a control to confirm the measurement detects real shifts. Rendering is unchanged; this is purely a fix to what assistive technology reports. -
0e2c676: chore(DST-1680): update React Aria to the 1.20.0 line.
What changed:
react-aria-components1.19.0 → 1.20.0, which pinsreact-aria3.51.0 andreact-stately3.49.0.@internationalized/date→ 3.12.3 and@react-types/shared→ 3.36.1. Both are required rather than cosmetic: RAC 1.20.0 declares^3.12.3/^3.36.1, and pnpm will not move an in-range dependency unless the specifier changes, so leaving the old floors keeps a second (runtime-bearing)@internationalized/datecopy in the tree.- The remaining declared floors now match the versions actually installed, which are also the latest published ones:
@react-aria/form→^3.2.1,@react-aria/live-announcer→^3.5.1,@react-stately/form→^3.3.1. Every other@react-aria/*and@react-stately/*entry was already current.
Impact:
No API change in Marigold components. Consumers pick up the upstream 1.20.0 fixes, including Table focus restoration,
FocusScoperestore-without-scrolling, and DatePicker focus handling in Firefox.One upstream behaviour change did need handling on our side: RAC 1.20.0 exposed a latent problem in the mobile
ComboBox/Autocompletetray, which lost its place in the accessibility tree. See the separate entry for that fix.@react-types/{button,checkbox,grid,table}deliberately stay on their type-only lines. All four latest minors pull@react-spectrum/provider— three as a direct dependency andgrid3.4.0 as a peer dependency — which drags in@adobe/react-spectrumand splits the i18n and overlay contexts. See the hold rule in.github/renovate.json. -
6cfcea4: fix(DST-1686): make
controla ground-adaptive track fill, and give theSliderrail the same token asSwitchandSegmentedControlThe Slider rail was the wrong token, painted twice. It used
bg-border— the token for structural lines (dividers, grid lines, table rules) — where theSwitchgroove and theSegmentedControltrack both usebg-control. On top of that,Sliderapplied itstrackstyle to two exactly-overlapping elements (theSliderTrackand an inner raildiv), so the translucentbg-bordercomposited with itself and the rail rendered at ~0.26 effective alpha instead of 0.14 — measuring#c0bfbeon white where the token specifies#dddddc. The redundant inner element is gone; theSliderTrackitself is the rail. Geometry is unchanged (both wereh-2at the same position) andtouch-none,select-noneand the disabled cursor stay on the interactive track element.controlis now translucent (charcoal-950 / 16%, was the opaquecharcoal-300). A track is not painted on one known background — it appears on a white Card, the gray page ground, amutedfill, and inside a hovered Table or ListBox row — and a fixed palette step drifts across those. charcoal-300 measured 1.53:1 on white but only 1.21:1 inside a hovered row, where the groove half-dissolved into the row it sits in. At 16% the four grounds land within 0.02 of each other (1.41–1.43:1), so a track weighs the same wherever it goes. Same rationale asborderin DST-1672.The three tracks (
Switch,SegmentedControl,Slider) read a touch lighter on white surfaces as a result:#d8d8d7rather than#d4d0ce. The trade-off is that the white Switch thumb and SegmentedControl indicator now vary against the track by ground (1.43:1 on white, 1.79:1 on a hovered row) where the opaque step held a flat 1.53:1 — track-vs-ground and thumb-vs-track cannot both be constant while the thumb is opaque, and ground legibility wins because it decides whether the control reads as a control at all.The
SegmentedControlindicator is larger. The frame around the selected thumb went from 4px to 3px (inset-y-[3px]on the indicator,p-[3px]on the list), so the thumb is 30px tall instead of 28px. Since the thumb's own 1px rim occupies the innermost pixel of that frame, 2px of bare track is what you see.The
SegmentedControlthumb's focus ring is now the sharedui-state-focus. It previously hand-rolled only the outline, so it missed the other half of that utility — firming--ui-border-colorto the opaque ring colour — and read noticeably lighter than every other focused control. A focused thumb and a focusedInputnow resolve identically: 3pxoutline-ring/50atoutline-offset-0, plus a 1px opaqueoklch(0.52 0.008 54)rim. The ring stays outside the thumb, and 3px is the minimum frame that clears it: the list is a scroll container clipping at its padding box, so that padding is the only room an outset ring can grow into. Below 3px the first and last thumbs get a visibly shaved ring.The
SegmentedControltrack's corners are now concentric with the indicator's. Both used the sharedrounded-surface, but two rounded rectangles nested with a gap only look like parallel arcs when the outer radius is the inner radius plus that gap. With the thumb at 8px and 3px of frame around it, the track needs 11px; at 8px its corner read visibly tighter than the arc it frames. The track is nowcalc(var(--radius-surface) + 3px)— derived from the token, so it stays concentric if the radius is retuned. This is a deliberate exception to usingrounded-surfaceeverywhere.The
SegmentedControlindicator's resting rim is re-derived from the track.ui-framedraws its rim as an outset ring, so the indicator's rim lands on the track and composites overbg-control— it reads denser than the samecontrol-bordertoken does on a field. The old compensation subtracted a flat 0.08, hand-tuned against the previous opaquecharcoal-300track, which left the rim at an effective 0.31 against a field's 0.26. It is now derived from the track's own alpha (--control-alpha, newly exposed on the token), so a resting indicator rim and a restingInputedge render the same on every ground, and retuning the track cannot silently detune the rim.If you use
bg-controlin your own code, note that it is now translucent: two stacked elements that both carry it composite into a darker track than the token specifies, and anything that paints a translucent edge over a track has to account for the track underneath it. -
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
-
Updated dependencies [b7122c0]
- @marigold/system@18.0.0-rc.5
18.0.0-beta.4
Major Changes
-
9918172: feat(DST-1545): replace
ActionBar.Buttonwith a plain<Button>via aButtonContextcascade.ActionBarnow provides aghost/defaultcascade to its toolbar, so authors place a standard<Button>inside the bar and it adapts to the toolbar look automatically, with the full Button API available (disabled,loading,slot,size="icon"). This mirrors the pattern already used byPanel.HeaderandButtonGroup.Breaking:
ActionBar.Buttonis removed. Replace<ActionBar.Button>…</ActionBar.Button>with<Button>…</Button>. For icon-only actions use<Button size="icon" aria-label="…">, which also fixes an accessibility defect where the old wrapper silently droppedaria-label, shipping unlabeled icon buttons. The duplicatedactionButtontheme style is gone (it hand-mirrored Button'sghostvariant at the default size, minus the press and loading affordances a real<Button>now brings).// Before <ActionBar selectedItemCount={3} onClearSelection={clear}> <ActionBar.Button onPress={edit}> <Pencil /> Edit </ActionBar.Button> </ActionBar> // After <ActionBar selectedItemCount={3} onClearSelection={clear}> <Button onPress={edit}> <Pencil /> Edit </Button> </ActionBar> -
0b7f87f: chore(DST-1164): remove the unused
Breakoutcomponent and the now-deadalignAPI fromContainer.Breakouthad 0% usage across all scanned production repositories, so it is removed entirely (component, stories, tests, and docs).Container'salignprop, together with its internalgridColumn/gridColsAligngrid setup, only ever took effect via a[data-breakout]child, so it became dead code onceBreakoutwas gone and is removed as well.Migration: remove any
alignprop from<Container>usages. ThecontentLength,alignItems, andspaceprops are unchanged. -
d72f464: feat(DST-1360): introduce
AppShell,Page,Page.Header, andPage.Content; removeAppLayoutRenames
AppLayouttoAppShelland removes its three pass-through subcomponents (AppLayout.Sidebar,AppLayout.Header,AppLayout.Main) —<Sidebar>,<TopNavigation>, and<Page>now sit directly inside<AppShell>(each owns its grid area, so child order does not matter).AppShellabsorbsSidebar.Providervia thedefaultSidebarOpenprop; render your own<Sidebar.Provider>around<AppShell>for controlled state,variant, orsizeand it is detected and used instead of the internal one.Adds
<Page>— the<main>landmark with page padding (p, orpx/py; defaultsquare-relaxed) and vertical rhythm between sections (space; defaultgroup). The page's<main>is named by its<h1>viaaria-labelledby; when there is no<Title>, passaria-label(or your ownaria-labelledby) instead. With none of these,<Page>warns in development so the landmark is never silently unnamed. Like<Panel>,<Page>forwards standard HTML attributes (id,data-*, event handlers) and arefto its<main>.Adds
<Page.Header>— a slot-based title/description/actions header that mirrorsPanel.Header— and an optional<Page.Content>(with its ownspace) for when the rhythm between sections should differ from the header-to-content gap. The page heading outline now falls out of the defaults:<Title>inPage.Headeris anh1,<Title>inPanel.Headeranh2,<Title>inPanel.Collapsibleanh3(override per<Page>withheadingLevel).Migration:
-<Sidebar.Provider defaultOpen> - <AppLayout> - <AppLayout.Sidebar>…</AppLayout.Sidebar> - <AppLayout.Header>…</AppLayout.Header> - <AppLayout.Main>{content}</AppLayout.Main> - </AppLayout> -</Sidebar.Provider> +<AppShell defaultSidebarOpen> + <Sidebar>…</Sidebar> + <TopNavigation>…</TopNavigation> + <Page> + <Page.Header> + <Title>Billing</Title> + <Description>Manage your plan and invoices.</Description> + <Button variant="primary">Upgrade plan</Button> + </Page.Header> + {content} + </Page> +</AppShell> -
8418ee7: refactor(DST-1548): rename
Card.BodytoCard.ContentAligns the Card body sub-component with
Panel.ContentandPage.Contentso all three container primitives expose the main body region under one name.Breaking change:
Card.Body(CardBody) is removed. Rename usages toCard.Content:- <Card.Body>...</Card.Body> + <Card.Content>...</Card.Content>The
bleedprop and padding behavior are unchanged. The internaldata-card-bodyattribute has been removed to matchPanel.Content.The
Cardtheme slot key is renamed frombodytocontentin the@marigold/systemThemetype and in@marigold/theme-rui. Theme authors overriding this slot must rename their key accordingly. -
fc8ca13: refa([DST-1549]): Breaking change: Rename compound member
Tabs.TabPanel→Tabs.PanelTabsnow exposes.List,.Item, and.Panel, so every compound member follows one predictable naming rule.<Tabs.TabPanel>is removed (hard rename, no deprecated alias).Migration:
Before After <Tabs.TabPanel id="…"><Tabs.Panel id="…"> -
2a275bb: fix(DST-1559): remove dead and mis-named props from
TextField,FileTrigger, andLoader.TextField: drop themin/maxprops. They were never forwarded to the underlying<input>(react-aria filters them out of both the input and wrapper props), so they had no effect. Numeric constraints belong onNumberField.FileTrigger: remove the mis-named singularacceptedFileTypeprop. Its key did not match react-aria'sacceptedFileTypes, so file-type filtering silently never applied. Use the inheritedacceptedFileTypesinstead.Loader: fix theloaderTypeJSDoc, which documented a non-existentcyclevalue. The accepted values arexloaderandcircle(defaultcircle).
-
d0bb11c: fix(DST-1556): rename SectionMessage's controlled visibility prop from
closetoopen<SectionMessage>'s controlled visibility prop was namedclosebut its truthiness meant visible ,close={true}showed the message andclose={false}hid it, the opposite of what the name and docs implied. It's nowopen, matching the polarity used by<Dialog>,<Drawer>,<Tray>, and<Sidebar>.Before After close={isVisible}(truthy = visible)open={isVisible}(truthy = visible)close={!isDismissed}open={!isDismissed}onCloseChange={setX}(receives current value)onOpenChange={(open) => ...}(receivesfalseon dismiss)A new
defaultOpenprop (defaulttrue) sets the initial visibility in uncontrolled mode. The uncontrolled default behavior (visible, self-dismisses via the close button) is unchanged.
Minor Changes
-
c789dee: feat(DST-1381): add
master/adminaccess variants toLinkandMenuItemthat mark actions requiring elevated access rights with an icon (lock = master, key = admin).Badgerenders itsmaster/adminvariants with the same icons.The components render the icon as a decorative
<svg>colored by the theme's access foreground tokens (which also keeps it visible in forced-colors mode). OnLinkandMenuItemthe restriction is exposed to assistive technology through a visually hidden "Master"/"Admin" text label rendered after the visible label, so restricted links and menu items carry the access level in their accessible name.Badgerenders no extra label because its visible text already is the access level, which rules out double announcements by design.Note that
variantis a single axis: an access variant cannot be combined with another variant (e.g.destructiveonMenuItem). For destructive actions that are access-restricted, the access variant takes precedence (variant="master"), with the destructive nature conveyed by the action's label and confirmation flow. See the Admin & Master Mark pattern docs. -
f1990eb: feat(DST-1551): add
DateRangePickercomponentNew
<DateRangePicker>lets users enter or select a start–end date range through a single field, mirroring<DatePicker>'s API and behaviour. Two date inputs (start/end) sit in one field group with a calendar button that opens a<RangeCalendar>in a popover on desktop and a tray on small screens. Supports per-input paste (ISO/EU/US formats),granularity(inline time segments),visibleDuration(up to three months), and the usual Marigold field props (disabled,readOnly,required,error,errorMessage,description,minValue,maxValue,dateUnavailable,width,variant,size). Adds a matchingDateRangePickertheme entry totheme-rui. -
d72b30a: feat(DST-765): add
<SegmentedControl>componentAdds a new
<SegmentedControl>for compact, single-select view switching and quick filters. It is built on react-aria'sRadioGroup/RadioField/RadioButtonwith aSelectionIndicator, so it is a real form field:value/defaultValue/onChange, thenameattribute (submits like a radio group),required,error+errorMessage,description,readOnly, and validation all work exactly like the other Marigold form components (label/description/error route through<FieldBase>). The selected segment is marked by an animated indicator that slides between options.Options are declared via the compound API
SegmentedControl.Option(also exported asSegmentedControlOption), each with avalue:<SegmentedControl label="View" defaultValue="list"> <SegmentedControl.Option value="list">List</SegmentedControl.Option> <SegmentedControl.Option value="grid">Grid</SegmentedControl.Option> </SegmentedControl>Two variants —
default(abg-controltrack with a raisedui-surfacethumb, mirroring theSwitch) andghost(track-less, with a translucent ghost-Button-style indicator for dense toolbars) — at a singledefaultsize (matching theh-controlInput height). Hover and focus reuse the sharedui-*utilities (ui-state-focus,ui-state-hover-ghost); the indicator slides between options (ease-out-quint) and respectsprefers-reduced-motion.To make segments divide the available width equally, use the standard
widthprop — e.g.width="full". There is no separatefullWidthprop.When the options exceed the available width the control scrolls horizontally instead of compressing the segments, keeping the selected option scrolled into view (reduced-motion aware). A scroll-driven edge fade signals there is more to scroll where supported, falling back to a native scrollbar otherwise.
ToggleButtonGroupnow logs a dev-only warning when used withselectionMode, steering single-select use cases towardsSegmentedControl(it remains for independent on/off actions in toolbars). -
9b613e6: feat(DST-1369): adopt the slot-configuration pattern in
Dialog,Drawer, andTrayThe three overlay components now follow the same slot-configuration pattern as
PanelandCard. Each publishes the slot contexts at its root, so the title, description, and action primitives pick up the overlay's theme classes wherever they are dropped:Dialog.Title/Drawer.Title/Tray.Titleare thin wrappers over<Title slot="title">.- New
Dialog.Description/Drawer.Description/Tray.Descriptionwrap<Description slot="description">. - New
Dialog.Header/Drawer.Header/Tray.Headerare optional layout wrappers that group a title and description. A bare<Title slot="title">(or<*.Title>) without a header is a first-class, accessible authoring form —aria-labelledbyresolves to it automatically.
The compound-component API is unchanged. The
<header>element that previously wrapped the title is gone; the title now carries the header chrome directly, with no change to the rendered visuals. -
e9996ef: feat(DST-1635): add a
bleedprop toDrawer.Contentso edge-aware children can span the full Drawer width.What changed:
<Drawer.Content bleed>drops the Drawer's horizontal content padding and publishes a--bleed-pxcustom property, mirroringPanel.Content'sbleed.- The horizontal padding shared by the sectioned overlay surfaces (
ui-panel-header/ui-panel-content/ui-panel-actions) now comes from a single--ui-panel-pxtoken, and a bledDrawer.Contentre-publishes that exact token as--bleed-pxso the two can't drift. - Edge-aware children stay aligned with the Drawer title while their dividers/backgrounds reach the Drawer edges:
Accordionreads--bleed-pxdirectly, andTable's edge-cell padding now falls back to--bleed-px(after the Panel-only--panel-px), so it aligns inside a bled Drawer too.
Why:
Placing an
<Accordion>(orTable) inside<Drawer.Content>previously trapped it inside the content padding, so item dividers and hover/selection backgrounds could not reach the Drawer edges.bleedgives the same full-width alignmentPanel.Content bleedalready offered.Impact:
- Default behavior is unchanged: without
bleed,Drawer.Contentkeeps the paddedui-panel-contentand--bleed-pxstays unset (children resolve their inset to0px). The--ui-panel-pxtoken resolves to the same24pxthe surfaces used before, so Dialog/Drawer/Tray are visually identical.
-
c20abe3: feat(DST-1282): scroll the Tabs row horizontally when it overflows
When more tabs are rendered than fit the available width,
Tabs.Listnow scrolls horizontally instead of wrapping onto multiple lines or pushing the page wide. Tabs keep their natural width (shrink-0) and snap gently into place (proximity) as you scroll, with the adjacent tab kept peeking past the edge so the scrollability stays discoverable. A vertical mouse wheel scrolls the row horizontally (pointer users without a trackpad), without hijacking normal page scroll. Horizontal overscroll is contained so it does not trigger browser back/forward gestures, and scrolling is smooth for users who allow motion. On browsers that support scroll-driven animations the overflowing edges fade out (ui-scroll-mask-x); elsewhere it falls back to a plain scroll container. When all tabs fit, nothing changes visually.The sliding selection indicator stays correct while react-aria scrolls an off-screen tab into view (the scroll container is a
layoutScrollmotion element). No runtime API change.Breaking change (
@marigold/system): theTabsthemeRecordgains a new requiredtabsListScrollslot. It is deliberately required so a theme cannot shiptabsList(whosew-maxtriggers the overflow) without the scroll container that makes it behave. Custom themes that define aTabsblock must add atabsListScrollentry to type-check. -
c799448: feat(DST-1509): add
collapseAttoTag.GroupTag.Groupnow accepts acollapseAt={n}prop: the firstntags render as usual, and the rest collapse behind a "Show N more" / "Show N less" toggle, matching the behavior already available onCheckbox.GroupandRadio.Group.Unlike those groups,
Tag.Group's tags are a RAC collection (selection, removal, keyboard navigation), so collapsed tags stay mounted inside the<TagList>and are hidden via the nativehiddenattribute rather than being pulled out into a separate<Collapsible>. This keepsonRemove,removeAll, andemptyStateworking unchanged, and the collapsed count automatically shrinks as tags are removed. If a hidden tag is part of the initial selection, the group expands automatically.collapseAtonly applies to static children; dynamic collections (items+ a render function) are unaffected.When both
collapseAtandremoveAllare used together, "Show N more" bottom-aligns next to the last visible tag, while "Remove all" stays in its own trailing column so it never mixes into the tag wrap. -
dd044be: Add relative date presets to
Calendar,RangeCalendar,DatePicker, andDateRangePickervia a newpresetsprop. On desktop the presets render as a quick-selection list beside the calendar. On small screens the grid renders first with a "Quick selection" row: inline calendars open the preset list in a bottom sheet, while the pickers switch their existing sheet to the list in place. Ships built-in localized presets (today,yesterday,tomorrow,this-week,next-7-days,next-30-days,last-7-days,last-30-days,this-month,this-quarter), supports custom presets with value resolvers, and exportsuseDatePresets/useDateRangePresetsfor userland compositions. -
ecd739f: feat(DST-1533): add
Table.FootercomponentNew
<Table.Footer>renders a semantic<tfoot>after<Table.Body>for summary rows like totals, counts, or averages, composed from<Table.Row>and<Table.Cell>just like the body. Supports astickyprop that pins the footer to the bottom of the viewport while scrolling, mirroring sticky table headers. Adds a matchingfootertheme entry totheme-rui. -
c30f224: feat(DST-1568): add
erroranderrorMessagesupport toSwitchandCheckboxWhen
erroris set, the field is marked invalid and theerrorMessageis shown in place of thedescription, wired to the input viaaria-describedby. When both are unset, rendering is unchanged.Internally,
SwitchandCheckboxnow render theirHelpTextinside the RAC field (SwitchField/CheckboxField), relying on RAC's nativearia-describedbyandFieldErrorContextwiring instead of re-plumbing it by hand. No other public API change. -
b6666b4: fix(DST-1621): keep
AccordionstickyHeaderpinned when the header has actionsAccordion.Headernow accepts anactionsprop for content shown next to the title, such as buttons. Previously actions were added by wrappingAccordion.Headerin a layout component, which shrank the sticky header's containing block to the header row sostickyHeadercould no longer pin the header while scrolling. Passing actions throughactionskeeps the sticky wrapper a direct child of the item, so the header stays pinned together with its actions. -
e5701c4: feat(DST-1634): standardize
Inputtrailing-action alignment and makesize="icon"a publicButtonAPI.The
Inputleading icon is clamped to 16px so it no longer overlaps the placeholder. Every trailing action (clear button, chevron, loading spinner, or a custom icon button) now sits in a control-sized centered box flush to the edge, so its icon aligns at the same inset as the leading icon acrossInput,SearchField,ComboBox,Autocomplete,TagField, andDatePicker.Button'ssize="icon"is now public and documented as the way to build an icon button, composing with anyvariant(for examplevariant="ghost" size="icon").Migration:
variant="icon"was never a real Button variant. It silently rendered a default button, so any usage from older docs should switch tosize="icon"(with a variant, for examplevariant="ghost" size="icon"). -
306fe23: feat(DST-1643): add a
fullscreensize toDialog<Dialog size="fullscreen">fills the viewport (minus a small margin) at every breakpoint, giving content-heavy picks room for search, filters, and a long scrollable list while the title and actions stay fixed. The existingxsmall/small/medium/largesizes are unchanged. -
106821a: feat(DST-990): enrich
<Menu>with selection visuals, keyboard shortcuts, and dividers<Menu>gains richer building blocks for advanced menus:- Selected-item visuals. In
selectionMode="single"or"multiple", items show a leading checkmark and a highlighted row, aligned like<ListBox>. Command menus (noselectionMode) render exactly as before. - Keyboard-shortcut hints via a new shared
<Keyboard>primitive (a sibling to<TextValue>and<Description>). It renders a<kbd>key-cap on its own and adapts to its container, so inside aMenu.Itemit becomes a muted, right-aligned hint wired to react-aria'saria-describedby. - Dividers. Drop the shared
<Divider>between<Menu.Item>s to separate groups with arole="separator"line.
Breaking (
@marigold/system): theMenurecord in theThemetype now requires akeyboardkey. Custom themes implementingMenumust add it to keep compiling. All@marigold/componentsadditions are backward compatible. - Selected-item visuals. In
-
3231866: feat(DST-1587): share wheel-to-horizontal-scroll between
TabsandSegmentedControlThe wheel handler that lets pointer users without a trackpad reach overflowing
Tabsis now a shareduseWheelScrollXhook, andSegmentedControladopts it too. Wheeling vertically over an overflowingSegmentedControltrack now scrolls it horizontally, matchingTabs. No public API change on either component. -
867f3cc: fix(DST-1573): default
<Page>and<Page.Content>spacing toregularThe
spaceprop on<Page>and<Page.Content>— which controls the vertical rhythm between a page's children (the<Page.Header>and the<Panel>s/sections below it) — now defaults toregular(spacing(6), 24px) instead ofgroup(spacing(12), 48px). The previous default produced too much whitespace between sections. Consumers can opt back into the larger gap withspace="group". -
b41a3e3: feat(DST-1513):
<Select>'srenderValuenow receives a seconddetailsargument with the selectioncount, and works when options are provided as static<Select.Option>children (previously it was silently skipped unless the options came from theitemsprop).This makes it easy to summarise a multi-select trigger instead of listing every value, e.g.
renderValue={(items, { count }) => `${count} selected`}. The default trigger rendering is unchanged: withoutrenderValue, a multi-select still lists the selected values. -
766a46b: feat(DST-1370): migrate
ContextualHelp,SectionMessage, andEmptyStateto the slot-configuration patternSectionMessage.Titlenow renders a semantic heading (<h3>by default) instead of a<div>, fixing an a11y gap. The level is configurable via the newheadingLevelprop on<SectionMessage>. When a title is present, the container becomes arole="group"labelled by the title viaaria-labelledby.- New
<SectionMessage.Description>sub-component for a short summary between title and content. ContextualHelp.Titlenow usesslot="title", so the popover dialog gets a properaria-labelledby. The title tag changes from<h3>to<h2>(same asDialog.Title); visual appearance is unchanged.- New
<ContextualHelp.Description>sub-component. - The
Themetype now requires adescriptionkey on theSectionMessageandContextualHelpstyle records; themes defining styles for these components must add it. EmptyState'stitlenow renders as a semantic heading (<h3>by default, configurable via the newheadingLevelprop), and itsdescriptionrenders through the<Description>primitive (same DOM as before, now sitting 4px below the title to match the description rhythm of the other components). The flat-props API is unchanged.- All three roots now also publish a
ButtonContext, completing the slot-configuration set. It scopes action buttons (e.g. those placed inSectionMessage.Content, theEmptyStateaction, orContextualHelpcontent) to a clean baseline so they never inherit a surrounding container's button cascade (such as aPanel.Header's ghost/small look). No variant or positioning is imposed, so existing usage renders unchanged.
Patch Changes
-
28c4e40: feat(DST-1461):
Accordionaligns likeTableinside a bledPanel.What changed:
- A bled
Panel.Content/Panel.CollapsibleContentnow publishes a--bleed-pxcustom property (set to the Panel's--panel-px). Non-bled content is unchanged and does not set it. - The
defaultAccordionheaderandcontentinset themselves by--bleed-px(via--accordion-x-padding, which falls back to0px). So inside a bled Panel the item dividers span edge-to-edge while the header/content align with the Panel title. - In a bled Panel the full-width header (and its focus ring) is inset off the Panel border by one spacing step, matching
Panel.Collapsible.
Why:
Dropping an
<Accordion>into<Panel.Content bleed>now gives full-width item dividers and header/content aligned with the Panel title — the same behaviorTablealready had, with no new Accordion prop or variant.Impact:
- Standalone Accordions are unchanged (
--bleed-pxis only set by a bled Panel container, so the inset resolves to0px). - Accordions inside a non-bled
Panel.Contentare also unchanged — the inset stays0px, so header/content keep aligning with the dividers as before (no double indent). - Only Accordions inside a bled Panel gain the inset. The
cardvariant is unaffected; it keeps its ownpx-4.
- A bled
-
be0eeb9: style(DST-1586): scale breadcrumb separators with the size variant and emphasize the current page
The chevron separator now scales with the breadcrumb size (
small/default/large) instead of rendering at a fixed 16px, so it stays a quiet mark between crumbs; gaps tighten onsmallaccordingly. The current page reads a tier above the trail — medium weight in theforegroundink — matching how the sidebar marks the active item.The
<Breadcrumbs>chevrons drop their hardcodedsize={16}prop: the theme'sBreadcrumbsitemslot now owns the separator size ([&_svg]:size-*, which wins over the SVG's width/height), so the number in the component was dead and misleading. Themes that don't set a separator size fall back to the icon's default size. -
13a1982: feat([DST-1339]): FileField gains a
size="small"compact layout renders as a single-row input-height control (upload button + file list) instead of the full drop-zone, suited for space-constrained forms. -
9fd4000: feat(DST-1439): give
SectionMessagea neutral surface with a muted variant borderSectionMessageno longer fills its background with a per-variant tint (bg-info,bg-success,bg-warning,bg-destructive). It now sits on a neutralui-surfacewith neutral title and body text. The severity is carried by a muted per-variant colored border (the accent mixed halfway into the neutral border) plus the colored icon.This is a visible design change for every variant. Because the surface stays neutral, standard
<Button>and<Link>actions placed inside read correctly instead of floating on a colored fill. On the old tint the default<Button>(variantsecondary, which has its ownui-surfacefill) rendered as a foreign chip on the colored container for every variant except error. The muted border sits at the container edge, away from the content, so it signals the variant without touching the actions. The border color is set throughui-surface's--ui-border-colorhook, which is registered as a non-inheriting custom property, so it stays scoped to the container and does not leak into nested action borders.Variants stay distinguishable without relying on color alone through the colored border, the distinct icon shape and color, and the title. The bordered, in-flow treatment keeps an inline message visually distinct from the floating, shadowed
<Toast>. No API changes. -
f715905: fix(DST-1501):
<Panel p={number}>now applies paddingA numeric
p(e.g.p={4}) silently produced no padding: the value was suffixed with-x/-yand resolved to a non-existentvar(--spacing-4-x). A scale value is now applied directly (calc(var(--spacing) * 4)) on both axes, matchingpx/pyand<Page>. Named inset tokens are unchanged. -
0637671: Extract
resolveInsetAxeshelper to centralise inset-padding axis resolution.The
p→px/pyresolution logic (branching on whether the value is a numeric scale or a named token) was copy-pasted acrossPage,Panel, andCard. This duplication caused the<Card p={number}>silent bug (resolving to a non-existentvar(--spacing-4-x)), the same class of bug that had already been fixed independently inPanel(DST-1501) andPage(DST-1360).- Adds
resolveInsetAxes({ p, px, py, defaultInset })to@marigold/systemalongsidecreateSpacingVar. - Adopts the helper in
Card,Panel, andPage, fixing the live<Card p={number}>bug as part of the refactor. - Fixes the same numeric-
pbug inSelectList(inline, since its conditional-axis pattern differs).
- Adds
-
e686474: chore(DST-1503): Migrate
Checkbox,Switch, andRadiooff the deprecated react-aria-components single-element exports (Checkbox/Switch/Radio) to the*Field+*Buttoncomposition introduced inreact-aria-components@1.18.0. This removes thets(6385)deprecation warnings with no change to the public API, behavior, or visual output. -
50d8339: chore(DST-1517): HelpText renders the shared Description component
HelpTextnow renders the description through the sharedDescriptioncomponent instead of react-aria's raw<Text slot="description">.Descriptionis just<Text slot="description">, so the rendered output andaria-describedbywiring are unchanged. The win is a singleDescriptionbuilding block shared by both the slot-configuration containers and the form fields, so the two cannot drift apart. No names, output, or behaviour change. -
2fc7b96: refactor(DST-1534): build the
Calendaryear dropdown on react-aria'sCalendarYearPickerThe year dropdown now consumes react-aria's
CalendarYearPickerrender-prop (mirroring how the month dropdown already usesCalendarMonthPicker), replacing the hand-rolled year list and its localizedaria-labelworkaround. This was unblocked by react-aria's June 2026 fix that makesmaxValueinclusive, so the boundary year is reachable. Unbounded calendars keep the ±20-year window and bounded ranges stay fully reachable at both ends. When only one bound is set, the open side now widens to keep that bound reachable instead of staying at a fixed ±20 years. -
586ffd1: refactor(DST-1546): replace the bespoke TagGroup "Remove all" wrapper with a plain
<Button>via aButtonContextcascadeTagGroupnow provides alink/smallButtonContextaround its internalRemoveAllrender, so the "Remove all" action is a bare Marigold<Button>instead of the raw react-ariaButtonwith hand-rolled link styling. This mirrors the cascade pattern already used byActionBarandPanel.Header.The change is internal-only.
TagGroupRemoveAllis not part of the public API (TagGrouprenders it itself), the authoring API (removeAll/onRemove) is unchanged, and there is no behavioral or accessibility change.The redundant
removeAlltheme style is removed fromTag.styles.ts(thelinkvariant atsize="small"reproduces it), and the now-unusedremoveAllkey is dropped from theTagtheme type. -
af7767c: chore(DST-1547): move z-index classes out of theme style files into component implementations
Per the z-index management rule (
CLAUDE.md),z-*utilities belong in component implementations, never in theme*.styles.tsfiles. The local focus/drop/sticky stacking classes forCalendar/RangeCalendar,LegacyTable,ListBox,Table,ToggleButtonandSegmentedControlhave been moved from theirtheme-ruistyles into the matching componentclassName(viacn()), preserving the exact modifiers and important flag. No visual or stacking change. -
508ec2c: fix(DST-1553): drop the dead
'small' | 'medium' | 'large'literals fromTabssizeThe
sizeandvariantprops onTabsresolved to nothing after the RUI theme size variants were removed (2025-03-04).sizenow accepts a plainstring(matchingLabelandHelpText) instead of advertising specific values that no theme backs. The props stay in place as theme hooks, so a consumer theme can define its ownsize/variantvariants without the misleading built-in union. -
018c055: fix(DST-1565): stop the DatePicker and DateRangePicker popover from stretching to the trigger width
The shared
Popoverforces its width to at least the trigger's viamin-w-(--trigger-width). That is right for field dropdowns (Select, ComboBox) whose list should line up with the field, but wrong for a calendar, whose width is its own. A newmatchTriggerWidthprop (defaulttrue, so every existing popover is unchanged) lets DatePicker and DateRangePicker opt out, so the calendar sizes to its content instead of the full field width. -
0e4b915: refactor(DST-1585): drive SegmentedControl's reduced-motion scroll from CSS
SegmentedControl now gates its selection-reveal scroll animation with the same CSS approach as Tabs: the scroll container carries
motion-safe:scroll-smoothand the component'sscrollTousesbehavior: 'auto', which follows that CSS — animating when motion is allowed and jumping instantly under reduced motion. This replaces the previous JSwindow.matchMedia('(prefers-reduced-motion)')check. Behavior is unchanged; the initial mount reveal stays instant. No API change. -
51484fd: style(DST-1602): drop the removed elevation shadow from SelectionIndicator
SelectList'sSelectionIndicatorno longer appliesshadow-elevation-border, which is removed fromtheme-ruiin the accompanying change. The indicator keeps itsborderand surface fill. -
7605d46: fix(DST-1629): apply a
SelectListitem'sactionslot styling to a trailing MarigoldButton,LinkButton, orActionMenuso the action spans both rows and stays centered. The action slot className was only provided on RAC'sButtonContext, which Marigold'sButtonignores, so the action auto-placed into the title row and stretched it, pushing the description down. The className now flows through the MarigoldButtonContextthat these components read. -
40b006e: fix(DST-1630): match the Panel collapsible header caret to the Accordion chevron. It rendered at the default 24px in the foreground color, while Accordion uses a 16px
text-secondarycaret, so the two collapsible patterns looked inconsistent. The Panel caret now renders at 16px and its color is driven by a new themeablecollapsibleIconslot (defaulting totext-secondaryin the RUI theme). -
5d0b6c0: fix(DST-1632): center the section
Loadertogether with its label and give theTabledrag handle edge spacing.The section
Loadersized its container to a fixed square, so a labelled loader overflowed the box and the section wrapper centered the box instead of the spinner-and-label group. The spinner now carries the fixed size and the container is content-sized, so the whole group centers as one. TheTabledrag cell had no padding, leaving the grip flush against the row edge. It now uses the shared cell edge padding and its column matches the checkbox column width, so the grip lines up with its header and the first cell. -
199e066: fix(DST-1645): align preset quick-selection rows with the tray nav row on small screens. The preset listbox rows reuse the shared
ListBoxp-1focus-ring gutter, which insets them narrower than the full-width nav row. On small screens the list now negates that gutter (-mx-1) so rows span the tray edge-to-edge and line up with the nav row, while the gutter still keeps each row's focus outline from being clipped by the list's overflow. -
40e6b21: fix: stop exposing
styleonLabelLabelonly removedclassNamefrom its react-aria props, leavingstylein the public interface. It now omits both, matching theclassName/styleremoval convention used across the design system (e.g.Description,TextValue). Theme the label viavariant/sizeinstead. -
b954ab2: fix(DST-1622):
ProgressCircleandLoaderrespect a consumer-providedaria-label/aria-labelledby.What changed:
ProgressCircleno longer overwrites a caller's accessible name. The built-in localized "loading" message is now only a fallback, applied solely when the consumer provides neitheraria-labelnoraria-labelledby.Loader(BaseLoader) uses the same fallback: the localized message is applied only when there is noaria-label,aria-labelledby, or visiblechildrenlabel — and it no longer emits a redundantaria-labelnext to a consumer'saria-labelledby.- A fullscreen
Loadernow stays reliably named: when the consumer supplies their ownaria-labelledby, the overlayDialogreferences that element directly instead of the intermediate loader node (the accessible-name spec does not follow a secondaria-labelledbyhop, which otherwise left the modal unnamed).
Why:
Previously the
aria-labelwas set after{...props}was spread, so a caller passingaria-label(oraria-labelledby) had no effect and every progress circle announced the same generic "Loading…" string. This prevented labelling a spinner for its context (e.g. "Sending reminders" in a bulk-action flow).Impact:
- Callers that pass no label (e.g. the spinners inside
Button,ComboBox,SearchInput) are unchanged — they still get the localized fallback. - Callers that pass
aria-label/aria-labelledbynow get their own accessible name.
-
2b3e286: fix(ProgressCircle): resolve named
sizetokens to a numeric SVG dimensionA named
sizetoken (default|large|fit) was forwarded unchanged to the underlying<SVG>element, which renderswidth/heightas`${size}px`— producing invalid attribute values likewidth="defaultpx"and emitting console errors. The SVG now resolves named tokens to the pixel dimension of their themesize-*class (default→ 80,large→ 144) for itswidth/heightattributes and stroke-width math, so the stroke stays proportionate and the rendered output is unchanged.fitis content-sized and has no intrinsic dimension, so it falls back to the<SVG>default of24.The stroke-width comparison also switched from a string compare (
size <= '24') to a numeric one, which additionally fixes multi-digit sizes that were previously mis-classified (e.g.size="100"computed astrokeWidthof2instead of4). -
be0eeb9: style(DST-1586): remove the overshoot from the sidebar toggle icon animation
The sidebar toggle icon's panel/chevron animation eased with a spring-like overshoot bezier. It now settles on
ease-out-quint, matching the theme's motion register — fast start, smooth stop, no bounce. -
ccd3bb3: fix(DST-1642): keep the Slider thumb from being clipped at the track ends
The Slider thumb is centered on the track position, so at its min/max values it overhangs the track ends by half its width. Inside a scroll container such as
Drawer.Content— whoseoverflow-y: autopromotesoverflow-xto a clipping value — the overhang was sliced off, leaving a half-circle thumb (and it will be clipped unconditionally onceDrawer.Contentgains ableedprop with no horizontal padding). The track is now inset by half the thumb width so the thumb always stays within the Slider's own box, independent of any ancestor padding. -
0e3971a:
Titlelevelnow accepts the string form (level="2") in addition to a number, matchingHeadline. The two heading primitives now share oneleveltype. Non-breaking: existing numericlevel={2}usage is unaffected. -
4d44517: fix: make Select and Menu overlay appear above Drawer on small screens
On small screens,
SelectandMenurender their options in aTray(bottom sheet). TheTrayoverlay hadz-40in the theme while theDraweroverlay usesz-50, so the tray rendered behind an open drawer and was unreachable.Moved the
z-indexfrom the theme style file into theTrayModalcomponent implementation (matching the project's z-index architecture rule), and raised it toz-50. Both theDrawerandTrayportal todocument.body; at equal z-index, DOM order determines stacking. TheTrayis always mounted after theDrawer, so it correctly appears on top. -
Updated dependencies [d72b30a]
-
Updated dependencies [9b613e6]
-
Updated dependencies [c20abe3]
-
Updated dependencies [d72f464]
-
Updated dependencies [0637671]
-
Updated dependencies [dd044be]
-
Updated dependencies [586ffd1]
-
Updated dependencies [8418ee7]
-
Updated dependencies [40b006e]
-
Updated dependencies [106821a]
-
Updated dependencies [766a46b]
- @marigold/system@18.0.0-beta.4
18.0.0-beta.3
Minor Changes
-
5945653: feat(DST-1460): animated open/close caret in
Accordion.HeaderAccordion.Headernow uses the newMorphCareticon, which smoothly animates between the closed (down) and open (up) states by morphing its SVGdpath. Respectsprefers-reduced-motion. The unusedChevronDownicon has been removed. -
141a2cc: feat(DST-1373): adopt the slot-configuration pattern in
CardCard.Headeris now a slot provider: drop a<Title>and an optional<Description>directly inside it and the header wires up the heading level, id, accessible name, and theme classes automatically. A bare<Title>placed directly inside<Card>(noCard.Headerwrapper) is also picked up by the root, so title-only cards can skip the header and still get the right padding andaria-labelledbywiring.<Card>itself now renders an<article>landmark and is automatically labelled by its<Title>viaaria-labelledby, or by an explicitaria-label. A newheadingLevelprop (default3) controls the underlying heading tag for the document outline.The theme
Cardslot map gainstitleanddescriptionentries — the typography previously carried on theheaderslot has moved totitle. Variant text color now flows through a new--card-accentCSS custom property, somasterandadmincards pick up the matching accent automatically. Raw<Stack>/<Headline>composition insideCard.Headerstill renders but does not pick up the slot wiring; prefer<Title>/<Description>going forward. -
bd45aee: feat(DST-876): add Card usage guidelines
Renames the
Card.Previewslot toCard.Mediaacross components, theme, and docs. This is a breaking change: consumers using<Card.Preview>, thedata-card-previewselector, or thepreviewtheme slot key must migrate toCard.Media,data-card-media, and themediaslot key respectively.Adds a "Usage" section to the Card docs covering when to use cards, media slot guidance.
-
141a2cc: feat(DST-1480): forward arbitrary HTML attributes on
<Panel><Panel>now extendsHTMLAttributes<HTMLElement>(minusclassName/style) and spreads the remaining props onto its root<section>, matching the<Card>API. Consumers can now passid,data-*, event handlers, and other standard attributes directly to a Panel.A consumer-supplied
aria-labelledbyis preserved instead of being overwritten withundefinedwhen no<Title>is present — the slot-ownedtitleIdstill wins when a<Title>renders. This mirrors the fallback adopted byCardin DST-1373. -
4d20fb6: feat(DST-1483): remove ActionButton in favor of a slot-aware Button (rename ActionGroup → ButtonGroup)
The beta-only
<ActionButton>is removed.<Button>is now slot-aware: it adapts automatically inside a button container, so you write<Button>everywhere instead of learning a second button component.<ActionButton>is removed. Use<Button>; it adapts inside<ButtonGroup>and<Panel.Header>. Opt a button out of the cascade withslot={null}.<ActionGroup>is renamed to<ButtonGroup>, mirroring the existingToggleButtonGroup → ToggleButtonContext → ToggleButtontrio.- A single Marigold-owned
ButtonContextdrives the cascade (replacesActionButtonContext+ActionGroupContext). RAC's ownButtonContext(close/increment/decrementslots) is untouched. - Uniform precedence: a local prop (
variant,size,disabled) always wins over the container. This drops the formerActionGroupsize-group-wins outlier. <ButtonGroup>cascadesvariant: 'secondary'when unset, the same baseline as a standalone<Button>. Slot-aware parents override it where they want lower emphasis:<Panel.Header>cascadesvariant: 'ghost'+size: 'small', so a labelled header action stays readable. An icon-only action (a bare-icon<Button>, an<ActionMenu>kebab) setssize="icon"to render as a square.<ButtonGroup>now owns a structuralflex gap-1layout (orientation-aware), so a standalone cluster is spaced correctly —<ActionGroup>had no layout of its own. A container's positional className (e.g. Panel's[grid-area:actions]) still rides along and positions the group.- Overlays (
Popover,Modal,Tray,Drawer) resetButtonContextat their content root, so a header/group cascade can't leak through the portal into an overlay'sslot="close"orDialog.Actionsbuttons. <SelectList.Option>cascadesvariant: 'ghost'to a nested<Button>,<LinkButton>, or<ActionMenu>, so a trailing in-row action reads as low-emphasis chrome without an explicitvariant.
Migration
<ActionButton>→<Button>(itsdefaultvariant maps tovariant="ghost").<ActionGroup>→<ButtonGroup>.ActionButtonContext/ActionGroupContext→ButtonContext.<ActionMenu>keeps its public name. Its trigger is now a slot-aware<Button>that inherits the cascade instead of hardcoding a variant: it renderssecondaryon its own (the standalone<Button>baseline, matching the pre-unification look) andghostinside<Panel.Header>,<SelectList.Option>, or a<ButtonGroup>. Avariantset on the<ActionMenu>still wins.
Patch Changes
-
16bcb56: feat([DST-1395]): SelectList horizontal layouts now automatically flip to a vertical stack when the wrapping container is narrower than
40rem(~640px). -
75cab86: feat(DST-1286): Panel renders a
data-panelattribute on its rootThe root
<section>rendered by<Panel>now carries a valuelessdata-panelattribute. External stylesheets and host pages can use it as a stable selector (e.g.:not(:has([data-panel]))) to detect whether a Panel is present without depending on Tailwind utility classes. -
0760ecc: refactor(DST-1374): use
<TextValue>and<Description>for selection-container itemsConsumer-facing JSX in component stories and documentation demos for
<Select>,<SelectList>,<ListBox>,<Menu>,<ComboBox>, and<Autocomplete>now composes item content with the<TextValue>and<Description>primitives instead of hand-written<Text slot="label">/<Text slot="description">. The primitives are drop-in replacements that render the same RAC<Text>with the same default slot values, so rendering,aria-describedbywiring, and accessibility are identical.<Menu.Item>gains first-classlabelanddescriptiontheme slots, mirroring<SelectList.Option>.MenuItemmerges the Marigold theme classNames into RAC'sTextContextso nested<TextValue>/<Description>pick up Menu styling without losing RAC's slot wiring. Menu items adopt a two-column grid layout (icon column + content column) so descriptions render below labels; existing plain-text and icon+text menu items are unaffected.The
Menutheme type in@marigold/systemis extended with requiredlabelanddescriptionslot keys. Consumers maintaining a custom theme that overridesMenuwill need to add these two slots to satisfy the type.@marigold/theme-ruiis updated accordingly in this release.No public API change on
Select.Option,SelectList.Option,ListBox.Item,Menu.Item,ComboBox.Option, orAutocomplete.Option. -
14f1324: fix(DST-1467): make
MorphCaretSSR-safeThe shared
reducedMotionconstant inutils/reducedMotion.tssampledwindow.matchMediaat module evaluation, so the server bundle always resolved tofalsewhile a client withprefers-reduced-motion: reduceresolved totrue— producing a React 19 hydration mismatch (silently absorbed in production, logged as an error in dev).MorphCaretnow reads the preference viauseReducedMotion()frommotion/react, matchingSidebarToggleIconandTrayModal. The obsoleteutils/reducedMotion.tshas been removed. -
431d4dd: fix(DST-1480): only set
aria-labelledbyon Panel when a Title is present<Panel>previously renderedaria-labelledby={titleId}whenever noaria-labelwas given, even if no<Title>was present. That left the<section>landmark pointing at an id no element carried, producing a broken/empty accessible name.The guard now also checks
hasTitle, soaria-labelledbyis only applied when a<Title>actually renders. This mirrors the stricter guard adopted byCardin DST-1373. -
fc9ffb1: fix(DSTSUP-256): show
cursor-not-allowedon disabled TagFieldThe hidden trigger button inside TagField had
cursor-pointerhardcoded, so hovering a disabled TagField showed the text/caret cursor instead ofnot-allowed— inconsistent with Select and ComboBox. Addeddisabled:cursor-not-allowedto the trigger button so the cursor now matches the rest of the form components. -
334688e: chore(DST-1364): migrate
ListBoxitem label/description styling off descendant selectorsListBoxnow exposeslabelanddescriptionas first-class theme entries, andListBox.Iteminjects their classNames into react-aria'sTextContext(merging rather than replacing, so RAC'saria-describedbywiring is preserved) instead of styling[slot=description]via a descendant selector onitem. This also benefitsSelect.Option,ComboBox.Option, andAutocomplete.Option, which re-exportListBox.Item.The
Themetype in@marigold/systemnow requireslabelanddescriptionkeys on theListBoxrecord, so custom themes implementingListBoxmust add these entries. No public API change in@marigold/components; visually identical exceptdescriptionnow explicitly setsfont-normal(parity withSelectList). -
334688e: chore: extract shared
useMergedTextSlotshelper for RACTextContextslot stylingListBox.ItemandSelectList.Optionboth mergedlabel/descriptiontheme classNames into react-aria'sTextContext(spreading the parent slot first to preserve RAC'saria-describedbyid). That accessibility-critical logic — and itsSlottedContextValuetype — now lives in a singleuseMergedTextSlotshook that both consume. No public API or visual change. -
9cdb389: fix(DST-1464): keep wide content inside
<AppLayout.Main>from overflowing the viewport. The shell grid usesgrid-cols-[auto_1fr]and the main grid item defaulted tomin-width: auto, so any content wider than the available track (most visibly a<Select selectionMode="multiple">with several long selected items) pushed the main column past the viewport and added a horizontal scrollbar. Addingmin-w-0toAppLayoutMainlets the1frtrack actually shrink, and children liketruncateon the Select trigger can now clip at the right place. -
Updated dependencies [141a2cc]
-
Updated dependencies [0760ecc]
-
Updated dependencies [4d20fb6]
-
Updated dependencies [334688e]
- @marigold/system@18.0.0-beta.3
18.0.0-beta.2
Major Changes
-
3a62175: feat([DST-1407]):
Drawerenforces one open at a time.Opening a sibling
<Drawer>while one is already open dismisses the first. Applies to desktop and mobile. The dismissed Drawer'sonOpenChange(false)is invoked so controlled-state consumers stay in sync.A
<Drawer.Trigger>nested inside an already-open Drawer is treated as a sub-flow: the nested Drawer opens over its parent and the parent stays mounted. Dismissing the parent in that situation would also unmount the nested trigger and tear down the new Drawer.Migration: No API change. If a flow relied on multiple simultaneous sibling drawers, refactor to a single drawer with switchable content, or use
<Modal>for layered interactions.
Minor Changes
-
d51416c: feat([DST-761]): export
useLandmarkfrom@marigold/components.Marigold now re-exports React Aria's
useLandmarkhook (and itsAriaLandmarkRole/AriaLandmarkPropstypes) so consumers can register custom regions as ARIA landmarks without adding@react-aria/landmarkas a direct dependency.import { useRef } from 'react'; import { useLandmark } from '@marigold/components'; const ref = useRef<HTMLElement>(null); const { landmarkProps } = useLandmark( { role: 'search', 'aria-label': 'Site search' }, ref );A new accessibility guide on landmarks and a dedicated
useLandmarkreference page have been added to the documentation. -
a59d2dd: fix([DST-1363]): make
<TagGroup>errorMessagerender and bridge it to form validation<TagGroup>acceptederrorMessagevia<FieldBase>but never rendered it because RAC'sTagGroupdoes not populateFieldErrorContext. The internal<HelpText>short-circuits on a missing context, so the error path was a silent no-op and<Form>-level validation never reached the user.Bridges
<TagGroup>to validation the same way<SelectList>does:useFormValidationState+useFormValidationon a hidden<select>(replacing the previous<input type="checkbox">shim), with<FormContext>inheritance forvalidationBehavior. The shared hidden control lives atHiddenSelection/and is now consumed by both<SelectList>and<TagGroup>so future fixes only happen once.New props on
<TagGroup>:error,required,disabled,validate,validationBehavior,form. Public API normalised to Marigold's convention —isInvalid/isRequired/isDisabledare removed andonSelectionChangeis renamed toonChange.selectionModenow defaults to'multiple'.disablednow propagates to each<Tag>via context so interaction is blocked alongside the form-disabled state. -
9a407ef: feat([DST-753]):
SectionMessageexposes anannounceprop and uses react-aria'sLiveAnnouncerto notify assistive technology.What changed (DST-753):
<SectionMessage>accepts a newannounce?: booleanprop. When set, the message text is sent to a shared, always-mounted live region maintained by@react-aria/live-announcer. Priority ispoliteforinfo/success/warningandassertiveforerror.announcedefaults totrueforvariant="error"andfalsefor all other variants, preserving today's behavior for the common error case while letting consumers opt in for confirmations and informational updates.- The wrapper element no longer carries
role="alert"for the error variant. Announcements are now delegated to the singleton live announcer instead. - Re-announcing the same message uses the React
keypattern: pass a changingkeyto force a remount.
Why:
The previous implementation only announced the
errorvariant, and it did so by addingrole="alert"to a conditionally rendered element. Per the WAI-ARIA spec and MDN guidance,role="alert"should be on an element that already exists in the DOM before its content is injected, and it should not contain interactive elements. Marigold'sSectionMessageviolated both constraints (the alert was mounted together with its content, and it can contain close buttons and action links), making announcements unreliable on some screen reader / browser combinations.The new implementation uses
@react-aria/live-announcer, which maintains persistent polite and assertive live regions at the document root. This is the same mechanism used across React Spectrum and avoids the conditional-rendering and interactive-content pitfalls of inlinerole="alert". It also unifies the API: opt in to announcement for any variant with a single prop.Additional cleanup bundled with this release (beyond DST-753):
- Close button now matches the rest of the system. The previous theme defined a
closeslot forSectionMessagewith bespoke overrides (size-8,[&_svg]:size-6,text-foreground, negative margins) that produced a visibly larger close button than every other close button in the design system. The component now renders the shared<CloseButton>with no overrides, so it gets the same 16px icon, focus ring, hover-opacity, and rounded-full styling as Dialog, Drawer, etc. Thecloseslot has been removed from theSectionMessagetheme type. - Component cleanup. Dropped a stale
useButton(props, buttonRef)call that was applying div-level props to a button, the unusedbuttonRef, and the{...buttonProps}spread on<CloseButton>. TheButtoninsideCloseButtonalready provides all keyboard/press semantics. - Theme variant order normalized.
info(the default) is now listed first across thecontainer,content, andiconslots intheme-rui, matching the variant table in the docs and the existingdefaultVariantssetting.
Docs:
- New anatomy SVG matching the Card / Sidebar / SelectList style; title and close button marked as optional, with content rules (no period in title, don't repeat title in body).
- Two realistic announcement demos: a bulk-archive form (polite, with RAC
validateand thekeyre-announce pattern) and a server-availability save error (assertive). - Added focus-management guidance for dynamic appearance and post-dismiss.
- Added form-summary placement rule pairing
<SectionMessage>with field-level validation. - Added action constraints (one primary action, verb+noun labels, descriptive link text).
- Added two-line body rule with a link-out overflow pattern for longer content.
- Folded the previous Position subsection into Usage; removed redundant Do/Don't tiles; renamed subsections to Dismissal / Actions / Announcements.
- Drive-by: typo fix in the
feedback-messagespattern doc.
Migration:
- Code relying on
getByRole('alert')or[role="alert"]selectors to find renderedSectionMessageerror nodes needs to be updated. The message text itself is still rendered as before; only the wrapper role is gone. - Consumers who previously wrapped a dynamic
<SectionMessage>in their own<div role="status">or<div aria-live="polite">can replace that wrapper with<SectionMessage announce>. - Custom themes that defined a
SectionMessage.closeslot will now see a type error. Remove the slot. Close button styling now flows entirely from theCloseButtontheme. - The SectionMessage's close button is visually smaller after this release (matches every other close button in Marigold). If you previously relied on the larger size, that was an inconsistency, not a feature.
Patch Changes
-
2a34a64: refactor(DST-1367): Panel adopts the slot-configuration pattern
Panel.Headeris now a single<Provider>that configuresHeadingContext,TextContext,ActionButtonContext, andActionGroupContextfor everything nested inside it. Consumers drop slot-aware primitives directly into the header —<Title>,<Description>, and any of<ActionButton>,<ActionGroup>,<ActionMenu>,<LinkButton>— and the Panel injects level, ids, ref wiring, grid-area positioning, and the action cascade via context.The compound sub-components that paired with
Panel.Headerare removed because slot-aware role primitives subsume their responsibilities:<Panel.Title>→ use<Title>.<Panel.Description>→ use<Description>.<Panel.HeaderActions>→ drop the wrapper; the action primitives themselves (<ActionButton>,<ActionGroup>,<ActionMenu>,<LinkButton>) land in the actions grid cell via the context className thatPanel.Headerpublishes.
Multiple actions belong inside an
<ActionGroup>— the cluster claims one cell and renders as a toolbar. A raw<Button>insidePanel.Headeris intentionally not slot-aware: it stays as a footgun so the action primitives are the obvious choice for header chrome.Panel.CollapsibleHeaderadopts the same shape:<Panel.CollapsibleTitle>/<Panel.CollapsibleDescription>are removed in favour of plain<Title>and<Description>inside the header.Panel.CollapsibleHeaderpublishes slot-keyedHeadingContextandTextContextinside its disclosure trigger so the primitives render as spans (matching the heading-inside-button constraint), while the structural<hN>semantics come fromPanel.CollapsibleHeaderitself.<Description>now honourselementTypefrom its surroundingTextContextslot config.Panel.HeaderdeliverselementType: 'p'so the description renders as a paragraph;Panel.CollapsibleHeaderdeliverselementType: 'span'so it nests cleanly inside the disclosure trigger button. Elsewhere,<Description>continues to render as RAC's default<span>.<Headline>now defaults to opting out of any surroundingHeadingContextslot config (slotdefaults to the no-slot opt-out instead ofundefined). This avoids "A slot prop is required" runtime crashes when a bare<Headline>is rendered inside a container that publishes a slot-keyedHeadingContext— such as a<Panel>that publishes itstitleslot at the root. An explicitslotprop on<Headline>still overrides the default. -
61f917f: fix(DST-1447): restore focus to the Tray trigger on close under
prefers-reduced-motion: reduce.TrayModalnow skipsAnimatePresencein that branch and renders a plain RACModalOverlay, soFocusScope.restoreFocusruns synchronously and the trigger reliably regains focus. Users without the preference still hit the same race — a full fix is tracked as follow-up. -
Updated dependencies [9a407ef]
- @marigold/system@18.0.0-beta.2
18.0.0-beta.1
Major Changes
-
9f4dc97: refa([DST-1324]): Breaking change: Rename Inset's
space/spaceX/spaceYprops top/px/pyThe padding props on
Insetare renamed to align withPanel's existing API, so that across the design systemspacealways means gap between children andp/px/pyalways mean inner padding. Previously,spacecarried two different meanings depending on the component, which was a source of confusion.Migration:
Before After <Inset space="…" /><Inset p="…" /><Inset spaceX="…" spaceY="…" /><Inset px="…" py="…" />The discriminated union shape is unchanged:
pis mutually exclusive withpx/py. Token vocabularies are unchanged (InsetSpacingTokensforp,PaddingSpacingTokensforpx/py).
Minor Changes
-
727163c: feat([DST-1134]): add
<RangeCalendar>component (alpha)Adds a new
<RangeCalendar>for selecting a contiguous or non-contiguous date range, built on react-aria's<RangeCalendar>with Marigold conventions (disabled,readOnly,error,dateUnavailable,allowsNonContiguousRanges). Supports up to three side-by-side months viavisibleDuration, stacking vertically below thesmbreakpoint; the same responsive stacking now applies to multi-month<Calendar>for parity.descriptionanderrorMessageroute through<FieldBase>so the help/error UI matches the rest of the form-component family (TriangleAlert icon + HelpText container). Ships as an alpha component with a stub docs page under the form section. -
cc568e3: feat([DST-1429]):
Cardnow exposes aPanel-aligned padding API.What changed:
Cardacceptsp/px/pyprops (mutually exclusivepvspx+py), resolving to CSS custom properties--card-pxand--card-pyon the container. Defaults tosquare-regular.- A new
spaceprop controls the gap between slots, resolving to--card-gap. Defaults toregular. Card.BodyandCard.Footeraccept an opt-inbleedprop to skip horizontal padding for tables, media, or full-width action bars.- Internally,
Cardswitched from CSS grid withgrid-template-areasto a flex column withgap-y. JSX order now determines visual order — placeCard.Previewfirst when used. - Slot theme styles (
header,body,footer) no longer hardcodepx-4/py-*; padding lives in the component layer and is driven by the CSS variables above. Card.Previewautomatically escapes the container's vertical padding when used as the first or last child via negative margins.
Why:
Cards previously had no consumer-controllable padding API and no default padding on the container — content rendered as direct children of
<Card>was visually broken. The new API mirrorsPanel's padding model so the two surfaces behave consistently.Migration:
- Wrap bare children in
<Card.Body>. Bare children inside<Card>are no longer rendered with horizontal padding; this matchesPanel's composition contract. - If you used
Card.Previewfor media at the top, keep doing so — it stays edge-to-edge. - No changes needed for the canonical composition (
Preview+Header+Body+Footer).
-
4742e8e: feat([DST-901]): styleProps for
width,maxWidth,height,space,spaceX,spaceY,pr,pl,pt,pbnow accept both numeric scale values (4) and their string equivalents ("4"). The public types are now declarative (Scale | Fraction | WidthKeyword, etc.) instead of being derived from the internal class-name maps.Components that previously resolved
width,maxWidth, andheightvia class-name lookup (Form, Calendar, legacy Table column header / select-all cell, Slider, Scrollable, Switch, Grid) now resolve them through CSS custom properties (createWidthVar/createHeightVar) targeting--width,--max-width,--height. Those variables — along with--container-widthand--field-widthalready used byFieldBase— are registered as non-inheriting (@property … inherits: false) in the RUI theme so they cannot leak into descendants.createWidthVargained support for the previously missing keywords (svh,lvh,dvh,px,container), and a newcreateHeightVarhelper was added. Both share a common factory and a base keyword set, so they remain trivially in sync.The runtime class-name maps
width,maxWidth,height,gapSpace,paddingSpace,paddingSpaceX,paddingSpaceY,paddingRight,paddingLeft,paddingTop,paddingBottomare no longer exported from@marigold/system. These were internal utilities consumed only by@marigold/components. Use the prop types (WidthProp,HeightProp, …) and the CSS-var helpers (createWidthVar,createHeightVar,createSpacingVar) instead. The corresponding TypeScript prop types are unchanged. -
496a9f2: feat(SelectList): standardized API, item layout, and visual distinction from ListBox (DST-1076)
<SelectList>has been refined into a first-class form field for picking one or many items from a visible list of rich two-line rows. This release contains breaking renames and a tightened type surface.Breaking changes
SelectList.Item→SelectList.Option. The option semantic matchesSelect.Optionand the HTML<option>mental model. Update any<SelectList.Item>usage to<SelectList.Option>.SelectList.Actionhas been removed. Drop your<ActionMenu>or<IconButton>directly inside<SelectList.Option>— the component positions, sizes, and styles the nested control automatically viaButtonContext. Limit: one action per option (multi-button groups will arrive with a futureActionGroup).- Leading-image slot has been removed. Compose images inside
<Text slot="label">(or anywhere in children) as you see fit. selectionMode="none"is no longer accepted.SelectListis a form field; the default is now"single".onChangeis strictly typed perselectionMode:(key: Key | null) => voidfor single,(keys: Key[]) => voidfor multiple. The shape matchesSelect<T, M>. PassingsetStatedirectly may require adapting the callback.
Other changes
- Selection indicator — single-select rows render a visible radio circle; multi-select renders a checkbox.
- Label & description slots — use
<Text slot="label">and<Text slot="description">inside<SelectList.Option>. The row skeleton isselection · label + description · action (optional). - Dev-mode warning when
textValueis missing on an option whose children aren't a plain string. - Own theme entry —
SelectListships a dedicated theme component. The theme exposes first-classlabel,description, andactionentries; slot styling no longer uses descendant selectors. Consumers with custom themes must add or update aSelectListentry.
Documentation
The SelectList docs page is rewritten around the new API. Adds an anatomy diagram, a decision table for choosing between
<SelectList>and lighter controls (<Radio.Group>,<Checkbox.Group>,<Select>,<Combobox>,<TagField>), and dedicated sections for multi-selection, per-row actions (decision-help and configuration patterns), horizontal orientation, and empty state. Replaces selected prose with Do/Don't tiles. Tightens the accessibility section to what's specific to SelectList (keyboard model, label requirement,textValuefor rich rows).Migration
- <SelectList selectionMode="none"> - <SelectList.Item id="free"> - <SelectList.Action> - <IconButton aria-label="Info"><Info /></IconButton> - </SelectList.Action> - Free - </SelectList.Item> - </SelectList> + <SelectList selectionMode="single"> + <SelectList.Option id="free"> + Free + <IconButton aria-label="Info"><Info /></IconButton> + </SelectList.Option> + </SelectList> -
8b754f0: feat(DST-1404): add
renderValueprop to<Select>for custom trigger rendering. When provided, the callback receives the selected items and replaces the default trigger render. Useful when the trigger should look different from the option (e.g. avatar plus name in the trigger, avatar plus name plus role in the dropdown). The placeholder still renders when nothing is selected. -
2ff7bda: feat(DST-1098): persistent idle sort indicator on sortable columns
Table.ColumnwithallowsSortingnow shows a Lucidearrow-down-upicon when the column is sortable but not currently the active sort column. The active ascending/descending icons (SortAscending/SortDescending) are unchanged.
Patch Changes
-
566c468: fix([DST-1295]): replace
gapbetweenCheckboxGroupandRadioGroupitems with per-item padding so the full space between items is clickable. Vertical items now meet the 24px target-size minimum; horizontal spacing keeps visual parity. StandaloneCheckboxis unaffected.Also align the label and icon: switched the inner row layout from
items-centertoitems-startso the icon stays on the first line when the label wraps.Radiolabels now useleading-4to matchCheckbox, andRadio's icon-to-label gap moves from an inlinegap-[1ch]to the theme-drivengap-x-2for parity withCheckbox. -
3c6a943: fix([DST-1410]): restore RangeCalendar build by using
createWidthVarfor the width prop. The component still imported thewidthruntime map from@marigold/system, which DST-901 removed when it migrated dimension props to CSS variables. This brokemainfor everyone — typecheck, unit tests, and Storybook tests all failed on every open PR. Apply the same migration pattern Calendar already uses:w-(--width)className plusstyle={createWidthVar('width', width)}. -
496a9f2: fix(FieldBase): forward
isInvalid,isRequired, andisDisabledto RAC components passed viaasWhen
FieldBaserenders through a React Aria Components element (e.g.as={RACComponent}), validation props are now forwarded so the underlying RAC element receives them. Plain DOM elements continue to skip these props to avoid unknown attribute warnings. -
5744bbf: feat([DST-1396]): mobile-optimized pagination layout
Paginationnow hides the numbered page buttons on small viewports (max-sm) and spreads the previous/next navigation buttons across the full width usingjustify-between. This produces a cleaner, touch-friendly pagination on mobile while preserving the full layout on larger screens. -
2d9d6fd: feat(DST-1366): introduce slot-configurable primitives
Adds three text-bearing role primitives —
Title,Description,TextValue— and three action primitives —ActionButton,ActionGroup,ActionMenu— that participate in slot-keyed context. Text/heading slots use React Aria'sHeadingContext/TextContextdirectly; action slots use Marigold-owned contexts (ActionButtonContext,ActionGroupContext,ActionMenuContext) consumed viauseContextProps.Titlewraps RAC's<Heading>withslot="title"andlevel={2}as defaults, both overridable byHeadingContext. Thelevelprecedence is default ← context ← local, so a container can publish{ level: 4 }and drive a stretch of nested<Title>s to<h4>without each call site setting it.DescriptionandTextValueforward straight to RAC's<Text>withslot="description"andslot="label"defaults respectively, letting<Text>consumeTextContexton its own. None of the three carry typography props. Styling cascades from the surrounding container (or selection item) viaHeadingContext/TextContext. Consumers drop these into containers without anyslotwiring. The container provides level, layout (e.g. a grid area), size, variant, color, and any other styling through a singleProvider.ActionGroupis its own top-level component (own folder, own docs page, own Storybook entry) — there is noActionButton.Groupcompound. It cascadessize,variant, anddisabledto nested<ActionButton>,<LinkButton>, and<ActionMenu>triggers viaActionGroupContext, with explicit per-prop precedence:size: group wins (visual uniformity within a cluster).variant: local wins (so a single destructive action can sit inside an otherwise uniform group).disabled: local wins; the group provides the default. Writingdisabled={false}on a child re-enables it inside an otherwise-disabled group.
ActionMenuis rebuilt to compose its ownMenuTrigger+<ActionButton>+Popover/Tray+ RACMenurather than delegating to Marigold'sMenu. The trigger uses<ActionButton>so an outerActionButtonContextcascades to it. Marigold'sMenuis untouched.LinkButtonis now slot-aware: it picks upActionButtonContextandActionGroupContextso a navigating action can sit alongside<ActionButton>inside an<ActionGroup>and inherit the same cascade. Adestructive-ghostvariant is added to match<ActionButton>. Context is consumed read-only (viauseSlottedContext) to sidestep the anchor/button ref-type mismatch thatuseContextPropswould have created. The read-only consumption now also absorbsclassNamefromActionButtonContext(mirroring<ActionButton>'suseContextProps-driven className merge) so positional classes published by a parent container — e.g. a grid-area class injected viaActionButtonContext— reach the rendered anchor. This lets<LinkButton>participate in container-driven layouts the same way<ActionButton>does.The container-driven layout pattern this enables comes with a corresponding convention: positional
classNameflows through slot contexts and is absorbed at the first layout boundary.<ActionGroup>enforces the convention at its own boundary by scrubbingActionButtonContextfor its descendants — it republishes an empty value so nested<ActionButton>s and<LinkButton>s do not individually re-claim a positional class that was meant for the group as a whole. Cascading props (size,variant,disabled) still reach the children viaActionGroupContext, which they read independently. This convention scales to every future container that adopts the slot-configuration pattern.<ActionBar>'s legacy top-levelActionButtonslot is internalized and re-exposed asActionBar.Button. Existing consumers that already use<ActionBar.Button>are unaffected.Typography prep:
HeadlineexportsHeadlineSize,TextexportsTextSizeandTextVariant. The aliases aren't yet consumed by other primitives, but exposing them now lets a future typography-token PR replace runtime classes without rewriting consumer-facing prop types. -
Updated dependencies [727163c]
-
Updated dependencies [4742e8e]
-
Updated dependencies [2d9d6fd]
- @marigold/system@18.0.0-beta.1
18.0.0-beta.0
Major Changes
-
326f707: feat(AppLayout): switch to page-level scroll
AppLayoutno longer owns an interior scroll container. The document (<html>/<body>) scrolls the whole page; the sidebar sticks viaposition: stickyand the top header stays pinned throughTopNavigation's own sticky positioning.Why page-level scroll
- Mobile URL bar collapses on scroll. With interior scroll, Safari and Chrome mobile keep the URL bar expanded forever, wasting ~8% of the screen. Only document scroll lets the browser hide it.
- Pull-to-refresh works. Interior scroll disables it.
- Browser scroll restoration on back/forward only works reliably for the document, not interior containers. Interior scroll produces subtle "lost scroll position" bugs.
Cmd+Ffind-in-page scrolls the document, not an interior container, so matches outside the viewport scroll into view correctly.- Anchor links (
#section), iOS status-bar tap (scroll-to-top) and native keyboard nav (PgUp/PgDn/Space/Home/End) all behave predictably. IntersectionObserverwith default root, scroll-snap, sticky elements,scroll-margin-top— all simpler when there is one scroll container.
Breaking changes
- Code reading
mainRef.current.scrollTop(or similar) will no longer see user scroll. Readwindow.scrollY/document.documentElement.scrollTopinstead. - Styles assuming a fixed-height main region (
height: 100%on direct children of<AppLayout.Main>, for example) will no longer be bounded by the viewport. Usemin-h-dvhor remove the constraint.
Known trade-offs
- Pure app-shell look via
position: stickycan flicker on iOS Safari momentum scroll. Cosmetic, usually acceptable. - Sticky elements may show a brief re-paint when overlays close. Not a correctness bug.
-
f629319: refactor([DST-1283]): Breaking Change — Remove
<Multiselect>(and thereact-selectdependency) from@marigold/components.Use
<TagField>instead. -
cddcfd3: fix(DST-1353): remove
width="fit"from Select, ComboBox, and AutocompleteBREAKING CHANGE: The
fitvalue for thewidthprop is no longer accepted onSelect,ComboBox, andAutocomplete. These components use a popover with virtualized rendering, where the react-aria Virtualizer controls item sizing and ignores CSS layout. This caused dropdown content to be clipped whenwidth="fit"was used. Affected usages should switch to an explicit width value instead. -
00d93c8: feat(DST-1246): update Switch component layout and sizing to align with Checkbox and Radio
The Switch component previously rendered its label on the left and toggle on the right, which was inconsistent with Checkbox and Radio where the control sits on the left. When used together in forms, this created a visually misaligned layout.
Layout: Toggle now renders before the label (control on the left, label on the right), matching Checkbox and Radio. This ensures consistent visual alignment when Switch is used alongside other boolean controls in form layouts.
Sizing: Reduced the default track size from 24x40px to 16x28px and thumb from 20px to 12px. This brings the Switch closer in visual weight to Checkbox/Radio (16px), making it fit better in the flow of forms.
Settings variant: A new
variant="settings"mirrors the default layout — label and description on the left, toggle on the far right. This is the common pattern used on settings/preferences pages. The variant is propagated toBooleanFieldso that grid columns and description placement adjust accordingly.Description support: Switch now accepts a
descriptionprop (help text rendered below the control), matching Checkbox's existing support. The description text aligns with the label text using CSS grid + subgrid, automatically adapting to any control size without hardcoded padding. Properly wired witharia-describedbyfor accessibility.Form support: The
nameprop passes through to the underlying input for HTML form submission.Shared BooleanField: Extracted a reusable
BooleanFieldwrapper used by both Checkbox and Switch for consistent description rendering andaria-describedbywiring. Uses CSS grid with subgrid to align description text with label text across both components.Breaking changes
Restoring the old Switch behavior
The default Switch layout has changed: the toggle is now on the left and the label on the right (previously reversed). If you need the old layout (label left, toggle right), use the new
variant="settings":- <Switch label="Wi-Fi" /> + <Switch label="Wi-Fi" variant="settings" />The
size="large"prop has been removed. The default size is now smaller (16x28px track). There is no built-in way to get the old large dimensions (24x40px track) — if needed, create a custom size variant in your theme'sSwitch.styles.ts.Custom theme migration
This release introduces a new required theme component
BooleanFieldand changes the layout model of theCheckboxandSwitchcontainer slots from flexbox to CSS grid. Custom themes must be updated or Checkbox/Switch will throw a runtime error.1. Add
BooleanFieldto your theme (required)BooleanFieldis a new multi-slot theme component used internally by bothCheckboxandSwitchto render descriptions. If your theme does not include it, anyCheckboxorSwitchwith adescriptionprop will throw:Error: Component "BooleanField" is missing styles in the current theme.Add the following to your theme's component styles:
import { cva } from '@marigold/system'; export const BooleanField = { container: cva({ base: 'grid gap-x-2', variants: { variant: { default: 'grid-cols-[auto_1fr]', settings: 'grid-cols-[1fr_auto]', }, }, defaultVariants: { variant: 'default' }, }), description: cva({ base: 'mt-0.5', variants: { variant: { default: 'col-start-2', settings: 'col-start-1', }, }, defaultVariants: { variant: 'default' }, }), };container: Defines the 2-column grid layout wrapping the control and its description. Thedefaultvariant usesgrid-cols-[auto_1fr](control left, label right). Thesettingsvariant usesgrid-cols-[1fr_auto](label left, control right).description: Styles the description text wrapper. Placed under the label column viacol-start-2(default) orcol-start-1(settings).mt-0.5adds vertical spacing between the label row and description.
Then export it from your theme's component index file:
export { BooleanField } from './BooleanField.styles';2. Update
Checkboxcontainer slot (required if customized)The
Checkboxcontainer slot changed from flexbox to CSS grid with conditional subgrid support:Before:
container: cva({ base: 'cursor-pointer read-only:cursor-default gap-2' }),After:
container: cva({ base: [ 'grid grid-cols-[auto_1fr] gap-x-2 items-center', 'cursor-pointer read-only:cursor-default', 'group-data-[booleanfield]/booleanfield:grid-cols-subgrid group-data-[booleanfield]/booleanfield:col-span-full', ], }),Key changes:
gap-2changed togap-x-2(column gap only, since row gap is now handled byBooleanField.description)grid grid-cols-[auto_1fr] items-centerreplaces theflex items-centerthat was previously hardcoded in the componentgroup-data-[booleanfield]/booleanfield:grid-cols-subgridandgroup-data-[booleanfield]/booleanfield:col-span-fullenable subgrid when inside aBooleanFieldwrapper, so the description aligns with the label
3. Update
Switchcontainer slot (required if customized)The
Switchcontainer slot also changed from minimal styles to CSS grid with subgrid:Before:
container: cva({ base: 'disabled:cursor-not-allowed disabled:text-disabled-foreground', }),After:
container: cva({ base: [ 'grid gap-x-2 items-center', 'disabled:cursor-not-allowed disabled:text-disabled-foreground', 'group-data-booleanfield/booleanfield:grid-cols-subgrid group-data-booleanfield/booleanfield:col-span-full', ], variants: { variant: { default: 'grid-cols-[auto_1fr]', settings: 'grid-cols-[1fr_auto]', }, }, defaultVariants: { variant: 'default' }, }),Key changes:
- Added
grid gap-x-2 items-center(replacesflex items-center gap-2that was previously hardcoded in the component) - Grid columns moved to
variantto support both default and settings layouts - Added subgrid support for BooleanField integration
-
724f0ce: refa([DST-1162]): Breaking changes: The
Cardcomponent has been refactored into a compound component pattern.What changed:
- The previous prop-based API (
padding,space, etc.) has been removed. - Content must now be composed using explicit sub-components:
Card.Header,Card.Body,Card.Footer, andCard.Preview. - A
CardContextis now required — sub-components will throw an error if used outside of a<Card>.
Migration:
// Before <Card> <SomeContent /> </Card> // After <Card> <Card.Header>Title</Card.Header> <Card.Body><SomeContent /></Card.Body> <Card.Footer>Actions</Card.Footer> </Card> - The previous prop-based API (
-
62cca29: refa([DST-1281]): Breaking change:
<Tooltip>no longer acceptsopen. Controlled visibility is only supported on<Tooltip.Trigger>(open/onOpenChange). Removes the internal React context that previously forwardedopenfrom<Tooltip>to the trigger.
Minor Changes
-
6587493: refa([DST-1298]): Refactor Divider component: API, styling, and docs
We fixed the vertical orientation of the divider, which previously didn't work. Added new Divider stories and updated the Divider docs.
-
93f9ef1: feat(DST-1257): add universal
nonespacing token- Introduce
NoSpacingToken = 'none'shared across all spacing token families - Add
'none'toSpacingTokens,PaddingSpacingTokens, andInsetSpacingTokens - Add
--spacing-none: --spacing(0)CSS custom property to the theme
'none'now works wherever a spacing token is accepted:Stack/Inlinegap (space="none"),Insetaxis padding (spaceX="none"/spaceY="none"), andInsetrecipes (space="none") — useful for wrappers that should render without adding any spacing (e.g. an edge-to-edgeTableinside a containing component). - Introduce
-
8326bf7: feat(DST-1326): introduce
Panel.CollapsibleHeader,Panel.CollapsibleTitle, andPanel.CollapsibleDescription. The collapsible mirrorsPanel.Header— a header wrapper with a title plus an optional description — and the whole visual surface is a single click target: title and description render as spans inside the trigger<button>, with the accessible name wired viaaria-labelledbyand the description viaaria-describedby. The chevron icon uses a reusableMorphCaretthat animates via SVG path morphing (honoursprefers-reduced-motion). -
e33a1e7: feat(DST-1322): add
currentprop toSidebar.Navfor automatic active item detectionSidebar.Navnow accepts acurrentprop that resolves the active leaf automatically — pass the current pathname (string) for smart segment-aware matching, or a predicate(href, key) => booleanfor full control. Removes the per-itemactive={pathname === '/...'}boilerplate. The per-itemactiveprop onSidebar.Itemstill works as a local override.
Patch Changes
-
b7c132d: fix(DST-1354): restore collapsing
Table.EditableCelledit triggerThe overlay/ring affordance introduced in #5250 (DST-1275) did not read as editable in user testing: sighted users did not associate the hover ring with inline editing, and there was no discoverable trigger for keyboard or touch. This change reverts that approach and restores the explicit pencil edit button.
The trigger collapses to zero layout space at rest (
w-0 overflow-hidden) and expands on row hover or keyboard focus, so static layout remains clean while the affordance is discoverable the moment the user interacts with the row. When expanded, the wrapper switches tooverflow-visibleso the button's focus outline is not clipped. The cell itself stays clickable as a touch target. Enabled editable cells always truncate their content to stay aligned with column headers and match the single-line editing controls; disabled cells behave like a regularTable.Cell. -
f16b887: fix(DST-1352): use correct outline for focus + error state in compound fields
-
bfea9df:
Panel.Titlemay now be used as a direct child ofPanelwhen the Panel has only a title (no description, no actions) —Panel.Headeris the layout wrapper for title + description + actions, but a title-only Panel doesn't need it. Accessibility (aria-labelledby) and horizontal panel padding still resolve correctly.Panel.DescriptionandPanel.HeaderActionscontinue to require aPanel.Headerwrapper. No change to existing usages. -
8326bf7: test(DST-1329): add comprehensive unit and play-test coverage for
Paneland its sub-components (Header, Title, Description, HeaderActions, Content, Footer, Collapsible, CollapsibleHeader, CollapsibleTitle, CollapsibleDescription, CollapsibleContent, Context). No runtime changes. -
1cac70d: docs: improve
AutoTypeTableprop renderingCentralizes the display of design-system aliases in the component docs' prop tables. Props whose types reference aliases from
@marigold/systemor@marigold/types(e.g.SpacingTokens,Scale,WidthProp,NonZeroPercentage) now render with a meaningful summary in the main cell and the full list of resolvable literal values on row expand — instead of a wall of literals in the cell and a redundant alias name on expand.Before:
- Cell:
SpacingTokens<Tokens>(a fabricated generic, inconsistent across components) - Expand:
SpacingTokens | Scale | undefined(same alias names, no new info)
After:
- Cell:
SpacingTokens | Scale(accurate, derived from the real type) - Expand:
"96" | "80" | ... | "tight" | "related" | 0(every concrete value)
Under the hood this replaces 27 per-prop
@remarks \TypeName`JSDoc overrides with a single fumadocs-typescript transform in the docs site, so future components pick up the same behavior automatically. A@remarks` tag on a prop still wins as an escape hatch.Multiselect.widthandComboBox.widthnow useWidthProp['width']directly instead ofFieldBaseProps<'label'>['width']— structurally identical, no runtime change. - Cell:
-
c2a1c72: fix: apply
alignXfromTable.Columnto first column cellsTableCellContentused a truthy check oncolumnIndex, causing it to skip thealignXlookup whencolumnIndexwas0(first column). Replaced with a nullish check so all columns correctly inherit their alignment. -
de34b15: chore(deps): update
react-aria-components,@react-aria/*,@react-stately/*,@react-types/*, and@internationalized/*packages to their latest versions. -
04111ca: fix(DST-1355): widen
variantandsizeprop types onLoaderandProgressCircleto accept arbitrary strings via| (string & {}). Matches the pattern already used byButton,Panel, and other components, and lets consumer themes register their own variant/size tokens without TypeScript errors while preserving IDE autocomplete for the built-in RUI values. -
Updated dependencies [adb8a18]
-
Updated dependencies [f629319]
-
Updated dependencies [93f9ef1]
-
Updated dependencies [8326bf7]
-
Updated dependencies [20a42b0]
-
Updated dependencies [724f0ce]
-
Updated dependencies [de34b15]
- @marigold/system@18.0.0-beta.0
17.9.1 (Released on Jul 10, 2026)
Patch Changes
-
76fca24: fix(DSTSUP-267):
FileFieldappends files across selections whenmultipleis setPreviously, when
multiplewas set, selecting or dropping files in a second interaction replaced the existing selection instead of adding to it — only files chosen in a single action were kept.FileFieldnow accumulates files across separate selections and drops, de-duplicating identical files (matched by name, size, and last-modified time). Behavior withmultipleunset is unchanged: the latest single file still wins.- @marigold/system@17.9.1
17.9.0 (Released on Jul 8, 2026)
Minor Changes
-
ed2d9ae: feat(DST-1551): add
DateRangePickercomponentNew
<DateRangePicker>lets users enter or select a start–end date range through a single field, mirroring<DatePicker>'s API and behaviour. Two date inputs (start/end) sit in one field group with a calendar button that opens a<RangeCalendar>in a popover on desktop and a tray on small screens. Supports per-input paste (ISO/EU/US formats),granularity(inline time segments),visibleDuration(up to three months), and the usual Marigold field props (disabled,readOnly,required,error,errorMessage,description,minValue,maxValue,dateUnavailable,width,variant,size). Adds a matchingDateRangePickertheme entry totheme-rui.
Patch Changes
-
e686474: chore(DST-1503): Migrate
Checkbox,Switch, andRadiooff the deprecated react-aria-components single-element exports (Checkbox/Switch/Radio) to the*Field+*Buttoncomposition introduced inreact-aria-components@1.18.0. This removes thets(6385)deprecation warnings with no change to the public API, behavior, or visual output. -
2fc7b96: refactor(DST-1534): build the
Calendaryear dropdown on react-aria'sCalendarYearPickerThe year dropdown now consumes react-aria's
CalendarYearPickerrender-prop (mirroring how the month dropdown already usesCalendarMonthPicker), replacing the hand-rolled year list and its localizedaria-labelworkaround. This was unblocked by react-aria's June 2026 fix that makesmaxValueinclusive, so the boundary year is reachable. Unbounded calendars keep the ±20-year window and bounded ranges stay fully reachable at both ends. When only one bound is set, the open side now widens to keep that bound reachable instead of staying at a fixed ±20 years. -
508ec2c: fix(DST-1553): drop the dead
'small' | 'medium' | 'large'literals fromTabssizeThe
sizeandvariantprops onTabsresolved to nothing after the RUI theme size variants were removed (2025-03-04).sizenow accepts a plainstring(matchingLabelandHelpText) instead of advertising specific values that no theme backs. The props stay in place as theme hooks, so a consumer theme can define its ownsize/variantvariants without the misleading built-in union. -
4d44517: fix: make Select and Menu overlay appear above Drawer on small screens
On small screens,
SelectandMenurender their options in aTray(bottom sheet). TheTrayoverlay hadz-40in the theme while theDraweroverlay usesz-50, so the tray rendered behind an open drawer and was unreachable.Moved the
z-indexfrom the theme style file into theTrayModalcomponent implementation (matching the project's z-index architecture rule), and raised it toz-50. Both theDrawerandTrayportal todocument.body; at equal z-index, DOM order determines stacking. TheTrayis always mounted after theDrawer, so it correctly appears on top.- @marigold/system@17.9.0
17.8.0 (Released on Jun 18, 2026)
Minor Changes
-
bdda185: build(DST-1315): unbundle the build output for tree-shaking
@marigold/componentspreviously shipped its entire ESM build as a single concatenated barrel (index.mjsre-exporting 74+ components). Because every export lived in one module, bundlers could not statically prove which parts were unused, so importing a single leaf component (e.g.Stack) pulled in essentially the whole library. On rspack this meant ~57 kB (≈82% of the lib) for aStack + Text + Cardimport.The build now emits one file per source module (
unbundle: true, thepreserveModulesequivalent) while keeping the.barrel import fully backward compatible. Consumer bundlers (rspack, vite, esbuild) can now drop unused components: the sameStack + Text + Cardimport drops to ~0.8 kB, and a singleButtonimport drops from ~57 kB to ~1.7 kB.Why a build flag alone wasn't enough (source changes explained)
Flipping
unbundle: trueis necessary but not sufficient. The old single-barrel build concatenated every module into one file, which hid problems that only matter once each module stands on its own and a bundler starts deciding, per module, what it can safely drop.unbundleexposed those problems, so the following source changes were required to make tree-shaking actually work — without them the flag delivers little or no benefit:- Toast queue: removed a module-scope side effect.
ToastProviderexportedconst queue = new ToastQueue(...)at module top level. That constructor runs the moment the module is imported and touchesdocument(view-transition setup). The package declaressideEffects: false, which tells bundlers "importing any module here does nothing observable, so unused ones are safe to delete." A top-levelnewthat touchesdocumentdirectly contradicts that promise: it's a real side effect on import, it can break SSR, and it makes thesideEffects: falseclaim dishonest (risking either dropped-needed-code or kept-unneeded-code depending on the bundler). Fix: construct the queue lazily on first use viagetToastQueue(), keeping the singleton but making the module genuinely side-effect-free. (Tests, stories, andToastProviderwere updated to callgetToastQueue().) motion: switched off the non-shakeablemotionproxy.import { motion } from 'motion/react'pulls motion's entire feature set, and themotion.*proxy is by design not tree-shakeable — referencingmotion.divdrags in the whole renderer (~34 kB). In the old concatenated barrel this cost was paid once and amortized across the whole library, so it was easy to miss. Underunbundle, that cost attaches to each module that importsmotion(ActionBar,Tabs,Tray), so importing any one of them would re-pull motion's full bundle — defeating the point. Fix: use the lightweightmcomponents frommotion/react-m(tiny core, no features) and load thedomMaxfeature set through aLazyMotionboundary via a dynamicimport()of a local module (motionFeatures.ts), so bundlers split it into its own async chunk that only loads when an animated component actually renders. (The dynamic import targets a local file rather thanmotion/reactdirectly because importing the dep dynamically made vite's optimizer re-bundle mid-run and drop named exports during tests.)hooksbarrel: replacedexport *with explicit named re-exports.export * from './hooks'forces a bundler to pull in and consider the entire namespace of the re-exported module; explicit named re-exports let it trace precisely which symbols are reachable. Minor on its own, butexport *chains are a classic way to silently anchor unused code.react-select: externalized and declared as a dependency. Underunbundle, rolldown copies any non-externalized dependency into the output per-importing-module.react-select(~2 MB with@emotion) was being bundled into the dist without even being a declared dependency — invisible in the old barrel, but under unbundle it bloated every chunk that referenced it. Fix: mark itexternalintsdown.config.tsand add it todependenciesso it resolves transitively at install time. It's used only by the deprecatedMultiselect; drop both together in the next major.- Test/mock updates that follow the source changes.
Tray.test.tsx'svi.mock('motion/react')had to gainLazyMotion/domMax, plus a newvi.mock('motion/react-m')providingcreate, becauseTrayModalnow importscreatefrommotion/react-m.Toast.test.tsx/Toast.stories.tsxswitched from the removed module-levelqueueexport togetToastQueue(). - A
size-limitbudget gate (pnpm --filter @marigold/components size, run in CI) was added so these wins don't silently regress — e.g. someone re-introducing amotionproxy import or a module-scope side effect.
No public API changes: all imports from
@marigold/componentscontinue to work exactly as before. - Toast queue: removed a module-scope side effect.
Patch Changes
-
a609642: chore(DST-1512): import
I18nProviderfromreact-aria-componentsin remaining stories/tests/demosFollow-up to DST-1505. Migrates the remaining
I18nProviderimports off the@react-aria/i18nshell package to stay consistent with the RAC-first principle (import an API fromreact-aria-componentswhenever it re-exports it, so provider and consumers share oneI18nContext). Component stories/tests now import fromreact-aria-components/I18nProvider, and docs demos use the public@marigold/componentsexport. Thepackages/systemformatter tests intentionally stay on@react-aria/i18n, because the formatters under test read locale from that package directly andpackages/systemdoes not depend onreact-aria-components. -
60b6e03: fix(DST-1507): make
Table.EditableCellinline editing work after SSR hydrationIn a server-rendered app (for example Next.js), editable cells were inert after hydration: clicking a cell did not open its inline editor until an unrelated re-render (such as a window resize) happened to occur. React Aria builds the table collection in a separate render pass, and the editing state previously lived in that build pass, so the rendered cell content stayed bound to the server pass's closures and never reconnected to the live component after hydration. The editing state and overlay now live in an inner component rendered inside the
Cell, i.e. in the collection's content pass, so interaction reconnects on its own after hydration (the same structure React Spectrum's S2TableViewuses).- @marigold/system@17.8.0
17.7.0
Minor Changes
-
f4608c6: feat(DSTSUP-262): add
largesize to Dialog for wider layoutsDialog(andConfirmationDialog, which inherits the prop) now acceptssize="large", which sets the dialog width to1024px— matching the Tailwindlgbreakpoint. Use it for content that doesn't fit the previousmediumcap of768px, e.g. multi-month calendars or wider forms. The existingmin()width formula keeps the dialog viewport-safe on smaller screens. -
e0d5c7b: feat(DST-1500): default auto-dismiss timeout for toasts
addToastnow applies a defaulttimeoutbased onvariantwhen none is given:success,infoand the default variant auto-dismiss after 5000ms, whilewarninganderrorstay until dismissed. Pass an explicittimeoutto override it (values are clamped up to a 5000ms minimum), ortimeout: 0to keep a toast on screen until it is manually dismissed.Behavior change:
success,infoand default toasts that previously stayed until dismissed now auto-dismiss after 5 seconds. Passtimeout: 0to restore the old behavior.
Patch Changes
-
a6a1cb3: fix(DSTSUP-260):
Paginationfollows the controlledpageprop after mountPreviously the
pageprop only seeded internal state, so external updates (e.g. resetting to page 1 on a filter change) were ignored — the page indicator and the accessible<nav>label kept showing the stale page.Paginationnow usesuseControlledStatefrom react-stately: whenpageis set, it is the single source of truth andonChangereports requested page changes;defaultPageremains the uncontrolled initial value. As part of this,onChangeno longer fires when the active page is selected again, and the reset-to-page-1 behavior onpageSizechanges only triggers whenpageSizeactually changed. -
4242aa1: fix(DST-1505): re-export
I18nProviderfromreact-aria-componentsto prevent locale context splitsI18nProviderwas re-exported from@react-aria/i18n, which resolvesreact-ariavia a caret range whilereact-aria-componentspins it exactly. A consumer's lockfile can therefore install tworeact-ariacopies, splitting theI18nContext: the locale set through Marigold'sI18nProviderlanded in one copy's context while the react-aria-components rendering Marigold's UI read the other — silently falling back to the default locale for aria labels, date/number formatting, and RTL detection.Re-exporting
I18nProviderfromreact-aria-componentsmakes provider and consumers share one context by construction, regardless of how the lockfile resolvesreact-aria. Same failure class as the mobileSelecttray bug (DSTSUP-261). -
da46e58: fix(DSTSUP-261): make
Trayimmune to a split react-ariaHiddenContext(mobileSelecttray selecting nothing)On a touch/mobile viewport,
Select(and other components that fall back to aTray) could open an empty bottom sheet next to the real one: tapping an option selected nothing, the trigger kept showing the placeholder, and the page was leftinertuntil reload.Root cause was a dependency-resolution split, not component logic.
Trayguards the collection hidden pass withuseIsHidden()from@react-aria/collections(which depends onreact-ariavia a caret range), whilereact-aria-componentspinsreact-ariaexactly and itsSelect(acreateHideableComponent) sets theHiddenContextfrom its own copy. Both read that context fromreact-aria/private/collections/Hidden, so they only agree whenreact-ariaresolves to a single version. When a consumer's lockfile resolves the two edges to differentreact-ariagenerations, the guard reads a context the collection renderer never sets: it never fires, a duplicate (empty) tray modal leaks into the DOM, and the two modalsinerteach other so options are no longer hit-testable.Traynow verifies the hidden pass through the DOM as well: react-aria renders the hidden pass into a<template>element, whose content lives in a detachedDocumentFragment. A hidden probe element rendered alongside the modal is therefore never connected to the document during the hidden pass, and the tray skips mounting its modal whenever the probe is detached. This holds no matter how the consumer's lockfile resolvesreact-aria— including future react-aria releases that would re-arm the split (@react-aria/collections' caret range resolves to the newestreact-aria, whilereact-aria-componentsstays pinned) — so no dependency pins are needed.The durable upstream fix is for react-aria-components'
Modalto skip the collection hidden pass like itsPopoveralready does (which is why the desktopPopoverpath was never affected), or for it to exportuseIsHidden. Once either lands, the guard inTraycan be reduced again.- @marigold/system@17.7.0
17.6.0
Patch Changes
-
6f24f07: fix(DST-1447): restore focus to the Tray trigger on close under
prefers-reduced-motion: reduce.TrayModalnow skipsAnimatePresencein that branch and renders a plain RACModalOverlay, soFocusScope.restoreFocusruns synchronously and the trigger reliably regains focus. Users without the preference still hit the same race — a full fix is tracked as follow-up. -
9436cbc: fix(DST-1482): make the
widthprop size field components againSetting
widthon a field component (<Select>,<TextField>,<NumberField>, …) had no visible effect — the field sized to its content and consumers had to wrap it in an extra element.FieldBasesets the--field-widthCSS variable for its child field element to consume viaw-(--field-width), but the variable was registered with@property … { inherits: false }, so it never reached the child andwidthfell back toauto.--field-widthis now registered withinherits: true, restoring the intended parent→child handoff. The same-element layout variables (--width,--max-width,--height,--container-width) keep their non-inheriting leak protection.Also clarifies in the prop docs that numeric
widthvalues are spacing-scale tokens, not pixels:width={64}resolves tocalc(var(--spacing) * 64)≈ 16rem (256px). -
737c0a9: fix(DSTSUP-255): honor minValue/maxValue in Calendar and RangeCalendar year picker
The year picker used to always show 41 years (the focused year ±20) and just greyed out the ones outside the allowed range. With
minValueset, it opened on a list of disabled past years that you had to scroll past first. The year list is now derived fromminValue/maxValue(both bounds inclusive), so out-of-range years simply aren't shown, while the month picker still shows all twelve months with out-of-range ones disabled.When a picker opens, the selected option is now scrolled to the middle of the list instead of the bottom.
The open year/month picker now exposes a localized accessible name ("year"/"month") instead of an internal identifier, so screen readers announce it correctly.
This also fixes a follow-up problem with the RangeCalendar month/year dropdown (from DSTSUP-257): if you had started picking a range and then used the dropdown to jump to another month or year, that tap could wrongly finish the range. The dropdown now only changes the view, and picking an option still works on touch.
-
c619ffd: fix(DSTSUP-257): commit RangeCalendar month/year dropdown selection on touch
The dropdown overlay attached an unconditional
pointerupstopPropagationlistener to guard against react-aria's range-commit on overlay taps. On touch devices that also swallowed the event before react-aria'susePressclick-completion fallback could run, so tapping a month or year never firedonPressand the selection was silently lost (the dropdown stayed open and the grid did not switch). The guard now skipsrole="option"targets, letting option taps bubble through while still protecting taps on empty overlay area. Desktop mouse behaviour is unchanged. -
1c5c5fd: chore: single-source NonModal's overlay state to close a cross-copy react-aria seam
NonModalpreviously created its overlay state and types from the umbrellareact-statelywhile readingOverlayTriggerStateContextfromreact-aria-components. When a duplicatereact-aria/react-statelyis installed, those resolve to different copies and the overlay context silently splits — the same failure mode theCalendarfix addressed in this release.useOverlayTriggerState,OverlayTriggerState, andOverlayTriggerPropsnow come from the granular@react-stately/overlayspackage, matching the convention the rest of the package already follows. The umbrellareact-statelydirect dependency is dropped (its only remaining consumer, a Table story, now uses the localuseListDatare-export). -
a289d42: chore(deps): update react-aria
Bumps the react-aria packages and
tailwindcss-react-aria-components(theme-rui).Note: following the react-aria update,
Switchnow toggles with the Space key to match native checkbox behavior. It no longer toggles on Enter. -
Updated dependencies [9436cbc]
-
Updated dependencies [a289d42]
- @marigold/system@17.6.0
17.5.1
Patch Changes
- 3b29d91: fix(DSTSUP-252): make
Drawercontent scroll on small screens. On the mobile breakpoint theDrawerfalls back to aModal/Dialogoverlay, but theModalwrapper had no defined height. That madeDialog'sh-fullcollapse to the content's intrinsic height, so thegrid-template-rows: auto 1fr autolayout andDrawer.Content'soverflow-y-autonever engaged — long content extended the drawer past the viewport and clipped both the content tail and the action bar. The mobile wrapper now usesh-(--visual-viewport-height)(the React Aria-recommended approach, which tracks mobile browser chrome), so the dialog is constrained to the visible viewport andDrawer.Contentscrolls correctly while title and actions stay pinned. - Updated dependencies [c65d2a7]
- @marigold/system@17.5.1
17.5.0
Minor Changes
-
727163c: feat([DST-1134]): add
<RangeCalendar>component (alpha)Adds a new
<RangeCalendar>for selecting a contiguous or non-contiguous date range, built on react-aria's<RangeCalendar>with Marigold conventions (disabled,readOnly,error,dateUnavailable,allowsNonContiguousRanges). Supports up to three side-by-side months viavisibleDuration, stacking vertically below thesmbreakpoint; the same responsive stacking now applies to multi-month<Calendar>for parity.descriptionanderrorMessageroute through<FieldBase>so the help/error UI matches the rest of the form-component family (TriangleAlert icon + HelpText container). Ships as an alpha component with a stub docs page under the form section. -
4742e8e: feat([DST-901]): styleProps for
width,maxWidth,height,space,spaceX,spaceY,pr,pl,pt,pbnow accept both numeric scale values (4) and their string equivalents ("4"). The public types are now declarative (Scale | Fraction | WidthKeyword, etc.) instead of being derived from the internal class-name maps.Components that previously resolved
width,maxWidth, andheightvia class-name lookup (Form, Calendar, legacy Table column header / select-all cell, Slider, Scrollable, Switch, Grid) now resolve them through CSS custom properties (createWidthVar/createHeightVar) targeting--width,--max-width,--height. Those variables — along with--container-widthand--field-widthalready used byFieldBase— are registered as non-inheriting (@property … inherits: false) in the RUI theme so they cannot leak into descendants.createWidthVargained support for the previously missing keywords (svh,lvh,dvh,px,container), and a newcreateHeightVarhelper was added. Both share a common factory and a base keyword set, so they remain trivially in sync.The runtime class-name maps
width,maxWidth,height,gapSpace,paddingSpace,paddingSpaceX,paddingSpaceY,paddingRight,paddingLeft,paddingTop,paddingBottomare no longer exported from@marigold/system. These were internal utilities consumed only by@marigold/components. Use the prop types (WidthProp,HeightProp, …) and the CSS-var helpers (createWidthVar,createHeightVar,createSpacingVar) instead. The corresponding TypeScript prop types are unchanged. -
6587493: refa([DST-1298]): Refactor Divider component: API, styling, and docs
We fixed the vertical orientation of the divider, which previously didn't work. Added new Divider stories and updated the Divider docs.
-
e33a1e7: feat(DST-1322): add
currentprop toSidebar.Navfor automatic active item detectionSidebar.Navnow accepts acurrentprop that resolves the active leaf automatically — pass the current pathname (string) for smart segment-aware matching, or a predicate(href, key) => booleanfor full control. Removes the per-itemactive={pathname === '/...'}boilerplate. The per-itemactiveprop onSidebar.Itemstill works as a local override. -
2ff7bda: feat(DST-1098): persistent idle sort indicator on sortable columns
Table.ColumnwithallowsSortingnow shows a Lucidearrow-down-upicon when the column is sortable but not currently the active sort column. The active ascending/descending icons (SortAscending/SortDescending) are unchanged.
Patch Changes
-
3c6a943: fix([DST-1410]): restore RangeCalendar build by using
createWidthVarfor the width prop. The component still imported thewidthruntime map from@marigold/system, which DST-901 removed when it migrated dimension props to CSS variables. This brokemainfor everyone — typecheck, unit tests, and Storybook tests all failed on every open PR. Apply the same migration pattern Calendar already uses:w-(--width)className plusstyle={createWidthVar('width', width)}. -
b7c132d: fix(DST-1354): restore collapsing
Table.EditableCelledit triggerThe overlay/ring affordance introduced in #5250 (DST-1275) did not read as editable in user testing: sighted users did not associate the hover ring with inline editing, and there was no discoverable trigger for keyboard or touch. This change reverts that approach and restores the explicit pencil edit button.
The trigger collapses to zero layout space at rest (
w-0 overflow-hidden) and expands on row hover or keyboard focus, so static layout remains clean while the affordance is discoverable the moment the user interacts with the row. When expanded, the wrapper switches tooverflow-visibleso the button's focus outline is not clipped. The cell itself stays clickable as a touch target. Enabled editable cells always truncate their content to stay aligned with column headers and match the single-line editing controls; disabled cells behave like a regularTable.Cell. -
f16b887: fix(DST-1352): use correct outline for focus + error state in compound fields
-
1cac70d: docs: improve
AutoTypeTableprop renderingCentralizes the display of design-system aliases in the component docs' prop tables. Props whose types reference aliases from
@marigold/systemor@marigold/types(e.g.SpacingTokens,Scale,WidthProp,NonZeroPercentage) now render with a meaningful summary in the main cell and the full list of resolvable literal values on row expand — instead of a wall of literals in the cell and a redundant alias name on expand.Before:
- Cell:
SpacingTokens<Tokens>(a fabricated generic, inconsistent across components) - Expand:
SpacingTokens | Scale | undefined(same alias names, no new info)
After:
- Cell:
SpacingTokens | Scale(accurate, derived from the real type) - Expand:
"96" | "80" | ... | "tight" | "related" | 0(every concrete value)
Under the hood this replaces 27 per-prop
@remarks \TypeName`JSDoc overrides with a single fumadocs-typescript transform in the docs site, so future components pick up the same behavior automatically. A@remarks` tag on a prop still wins as an escape hatch.Multiselect.widthandComboBox.widthnow useWidthProp['width']directly instead ofFieldBaseProps<'label'>['width']— structurally identical, no runtime change. - Cell:
-
5744bbf: feat([DST-1396]): mobile-optimized pagination layout
Paginationnow hides the numbered page buttons on small viewports (max-sm) and spreads the previous/next navigation buttons across the full width usingjustify-between. This produces a cleaner, touch-friendly pagination on mobile while preserving the full layout on larger screens. -
c2a1c72: fix: apply
alignXfromTable.Columnto first column cellsTableCellContentused a truthy check oncolumnIndex, causing it to skip thealignXlookup whencolumnIndexwas0(first column). Replaced with a nullish check so all columns correctly inherit their alignment. -
de34b15: chore(deps): update
react-aria-components,@react-aria/*,@react-stately/*,@react-types/*, and@internationalized/*packages to their latest versions. -
04111ca: fix(DST-1355): widen
variantandsizeprop types onLoaderandProgressCircleto accept arbitrary strings via| (string & {}). Matches the pattern already used byButton,Panel, and other components, and lets consumer themes register their own variant/size tokens without TypeScript errors while preserving IDE autocomplete for the built-in RUI values. -
Updated dependencies [727163c]
-
Updated dependencies [4742e8e]
-
Updated dependencies [de34b15]
- @marigold/system@17.5.0
17.4.0
Minor Changes
-
f4f7a05: feat(DST-1306): migrate Card padding props to semantic spacing tokens
- Refactor Card to use
createSpacingVarinstead of static padding class maps spaceprop (gap between children) continues to accept relationalSpacingTokens(tight,related,regular,group,section) and numeric scale valuespprop (all sides) now acceptsInsetSpacingTokens(square-*,squish-*,stretch-*) and numeric scale valuespx/py/pt/pb/pl/prnow acceptPaddingSpacingTokens(padding-tight,padding-snug,padding-regular,padding-relaxed,padding-loose) and numeric scale values
- Refactor Card to use
-
f560d95: feat(DST-1239): migrate Inset component to semantic spacing tokens
spaceprop accepts inset recipe tokens (square-*,squish-*,stretch-*) and numeric scale valuesspaceX/spaceYprops accept single-value padding tokens (padding-tight,padding-snug,padding-regular,padding-relaxed,padding-loose) and numeric scale values- Add
InsetSpacingTokenstype for multi-value inset recipes - Add
PaddingSpacingTokenstype for single-value per-axis padding - Add
--spacing-padding-*CSS custom properties to theme
-
a4b467f: feat(DST-1323): always-on virtualization for
<Select>,<ComboBox>, and<Autocomplete>dropdownsFollow-up to #5307. Large datasets (hundreds to thousands of items) no longer freeze the browser when opening or filtering these components — the internal
<ListBox>is now virtualized withreact-aria'sVirtualizer+ListLayout(same pattern used by<TagField>).<Select>,<ComboBox>,<Autocomplete>: virtualization is enabled by default on desktop, with no public API change<ListBox>: the virtualized list now has a bounded height (max-h: 24rem) so the virtualizer has a viewport to clip against when used inside a<Popover>
Patch Changes
-
bbf0832: refactor([DSTSUP-245]): Clean up Calendar styles
Move hardcoded Tailwind classes from Calendar component files into theme slots, reduce cell padding from
p-2top-1, and add newcalendarHeadingtheme slot. -
3f77810: Remove redundant subcomponent exports (
AccordionItem,ListBoxItem,SelectListItem,ProgressCircleSvg) from the public index. These are already accessible via their parent compound components (e.g.,Accordion.Item) or are internal implementation details. -
85b2eb0: fix(DST-1275): improve EditableCell hover/focus affordance with data-editable attribute
-
50566a2: fix(DSTSUP-241): remove redundant label from mobile Menu tray
The Menu component's
labelprop serves as trigger button text. On mobile, it was also rendered as<Tray.Title>, duplicating the label the user just tapped. Unlike form components (Select, ComboBox, DatePicker) where the label describes a field, the Menu label has no additional context value inside the tray. Removing it keeps the mobile tray clean and avoids showing non-text labels (e.g. icons from ActionMenu) as tray titles. -
203baca: Replace local
useRenderPropshook with the export fromreact-aria-components, removing redundant code. -
969c8cc: chore([DST-1290]): Upgrade
lucide-reactfrom v0.575.0 to v1.xUpgraded
lucide-reactto the stable v1 API, which brings ~32% bundle size reduction and defaultaria-hiddenon icons. No icon renames or removals affect the codebase since no brand icons from lucide are used. -
Updated dependencies [bbf0832]
-
Updated dependencies [d341a9d]
-
Updated dependencies [f560d95]
- @marigold/system@17.4.0
17.3.1
Patch Changes
- d3374cd: fix: Replace arbitrary Tailwind variant with built-in group variant in TableEditableCell to fix CSS parsing error in Next.js (LightningCSS)
- @marigold/system@17.3.1
17.3.0
Minor Changes
- a48059c: feat([DST-1208]): Introduce AppLayout Component
- CSS Grid layout with
Sidebar,Header, andMainslot sub-components - Full viewport height (
100dvh) with scrollable main content area and fixed sidebar/header - Compound component pattern with ref support
- Fixed header height of
3.5rem(h-14) - App Shell pattern documentation with full-page demo
- Updated TopNavigation demos to use
Sidebar.Toggle - Aligned Sidebar header height with AppLayout header
- CSS Grid layout with
Patch Changes
- 6a29a6c: style([DST-1256]): Replace hardcoded values with semantic tokens
- 548dcb4: Wrap
useToastreturn values (addToast,clearToasts,removeToast) inuseCallbackso they are referentially stable across renders and safe to use inuseEffectdependency arrays- @marigold/system@17.3.0
17.2.1
Patch Changes
- @marigold/system@17.2.1
17.2.0
Minor Changes
-
ed928a0: Update ActionBar with enter/exit animations, keyboard support, and built-in Table integration.
- Add
useActionBarhook andActionBarContextfor managing selection state between ActionBar and Table - Add
actionBarrender prop to Table for automatic selection wiring and ActionBar positioning - Add enter/exit animations using
motion/reactand react-ariauseEnterAnimation/useExitAnimation - Add Escape key support to clear selection via
FocusScopeanduseKeyboard - Add screen reader announcement when ActionBar appears
- Add localized
selectedCount/selectedAllmessages (en-US, de-DE) - Update ActionBar theme slots: rename
actionstotoolbar, addselectionslot - Update theme type definition to match new slot names
- Add
-
5d4c915: feat([DST-1240]): Add auto-collapse behavior to Breadcrumbs. The
maxVisibleItemsprop now defaults to'auto', which uses aResizeObserverto progressively show or hide breadcrumb items based on available container width. -
61bfc60: Refactor relational spacing scale for better semantic clarity and visual rhythm.
- Rename
--spacing-peertoken to--spacing-regular - Remove unused
--spacing-joinedand--spacing-contexttokens - Adjust spacing scale values: tight (4px→6px), regular (16px→24px), group (32px→48px), section (64px→96px)
- Move field-internal spacing from theme (
Field.stylesspace-y-2) into component implementations using newin-fieldcustom variant - Add
in-field:mb-1.5to Label andin-field:mt-1to HelpText for consistent field layout - Update
SpacingTokenstype to reflect new scale
- Rename
-
470d81c: feat(DST-979): Introduce a dedicated Sidebar component
Add new
Sidebarcomponent for persistent app-level navigation. Features compound component API (Sidebar.Header,Sidebar.Nav,Sidebar.Item,Sidebar.Footer,Sidebar.Toggle, etc.), drill-down sub-navigation with animated transitions, collapse/expand with keyboard shortcut (Cmd+B / Ctrl+B) and localStorage persistence, mobile-responsive sheet overlay, full accessibility support, and i18n (EN/DE). -
c3bf8e4: feat([DST-1168]): Introduce TopNavigation Component
- Three-slot grid layout (
Start,Middle,End) using compound component pattern - Semantic HTML with
<header>container and<nav>landmarks - Sticky by default, configurable alignment, and i18n ARIA labels
- Theme styles for
theme-ruiand type definitions in@marigold/system
- Three-slot grid layout (
Patch Changes
-
91eb222: Update ActionBar styling with surface contrast and dedicated button slot.
- Apply
ui-surface-contrastutility to ActionBar container for adaptive theming - Add
buttonslot to ActionBar theme for properly styled action buttons (replacesButton.ghost) - Add
clearButtonhover/focus/disabled styles using theme-aware utilities - Update
ActionButtonto useActionBar.buttonclassNames instead ofButton.ghost - Replace
CloseButtonwithIconButtonfor the clear selection button - Update stories to use
lucide-reacticons directly
- Apply
-
b3c7085: fix: Breadcrumbs auto-collapse now works correctly inside flex containers (e.g. TopNavigation). The hidden measurement wrapper uses
min-w-0 w-fullto prevent a feedback loop where collapsed content would shrink the container, keeping breadcrumbs permanently collapsed. -
3019d28: Add
z-50to the non-modal (desktop) Drawer overlay so it renders above sticky table headers and other positioned content. The mobile modal path already hadz-50. -
efbd292: fix: Add LayoutGroup in Tray test mock, and exclude stories when running unit tests
-
7ca2eb1: feat([DST-1227]): 💄 Implement Animated Transitions for Tabs Component, The active tab underline must slide smoothly between items
-
95c22b6: feat(DST-1214): Replace hardcoded English strings with centralized intl messages for proper i18n support. Components like Toast, Drawer, Pagination, SectionMessage, ProgressCircle, ActionBar, and TagField now use
useLocalizedStringFormatterso their aria-labels are translated when the locale changes. Consolidates SearchInput's local intl messages into the sharedintl/messages.tsfile and converts parameterized messages to functions for clean variable interpolation. -
4a24ad6: fix([DST-945]): Fix Tooltip controlled open prop positioning
-
600d09f: fix(DSTSUP-233): Added card shadows to master- and adminmark
-
f63e57f: refactor(DST-1233): remove tailwindcss-animate, standardize overlay animations
-
d963df2: chore: Update React Aria to newest version
-
Updated dependencies [91eb222]
-
Updated dependencies [ed928a0]
-
Updated dependencies [cf56729]
-
Updated dependencies [7ca2eb1]
-
Updated dependencies [beebd7c]
-
Updated dependencies [b115fda]
-
Updated dependencies [61bfc60]
-
Updated dependencies [c3bf8e4]
-
Updated dependencies [d963df2]
- @marigold/system@17.2.0
17.1.0
Minor Changes
-
fd1b092: feat(DST-1219): Improve click area of
<TagField>Improves the click area of the TagField component so that clicking anywhere on the field (not just the chevron button) opens the dropdown.
Patch Changes
- a3042ed: fix(DST-1220): Update to use ui classes instead of util classes in components
- Updated dependencies [fd1b092]
- @marigold/system@17.1.0
17.0.1
Patch Changes
- @marigold/system@17.0.1
17.0.0
Major Changes
-
196172e: BREAKING CHANGE: Comprehensive Table component rewrite with modern features
This release introduces a complete rewrite of the
Tablecomponent built on react-aria-components, providing enhanced accessibility, modern features, and improved developer experience.Breaking Changes
The old
Tablecomponent has been moved to@marigold/components/legacy. The mainTableexport now refers to the new implementation.Changed API Structure
Migration Required:
// Before (old Table) import { Table } from '@marigold/components'; // After - Option 1: Use legacy export (temporary) import { Table } from '@marigold/components/legacy'; // After - Option 2: Migrate to new Table API (recommended) import { Table } from '@marigold/components'; <Table> <Table.Header> <Table.Column>Name</Table.Column> <Table.Column>Email</Table.Column> </Table.Header> <Table.Body> <Table.Row> <Table.Cell>John Doe</Table.Cell> <Table.Cell>john@example.com</Table.Cell> </Table.Row> </Table.Body> </Table>Empty State Prop Location
The
emptyStateprop has been moved from theTablecomponent toTable.Body. This change provides better composition and follows react-aria-components patterns.Migration Required:
// Before (old Table) <Table emptyState={<EmptyMessage />}> <Table.Header> <Table.Column>Name</Table.Column> </Table.Header> <Table.Body> {/* rows */} </Table.Body> </Table> // After (new Table) <Table> <Table.Header> <Table.Column>Name</Table.Column> </Table.Header> <Table.Body emptyState={<EmptyMessage />}> {/* rows */} </Table.Body> </Table>Form Fields in Table Cells
Inlining form fields directly in table cells is no longer supported. This approach broke accessibility patterns and keyboard navigation as it created conflicting focus management between the table's row selection and form inputs.
Migration Required:
// Before (old Table) - NOT ACCESSIBLE <Table> <Table.Header> <Table.Column>Name</Table.Column> </Table.Header> <Table.Body> <Table.Row> <Table.Cell> <TextField /> {/* This breaks keyboard navigation */} </Table.Cell> </Table.Row> </Table.Body> </Table> // After (new Table) - Use TableEditableCell <Table> <Table.Header> <Table.Column>Name</Table.Column> </Table.Header> <Table.Body> <Table.Row> <Table.EditableCell field={<TextField name="name" defaultValue={value} />} onSubmit={handleSubmit} > {value} </Table.EditableCell> </Table.Row> </Table.Body> </Table>Cell Alignment Props
The
alignprop onTable.Column,Table.Cell, andTable.EditableCellhas been renamed toalignXfor consistency with other Marigold layout components.Vertical alignment (
alignY) is only available on theTablecomponent itself, not on individual cells. It controls the vertical alignment of all cell content.Migration Required:
// Before <Table.Column align="right">Balance</Table.Column> <Table.Cell align="right">{value}</Table.Cell> // After <Table.Column alignX="right">Balance</Table.Column> <Table.Cell alignX="right">{value}</Table.Cell> // Vertical alignment (table-level only) <Table alignY="top"> {/* ... */} </Table>Column Width Values
Tailwind CSS width classes are no longer supported on
Table.Column. Column widths now use pixel values or CSS grid units, which provides better content-fitting behavior and more predictable layouts.Migration Required:
// Before (old Table) <Table.Column width="w-32">Name</Table.Column> <Table.Column width="w-full">Description</Table.Column> // After (new Table) <Table.Column width="200px">Name</Table.Column> <Table.Column width="1fr">Description</Table.Column> {/* Default: 1fr */}By default, columns use
1fras their width, which distributes available space evenly. You can now specify exact pixel widths for columns that need fixed sizing, or use CSS grid units like2frfor proportional layouts.New Features
The new
Tablecomponent includes:Core Features
- Enhanced Accessibility: Built on react-aria with full ARIA pattern compliance, keyboard navigation, and screen reader support
- Sorting: Click column headers to sort ascending/descending with visual indicators (
SortAscending,SortDescendingicons) - Selection: Single or multiple row selection with checkboxes and keyboard support
- Row Actions: Support for action menus and interactive elements within rows
Advanced Features
- Editable Cells: Inline cell editing with
TableEditableCellcomponent supporting text inputs, selects, and custom editors - Drag and Drop: Reorder rows with visual drag preview and drop indicators
- Sticky Headers: Keep table headers visible while scrolling through data
- Empty States: Built-in support for displaying empty state messages
- Links: Clickable cells and proper link handling within table rows
Layout & Styling
- Text Overflow Control: Choose between truncation and wrapping for cell content
- Text Selection: Enable/disable text selection within table cells
- Cell Alignment: Flexible horizontal (
alignX) and vertical (alignY) text alignment options - Responsive Design: Better handling of different viewport sizes
- Column Width Control: Support for fixed and flexible column widths
New Components
This release adds several new subcomponents:
Table.Column- Define table columns with sorting, alignment, and width optionsTable.EditableCell- Editable table cells with inline editing supportTable.SelectableCell- Checkbox cells for row selectionTable.renderDropIndicator- Render function for custom drop indicatorsTable.renderDragPreview- Render function for custom drag previews
New Icons
Pencil- Indicates editable cellsSortAscending- Ascending sort indicatorSortDescending- Descending sort indicator
Theme Updates
- New theme styles for the modern
Tablecomponent in@marigold/theme-rui - Legacy
Tablestyles preserved asLegacyTable.styles.ts - Updated documentation theme (
@marigold/theme-docs) with new Table styles
Documentation
Comprehensive documentation updates including:
- Complete API reference with all new props and features
- Interactive demos for all features (sorting, selection, editing, drag-drop, etc.)
- Anatomy diagram showing component structure
- Migration guide from legacy Table
- Accessibility guidelines
Backward Compatibility
The legacy
Tablecomponent remains available at@marigold/components/legacyfor backward compatibility. However, it is now considered deprecated and will receive maintenance updates only. We strongly recommend migrating to the newTablecomponent to benefit from:- Better accessibility and ARIA compliance
- Modern features (sorting, selection, editing)
- Improved performance
- Active development and new features
- Better React 19 compatibility
Examples
Basic Table
<Table> <Table.Header> <Table.Column>Name</Table.Column> <Table.Column>Email</Table.Column> </Table.Header> <Table.Body> <Table.Row> <Table.Cell>John Doe</Table.Cell> <Table.Cell>john@example.com</Table.Cell> </Table.Row> </Table.Body> </Table>Sortable Table
<Table> <Table.Header> <Table.Column allowsSorting>Name</Table.Column> <Table.Column allowsSorting>Email</Table.Column> </Table.Header> <Table.Body>{/* rows */}</Table.Body> </Table>Selectable Table
<Table selectionMode="multiple"> <Table.Header> <Table.Column>Name</Table.Column> <Table.Column>Email</Table.Column> </Table.Header> <Table.Body>{/* rows with selection */}</Table.Body> </Table>Editable Table
<Table> <Table.Header> <Table.Column>Name</Table.Column> <Table.Column>Email</Table.Column> </Table.Header> <Table.Body> <Table.Row> <Table.EditableCell> {name => <TextField value={name} />} </Table.EditableCell> <Table.EditableCell> {email => <TextField value={email} />} </Table.EditableCell> </Table.Row> </Table.Body> </Table>Technical Details
- Built on
react-aria-componentsv1.5.0+ - Fully typed with TypeScript
- Comprehensive test coverage (unit + browser tests)
- Follows WCAG 2.1 AA accessibility standards
- Compatible with React 19
- Supports both controlled and uncontrolled modes
Minor Changes
-
d8ce791: feat([DST-1092]): Add TagField component and deprecate Multiselect
- Add
<TagField>component: a multi-select field that displays selected items as removable tags with a searchable dropdown, built on react-aria's Select, Autocomplete, and TagGroup - Support for controlled/uncontrolled selection, disabled state, error state, disabled keys, sections, and custom empty state
- Deprecate
<Multiselect>component with updated docs pointing to<TagField>
- Add
-
196172e: feat: Add ref forwarding support to Form component
-
cfa9b99: feat([DST-1206]): Mobile support for
<TagField> -
6c071f0: refa(DST-1146): Migrate
<Center>to semantic spacing tokens -
44d01a6: feat(DST-1141): Update
<Card>to use semantic spacing and addstretchproperty<Card>uses semantic spacing- Added
stretchin favor ofsize="full" - Updated test suite
- Fixed that the
<Card>always take full width
-
0c00d1d: ## 🎨 Changes
1. Refactored Surface Styling
What changed:
- Completely refactored the surface styling system to use
background-clipandbackground-originfor gradient borders - Improved contrast and depth across all surface-based components (inputs, cards, dialogs, etc.)
- DateInput: Added new
inputpart for styling
Technical Details:
- New
ui-surfaceutility class that works on single elements including<input> - Gradient borders transition from lighter (top) to darker (bottom) for improved depth perception
- Removed deprecated utilities:
util-focus-*,util-disabled - Introduced new state utilities:
ui-state-focus,ui-state-disabled,ui-state-error,ui-state-readonly - New elevation system:
ui-elevation-raised,ui-elevation-overlay
2. Semantic Spacing System (DST-1001)
New Relational Spacing Scale: Introduced semantic tokens that describe the strength of relationships between elements:
joined(0.25rem) - Elements attached as a single unittight(1rem) - Packed containers for high-density scanningrelated(2rem) - Minimal separation for related pairs (label + input)peer(4rem) - Self-contained equals in the same flowgroup(8rem) - Logical separation between content zonessection(16rem) - Distinct layout sectionscontext(32rem) - Complete contextual shift
New Inset (Padding) Scale:
tight,snug,regular,relaxed,loose- with square, squish, and stretch variants- Example:
--spacing-squish-regular,--spacing-stretch-relaxed
Benefits:
- Decouples intent from pixel values
- Consistent rhythm across the interface
- Improved scannability and hierarchy
- Reduced reliance on explicit containers (cards/borders)
3. Component Improvements
FileField:
- Removed hardcoded unchangeable styles
- Better grid-based layout for file items
- Added
itemRemovepart for styling - Proper internationalization for remove button
DatePicker:
- Fixed dropdown sizing - now fits content instead of input width
- Improved calendar popover positioning
Select & Input Components:
- Simplified container structure
- Better icon and action placement
- Improved accessibility with proper ARIA attributes
Dialog & Overlay Components:
- Consistent elevation styling
- Better scrollbar styling
- Improved focus management
📝 Documentation
- New Spacing Guide: Comprehensive documentation explaining the semantic spacing system
- Added visual examples for relational and inset spacing
- Guidance on implicit vs. explicit grouping
- Updated all example forms and patterns to use new spacing tokens
🔧 Technical Improvements
- Replaced deprecated data attributes with proper CSS selectors
- Better TypeScript typing for spacing tokens
- Improved theme component definitions
- Cleaner CSS with reduced specificity
- Better support for different component states (disabled, readonly, error, focus)
📊 Statistics
- 118 files changed
- 1,677 insertions, 690 deletions
- Components affected: TextArea, Input, DateField, FileField, Select, Calendar, Card, Dialog, Menu, Toast, and many more
⚠️ Migration Notes
Spacing Values
// Before <Stack space="fieldY"> <Inline space="fieldX"> // After <Stack space="peer"> <Inline space="related">Surface Styling
/* Before */ .util-surface-raised /* After */ .ui-surface /* uses raised elevation by default */ .ui-surface.ui-elevation-overlay /* for overlays */ - Completely refactored the surface styling system to use
-
59ed05f: feat([DST-900]): Introduce Internal
<Tray>Component for Mobile Support.<DatePicker>,<Menu>,<Autocomplete>,<Combobox>and<Select>have a new mobile experience. -
31a4e38: feat(DST-1184): Add
nameprop toFileField
Patch Changes
-
34c785a: style([DST-1154]): Update Admin/Master Badge Styling
-
96e145a: fix(Container): Fix a regression which made
<Container>not correctly work with<Breakout>anymore -
00a3c81: fix(DST-1205): Fix visuals of
<NumberField>stepper when disabled using min/max -
cc61968: refa(DST-1150): Remove
spaceprop from<TabList> -
01e6bdb: [DST-1157]: introduce new
<ActionBar>alpha component -
2244030: fix(DSTSUP-231): Scrolling when pointer hovers over
<Scrollable>works as expected. -
63f1603: style([DST-1143]): Improve ContextualHelp sizes
Breaking Change: Sizes have been removed, the default has a new style.
-
7928a23: Refactor z-index implementation to move all z-index values from theme style files to component implementations. This ensures consistent stacking order across all themes and makes z-index behavior theme-independent.
Changes:
- Moved z-index classes from theme style files (
*.styles.ts) to component implementations - Z-index values are now applied directly in component
classNameprops using Tailwind utilities - Updated 8 component files: ToastProvider, Popover, Tooltip, Underlay, DrawerModal, Drawer, ActionBar
- Updated 7 theme style files to remove z-index classes
- Added comprehensive z-index documentation to CLAUDE.md
- ActionBar moved to floating layer (z-30) for better integration with content overlays
Benefits:
- Z-index stacking order is now consistent across all themes
- Components control their own z-index, making it part of component behavior
- Easier maintenance - developers only check component files to understand stacking
- Future themes automatically inherit correct z-index stacking
- Moved z-index classes from theme style files (
-
5a90757: feat(DSTSUP-225): Introduce
<ToggleButton>and<ToggleButtonGroup>as alpha components -
4645c5d: style(DST-1197): Refine elevation shadows
-
8dd0455: feat([DSTSUP-222]): Introduce
<EmptyState>Component as beta -
1469268: [DST-1088]: add docs for
onActionprop -
f916a20: fest(DST-1149): Allow to use semantic spacing with
<Grid> -
726239d: feat(DST-1148): Allow to use semantic spacing with
<Container>. -
1bd9f27: feat(DST-1147): Allow to use semantic spacing in
<Columns> -
b7c64cc: fix(Checkbox): Correctly apply focus styling on checkboxes
-
8a70185: refa(DST-974): Refactoring width property on
FieldBaseand Form Elements likeInput,TextArea,DateInputandSelect. Labels and HelpText can now be wider as the actual input field. -
Updated dependencies [01e6bdb]
-
Updated dependencies [5a90757]
-
Updated dependencies [0c00d1d]
-
Updated dependencies [8dd0455]
-
Updated dependencies [8a70185]
- @marigold/system@17.0.0
16.1.0
Minor Changes
- c5bd98b: feat(DST-1136): Make clear that
"stretch"is the default for<Stack>
Patch Changes
- 89acee4: feat: Add a generic spacing scale that can be used with
createSpacingVar - 4ac589b: refa(DST-1130): Use CSS var instead of map for spacing in
<Stack> - d720c5e: feat(DST-1138):
<Inline>uses spacing helper instead of style-props - 0b8ca1e: feat(DST-1145): Use semantic tokens with
<Aside> - Updated dependencies [89acee4]
- Updated dependencies [4ac589b]
- Updated dependencies [c5bd98b]
- @marigold/system@16.1.0
16.0.1
Patch Changes
- 77a64e8: fix: Use relative imports & remove default React import usage
- b90a67e: fix(FileField): Use local svg instead from @marigold/icons
- @marigold/system@16.0.1
16.0.0
Major Changes
-
b947276: style(DST-1089): Add expand/collapse animation to
<Accordion> -
f10119a: refa(DST-1109): Remove required indicator from the label's text content
BREACKING CHANGE: We removed the
indicatorstyling from<Label>. The component is no longer a multi-part component. Rather than styling the required indicator through a dedicated part (previsoulyindicator), you can now apply it anyway you want, for example by using'group-required/field:after:content-["*"]'. -
4eebff4: [DSTSUP-191]: Breaking chnge:
<XLoader />renamed to<Loader />Added a new proploaderTypewhich is by defaultcycle. New optioncycleshows a spinning cycle.
Minor Changes
- 98bf929: [DST-1075]: Introduce
<FileField>component
Patch Changes
-
832e3fa: fix(styles): Remove extra spacing when hidden/a11y elements are causing it
-
845f26c: feat([DST-1025]): Adding possibilty to paste date values in
<DatePicker>component. -
1e98c67: [DST-1103]: Added a new section "Placement and order" onto the
<Button>component page. -
9027ce9: feat([DST-973]): Select value on focus in
<NumberField> -
2ac63f7: fix([DSTSUP-196]): Fix Listbox layout when more than one element is used.
-
29494b4: fix(DST-1110): Remove extra whitespace from
<Container>When there is no
<Breakout>inside the container we do not have to apply the 3 column layout. Otherwise this causes 2 empty columns to be there. -
57a2bd3: style([DST-1126]): Fix Breadcrumb styling
-
62692a6: style(DST-1086): Add a new destructive button variant
-
Updated dependencies [b947276]
-
Updated dependencies [98bf929]
-
Updated dependencies [f10119a]
-
Updated dependencies [4eebff4]
- @marigold/system@16.0.0
15.4.3
Patch Changes
- @marigold/system@15.4.3
15.4.2
Patch Changes
- @marigold/system@15.4.2
15.4.1
Patch Changes
- d710177: fix(drawer): Fix drawer styles for some enviroments
- @marigold/system@15.4.1
15.4.0
Minor Changes
- e985fe2: feat([DST-1091]): Add multiselection mode to
<Select>
Patch Changes
-
f621653: feat([DSTSUP-187]): Enhance Toast component with action support
- Introduced
actionproperty - Update description to support JSX
- Introduced
-
025d6e9: fix([DST-1095]): Don't break table header when sorting indicator is shown and use
cursorwhen sortable -
ffbebd0: refa([DST-1099]): Adjust icons sizes in some components to bette fit their container.
-
9ec4620: fix([DSTSUP-193]): update Inline components
alignY=inputnow also alignes with input elements regardless of description -
77e0417: fix([DST-1078]): Fix scrolling within
<ContextualHelp> -
Updated dependencies [f621653]
-
Updated dependencies [e985fe2]
-
Updated dependencies [77e0417]
- @marigold/system@15.4.0
- @marigold/types@1.4.0
15.3.0
Minor Changes
-
95b55b8: feat([DST-1074]): Introduce a
useConfirmationhook to conveniently open confirmation dialogs -
bad3ef4: feat([DST-1056]): Add a helper to conveniently parse form data
-
4395d2e: feat([DST-1047]): Improve
<List>styles and addsmallvariant -
97adc14: feat([DST-1061]): Add more alignment options to
<Inline>,<Stack>and<Grid> -
91a5e7b: feat([DST-1044]): Introduce
LinkButtoncomponent -
baf550b: feat([DST-940]): Introduce
<Drawer>componentAdded
<Drawer>component along with usage guideline and stories. The drawer offers a consisten way to present secondary content in a non-blocking way. -
4ccbec2: feat([DST-1077]): Add white space control to
<Text> -
5e62b84: feat([DST-1051]): Introduce
ConfirmationDialog -
beeba04: feat([DST-1042]): Add "destrutive" variant to
<Menu.Item>
Patch Changes
- c6fb6c2: feat: Expose
TimeValuetypes - ba5f502: feat([DST-1069]): Add
noWrapprop to<Inline> - 061b5e9: feat([DST-1050]): Card master and adminmark variant
- ce996ae: feat([DSTSUP-185]): added
stickyHeaderandiconPositionprops toAccordion - Updated dependencies [97adc14]
- Updated dependencies [4ccbec2]
- @marigold/system@15.3.0
15.2.0
Patch Changes
- @marigold/system@15.2.0
15.1.0
Minor Changes
- a3ddf47: feat([DST-1037]): Add
description(help text) to<Checkbox>component - 0583b77: feat([DST-1039]): Allow
<Text>to not wrap lines
Patch Changes
- 7b3caca: feat([DST-1035]): Apply
data-racattribute to our table elements. - Updated dependencies [a3ddf47]
- Updated dependencies [0583b77]
- @marigold/system@15.1.0
15.0.2
Patch Changes
- @marigold/system@15.0.2
15.0.1
Patch Changes
- df57868: Fix([DSTSUP-181]): Adjust Accordion.Header styles to support full width
- 00d230a: chore: allow
react-ariapatch version range as dependencies - b351484: feat([DST-981]): Drawer supports controlling the origin of the
<Drawer>by usingplacementproperty (e.g. left, right, top, bottom), also supports configurable sizes to adapt to different sizes. - Updated dependencies [00d230a]
- @marigold/system@15.0.1
15.0.0
Major Changes
-
9bac182: refa([DST-904]): Breaking Changes: Rename
noOptionsMessageproperty toemptyStatein<Multiselect>component. -
62ac4b8: refa([DST-919]): Remove
<Image>componentBreaking Change
The
<Image>component has been removed from Marigold. Please replace it with the native<img>element.If you previously used the
fitorpositionprops, you can replicate the same behavior using the corresponding Tailwind CSS utility classes.Replacement table
Prop type Prop value Tailwind class fit containobject-containcoverobject-coverfillobject-fillnoneunsetscaleDownobject-scale-downposition none— (no class) bottomobject-bottomcenterobject-centerleftobject-leftleftBottomobject-left-bottomleftTopobject-left-toprightobject-rightrightBottomobject-right-bottomrightTopobject-right-toptopobject-top -
0585db1: refa([DST-1010]): Separate
aria-labelandnamefor slider's thumbsBreaking Change: The aria-label (
thumbLabels) andnameattributes for slider thumbs are now separate. Update implementations to set both explicitly if needed.
Minor Changes
- 6d8358c: feat([DST-1003]): Improve type safety for component variants.
- 2a64b4f: feat([DST-1008]): Introduce a "remove all" function for
<Tag.Group> - 41da911: feat([DST-1005]): Add a "link" variant to
<Button> - 13d27bf: feat([DST-1006]): Introduce a collapsible section for long checkbox groups and radios
Patch Changes
-
44ceb28: bugfix([DST-935]): Controlled
<Dialog>now working correctly when dismissable is set totrue -
7e33a7f: docs: Add alpha to for top navigation (previously a recipe)
-
801e968: fix([DSTSUP-176]): Calendar - Hide, disable, limit the MonthListBox and YearListBox depening on minValue and maxValue
-
17318a8: fix([DSTSUP-172]): Fix alignment of buttons and inputs in
<Inline>component. -
6d2d2d4: refa([DST-916]): Remove
<Header>component and replace with native<header>Breaking Change:
<Header>component removedThe
<Header>component has been removed from Marigold. Please replace it with the native HTML<header>element.Example migration:
Before
<Header> <h1>Page title</h1> </Header>After
<header> <h1>Page title</h1> </header> -
5e06780: docs([DST-902]): Define asyncronous data loading patterns for components like
<Combobox>and<Autocomplete>.Both
<Combobox>and<Autocomplete>now accept a new prop calledemptyStatethat allows you to provide custom content to display when there are no items in the list, such as a message -
1ab48da: refa([DST-915]): Remove
FootercomponentBreaking Change:
<Footer>component removedThe
<Footer>component has been removed from Marigold. Please replace it with the native HTML<footer>element.Before
<Footer> <p>© 2025 Company Name</p> </Footer>After
<footer> <p>© 2025 Company Name</p> </footer> -
Updated dependencies [2a64b4f]
-
Updated dependencies [82370d2]
-
Updated dependencies [80a4427]
-
Updated dependencies [62ac4b8]
- @marigold/system@15.0.0
14.1.1
Patch Changes
- 424e2f4: feat([DST-998]): prevent page bounce when
<Scrollable>is used inside a page. - 81f1c9d: fix broken release
- Updated dependencies [81f1c9d]
- @marigold/system@14.1.1
- @marigold/types@1.3.2
14.1.0
Minor Changes
-
cc493fc: feat([DST-737]): Add Toast component
Added ToastProvider Component with corresponding documentation and stories. It's a small Temporary Notification on the edge of the screen, that should be used for messages that don’t need immediate interaction.
-
2163518: feat([DST-899]):Breadcrumb Component
We added a new Breadcrumbs component to improve navigation and accessibility in the UI. It supports collapsing long breadcrumb lists, custom separators (chevron or slash), and integrates with react-aria-components for full accessibility and keyboard navigation. The component is flexible, supports links and custom content, and includes comprehensive documentation and usage examples.
Patch Changes
- 930e633: chore: Update
react-aria(Release 22/07/2025) - 8f550ec: refa([DST-976]): Remove unused class names from
ContextualHelp - 69e7b61: refa([DST-978]): Add item and section as child component of
ActionMenu - ea0f758: fix(DST-968): Fix
<Tag>styles and add multiselect tag filter to filter pattern example - 8e178b7: fix([DST-942]): Fix
<Drawer>on mobile and refactor<OverlayContainerProvider> - 37f40ba: feat([DST-977]): Style icons inside
<Menu.Item> - Updated dependencies [cc493fc]
- Updated dependencies [930e633]
- Updated dependencies [2163518]
- @marigold/system@14.1.0
14.0.0
Major Changes
- 6d61be9: refa([DST-904]): Breaking Changes: Deprecate
classNameprop from<Button>component.- Styling should now use
variantorsizeprops instead. - Added
SelectListActiontoSelectListfor handing actions position.
- Styling should now use
Minor Changes
- 29e6133: feat([DST-937]): Add master and admin mark variants
Patch Changes
- a7ec9d3: fix[DSTSUP-169]: Fix width property on Calendar component
- 5e08185: docs([DST-925]): Introduce "admin- and master mark" pattern
fix([DST-925]): Adjust styles of Tabs to work better with badges
- @marigold/system@14.0.0
13.0.0
Major Changes
-
9a5791c: docs([DST-914]): Update Divider docs to match new structure of component pages
Breaking Change: Removed
classNameproperty on this component. -
c33ad07: docs([DST-921]): Revise text component page to new component page structure.
Breaking Change: Some propertys has been removed, including
classNameand HtMLElement props. -
d224a2f: style([DST-721]): Breaking Changes: Deprecate B2B and Core themes
- @marigold/theme-b2b and @marigold/theme-core are now deprecated and will no longer receive updates or maintenance. Please migrate to RUI theme package.
- The FieldGroup component has been removed and is no longer available in
@marigold/components. - All documentation and Storybook references to the B2B and Core themes, as well as FieldGroup, have been removed.
- If you are using either of these themes , please update your project to our lates release.
Minor Changes
-
854e00b: refa([DST-871]): Enhance Inline component to dynamically align buttons with input fields when descriptions are present.
-
430c266: feat([DSTSUP-158]): List accessibility for
<Stack>componentThe
<Stack>component supports a new propertyasListmaking it possible to provide accessibility when using a<Stack>which behaves as a list element. The<List>has an updated documentation.
Patch Changes
-
98bea2e: docs([DST-917]): Revise Headline documentation
-
16f6dbb: fix[DST-812]: Migrate from UNSTABLE_portalContainer to UNSAFE_PortalProvider
Changed UNSTABLE_portalContainer to UNSAFE_PortalProvider as UNSTABLE_portalContainer is deprecated.
-
Updated dependencies [d224a2f]
- @marigold/system@13.0.0
12.0.5
Patch Changes
- a6bcd89: chore(deps): update react-aria
- Updated dependencies [a6bcd89]
- @marigold/system@12.0.5
12.0.4
Patch Changes
- 3e19b71: feat([DST-883]): New variant for RUI table. You can now use a new variant for RUI theme.
- ed72011: feat(DSTSUP-150): add
ghostversion to<Menu>+ normalize svg sizes in buttons and menus - 6c230c7: feat[DST-731]: Add ContextualHelp Component with Docs We added a new ContextualHelp component to provide inline help and guidance within the UI. It displays contextual information in a popover triggered by an icon button, with configurable placement, size, and icon variant (help or info). The component is accessible, supports both controlled and uncontrolled open states, and is designed for flexible content layout.
- 17d28b5: feat([DST-885]): update default
<Link>styles and add link variant - 5127d58: feat([DST-884]): add vertical alignment property (alignY) to table
- Updated dependencies [6c230c7]
- @marigold/system@12.0.4
12.0.3
Patch Changes
-
7451134: feat([DST-863]): Improve
Accordion.Headerwhen using additional content in the header. -
12b00ed: feat[DST-856]: Add TimeField Component
We added a new TimeField component to support time-based user input. It allows users to select and edit time values, with configurable granularity (hours, minutes, seconds) and optional 12/24-hour format. The component supports accessibility features like keyboard navigation.
-
73edbb0: feat([DST-866]): Support
alignXandalignYproperties for<Grid>component. -
Updated dependencies [12b00ed]
- @marigold/system@12.0.3
12.0.2
Patch Changes
- 0bca5d8: Update React aria components
- ca26659: refa([DST-715]): Refactor
<Calendar>component, Fix resizing when open calendar listboxes - Updated dependencies [0bca5d8]
- Updated dependencies [ca26659]
- @marigold/system@12.0.2
- @marigold/types@1.3.1
12.0.1
Patch Changes
- 0e8211b: chore([DST-853]): Refa styles for
<Menu>button - af401e5: fix([DSTSUP-135]): Use correct padding on
<MultiSelect>component - 534ad77: refa([DST-738]): Adding checkmark icon as selection indicator in RUI theme for SelectList and Listbox components.
- Updated dependencies [0e8211b]
- @marigold/system@12.0.1
12.0.0
Major Changes
-
2ed500d: feat([DST-804]): Allow
Tagto be used in forms and overhaul its docsBREACKING CHANGE: Remove the
allowsRemovingprop. This didn't had an effect for a while and to make it more clear removing is enabled, if there is a function set on theonRemoveprop. -
c30993e: refa([DST-816]): Remove children prop, only label is now available
BREAKING CHANGE: The
childrenprop is no longer supported in the<Checkbox>,<Slider>and<Switch>component to display a label. Use the dedicated `label? prop instead.
Minor Changes
- 438b959: feat([DSTSUP-112]): Add sizes to RUI's
<Dialog> - fe4b9de: feat([DST-801]): Allow to format ranges with
<NumericFormat>
Patch Changes
- d7cfabd: fix([DST-808]): Don't render empty helptext when no description or error is present.
- 20ecd9c: fix([DST-803]): Span empty state over the whole table width.
- 4e510fb: [DST-763]: Migrate to eslint flat config.
- 9d57c1f: fix([DST-802]): remove unneeded classnames from
<Modal> - Updated dependencies [438b959]
- Updated dependencies [fe4b9de]
- Updated dependencies [4e0971e]
- @marigold/system@12.0.0
11.5.0
Minor Changes
- c9b95bc: feat([DST-799]): Add
unstyledandmaxWidthto<Form>
Patch Changes
-
8dab2e6: chore: update
react-aria(April 2025 release) -
70399e4: style([DST-724]): Adjust required icon for form elements in RUI style
-
337f9ee: doc[DST-727]: add copyable examples to the pagination documentation.
-
d24cee3: fix([DST-232]): Align icon in
<HelpText>to the start of text begin. -
4686a0d: refa([DST-754]): Add
<FocusScope>to<Pagination>to improve focus state. -
c42767f: refa([DST-762]): support
labelprop for<CheckBox>and<Switch>.Breaking Change: Deprecate
childrenproperty, uselabelinstead. With the next major versionchildrenwill be removed. -
2a87f43: feat[DST-759]: Implement
<CloseButton>component to be re-used into other components internally (e.g Dialog, Tag, Drawer and SectionMessage). -
Updated dependencies [8dab2e6]
-
Updated dependencies [c9b95bc]
-
Updated dependencies [2a87f43]
- @marigold/system@11.5.0
11.4.1
Patch Changes
-
81b2216: refa([DST-720]): Rename
optiontoitemin styles for<ListBox>Breaking Change: This change will break your styles if you use custom styles for the
<ListBox>Component.optionis now calleditem. -
953cf3d: Making the dialog titles independant
-
Updated dependencies [81b2216]
-
Updated dependencies [953cf3d]
- @marigold/system@11.4.1
11.4.0
Patch Changes
- @marigold/system@11.4.0
11.3.0
Minor Changes
- 611c2e8: feat(733): Introduce a
<Drawer>component - 7554cf9: refa([DST-755]): Cleanup
NumberFieldstyles for RUI + left align text when stepper is hidden
Patch Changes
- 888e852: [DST-769]: use useId from
react-ariautils to support React 17+ - 08ba5c7: chore([DSTSUP-109]): change visibility of icon to hidden when sorting…
- 8b404d2: fix([DST-750]): Do not set styles for content in
<Accordion> - Updated dependencies [611c2e8]
- @marigold/system@11.3.0
11.2.3
Patch Changes
- 3d1f8c6: feat(rui): Next version of RUI theme with small updates and styling fixes.
- Updated dependencies [3d1f8c6]
- @marigold/system@11.2.3
11.2.2
Patch Changes
-
9412037: RUI theme release 0.3.0
-
91c72e8: feat[DST-606]: Implement
<MultiSelect>componentIntrocude
<MultiSelect>as component! -
Updated dependencies [91c72e8]
- @marigold/system@11.2.2
11.2.1
Patch Changes
-
40db199: feat(rui): Add more styles to components
-
619b4b2: fix([DST-702]): add space for multiple selection mode in
<SelectList>There were no space between
<Checkbox>andchildrenwhen using<SelectList>in multiple selection mode.- @marigold/system@11.2.1
11.2.0
Minor Changes
- c387b43: feat: allow React >=17.0.0
Patch Changes
- c387b43: feat: allow React >=17.0.0
- a31881d: fix(DST-696): Make it possible to only pass in the color name without a prefix
- Updated dependencies [c387b43]
- Updated dependencies [a31881d]
- Updated dependencies [c387b43]
- @marigold/system@11.2.0
- @marigold/types@1.3.0
11.1.1
Patch Changes
- be665e7: fix(DST-691): Fix regression, allow to use custom color values with
<Text>,<Headline>and<SVG> - Updated dependencies [be665e7]
- @marigold/system@11.1.1
11.1.0
Minor Changes
- fd96b48: feat(DST-689): Allow to style body element and header row of a
<Table>
Patch Changes
- 300bfba: fix(DST-690): Rotate chevron when
Accordion.Itemis expanded + align header and content - Updated dependencies [fd96b48]
- @marigold/system@11.1.0
11.0.2
Patch Changes
-
8e58923: fix([DSTSUP-104]): mobile behaviour for
<Popover><Underlay>stayed remaining open on small screens while<Popover>was correctly closing, fixed this and added styles for<Popover>back.- @marigold/system@11.0.2
11.0.1
Patch Changes
- @marigold/system@11.0.1
11.0.0
Major Changes
-
964e025: refa([DST-665]): Refactoring Accordion
Added two Accordion components
Accordion.HeaderandAccordion.Content.Accordion.Headerreplaces the title inAccordion.Item.Accordion.Contentis now the place where the content needs to be.Reworked the
AccordionDocumentation Page. -
82c869c: refa: improve
<Container>and<Breakout>componentBREAKING CHANGE: This PR includes breaking changes, because we removed and changed a lot ot the props API of
<Container>and<Breakout>. The<Container>now only works with<Text>and<Headline>component. This allows for a smoother developer experience and prevents suprises.Make the
<Container>and<Breakout>component more usable for real world scenarios.<Container>supporstspacestyle prop- simplify
<Container>usage by removing unnecessary props - simplify
<Breakout>and make it composable with other layout components - make
<Text>and<Headline>adhere to a<Container>content length
-
d96b809: refa(DST-629): Align
<XLoader>modes with loading pattern naming conventionBREAKING CHANGE: Rename
modeprop to align with the "Loading state" pattern. Renamed"fullsize"to"fullscreen"and"inline"to"section".
Patch Changes
- Updated dependencies [964e025]
- @marigold/system@11.0.0
10.2.1
Patch Changes
-
bb2049f: bugfix[DSTSUP-100]: Bug in pagination component
- display of results counter fixed
- when page size changed the first page will now be selected
-
7f0841d: fix(DSTSUP-102): Set dimensions of checkmark
Fixes a bug in Safari where the checkmark was not displayed.
- @marigold/system@10.2.1
10.2.0
Minor Changes
- b89cd49: feat(DST-646): Improve a11y by translation fallback loading message
Patch Changes
- dc53196: fix(DST-644): Make
<XLoader>use underlay styles from theme in docs- @marigold/system@10.2.0
10.1.3
Patch Changes
- Updated dependencies [8b7be8e]
- @marigold/types@1.2.1
- @marigold/system@10.1.3
10.1.2
Patch Changes
- @marigold/system@10.1.2
10.1.1
Patch Changes
-
17fd7b4: docs([DST-621]): Revise
<Tiles>pageRevised
<Tiles>page according to our new structure of component pages. -
93f783a: feat([DSTSUP-98]): introduce controlled dismissable
<SectionMessage>Added possibility to control the dismissable state in
<SectionMessage>, you can now useonCloseandcloseto control the closing of a section message. -
d52e52f: docs([DST-624]): Revise
<Calendar>page and change some properties- Revised the page according to our new template.
- Rename
isDateUnavailabletodateUnavailable. - Remove the props:
visibleDurationandpageBehavior. - Added outline focus styles for keyboard navigation in both themes.
-
d326823: bugfix([DST-627]): replace useState import from storybook
Some controlled stories in Storybook were incorrect because the useState import from react was used, resulting in an error.
The stories of the following component were affected:
- Calendar
- DateField
- DatePicker
- Dialog
- HelpText
- SearchField
-
85e8cba: feat(DST-608): Make
<XLoader>accessible and update documentation- Refactored the
<XLoader>component to be more accessible - Updated the
<XLoader>documentation page - Adjusted styling to fit regular underlay styles when using "fullsize" mode
- Refactored the
-
38d461d: docs([DST-628]): Revise
<SearchField>pageRevised
<SearchField>documentation page according to the new structure. -
425ce62: fix(
<Text>): preventelementTypeprop from being passed down into the DOM. This is a prop used interally to make<Text>polymorphic. -
Updated dependencies [85e8cba]
- @marigold/system@10.1.1
10.1.0
Minor Changes
-
83ad341: feat(dialog): Introduce a dedicated button to close a dialog
Make it more convenient to have a button that closes the
<Dialog>. With this, there is less need to use the child function to access theclosemethod. Instead you can now use<Button slot="close">to render a close button.
Patch Changes
-
f2bae7e: fix: Remove
isOpenfrom<Select>The
isOpenprop was set by default. Remove it. Only required when controlled. -
80a9f5b: fix(Text): Only apply
elementTypewhen RAC Text component is used. -
2d701a6: docs[DST-611]: Revise
<Scrollable>documentation pageRevised the
<Scrollable>page according to our new structure of component documentation pages. -
a917acf: refa: Remove icons dependency from components package
Make
@marigold/componentsnot depend on@marigold/iconssince this might bloat the bundling. -
22200a0: docs([DST-581]): revise
<DateField>page according to new component page structureRevised the
<DateField>documentation page to our new layout of component pages. -
222f674: refa[DST-607]: revise
<Badge>pageThe
<Badge>was revised according to our new component guidelines. -
ac29d40: refa[DST-610]: Revise
<Card>pageThe
<Card>is now revised according to our new component page guidelines. -
ebc53cb: refa[DST-598]: Improve
<Slider>componentThe
<Slider>component appears in a new guise. Functionalities and documentation have been significantly revised. So make sure to check out the Marigold documentation and storybook. It's worth it.Some key features are:
- multithumb or range slider
- visual indicator for selected track
- use slider in forms
-
3bf3a8e: docs([DST-615]): Revise
<Center>documentationRevised the
<Center>page according to our new structure of component documentation. -
2cb5d38: feat(DST-596): add loading indicator in
<Button>componentIntroduced a new loading indicator for the
<Button>component's loading state, enhancing the visibility of its loading status. The<Button>now supports a loading property for this functionality. -
313f004: docs([DST-609]): Revise
<Columns>documentation pageRevised the
<Columns>page according to our new structure of component documentation pages. -
Updated dependencies [ebc53cb]
- @marigold/system@10.1.0
10.0.0
Major Changes
-
65608b4: fix([DSTSUP-94]): Adjust date unavailable property from
<DatePicker>Breaking Change: Adjusted
isDateUnavailableprop to our code guidelinesdateUnavailableAdded disabled styles for
data-unavailablein both b2b and core theme -
caefbe4: refa(listbox): Allow sections in
<Combobox>and<Autocomplete>, adjust Section API in<Select>,<Combobox>and<Autocomplete>.-
Added the possibility to use sections with
<Combobox>and<Autocomplete> -
Refactored the
<Section>(from<Listbox>) to fit our API, no need for the extra<Header>anymore. Instead you can do<Select.Section header="My header">, same for the other components -
Renamed
<Item>to<Option>in<Combobox>and<Autocomplete>to align with<Select> -
Updated the docs for
<Select>,<Combobox>and<Autocomplete> -
Updated Storybook for
<Select>,<Combobox>and<Autocomplete>with section stories -
Renamed the part of the
<ListBox>accordingly (fromsectionTitletoheader)BREAKING CHANGE: We changed the API of the
<Section>component that is used in<Select>,<Combobox>and<Autocomplete>. It is no longer necessary to add aHeaderwithin the<Section>.Use the newly added
headerprop instead. Additionally, to unify the APIs all choices of<Select>,<Combobox>and<Autocomplete>are now called<Option>instead of<Item>.
-
-
2d9917f: Breaking changes
Dialog.Headlinehas been renamed toDialog.Title. Please update your code accordingly.<Dialog.Content>and<Dialog.Actions>have been introduced for better organization and flexibility.- The internal layout now uses grid areas, ensuring consistent ordering and layout of the dialog elements.
- Existing implementations of the
<Dialog>component will need to be updated to use these new subcomponents.
Minor Changes
-
6f8e3a2: style(dialog): make
<Dialog>sizes responsiveUsing
sizewith a<Dialog>will allow the dialog to be at most sm/md/lg wide. Will use full width on smaller screens. -
6687af7: refa: remove footer from
<Dialog>+ allow styles- dialogs can only have action now
- align buttons in
<Dialog.Actions>correctly
-
2babc0b: feat(components): Mark layout components as regions for accessibility.
Added the ability to mark layout components as regions (ARIA role). This improves accessibility by allowing assistive technologies to identify significant sections of the page, making navigation easier for users with disabilities.
-
956982a: feat(components): Make
<Text>and<Headline>accessible by allowing ARIA labelling props<Text>and<Headline>will no longer cause type errors when ARIA labelling is used (aria-label,id, ...). -
df04623: Adding size to dialog component
Patch Changes
-
7ea3838: feat(Menu): pass
aria-labelto menu button instead of menu -
f18c8aa: [DST-494]: add loading states pattern
[DST-494]: added prop
modeto the<XLoader />to support inline and full-section loading -
d5386e4: fix(components): Display
<Checkbox>focus ring and adjust focus ring of<Table>Focus ring was not showing for the
<Checkbox>. It does now! -
5c029ec: feat(components): Expose
Selectiontype for easy usage withTableand other componentsWhen working with a
<Table>you can now useimport type { Selection } from '@marigold/components';instead of creating the type.
-
2169b6f: bugfix([DSTSUP-92]): fixed variants in table stories
At certain stories the control variants doesn't worked properly. Now it should work at least for all table stories.
-
bfd2843: chore: refa
<Text>component. Based on the slot property it now takes the RAC text or not. Needed to prevent other components breaking. -
0e77996: docs([DST-572]): Adding a general form guideline in docs explaining different concepts such as when to use lable and help text
-
b8cd92a: feat:
CheckboxGroupcan now be used as a compound component- Refactored the
CheckboxGroupto be a compound component and align it with other components:<CheckboxGroup>-><Checkbox.Group> - Adjusted the Checkbox appearance demo a bit
- Refactored the
-
45fb3c4: chore(deps): update react-aria to 1.4
-
f6a132c: docs([DST-582]): revise
<SectionMessage>page according to new component page structure feat(components): add close button on<SectionMessage>Revised the
<SectionMessage>documentation page to our new layout of component pages. And added a close button to allow the user to dismiss the<SectionMessage>this is now aligned with our feedback message pattern. -
Updated dependencies [caefbe4]
-
Updated dependencies [6687af7]
-
Updated dependencies [2babc0b]
-
Updated dependencies [45fb3c4]
-
Updated dependencies [956982a]
- @marigold/system@10.0.0
- @marigold/types@1.2.0
- @marigold/icons@1.2.58
9.0.2
Patch Changes
-
#4116
de0c9e9Thanks @aromko! - docs[DST-513]: Revise<Autocomplete>component page. -
#4102
d700af0Thanks @sebald! - feat: addasprop to Text to render different elements -
#4071
406fd1fThanks @sarahgm! - docs[DST-503]:Revise Select and add slots to text component -
#4125
46f06dbThanks @aromko! - docs[DST-517]: revise<Tabs>component -
#4146
66eae8fThanks @sarahgm! - fix: adjust visibility for autocomplete clear button -
#4143
77fe4adThanks @aromko! - Bugfix: fix datepicker storybook Controlled example -
#4134
d35cc6dThanks @sarahgm! - fix: fix DOM tree for empty tables -
#4110
b2b79d4Thanks @aromko! - docs[DST-511]: Revise switch component. -
#4115
0523f69Thanks @sarahgm! - fix: fix SelectListItem layout -
#4103
b8c991fThanks @sarahgm! - docs[DST-507]: revise<Inline>page -
Updated dependencies []:
- @marigold/system@9.0.2
- @marigold/icons@1.2.57
9.0.1
Patch Changes
-
#4056
5d53af4Thanks @aromko! - [DST-504]: Sorting indicator is shown only on sorted column. -
#4042
965512cThanks @sebald! - feat: allow to render an empty state when collection of<Table>is empty -
#4039
9598df4Thanks @sarahgm! - chore[DST-487]: align core styles to marigold -
Updated dependencies []:
- @marigold/system@9.0.1
- @marigold/icons@1.2.56
9.0.0
Major Changes
Patch Changes
-
#4032
0bf0940Thanks @sebald! - fix([DST-501]): Pass down appearance props and use context from CheckboxGroup to apply label width -
#4026
94e9a1bThanks @sebald! - fix: correctly apply styles to<Select>icon -
#4028
db4fa1dThanks @sebald! - docs: Introduce an appearance demo -
#4034
6195189Thanks @sebald! - fix([DST-500]): fix popover placement -
#4033
449de9bThanks @sebald! - fix([DST-501]): Don't render helptext if there is no error and description. -
#4027
391dcd1Thanks @sebald! - fix: pass down appearance props toFieldBaseinSelectandTextField -
Updated dependencies []:
- @marigold/system@9.0.0
- @marigold/icons@1.2.55
8.0.2
Patch Changes
-
#3992
ed3bd89Thanks @sebald! - refa: useFieldErrorContextin<HelpText>and fixkeyissue -
#4005
c64d71eThanks @OsamaAbdellateef! - Add ref to datepicker -
#3985
864ed08Thanks @sarahgm! - fix: adjust the triggerwidth of the autocomplete -
Updated dependencies []:
- @marigold/system@8.0.2
- @marigold/icons@1.2.54
8.0.1
Patch Changes
-
#3979
a02f284Thanks @sarahgm! - Fix: fix some props and add command to build step -
Updated dependencies [
a02f284]:- @marigold/system@8.0.1
- @marigold/icons@1.2.53
8.0.0
Major Changes
-
#3939
2cde433Thanks @sarahgm! - feat[DST-481]: rename<Message>in<SectionMessage> -
#3967
0773aa8Thanks @sebald! - refa: Update TypeScript and adjust<NumericFormat>props -
#3940
9c5b80cThanks @sarahgm! - [DST-461]: refactor<Message>component
Minor Changes
- #3942
5977cbaThanks @OsamaAbdellateef! - Keep our documentation props table dynamic
Patch Changes
-
#3959
d053e37Thanks @sebald! - chore: make github linter happy -
Updated dependencies [
2cde433,0773aa8,2658e2f,5977cba,3f7a4ec]:- @marigold/system@8.0.0
- @marigold/types@1.1.1
- @marigold/icons@1.2.52
7.8.2
Patch Changes
- Updated dependencies []:
- @marigold/system@7.8.2
- @marigold/icons@1.2.51
7.8.1
Patch Changes
-
#3924
290dc0eThanks @sebald! - fix: inconsistent naming ofSelectList -
Updated dependencies []:
- @marigold/system@7.8.1
- @marigold/icons@1.2.50
7.8.0
Minor Changes
Patch Changes
- Updated dependencies [
8c4631f]:- @marigold/system@7.8.0
- @marigold/icons@1.2.49
7.7.2
Patch Changes
- Updated dependencies []:
- @marigold/system@7.7.2
- @marigold/icons@1.2.48
7.7.1
Patch Changes
-
#3893
f57caecThanks @sarahgm! - feat: add className to MarigoldProvider -
#3898
a54d186Thanks @sebald! - feat: Ensure datepicker shows only date by default -
Updated dependencies []:
- @marigold/system@7.7.1
- @marigold/icons@1.2.47
7.7.0
Minor Changes
Patch Changes
-
#3885
72ece08Thanks @sebald! - fix:getColorcorrectly works with deeply nested values -
Updated dependencies [
72ece08,4a59427]:- @marigold/system@7.7.0
- @marigold/icons@1.2.46
7.6.0
Minor Changes
-
#3841
05d2ca0Thanks @sebald! - feat: Allow configure position of menu popover -
#3708
af1807bThanks @aromko! - Creating new componentSelectList
Patch Changes
- Updated dependencies []:
- @marigold/system@7.6.0
- @marigold/icons@1.2.45
7.5.4
Patch Changes
- Updated dependencies []:
- @marigold/system@7.5.4
- @marigold/icons@1.2.44
7.5.3
Patch Changes
-
#3834
7fd7ad7Thanks @OsamaAbdellateef! - Adding cursor hover for tag component in multiselect -
#3824
879a0e1Thanks @OsamaAbdellateef! - Adding Multiselect guideline -
#3829
81a84e5Thanks @sarahgm! - chore[DSTSUP-65]: fix demo and add overlayprovider to tooltip -
Updated dependencies []:
- @marigold/system@7.5.3
- @marigold/icons@1.2.43
7.5.2
Patch Changes
-
#3828
f996764Thanks @aromko! - BUGFIX: fix onClear on SearchInput.tsx -
#3827
95ce246Thanks @sebald! - fix: restore defaultcollapseAtfor<Columns> -
Updated dependencies []:
- @marigold/system@7.5.2
- @marigold/icons@1.2.42
7.5.1
Patch Changes
-
#3802
d4479c7Thanks @sarahgm! - fix: changing the token back to z-40 from underlay -
#3777
02f1934Thanks @sarahgm! - [DST-271]:feat: Column allow fit width of item -
#3810
dea175aThanks @aromko! - [DSTSUP-60]: add examples using state in table with input fields [DSTSUP-60]: adduseListDatahook to docs -
#3812
3d1e813Thanks @sarahgm! - [DSTSUP-59]:fix if no label no gap style -
#3803
886ff54Thanks @sarahgm! - fix: add possibility to align Checkbox to FieldGroups -
Updated dependencies [
fba5e92]:- @marigold/system@7.5.1
- @marigold/icons@1.2.41
7.5.0
Minor Changes
Patch Changes
-
#3764
ade96cfThanks @sarahgm! - [DSTSUP-54]: feat: update link token in core theme -
#3772
d6c44faThanks @OsamaAbdellateef! - Fix Select component in small screens -
Updated dependencies [
5643257,07d9277]:- @marigold/system@7.5.0
- @marigold/icons@1.2.40
7.4.0
Minor Changes
-
#3702
dbaadebThanks @sarahgm! - [DST-279]: remove overlay provider -
#3713
2b9e03eThanks @sebald! - feat: Render empty state of<Tag>
Patch Changes
-
#3750
ebea32eThanks @sebald! - fix([DSTSUP-31]): prevent immediately selection is Select/Combobox/Autocomplete -
#3722
c61895dThanks @sebald! - fix: corelinedTablevariant works again -
#3720
4d2f94fThanks @sarahgm! - fix[DSTSUP-41]: Combobox styles for icon -
#3715
7969fd9Thanks @sebald! - fix: add placeholder prop toComboboxtypes -
Updated dependencies [
4d2f94f]:- @marigold/system@7.4.0
- @marigold/icons@1.2.39
7.3.3
Patch Changes
-
#3690
b37c3eeThanks @sebald! - fix: unify clear buttons in search fields -
Updated dependencies []:
- @marigold/system@7.3.3
- @marigold/icons@1.2.38
7.3.2
Patch Changes
-
#3683
c2c7e71Thanks @sebald! - fix:placeholderprop was missing onTextArea -
Updated dependencies []:
- @marigold/system@7.3.2
- @marigold/icons@1.2.37
7.3.1
Patch Changes
-
#3660
35ff260Thanks @sarahgm! - fix: fixSwitchpositioning in themes -
#3668
01148acThanks @OsamaAbdellateef! - [DSTSUP-30]: Fix-select-width -
#3676
63d407eThanks @sebald! - feat: usesize-util (also fixes linting) -
Updated dependencies [
f8ed8d1,63d407e]:- @marigold/icons@1.2.36
- @marigold/system@7.3.1
7.3.0
Minor Changes
Patch Changes
-
#3653
34a7482Thanks @sebald! - fix([DSTSUP-23]): Correctly prefix days/months with zeroes -
#3654
fd16ef5Thanks @sebald! - fix([DSTSUP-19]): Allow Popovers to outgrow their trigger element -
#3645
7e3aa28Thanks @OsamaAbdellateef! - Adding onClear prop over Autocomplete component -
#3656
c1fb6aaThanks @sarahgm! - feat[DSTSUP-17]: add placeholder text styles for b2b theme -
#3649
299941bThanks @sebald! - feat([DSTSUP-22]): Disablecmd+a(open all items) in<Accordion> -
Updated dependencies [
b4999d8]:- @marigold/system@7.3.0
- @marigold/icons@1.2.35
7.2.0
Minor Changes
-
#3592
0b23a25Thanks @sebald! - feat: Enable built-in browser validation -
#3596
9f1ae32Thanks @OsamaAbdellateef! - Added new Helpers componentsNumericFormat&DateFormat -
#3589
b228e09Thanks @sarahgm! - chore: Updatereact-aria-componentsto v1.0.0 -
#3575
cba7099Thanks @sarahgm! - feat[DST-263]: new component<Scrollable>!!! -
#3593
46e1a41Thanks @OsamaAbdellateef! - Adding sticky header feature to tables
Patch Changes
-
#3517
7a8d40aThanks @sarahgm! - chore[DST-220]: seperate data-theme attribute and classnames on provider (so you don't need any data-theme attribute anymore) -
#3623
6697a67Thanks @sarahgm! - chore: [DSTSUP-13]: add disabled also on the<ActionMenu> -
#3639
d76a835Thanks @OsamaAbdellateef! - Fixing Table Selectable header alignment -
Updated dependencies [
7a8d40a,9f1ae32]:- @marigold/system@7.2.0
- @marigold/icons@1.2.34
7.1.0
Minor Changes
-
#3551
49a702446Thanks @OsamaAbdellateef! - Adding Table Column alignment feature -
#3576
08e89a407Thanks @sebald! - feat: expose form fromreact-aria-components
Patch Changes
-
#3571
6a4d1e8d0Thanks @sarahgm! - fix[DSTSUP-10]: add min/max props to textfield -
#3554
b6cb6edceThanks @sarahgm! - RAC: DatePicker as react aria component -
#3563
4fa5dee85Thanks @sarahgm! - fix: add placeholder property to autocomplete -
#3564
a984d90e2Thanks @sebald! - refa: remov cloning children in<Columns> -
#3562
b3fd3e5e0Thanks @sarahgm! - fix:<Menu>can contain disabled button -
#3557
47f300029Thanks @aromko! - [DSTSUP-5]: Bugfix: Loss of input values after collapsing accordion elements is now prevented by hiding the corresponding section. -
#3577
63b093ad8Thanks @OsamaAbdellateef! - Fixing Scrollable table story -
#3552
e2fa304a6Thanks @aromko! - [DSTSUP-4] bugfix accordion item do not collapse and hide after first click -
Updated dependencies [
47f300029,535d1088b]:- @marigold/system@7.1.0
- @marigold/icons@1.2.33
7.0.0
Major Changes
-
#3542
3952ee0e8Thanks @sarahgm! - RAC: Menu react aria components[!WARNING] >BREAKCING CHANGE<Menu.Item>no longer us thekeyprop as unique identifier, use theidprop instead. To migrate, rename all<Menu.item key="something"/>to<Menu.item id="something"/>. -
#3535
e4cfbc7d1Thanks @OsamaAbdellateef! - Migrate Select component to RAC[!WARNING] >BREAKCING CHANGE<Select.Option>no longer us thekeyprop as unique identifier, use theidprop instead. To migrate, rename all<Select.Option key="something"/>to<Select.Option id="something"/>. -
#3546
9c61ffe09Thanks @sebald! - refa: MigrateComBoxto RAC[!WARNING] >BREAKCING CHANGE<ComboBox.Item>no longer us thekeyprop as unique identifier, use theidprop instead. To migrate, rename all<ComboBox.item key="something"/>to<ComboBox.item id="something"/>. -
#3550
30167bb78Thanks @sarahgm! - RAC: Autocomplete[!WARNING] >BREAKCING CHANGE<Autocomplete.Item>no longer us thekeyprop as unique identifier, use theidprop instead. To migrate, rename all<Autocomplete.item key="something"/>to<Autocomplete.item id="something"/>.
Patch Changes
-
#3544
dc5c193e0Thanks @sarahgm! - feat: new table variant borderedTable for b2b theme -
#3527
4ae97c004Thanks @aromko! - chore[DST-258]<Checkbox>storybook improvements -
#3540
72125e114Thanks @aromko! - RAC: migrate<Calendar>,<DatePicker>,<DateField>component -
#3529
f3a45c302Thanks @aromko! - RAC: use new<Input>component in all affected components -
Updated dependencies [
72125e114]:- @marigold/system@7.0.0
- @marigold/icons@1.2.32
6.11.0
Minor Changes
-
#3520
bc96dda88Thanks @OsamaAbdellateef! - Introduce RAC popover component -
#3445
91badb0e1Thanks @OsamaAbdellateef! - migrate ListBox component to RAC
Patch Changes
-
#3522
a748252c5Thanks @aromko! - chore[DST-255]:<Button>storybook improvements -
#3537
148034202Thanks @sebald! - feat: MakePopoverat least as wide as trigger element -
#3531
071bd792aThanks @aromko! - chore: add placeholder to TextFieldProps -
#3530
51611dbe0Thanks @sarahgm! - fix: remove Dialog trigger out of Popover -
#3521
f972b3a25Thanks @sarahgm! - chore[DST-256]:<XLoader>storybook improvements -
#3525
cf59ce1e4Thanks @aromko! - chore[DST-257]:<Card>storybook improvements -
#3536
bc09a9ce1Thanks @sarahgm! - RAC: add "Tray" behavior inside Popover -
#3519
849f4c534Thanks @sarahgm! - chore: remove unusedstretchprop and improve storybook story -
#3513
cdc17ee83Thanks @aromko! - RAC: migrate<TagGroup>component -
Updated dependencies [
cdc17ee83]:- @marigold/system@6.11.0
- @marigold/icons@1.2.31
6.10.0
Minor Changes
-
#3501
14f5d5d30Thanks @OsamaAbdellateef! - Migrate Tabs to RAC Tabs -
#3514
5a3d71caeThanks @sebald! - feat([DST-249]): Add feedback variants to<Badge>
Patch Changes
-
#3512
213d32f5bThanks @sebald! - fix([DST-243]): Fix<Listbox>overflowing the<Popover> -
#3515
aac41db30Thanks @sebald! - fix: SearchField is missing from export index -
#3516
71eb13b30Thanks @aromko! - chore: remove some unnecessary exports -
Updated dependencies [
14f5d5d30]:- @marigold/system@6.10.0
- @marigold/icons@1.2.30
6.9.1
Patch Changes
- Updated dependencies []:
- @marigold/system@6.9.1
- @marigold/icons@1.2.29
6.9.0
Minor Changes
-
#3505
c068869a9Thanks @sebald! - feat: add a success<Message>variant -
#3482
a16541314Thanks @OsamaAbdellateef! - Dialog & Modal migration
Patch Changes
-
#3500
79eaec78cThanks @aromko! - RAC: migrate<NumberField /> -
#3481
729158c87Thanks @aromko! - RAC: migrate TextField component -
#3499
f19a502d4Thanks @sarahgm! - RAC:DateFieldto react-aria-components -
#3487
75bad8b84Thanks @sarahgm! - RAC:<Tooltip>to react aria components -
Updated dependencies []:
- @marigold/system@6.9.0
- @marigold/icons@1.2.28
6.8.0
Minor Changes
- #3471
c76bd48a2Thanks @OsamaAbdellateef! - Adding a fixed-height scrollable table example
Patch Changes
-
#3476
30b94e542Thanks @OsamaAbdellateef! - Fixing Scrollable table story -
#3483
3a21b538aThanks @aromko! - chore: add data-required attribute for label -
#3480
4c76cf114Thanks @sarahgm! - RAC: addFieldErrorinHelpText -
Updated dependencies []:
- @marigold/system@6.8.0
- @marigold/icons@1.2.27
6.7.0
Minor Changes
- #3473
22446fa66Thanks @sebald! - refa: Updatereact-aria-componentstorc.0,CheckboxGroupandHelpText
Patch Changes
- Updated dependencies []:
- @marigold/system@6.7.0
- @marigold/icons@1.2.26
6.6.4
Patch Changes
-
#3466
174f534b5Thanks @sarahgm! - chore: adjust core switch -
#3468
cac5ef60dThanks @OsamaAbdellateef! - Adding selected prop over Switch component -
Updated dependencies []:
- @marigold/system@6.6.4
- @marigold/icons@1.2.25
6.6.3
Patch Changes
- Updated dependencies []:
- @marigold/system@6.6.3
- @marigold/icons@1.2.24
6.6.2
Patch Changes
- Updated dependencies []:
- @marigold/system@6.6.2
- @marigold/icons@1.2.23
6.6.1
Patch Changes
- Updated dependencies []:
- @marigold/system@6.6.1
- @marigold/icons@1.2.22
6.6.0
Minor Changes
-
#3452
43e792d6aThanks @sarahgm! - feat: exposeRouterProvider -
#3416
7704debbeThanks @OsamaAbdellateef! - [DST-38]: Implement mobile optimization forDatePicker
Patch Changes
-
#3451
f2b764380Thanks @sebald! - fix:<Checkbox>"checked" state -
Updated dependencies [
7704debbe]:- @marigold/system@6.6.0
- @marigold/icons@1.2.21
6.5.1
Patch Changes
-
80ac67eacThanks @sebald! - fix:FieldBaserenders empty element when no label is given -
Updated dependencies []:
- @marigold/system@6.5.1
- @marigold/icons@1.2.20
6.5.0
Minor Changes
Patch Changes
-
#3434
5e1219c84Thanks @sebald! - fix([DST-228]): Hotfixreact-ariaso space works inside forms in an accordion -
Updated dependencies []:
- @marigold/system@6.5.0
- @marigold/icons@1.2.19
6.4.0
Minor Changes
-
#3405
1eb93352aThanks @sarahgm! - RAC: updatedButtonto react aria components -
#3429
3e328198cThanks @sebald! - feat: adjust<SliderOutput>position -
#3422
e5869b2f3Thanks @sebald! - refa: Make<FieldBase>work with RAC components -
#3406
e968e5eb5Thanks @sarahgm! - RAC: Label as React aria Component -
#3408
78840aa04Thanks @sarahgm! - RAC: Headline as React Aria Component -
#3407
0fbb7f963Thanks @sarahgm! - RAC: Divider as React Aria Component -
#3400
700cdf296Thanks @OsamaAbdellateef! - Replace oldSliderwith the new RACslider -
#3424
5a2a03ae0Thanks @sebald! - feat: add styles to checkbox and radio groups -
#3392
5ed86abd0Thanks @sarahgm! - RAC: Link as react aria component
Patch Changes
-
#3432
9b0ed3862Thanks @sebald! - fix: adjust chevrons in accordion -
#3423
470d00c6dThanks @sebald! - fix: add gap in checkbox group -
Updated dependencies [
3e328198c,e5869b2f3,5a2a03ae0]:- @marigold/system@6.4.0
- @marigold/types@1.1.0
- @marigold/icons@1.2.18
6.3.1
Patch Changes
-
#3402
d8b3cca2dThanks @sarahgm! - fix[DST-222]: Select width by item -
Updated dependencies []:
- @marigold/system@6.3.1
- @marigold/icons@1.2.17
6.3.0
Minor Changes
Patch Changes
-
#3394
ea9db88fdThanks @sarahgm! - fix: width props for switch and slider -
Updated dependencies []:
- @marigold/system@6.3.0
- @marigold/icons@1.2.16
6.2.6
Patch Changes
-
#3366
1d305f963Thanks @sarahgm! - fix: allow width on datepicker -
Updated dependencies []:
- @marigold/system@6.2.6
- @marigold/icons@1.2.15
6.2.5
Patch Changes
-
#3331
b9e1d147aThanks @sebald! - fix: correctly apply spacing in<Inset> -
#3339
581702881Thanks @sarahgm! - chore: add<Card>size to b2b theme -
Updated dependencies []:
- @marigold/system@6.2.5
- @marigold/icons@1.2.14
6.2.4
Patch Changes
- Updated dependencies []:
- @marigold/system@6.2.4
- @marigold/icons@1.2.13
6.2.3
Patch Changes
-
#3273
f7c475053Thanks @renovate! - chore(deps): update react-aria -
Updated dependencies []:
- @marigold/system@6.2.3
- @marigold/icons@1.2.12
6.2.2
Patch Changes
-
46e86e2b3Thanks @sebald! - fix: Resolve conflicting type dependencies inreact-aria -
Updated dependencies []:
- @marigold/system@6.2.2
- @marigold/icons@1.2.11
6.2.1
Patch Changes
-
#3314
a5515f34bThanks @sarahgm! - change jsx compiler option to react-jsx -
Updated dependencies []:
- @marigold/system@6.2.1
- @marigold/icons@1.2.10
6.2.0
Minor Changes
- #3293
3eba5fdd4Thanks @OsamaAbdellateef! - fix with for checkbox in multi-select tables
Patch Changes
-
#3311
6329c32acThanks @OsamaAbdellateef! - [DST-96]: Improve sorting table -
Updated dependencies []:
- @marigold/system@6.2.0
- @marigold/icons@1.2.9
6.1.0 (Released on Aug 27, 2026)
Minor Changes
-
#3270
c2629d7c8Thanks @OsamaAbdellateef! - Adding option to specify table column width -
#3250
989f094e7Thanks @OsamaAbdellateef! - [DST-111]: enhance styling tabs -
#3268
c61999892Thanks @sebald! - feat: checkbox adheres labelwidth when inside<FieldGroup>
Patch Changes
- Updated dependencies [
566ec30e4,989f094e7,8a4ef1805]:- @marigold/system@6.1.0
- @marigold/icons@1.2.8
6.0.1
Patch Changes
-
#3232
fd10c294aThanks @OsamaAbdellateef! - [DST-65]: Spacing of Popover can me customized based on themes -
Updated dependencies [
fd10c294a]:- @marigold/system@6.0.1
- @marigold/icons@1.2.7
6.0.0 (Released on Aug 11, 2026)
Major Changes
- #3117
79be927e6Thanks @sebald! - Switch @marigold/styles to Tailwind CSS, replaces Emotion CSS & Theme-UI
Patch Changes
-
#3137
1d0fd2ac5Thanks @sebald! - fix:<Text>component doesn't enforce defaults -
#3229
7b7348f30Thanks @sarahgm! - chore[DST-60]: change depricated API -
#3003
9082cfe4fThanks @renovate! - chore(deps): update react-aria -
Updated dependencies [
79be927e6]:- @marigold/system@6.0.0
- @marigold/icons@1.2.6
5.6.0
Minor Changes
-
#2947
a35f82a13Thanks @OsamaAbdellateef! - Releasing DateField component -
#2953
992d76d1bThanks @OsamaAbdellateef! - Introducing DateField component -
#2912
3fbeb7b17Thanks @OsamaAbdellateef! - Introducing Tabs component -
#2951
fc5411f39Thanks @aromko! - feat: Add tag group component<Tag/>+<Tag.Group/> -
#2932
85039a29cThanks @OsamaAbdellateef! - Introducing Calendar component -
#2955
e285e0c94Thanks @OsamaAbdellateef! - Adding New ComboBox Component
Patch Changes
-
#2928
dc791efabThanks @renovate! - chore(deps): update react-aria -
Updated dependencies []:
- @marigold/system@5.6.0
- @marigold/icons@1.2.5
5.5.0 (Released on Jul 8, 2026)
Minor Changes
-
#2915
4c2cd1b45Thanks @sarahgm! - feat: new Accordion Component -
#2921
b07dab50cThanks @sebald! - feat: let the<Body>flex 💪 -
#2920
a56d83788Thanks @sebald! - feat:<Card>is no a flex col by default + configure gap viaspaceprop
Patch Changes
-
#2877
862963f54Thanks @OsamaAbdellateef! - feat: added menu section -
Updated dependencies []:
- @marigold/system@5.5.0
- @marigold/icons@1.2.4
5.4.0 (Released on Jun 15, 2026)
Minor Changes
Patch Changes
-
#2894
b3d577339Thanks @renovate! - chore(deps): update dependency @types/react to v18.0.29 -
Updated dependencies [
b3d577339,8972cbaca]:- @marigold/types@1.0.1
- @marigold/system@5.4.0
- @marigold/icons@1.2.3
5.3.0
Minor Changes
-
#2826
aaf6b55c6Thanks @sarahgm! - refa: Improved<Input>with icons/actions -
#2846
3a766be9dThanks @sebald! - feat: Styles for<Autocomplete>
Patch Changes
-
#2816
cda6ac809Thanks @renovate! - chore(deps): update react-aria -
Updated dependencies [
aaf6b55c6,80cdbe062]:- @marigold/system@5.3.0
- @marigold/icons@1.2.2
5.2.0
Minor Changes
-
#2807
f9175829dThanks @sarahgm! - chore: update storybook to version 7 + fix coverage -
#2824
33329ace2Thanks @sarahgm! - chore: refa<Input>and<Input.Field>components and support icons -
#2805
c0609c0b3Thanks @sebald! - feat: introduce<Inset>component
Patch Changes
- Updated dependencies [
f11e2d7db]:- @marigold/system@5.2.0
- @marigold/icons@1.2.1
5.1.0
Patch Changes
5.0.0
Major Changes
-
#2764
1ff29cc0cThanks @sebald! - refa: fix polymorph types + remove style props from<Box>BREAKING CHANGE:
We deprecated the available short hands for styling on the
<Box>component (also known as style props), for example<Box p="small">. This way it is more clear what to use when ->always thecss` prop.How to update your code: Basically move all style props to the
cssprop. E.g.<Box p="small" bg="primary">becomes<Box css={{ p: "small, bg; "primary" }}>. -
#2740
7a61d39f4Thanks @sarahgm! - chore: rename onSelect to onAction in Menu component -
#2733
9cb030c11Thanks @sarahgm! - chore: change prop onSelectionChange to onChange for select component
Minor Changes
-
#2766
6d9b36b6aThanks @sebald! - feat: addopenprop toDialog.Controller -
#2760
fafc52cbbThanks @sarahgm! - feat: Allow<Dialog>to be controlled via<Dialog.Controller‚> -
#2759
596b7b901Thanks @sarahgm! - feat: update Menu.Trigger with open and onOpenChange property
Patch Changes
-
#2741
f65487486Thanks @sarahgm! - chore: add<ActionMenu>Component with dots -
#2726
0f539b788Thanks @renovate! - chore(deps): update dependency @types/react to v18.0.27 -
Updated dependencies [
1ff29cc0c,0f539b788]:- @marigold/system@5.0.0
- @marigold/types@1.0.0
- @marigold/icons@1.1.17
4.2.2
Patch Changes
-
#2714
55c7cd7eThanks @benediktgrether! - fix: set max-height to ul instead of div -
#2699
c9725e77Thanks @renovate! - chore(deps): update react-aria -
Updated dependencies []:
- @marigold/icons@1.1.16
- @marigold/system@4.2.2
- @marigold/tokens@3.1.0
4.2.1
Patch Changes
-
#2694
c7b919a3Thanks @sarahgm! - fix: fix on pointer event for menu and select -
Updated dependencies []:
- @marigold/system@4.2.1
- @marigold/icons@1.1.15
4.2.0
Minor Changes
- #2688
1bfe10cfThanks @sarahgm! - feat: add<Fieldbase>to<RadioGroup>and<CheckboxGroup>to support errorMessage and helptext
Patch Changes
-
#2689
8675c5f2Thanks @benediktgrether! - fix: add in FieldBase component position relative to fix position absolute bug in HiddenSelect component -
#2683
7be11c1aThanks @sarahgm! - feat: add<Tray>for responsiveness in<Menu>and<Select> -
#2684
14463546Thanks @sarahgm! - refa: removed icon dependency from @marigold/components -
#2687
7954ba24Thanks @sarahgm! - fix:<Radio>tabs in default selected value instead of first -
Updated dependencies []:
- @marigold/system@4.2.0
- @marigold/icons@1.1.14
4.1.5
Patch Changes
-
#2674
832da2a6Thanks @sarahgm! - refa: refactoring Popover with usePopover -
Updated dependencies [
832da2a6]:- @marigold/types@0.5.7
- @marigold/icons@1.1.13
- @marigold/system@4.1.5
- @marigold/tokens@3.1.0
4.1.4
Patch Changes
- Updated dependencies []:
- @marigold/system@4.1.4
- @marigold/icons@1.1.12
4.1.3
Patch Changes
- Updated dependencies []:
- @marigold/system@4.1.3
- @marigold/icons@1.1.11
4.1.2
Patch Changes
4.1.1
Patch Changes
-
Updated dependencies []:
- @marigold/system@4.1.1
- @marigold/icons@1.1.9
4.1.0
Minor Changes
-
#2647
f764d3a0Thanks @sebald! - feat: addfontWeightstyle prop to<Text>component -
#2576
7a9129c1Thanks @sarahgm! - feat: add side property to label
Patch Changes
-
#2652
40aeefd7Thanks @sebald! - feat: Improve<Message>look -
#2651
2e98753dThanks @sebald! - fix:<Menu>width is adjusted by its content not the trigger -
#2643
473ae72bThanks @renovate! - chore(deps): update react-aria -
#2619
727460fcThanks @sebald! - fix: set<Switch>width in flex so it doesn't shrink below a certain threshold -
Updated dependencies [
312a23cf,080b1fed,d250fc00]:- @marigold/system@4.1.0
- @marigold/types@0.5.6
- @marigold/icons@1.1.8
4.0.0
Major Changes
-
#2610
eb35da96Thanks @sebald! - feat:<Tiles>can now be used as a grid with fixed widths or fully respsonsive.BREAKING CHANGE: Renamed the whole API. Please checkout the documentation at https://marigold-ui.io/components/tiles/#props
Patch Changes
-
#2607
41f60e3dThanks @benediktgrether! - fix: add missing values for one point and set begin of first dot to 0.0s -
#2612
31e1219dThanks @sarahgm! - chore: add hover color and flex property -
Updated dependencies [
02bd8efe,be3f2060,f38ae20a,4554b26e]:- @marigold/icons@1.1.7
- @marigold/system@4.0.0
- @marigold/types@0.5.5
3.0.6
Patch Changes
- Updated dependencies [
d8fc387d]:- @marigold/system@3.0.6
- @marigold/icons@1.1.6
3.0.5
Patch Changes
-
#2575
0441cd20Thanks @sarahgm! - feat:<XLoader>component for loading states -
Updated dependencies []:
- @marigold/system@3.0.5
- @marigold/icons@1.1.5
3.0.4
Patch Changes
-
#2564
09745fcaThanks @sarahgm! - chore: add card, text style for core -
#2569
b20b0111Thanks @sarahgm! - chore: add gridAutoRows to<Tiles> -
#2568
51a95328Thanks @sarahgm! - feat: improve headline with align and color property -
Updated dependencies []:
- @marigold/system@3.0.4
- @marigold/icons@1.1.4
3.0.3
Patch Changes
-
#2561
04c7f2ebThanks @sebald! - fix:<Table>stretch works as expected -
Updated dependencies []:
- @marigold/system@3.0.3
- @marigold/icons@1.1.3
3.0.2
Patch Changes
-
#2560
7368d457Thanks @sebald! - fix: allow<NumberField>with little width -
Updated dependencies [
e65171c6,d9974f91]:- @marigold/system@3.0.2
- @marigold/icons@1.1.2
3.0.1
Patch Changes
-
#2509
fb7b1b9fThanks @benediktgrether! - refa: improve usage offitprop -
Updated dependencies [
4af6c016,eb7e453c]:- @marigold/types@0.5.4
- @marigold/system@3.0.1
- @marigold/icons@1.1.1
3.0.0
Major Changes
- #2463
fcb15230Thanks @sebald! - refa: Improve behavior of<Stack>and remove option to render it as a list (use<List>instead)<Stack>will no longer align items by default, since this will cause children to not take all the available space<Stack as="ul|ol">will no longer work, we have a<List>comopnent for that
Minor Changes
-
#2490
baf5bb57Thanks @sebald! - feat:Columnscan stretch to available height viastretchprop + don't collapse by default -
#2470
7b9c90ecThanks @sebald! - feat: introduceextendThemehelper, for more information see https://marigold-ui.io/introduction/theming/#extend-an-existing-theme
Patch Changes
-
#2458
20aeba63Thanks @sebald! - fix: style props override theme in<Text> -
#2460
4495fcb1Thanks @sarahgm! - chore: add height prop to Breakout and refactor docs page -
#2462
885e3ca4Thanks @sebald! - fix: use 'initial' for defaultContaineritem alignment -
#2496
d10bb310Thanks @benediktgrether! - chore: change property names in breakout to alignX and AlignY -
Updated dependencies [
87600058,a795f29a]:- @marigold/icons@1.1.0
- @marigold/system@3.0.0
2.2.0
Minor Changes
-
#2411
a4ccb92fThanks @sebald! - feat:cssprops supports array (again) + padding props for<Card> -
#2415
d5116b5dThanks @sebald! - refa: Improve<Container>API and make it reponsive
Patch Changes
-
#2313
75128374Thanks @renovate! - chore(deps): update dependency @types/react to v18.0.19 -
#2443
fb76bbbeThanks @sarahgm! - fix: downgrade aria-focus version -
#2440
515ea633Thanks @sarahgm! - fix: use useLocalizedStringFormatter instead of depricated useMessage… -
#2437
23a78264Thanks @renovate! - chore(deps): update testing (major) -
#2438
535f80daThanks @sebald! - fix:Columnswork with complex and different children types -
Updated dependencies [
75128374,f76f4870,23a78264,a4ccb92f]:- @marigold/types@0.5.3
- @marigold/system@2.2.0
- @marigold/icons@1.0.5
2.1.3
Patch Changes
-
#2399
beea5b0bThanks @sebald! - feat: Make text in non-interactive tables selectable -
#2378
d5fd75cbThanks @sarahgm! - docs: fix responsive layout and responsive table -
Updated dependencies [
d3143f65,f6b49c37]:- @marigold/icons@1.0.4
- @marigold/system@2.1.3
2.1.2
Patch Changes
-
#2361
b84e6ff5Thanks @sarahgm! - chore: update table with compact and expanded -
Updated dependencies [
630d8026,294e31e3]:- @marigold/icons@1.0.3
- @marigold/system@2.1.2
2.1.1
Patch Changes
- Updated dependencies []:
- @marigold/system@2.1.1
- @marigold/icons@1.0.2
2.1.0
Minor Changes
Patch Changes
-
#2326
6e236e78Thanks @sebald! - fix: correctly apply read only state to<Checkbox> -
Updated dependencies []:
- @marigold/system@2.1.0
- @marigold/icons@1.0.1
2.0.0 (Released on Aug 27, 2026)
Minor Changes
- #2285
6f3b6949Thanks @sebald! - feat:<Button>correctly pass through all native props and option to take full width
Patch Changes
-
#2272
fb9df312Thanks @renovate! - chore(deps): update testing -
Updated dependencies [
13695db8,32353f56,4c63400f,f4f308e4,8e9ea3da,406f186c,88a3d4b0,997ccfc1]:- @marigold/icons@1.0.0
- @marigold/tokens@3.1.0
- @marigold/system@2.0.0
1.3.0
Minor Changes
Patch Changes
-
#2211
527b222fThanks @sarahgm! - chore: next link component -
Updated dependencies [
c60f8527]:- @marigold/system@1.3.0
- @marigold/icons@0.7.7
1.2.2
Patch Changes
-
#2177
51132dd8Thanks @renovate! - chore(deps): update react-aria -
Updated dependencies []:
- @marigold/system@1.2.2
- @marigold/icons@0.7.6
1.2.1
Patch Changes
-
Updated dependencies [
b43464fc]:- @marigold/icons@0.7.5
- @marigold/system@1.2.1
- @marigold/types@0.5.2
1.2.0
Minor Changes
Patch Changes
-
#2152
8980b645Thanks @sebald! - feat: forward ref for<Switch> -
Updated dependencies [
82c376a9]:- @marigold/system@1.2.0
- @marigold/icons@0.7.4
1.1.1
Patch Changes
- Updated dependencies []:
- @marigold/system@1.1.1
- @marigold/icons@0.7.3
1.1.0
Minor Changes
Patch Changes
-
#2113
5a32c4b4Thanks @sebald! - feat: Show sorting in<Table> -
Updated dependencies []:
- @marigold/system@1.1.0
- @marigold/icons@0.7.2
1.0.1
Patch Changes
-
#2102
23c1a5ceThanks @sebald! - feat: Remove all occurances ofReact.FC -
Updated dependencies [
23c1a5ce,bfa0caea]:- @marigold/system@1.0.1
- @marigold/types@0.5.1
- @marigold/icons@0.7.1
1.0.0 (Released on Aug 11, 2026)
Major Changes
- #2069
c35afcf2Thanks @sebald! - refa:<Tooltip>- with arrow pointer yay!
- allows to change placement
- uses
useComponentStyles
- #2074
3aa2c100Thanks @sebald! - refa: Remove "variant" prop from<Box>, useuseComponentStylesinstead
Minor Changes
Patch Changes
- #2079
04db9229Thanks @sebald! - fix: Indeterminate is visual only + correctly render with checkbox only
-
#2049
5f64c882Thanks @sarahgm! - refa: switch with new styling -
Updated dependencies [
a41bb8a3,02d13e84,6a369f5f,2ab80ae6,f5128944,3abbc813,3aa2c100]:- @marigold/tokens@3.0.0
- @marigold/system@1.0.0
- @marigold/types@0.5.0
- @marigold/icons@0.7.0
1.0.0-beta.0
Major Changes
Minor Changes
Patch Changes
-
#2049
5f64c882Thanks @sarahgm! - refa: switch with new styling -
Updated dependencies [
02d13e84,6a369f5f,2ab80ae6,f5128944,3abbc813]:- @marigold/system@1.0.0-beta.0
- @marigold/types@0.5.0-beta.0
- @marigold/icons@0.7.0-beta.0
0.9.0
Minor Changes
Patch Changes
-
#1984
733f5488Thanks @sarahgm! - refa: Image new styling solution -
Updated dependencies [
424f1705,dbc55934,3dff2282,7c1129dc]:- @marigold/system@0.9.0
- @marigold/types@0.4.1
- @marigold/icons@0.6.1
0.8.0
Minor Changes
Patch Changes
-
#1926
5e5e0fccThanks @ti10le! - feat(comp): Container with grid -
Updated dependencies [
382ac6cc,2f45aa5d,5319745c,74c91e28]:- @marigold/system@0.8.0
- @marigold/icons@0.6.0
- @marigold/tokens@2.0.0
0.7.0
Minor Changes
Patch Changes
- Updated dependencies [
af566de4]:- @marigold/tokens@1.0.0
- @marigold/system@0.7.0
- @marigold/icons@0.5.1
0.6.0
Minor Changes
Patch Changes
-
#1852
25c8675eThanks @ti10le! - refa(comp): fill prop instead of css or __basCSS -
Updated dependencies [
4cc0ad3b,64b9089e,539d4198,e053b7b9]:- @marigold/system@0.6.0
- @marigold/icons@0.5.0
0.5.1
Patch Changes
-
#1798
9939b743Thanks @sebald! - fix(components): Use ownflattenChildrenhelper to fix ESM build -
Updated dependencies [
a178eafe]:- @marigold/system@0.5.1
- @marigold/icons@0.4.2
0.5.0
Minor Changes
- #1727
026300b1Thanks @sebald! - feat(components):<Text>add possibility to change font size via style props
Patch Changes
-
#1775
6da8eba2Thanks @ti10le! - feat(comp): Checkbox remove label prop and add children + refa -
Updated dependencies [
5936de75]:- @marigold/system@0.5.0
- @marigold/icons@0.4.1
0.4.0 (Released on Jul 8, 2026)
Minor Changes
Patch Changes
-
f9526234Thanks @sebald! - feat(comp): rewrite Field component with react-aria -
Updated dependencies [
f9526234,f9526234]:- @marigold/icons@0.4.0
- @marigold/system@0.4.0
- @marigold/types@0.4.0
0.3.2
Patch Changes
0.3.1
Patch Changes
-
#1676
379041bcThanks @ti10le! - remove the last mdx stories -
Updated dependencies [
379041bc]:- @marigold/icons@0.3.1
- @marigold/system@0.3.1
0.3.0 (Released on Jun 18, 2026)
Patch Changes
- #1189
be8dc989Thanks @sebald! - feat(components):<Stack>correctly uses whitespace and supports usage as list
- #1316
edfec8d9Thanks @ti10le! - aria-label for all usages of select component use SSR Provider which is exported from package components/Provider in Gatsby wrapper
- #1556
470f6e8dThanks @ti10le! - feat(comp): remove span from button and add some styles to the button element, add space prop to button
- #1521
00588fefThanks @ti10le! - feat(comp/docs): change Inline component default align + use it in DoAndDont
- #1230
ebd6e26fThanks @viktoria-schwarz! - feat: add GlobalStyles via theme
- #1448
ab879e66Thanks @ti10le! - feature: replace useStyles in Badge, Menu, Message and ValidationMessage
- #1506
7b2a0374Thanks @ti10le! - infra(packages): add icons package as dependency to component package
- #1221
3885f64cThanks @viktoria-schwarz! - feat(storybook): add Welcome stories and additional config
- #1131
0ccc10deThanks @sebald! - feat(types): Clarify and improve polymorphic types by calling it by its actual name ... polymorphic! We also added types when norefshould be passed.
-
#1589
8cbcb91aThanks @sebald! - feat: normalize<SVG>and move to system packageBREAKING:
<SVG>moved from@marigold/iconsto@marigold/system
-
#1132
b6614f1fThanks @sebald! - feat(compoents): Make<Text>and<Link>polymorphic<Text>- the
asprop supports arbitrary inputs - supporst ref
- supports style props (text-align, color, cursor, user-select)
<Link>- the
asprop supports arbitrary inputs - does not support
ref! - improved accessibility (react-aria)
- the
-
#1522
6a82a490Thanks @ti10le! - feat(comp): use Inline in ActionGroup -
Updated dependencies [
c030aa85,8eda245f,5a04de11,c1da52c0,1448ddca,5107b943,cd3a0d3e,ebd6e26f,6e485f5a,80a2abe5,e13e3cc1,1829cf17,1c1f8648,51af6693,a00b7eb9,7b2a0374,ec5baf85,0bb8f19e,c4ae5c5c,a1ef2108,2f7b936f,8cbcb91a,846eb640,5d63cd9c,46aede50]:- @marigold/system@0.3.0
- @marigold/icons@0.3.0