@nxgt/material 3.11.0 → 3.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +6 -7
  3. package/dist/components/components.css +1 -0
  4. package/dist/components/ui/feedback/toast/toast-expressive.css +17 -0
  5. package/dist/components/ui/layout/app-shell/activity-backdrop-shapes.css +49 -0
  6. package/dist/components/ui/layout/app-shell/activity-backdrop.css +0 -17
  7. package/dist/components/ui/layout/sidebar/sidebar-tokens.css +7 -2
  8. package/dist/{components-1GK7YIhY.js → components-yx1t_5_P.js} +13981 -13660
  9. package/dist/components.js +3 -3
  10. package/dist/editor.js +1 -1
  11. package/dist/lib/components/ui/display/badge/badge.d.ts +7 -2
  12. package/dist/lib/components/ui/display/entity-header/entity-header.d.ts +9 -1
  13. package/dist/lib/components/ui/display/entity-header/entity-stats.d.ts +16 -0
  14. package/dist/lib/components/ui/display/entity-header/partials/entity-header-actions.d.ts +6 -0
  15. package/dist/lib/components/ui/display/entity-header/partials/entity-header-body.d.ts +14 -0
  16. package/dist/lib/components/ui/display/entity-header/partials/entity-header-icon.d.ts +6 -0
  17. package/dist/lib/components/ui/display/entity-header/partials/shown.d.ts +2 -0
  18. package/dist/lib/components/ui/display/list-tile/list-tile.d.ts +8 -1
  19. package/dist/lib/components/ui/display/list-tile/partials/list-tile-body.d.ts +2 -1
  20. package/dist/lib/components/ui/display/stat-card/index.d.ts +1 -1
  21. package/dist/lib/components/ui/display/stat-card/partials/stat-card-compact.d.ts +12 -0
  22. package/dist/lib/components/ui/display/stat-card/stat-card-classes.d.ts +3 -2
  23. package/dist/lib/components/ui/display/stat-card/stat-card.d.ts +2 -2
  24. package/dist/lib/components/ui/display/stat-card/types.d.ts +9 -0
  25. package/dist/lib/components/ui/feedback/alert/alert-variants.d.ts +18 -0
  26. package/dist/lib/components/ui/feedback/alert/alert.d.ts +2 -6
  27. package/dist/lib/components/ui/layout/app-shell/activity-column.d.ts +17 -0
  28. package/dist/lib/components/ui/layout/app-shell/activity-layout.d.ts +3 -106
  29. package/dist/lib/components/ui/layout/app-shell/activity-layout.types.d.ts +113 -0
  30. package/dist/lib/components/ui/layout/app-shell/app-breadcrumb.d.ts +2 -1
  31. package/dist/lib/components/ui/layout/app-shell/app-sidebar-icon-item.d.ts +13 -0
  32. package/dist/lib/components/ui/layout/app-shell/app-sidebar-label-item.d.ts +11 -0
  33. package/dist/lib/components/ui/layout/app-shell/keep-shapes-inside.d.ts +6 -0
  34. package/dist/lib/components/ui/layout/app-shell/observe-layout.d.ts +11 -0
  35. package/dist/lib/components/ui/layout/app-shell/shape-units.d.ts +16 -0
  36. package/dist/lib/components/ui/layout/app-shell/shapes-clear-content.d.ts +13 -0
  37. package/dist/lib/components/ui/layout/app-shell/types.d.ts +10 -0
  38. package/dist/lib/components/ui/layout/app-shell/use-keep-shapes-inside.d.ts +14 -0
  39. package/dist/lib/components/ui/layout/app-shell/watch-content.d.ts +19 -0
  40. package/dist/lib/components/ui/tones.d.ts +1 -1
  41. package/dist/main.js +3 -3
  42. package/dist/material.css +1 -1
  43. package/dist/{use-chat-composer-Bt2ULsv6.js → use-chat-composer-B0_STpQN.js} +1 -1
  44. package/docs/components/data-display.md +40 -9
  45. package/docs/components/feedback-and-status.md +12 -1
  46. package/docs/components/navigation-and-layout.md +3 -2
  47. package/docs/guides/app-shell.md +52 -8
  48. package/docs/guides/backgrounds.md +2 -0
  49. package/docs/guides/theming.md +4 -3
  50. package/docs/previews/data-display-badge.webp +0 -0
  51. package/docs/previews/data-display-entityheader.webp +0 -0
  52. package/docs/previews/data-display-listtile.webp +0 -0
  53. package/docs/previews/data-display-statcard.webp +0 -0
  54. package/docs/previews/feedback-status-banner.webp +0 -0
  55. package/docs/previews/navigation-layout-appshell-footer-icon.webp +0 -0
  56. package/docs/previews/navigation-layout-appshell-menu-badge.webp +0 -0
  57. package/docs/previews/navigation-layout-appshell.webp +0 -0
  58. package/docs/previews/navigation-layout-sidebar.webp +0 -0
  59. package/docs/roadmap.md +18 -0
  60. package/docs/troubleshooting.md +17 -2
  61. package/lib/components/components.css +1 -0
  62. package/lib/components/ui/feedback/toast/toast-expressive.css +17 -0
  63. package/lib/components/ui/layout/app-shell/activity-backdrop-shapes.css +49 -0
  64. package/lib/components/ui/layout/app-shell/activity-backdrop.css +0 -17
  65. package/lib/components/ui/layout/sidebar/sidebar-tokens.css +7 -2
  66. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # @nxgt/material
2
2
 
3
+ ## 3.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1472](https://github.com/softistx/nxgt-material/pull/1472) [`d01b87a`](https://github.com/softistx/nxgt-material/commit/d01b87a5be1e5b82cc46749fb67fe9193aac338f) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `StatCard` gets a compact `size="sm"`, `EntityHeader` a `stats` prop, and `Banner` takes `Alert`'s look.
8
+
9
+ - `StatCard size="sm"` is a tile 40 to 56 px tall for a header band: the optional icon, then the value (tabular figures) over its label. It keeps `tone` and `variant`; `hint`, `delta` and `valueSize` are ignored. Tiles in a `flex flex-wrap` row wrap on a phone. New type `StatCardSize`.
10
+ - `EntityHeader` takes `stats` (`{ label, value, tone? }[]`), rendered as these tiles under `metadata`, so figures show as tiles while facts stay in `metadata`. New type `EntityStat`.
11
+ - `Banner` keeps its role and API (page level, `action`, `onDismiss`, default icon per tone) but now looks exactly like `Alert`: the light tone surface, the start accent bar, the tone-coloured icon, the title and description typography and the padding. It shares `Alert`'s variants, so the two cannot drift. Visual change: the solid tinted fill, the full tone border and the rounded corners are gone. `Alert` itself is unchanged, apart from its icon wrapper carrying `data-slot="alert-icon"` and its icon colour, size and margin rules now applying to the SVG inside that wrapper only, not to any SVG in its text.
12
+
13
+ - [#1467](https://github.com/softistx/nxgt-material/pull/1467) [`338a8fe`](https://github.com/softistx/nxgt-material/commit/338a8fe79cb47dccaa52632da1eaa5d49bc1ef38) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `Badge` becomes a status badge: a 20 px pill with the `label-sm` text, compact padding and no hover or pointer affordance (a `Badge` link no longer fades on hover). New `soft` variant, a tonal fill from the tone tokens and the recommended variant for a state, and a `tone` prop for `soft` and `outlined` (neutral by default; `BadgeTone` is the library's `Tone`, so a tone declared in `AppTones` works too); `outlined` is now a thin 1 px line at 40 % of the tone. Visual change: every Badge is 20 px high and a little smaller in text, `CountBadge` keeps its own h-4 / 10 px size and loses the hover. `ListTile` with an `href` now ends with a discreet, decorative chevron after `trailing` (flipped in right-to-left); `chevron={false}` opts out, `chevron` opts a button tile in. A tile that already passes its own `ChevronRight` as `trailing` shows two: drop yours or pass `chevron={false}`.
14
+
15
+ - [#1477](https://github.com/softistx/nxgt-material/pull/1477) [`90290fd`](https://github.com/softistx/nxgt-material/commit/90290fdedb66bd7a88932e910ad810e90e83826c) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `ActivityLayout` takes `breadcrumb` (default `true`): `breadcrumb={false}` hides the trail, for an error page whose matched routes would show a misleading one ([#1475](https://github.com/softistx/nxgt-material/issues/1475)). The trail is also hidden when every matched `handle.breadcrumb` renders `null`, and a crumb that renders `null` is left out with its separator. The Autocomplete and Combobox options no longer shrink below their content on a coarse pointer when the list scrolls: `ComboboxList` uses `auto-rows-max` ([#1474](https://github.com/softistx/nxgt-material/issues/1474)).
16
+
17
+ - [#1465](https://github.com/softistx/nxgt-material/pull/1465) [`af31879`](https://github.com/softistx/nxgt-material/commit/af31879654725cdf62ea753b994b6e2d2aee3386) Thanks [@SteveGT96](https://github.com/SteveGT96)! - ActivityLayout and `AppSidebar`: a `MenuItem` takes `display?: 'icon'`. On a `footer` entry (a "Settings") it is drawn as a round, icon-only `IconButton` in the collapsed rail, the expanded sidebar and the phone's menu sheet: the label is its tooltip and its accessible name, it is `aria-current="page"` and tonal when active, and its target is 44 px on a coarse pointer. Entries without it keep their icon and label.
18
+
19
+ **Visual change** (every `SidebarMenuItem`, `AppSidebar` and `ActivityLayout`): the active entry's label and icon are drawn in primary at 85 % of its lightness in light (`--sidebar-active-foreground`), so the label reads 4.5:1 or more on its pill for every theme preset (it was `--primary` itself, 3.7:1 on the corail preset's pill). The dark foreground and the pills are unchanged. A theme that sets `--sidebar-active-foreground` is unaffected.
20
+
21
+ ### Patch Changes
22
+
23
+ - [#1479](https://github.com/softistx/nxgt-material/pull/1479) [`f8779d6`](https://github.com/softistx/nxgt-material/commit/f8779d6d56a06eff970b1676e472884a769cd4b9) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `ActivityLayout`'s backdrop no longer draws a shape over the page's text or fields ([#1478](https://github.com/softistx/nxgt-material/issues/1478)). Shapes of a theme's background or of a `backdrop` `Background` (the motif and illustrated presets) are now hidden while they lie over, or within 8px of, a line of text or a control of the content: they fade out in 150ms (none under reduced motion) and fade back once clear, on scroll, resize and when the content changes. A moon, a planet or an eclipse is hidden whole, with its halo. They are hidden, never moved, so the shapes keep their places in the empty space, and nothing shows before the first check. The check keeps the content's boxes and only shifts them on scroll (rAF-throttled). The backdrop stays below the content (`-z-10`), under dialogs, sheets and sticky headers. Visible change: on a phone, and on a page that fills the column, fewer shapes show. Docs: the app-shell guide's "Where the shapes go".
24
+
25
+ - [#1481](https://github.com/softistx/nxgt-material/pull/1481) [`eff59eb`](https://github.com/softistx/nxgt-material/commit/eff59eb10fc9d272e3e84d1fc85bde0d46d18214) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Stacked toasts pass axe's `target-size` on a coarse pointer again. Fixes [#1480](https://github.com/softistx/nxgt-material/issues/1480).
26
+
27
+ A toast behind the front one in a collapsed stack is scaled and offset under it, so its covered close button (41.8 px once scaled, overlapping the front one's hit area) failed `target-size` since 3.11. The buttons (action and close) of such a toast are now hidden (`visibility: hidden`) until the stack opens on hover, or while focus is inside the toaster, so a Tab from the front toast still reaches them. Nothing changes for a single toast or an expanded stack.
28
+
3
29
  ## 3.11.0
4
30
 
5
31
  ### Minor Changes
package/README.md CHANGED
@@ -420,7 +420,7 @@ Each area a consumer starts from has its own page under `docs/guides/`.
420
420
  | --- | --- |
421
421
  | [Forms](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/forms.md) | wiring fields to React Hook Form and Zod, composite values (contacts, opening hours), config-driven `Field`, server errors, what each field emits |
422
422
  | [i18n](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/i18n.md) | adding your strings next to the package's, switching language, translated Zod messages, SSR without a text mismatch |
423
- | [App shell](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/app-shell.md) | laying out an app with `ActivityLayout` (route changes cross-fade by default, `routeTransition={false}` opts out; it draws the theme's background, `backdrop` is the exception and `backdrop={false}` a plain page), its `items` (rendered as links; `linkComponent` to pass your own), the brand (`logo`, `name`, and `context` for the phone sheet's tenant line), the header's title, a route's `handle.title` as the page's `h1` in the app bar (`AppShellHandle`, `PageTitle`; it labels `<main>`, and `usePageTitleFocus()` focuses it after a navigation), and `AccountMenu`, the active entry and breadcrumbs (needs a data router; `breadcrumbRoot` replaces the home icon with a text link), the `<main>` landmark, the `h1` title, document scrolling, and a background preset behind the shell (`backdrop`) |
423
+ | [App shell](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/app-shell.md) | laying out an app with `ActivityLayout` (route changes cross-fade by default, `routeTransition={false}` opts out; it draws the theme's background, `backdrop` is the exception and `backdrop={false}` a plain page), its `items` (rendered as links; `linkComponent` to pass your own), the brand (`logo`, `name`, and `context` for the phone sheet's tenant line), the header's title, a route's `handle.title` as the page's `h1` in the app bar (`AppShellHandle`, `PageTitle`; it labels `<main>`, and `usePageTitleFocus()` focuses it after a navigation), and `AccountMenu`, the active entry and breadcrumbs (needs a data router; `breadcrumbRoot` replaces the home icon with a text link, `breadcrumb={false}` hides the trail), the `<main>` landmark, the `h1` title, document scrolling, and a background preset behind the shell (`backdrop`) |
424
424
  | [Themes for your app](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/themes.md) | defining app themes, generating their stylesheets and types with the Vite plugin's `themes` option or the `nxgt-theme` command, the CI check |
425
425
  | [Theming](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/theming.md) | changing colours, radius or fonts, motion and corner tokens, dark mode, tones (the `data-tone` channel, app tones and the calm zone `data-density="calm"`), touch targets, using the compiled CSS without Tailwind |
426
426
  | [Printing](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/printing.md) | producing PDFs with `@nxgt/material/print` and getting the file in one call (download, new tab, preview, server `Response`) — its own entry since 2.0.0, with optional peers, a bundling trap on SSR servers, and the `next.config.ts` a Next.js route handler (and `output: 'standalone'`) needs |
@@ -593,20 +593,19 @@ Not components: what the stylesheet gives any element.
593
593
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-avatar.webp" width="120" alt="Avatar"> | [`Avatar`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#avatar), `AvatarImage`, `AvatarFallback`, `AvatarBase` | Image with a fallback and an optional online / offline dot; `shape` clips it to an expressive shape; `tone` colours the fallback. | `Avatar`, `AvatarImage`, `AvatarFallback` |
594
594
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-avatargroup.webp" width="120" alt="AvatarGroup"> | [`AvatarGroup`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#avatargroup) | Overlapping avatars with a `+N` overflow. | `AvatarGroup` |
595
595
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-shape.webp" width="120" alt="Shape"> | [`Shape`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#shape) | Material 3 Expressive's 35 shapes and a squircle as a backdrop, an icon container or a mask for a photo, with a morph; eight tones or an app tone. | — |
596
- | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-badge.webp" width="120" alt="Badge"> | [`Badge`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#badge) | Pill label: default, secondary, error, success, info, warning, outlined. | `Badge` |
596
+ | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-badge.webp" width="120" alt="Badge"> | [`Badge`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#badge) | Status pill, 20 px: default, secondary, error, success, info, warning, `soft` (tonal, for states), outlined. | `Badge` |
597
597
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-countbadge.webp" width="120" alt="CountBadge"> | [`CountBadge`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#countbadge) | Count in the corner of its children, capped at `99+` and hidden at 0; `animated` pops it in when it changes. | `CountBadge` |
598
- | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-countbadge.webp" width="120" alt="CountBadge"> | [`CountBadge`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#countbadge) | Count in the corner of its children, capped at `99+` and hidden at 0. | `CountBadge` |
599
598
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-dayseparator.webp" width="120" alt="DaySeparator"> | [`DaySeparator`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#dayseparator), `isNewDay`, `formatDayLabel` | "Today", "Yesterday", the weekday or the date between two hairlines, in the provider's language; sticky if asked. | — |
600
599
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-periodcards.webp" width="120" alt="PeriodCards"> | [`PeriodCards`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#periodcards) | Consecutive date ranges (terms, sprints) as cards: a "Current" marker with `aria-current`, a link over each card, as many 14rem columns as fit (one on a phone). | — |
601
600
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-chip.webp" width="120" alt="Chip"> | [`Chip`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#chip) | Compact pill in three looks (hairline, soft, tag) and a dashed add pill, with leading, avatar and trailing slots, a selected state and a dismiss button; a coloured soft chip reads as a status (the tone's container, its text colour on it). | `Chip` |
602
- | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-statcard.webp" width="120" alt="StatCard"> | [`StatCard`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#statcard) | KPI tile with value, hint, icon, toned delta and a loading skeleton; `tone` and `variant` (`outlined`, `tonal`, `filled`) colour it, `valueSize` enlarges the value. | `StatCard` |
601
+ | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-statcard.webp" width="120" alt="StatCard"> | [`StatCard`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#statcard) | KPI tile with value, hint, icon, toned delta and a loading skeleton; `tone` and `variant` (`outlined`, `tonal`, `filled`) colour it, `valueSize` enlarges the value, `size="sm"` makes a compact tile (it ignores `hint`, `delta` and `valueSize`). | `StatCard` |
603
602
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-metric-cards.webp" width="120" alt="TrendCard"> | [`TrendCard`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#metric-cards), `GoalCard`, `BreakdownCard`, `RankCard`, `CompareCard`, `HeatweekCard`, `FunnelCard`, `GaugeCard`, `SparkbarCard`, `DeltaListCard`, `BandCard`, `LatencyCard`, `RatioCard`, `ThresholdCard`, `PaceCard`, `HistogramCard`, `Sparkline` | Dashboard tiles including compare, heat, funnel, gauge, spark bars, delta list, range band, latency, ratio, threshold, pace and labelled histogram. Container queries. A `tone` (named, or your app's) draws the accent in it; deltas and breaches stay semantic. | `TrendCard`, `GoalCard`, `BreakdownCard`, `RankCard`, `CompareCard`, `HeatweekCard`, `FunnelCard`, `GaugeCard`, `SparkbarCard`, `DeltaListCard`, `BandCard`, `LatencyCard`, `RatioCard`, `ThresholdCard`, `PaceCard`, `HistogramCard` |
604
603
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-card-presets.webp" width="120" alt="FeatureCard"> | [`FeatureCard`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#card-presets), `MediaCard`, `PricingCard`, `ProfileCard`, `QuoteCard`, `OverlayCard`, `SpotlightCard`, `CrewCard`, `SplitCard`, `TicketCard`, `NoticeCard`, `TimelineCard`, `MessageCard`, `EventCard`, `StackCard`, `LinkCard`, `AlbumCard`, `TagCard`, `ReceiptCard`, `ReviewCard`, `OfferCard`, `PlaceCard`, `FileCard`, `StatusCard`, `ScoreCard`, `ShortcutCard`, `ChecklistCard` | Card presets including overlay, ticket, inbox, event, stack, link, album, tags, receipt, review, offer, place, file, status, score, shortcuts and checklist. Container queries. | `FeatureCard`, `MediaCard`, `PricingCard`, `ProfileCard`, `QuoteCard`, `OverlayCard`, `SpotlightCard`, `CrewCard`, `SplitCard`, `TicketCard`, `NoticeCard`, `TimelineCard`, `MessageCard`, `EventCard`, `StackCard`, `LinkCard`, `AlbumCard`, `TagCard`, `ReceiptCard`, `ReviewCard`, `OfferCard`, `PlaceCard`, `FileCard`, `StatusCard`, `ScoreCard`, `ShortcutCard`, `ChecklistCard` |
605
604
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-statusindicator.webp" width="120" alt="StatusIndicator"> | [`StatusIndicator`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#statusindicator) | Coloured status dot with an optional pulse and label. | `StatusIndicator` |
606
605
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-summarydata.webp" width="120" alt="SummaryData"> | [`SummaryData`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#summarydata) | Label / value pairs as a grid or inline; hides empty values. | `SummaryData` |
607
606
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-description.webp" width="120" alt="Description"> | [`Description`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#description) | Read-only label / value pair that renders nothing when empty. | `Description` |
608
- | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-entityheader.webp" width="120" alt="EntityHeader"> | [`EntityHeader`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#entityheader) | Page header with icon, title, status, metadata and actions. | `EntityHeader` |
609
- | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-listtile.webp" width="120" alt="ListTile"> | [`ListTile`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#listtile) | Row with leading / trailing slots, title and subtitle; becomes a link or button when interactive. `size="sm"` is the dense row. | `ListTile` |
607
+ | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-entityheader.webp" width="120" alt="EntityHeader"> | [`EntityHeader`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#entityheader) | Page header with icon, title, status, metadata, `stats` (figures as compact `size="sm"` StatCard tiles) and actions. | `EntityHeader` |
608
+ | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-listtile.webp" width="120" alt="ListTile"> | [`ListTile`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#listtile) | Row with leading / trailing slots, title and subtitle; becomes a link (with a decorative chevron) or button when interactive. `size="sm"` is the dense row. | `ListTile` |
610
609
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-accordioncard.webp" width="120" alt="AccordionCard"> | [`AccordionCard`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#accordioncard) | Renders `items` (title, content) as a styled accordion. | `AccordionCard` |
611
610
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-timeline.webp" width="120" alt="Timeline"> | [`Timeline`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#timeline), `TimelineItem`, `RelativeTime` | Vertical event timeline with toned icons and relative times. | `Timeline`, `TimelineItem`, `RelativeTime` |
612
611
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-display-eventchip.webp" width="120" alt="EventChip"> | [`EventChip`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-display.md#eventchip) | Calendar event pill — soft, solid or outlined — with its times, all-day and continuation edges. | `EventChip` |
@@ -682,7 +681,7 @@ Not components: what the stylesheet gives any element.
682
681
  | Preview | Component | What it does | @nxgt/material-vue |
683
682
  | --- | --- | --- | --- |
684
683
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-alert.webp" width="120" alt="Alert"> | [`Alert`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#alert) | Callout with icon, title and description in seven tones. | `Alert` |
685
- | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-banner.webp" width="120" alt="Banner"> | [`Banner`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#banner) | Dismissible info / success / warning / error banner with an action. | `Banner` |
684
+ | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-banner.webp" width="120" alt="Banner"> | [`Banner`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#banner) | Dismissible info / success / warning / error banner with an action, in the look of `Alert` (light surface, start bar). | `Banner` |
686
685
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-alertdialog.webp" width="120" alt="AlertDialog"> | [`AlertDialog`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#alertdialog), `AlertDialogContent`, `AlertDialogAction`, `AlertDialogCancel`… | Parts for a blocking confirmation dialog. | `AlertDialog` (same parts) |
687
686
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-confirmdialog.webp" width="120" alt="ConfirmDialog"> | [`ConfirmDialog`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#confirmdialog), `ConfirmationDialog`, `CustomAlertDialog` | Confirm / cancel dialog with async loading. `ConfirmationDialog` adds a trigger and an optional Zod form. | `ConfirmDialog`, `ConfirmationDialog`, `CustomAlertDialog` |
688
687
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-customdialog.webp" width="120" alt="CustomDialog"> | [`CustomDialog`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#customdialog) | Ready-made dialog with trigger, icon, title, body and footer. | `CustomDialog` |
@@ -55,6 +55,7 @@
55
55
  /* ActivityLayout: the route transition (cross-fade, none under reduced motion). */
56
56
  @import "./ui/layout/app-shell/route-transition.css";
57
57
  @import "./ui/layout/app-shell/activity-backdrop.css";
58
+ @import "./ui/layout/app-shell/activity-backdrop-shapes.css";
58
59
  /* DataTable cards and tiles: the item shell (hairline, tint, start bar, columns by the list's width). */
59
60
  @import "./ui/collections/data-table/data-table-items.css";
60
61
  @import "./ui/collections/data-table/data-table-items-compact.css";
@@ -107,6 +107,23 @@
107
107
  gap: 8px;
108
108
  margin-inline-start: auto;
109
109
  }
110
+ /* A stacked toast behind the front one (`data-expanded="false"`,
111
+ * `data-front="false"`) sits under it, scaled and offset by a few pixels:
112
+ * its buttons are covered, so a tap lands on the front toast, and a covered,
113
+ * scaled close button fails axe's `target-size` (#1480). Its buttons are
114
+ * hidden until the stack opens (sonner opens it on hover, not on focus) or
115
+ * focus is inside the toaster, so a Tab from the front toast still reaches
116
+ * them. Sonner's own `opacity: 0` for these does not apply to our unstyled
117
+ * (`data-styled="false"`) toasts. */
118
+ [data-sonner-toast][data-expanded="false"][data-front="false"]
119
+ .nxgt-toast-buttons {
120
+ visibility: hidden;
121
+ }
122
+ [data-sonner-toaster]:focus-within
123
+ [data-sonner-toast][data-expanded="false"][data-front="false"]
124
+ .nxgt-toast-buttons {
125
+ visibility: visible;
126
+ }
110
127
  .nxgt-toast-title {
111
128
  color: var(--toast-fg);
112
129
  }
@@ -0,0 +1,49 @@
1
+ /* Which shapes of the backdrop show (observe-layout.ts, watch-content.ts).
2
+ * Plain CSS in `@layer components`, beside activity-backdrop.css. */
3
+ @layer components {
4
+ /* The theme's backdrop keeps its shapes whole (keep-shapes-inside.ts):
5
+ * the scene waits for the first pass, then a shape that would cross the
6
+ * layer's edge or reach the header band is hidden, never cut. */
7
+ [data-keep-inside]:not([data-checked]) .mo,
8
+ [data-slot="activity-layout-backdrop"]
9
+ [data-background]:not([data-checked])
10
+ .mo {
11
+ visibility: hidden;
12
+ }
13
+ [data-keep-inside] .mo > [data-outside],
14
+ [data-slot="activity-layout-backdrop"]
15
+ [data-background]
16
+ .mo
17
+ > [data-outside] {
18
+ visibility: hidden;
19
+ }
20
+
21
+ /* A shape over the page's text or controls fades out and comes back once
22
+ * clear (watch-content.ts): it is hidden, never moved. A compound body (the
23
+ * moon, the planet, the eclipse: `.pt.mg`) is hidden whole, with its halo
24
+ * (`.pt.mh`). The scene stays invisible until the first check, so nothing
25
+ * flashes over the content. */
26
+ [data-keep-inside] .mo > *,
27
+ [data-keep-inside] .pt,
28
+ [data-slot="activity-layout-backdrop"] [data-background] .mo > *,
29
+ [data-slot="activity-layout-backdrop"] [data-background] .pt {
30
+ transition: opacity 150ms ease;
31
+ }
32
+ /* Important: a preset sets its own opacity on a body (`.md`, the dark
33
+ * moon's, a celestial body's); in a layer, `!important` beats every normal
34
+ * declaration of those. The 150 ms transition still runs. */
35
+ [data-keep-inside] .mo > [data-hidden],
36
+ [data-keep-inside] .pt[data-hidden],
37
+ [data-slot="activity-layout-backdrop"] [data-background] .mo > [data-hidden],
38
+ [data-slot="activity-layout-backdrop"] [data-background] .pt[data-hidden] {
39
+ opacity: 0 !important;
40
+ }
41
+ @media (prefers-reduced-motion: reduce) {
42
+ [data-keep-inside] .mo > *,
43
+ [data-keep-inside] .pt,
44
+ [data-slot="activity-layout-backdrop"] [data-background] .mo > *,
45
+ [data-slot="activity-layout-backdrop"] [data-background] .pt {
46
+ transition: none;
47
+ }
48
+ }
49
+ }
@@ -77,23 +77,6 @@
77
77
  display: none;
78
78
  }
79
79
 
80
- /* The theme's backdrop keeps its shapes whole (use-keep-shapes-inside.ts):
81
- * the scene waits for the first pass, then a shape that would cross the
82
- * layer's edge or reach the header band is hidden, never cut. */
83
- [data-keep-inside]:not([data-checked]) .mo,
84
- [data-slot="activity-layout-backdrop"]
85
- [data-background]:not([data-checked])
86
- .mo {
87
- visibility: hidden;
88
- }
89
- [data-keep-inside] .mo > [data-outside],
90
- [data-slot="activity-layout-backdrop"]
91
- [data-background]
92
- .mo
93
- > [data-outside] {
94
- visibility: hidden;
95
- }
96
-
97
80
  /* A preset fills the layer: the layer's size, not `100lvw x 100lvh`, which
98
81
  * counts the scrollbar and a phone's toolbar. */
99
82
  [data-slot="activity-layout-backdrop"] > [data-background] {
@@ -3,13 +3,18 @@
3
3
  :root {
4
4
  /* The active entry of the sidebar and the navigation rail: its tint, the
5
5
  * tint hovered, the start bar (the label's colour), and the icon and label drawn on it. Translucent primary
6
- * (these shares, 15 % and 20 % hovered); the label is primary itself. The
6
+ * (these shares, 15 % and 20 % hovered); the label is primary at 85 % of its lightness in light (a lavender of its hue in dark). The
7
7
  * utilities (`bg-sidebar-active`...) derive them on the element, so they
8
8
  * follow a `--primary` set below :root. To theme the rail set
9
9
  * `--sidebar-active`, `--sidebar-active-hover` and
10
10
  * `--sidebar-active-foreground` (all three, or the first two and the
11
11
  * foreground); the derived colours are not declared here, on purpose. */
12
12
  --nxgt-sidebar-active-share: 15%;
13
+ /* Light: primary itself reads 4.5:1 on the page but not on its own 15 % pill
14
+ * for every preset (corail 3.7:1), so the label is primary darkened to 85 %
15
+ * of its lightness (4.99:1 on the worst preset, hovered). The preset spec
16
+ * (sidebar-active-contrast.test.ts) reads this number back. */
17
+ --nxgt-sidebar-active-l: calc(l * 0.85);
13
18
  /* The height of the app bar and of the rail's header from `md` up, so the
14
19
  * rail's logo and the bar's title share one centre line. Phones keep the
15
20
  * bar alone at this height; the menu sheet's header is unconstrained. */
@@ -24,7 +29,7 @@
24
29
  /* The dark theme's primary is too dark to read on its surfaces (2.5:1), so
25
30
  * the rail's label is a saturated lavender of its hue (5.3:1: lightness
26
31
  * 0.72, chroma 0.15) on a denser pill (30 %, 35 % hovered). Light keeps the
27
- * lightness and chroma of primary (the `l` and `c` fallbacks). */
32
+ * chroma of primary and 85 % of its lightness. */
28
33
  --nxgt-sidebar-active-share: 30%;
29
34
  --nxgt-sidebar-active-hover-share: 35%;
30
35
  --nxgt-sidebar-active-l: 0.72;