@nxgt/material 3.104.0 → 3.106.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.
- package/CHANGELOG.md +12 -0
- package/dist/components/ui/collections/data-table/data-table-items-tiles.css +14 -0
- package/dist/components/ui/collections/data-table/data-table-items.css +22 -0
- package/dist/{components-B2wrH_W0.js → components-lIJfPhab.js} +1901 -1889
- package/dist/components.js +1 -1
- package/dist/lib/components/ui/collections/data-table/layout-types.d.ts +14 -0
- package/dist/lib/components/ui/collections/data-table/types.d.ts +2 -3
- package/dist/lib/components/ui/layout/app-shell/app-sidebar-entries.d.ts +3 -1
- package/dist/lib/components/ui/layout/app-shell/app-sidebar-group.d.ts +8 -3
- package/dist/lib/components/ui/layout/app-shell/app-sidebar.d.ts +3 -1
- package/dist/lib/components/ui/layout/app-shell/types.d.ts +15 -0
- package/dist/lib/components/ui/layout/pane-layout/pane-layout-phone-frames.d.ts +20 -0
- package/dist/main.js +1 -1
- package/dist/material.css +1 -1
- package/docs/components/data-table-filter-and-lists.md +1 -0
- package/docs/components/navigation-and-layout.md +1 -1
- package/docs/guides/app-shell.md +22 -2
- package/docs/guides/cards-and-tiles.md +20 -0
- package/lib/components/ui/collections/data-table/data-table-items-tiles.css +14 -0
- package/lib/components/ui/collections/data-table/data-table-items.css +22 -0
- package/package.json +1 -1
|
@@ -97,6 +97,7 @@ table enables, for typing your own column defs.
|
|
|
97
97
|
| `data` | `T[]` | — | rows; sorting, filtering and pagination run client-side |
|
|
98
98
|
| `layout` | `'table' \| 'cards' \| 'tiles' \| { phone, wide }` | `'table'` | `'cards'` lays the rows out as a list of cards, `'tiles'` as one column in a single surface ([Cards and tiles](../guides/cards-and-tiles.md)); both ignore `virtual`, `renderExpandedRow` and `showViewOptions` |
|
|
99
99
|
| `cardDensity` | `'comfortable' \| 'compact'` | `'comfortable'` | `compact` fits cards of at least `--nxgt-cards-min` (15rem), up to four a row, with a tighter padding; `layout="cards"` only ([Cards and tiles](../guides/cards-and-tiles.md#columns)) |
|
|
100
|
+
| `surface` | `'card' \| 'none'` | `'card'` | `'none'` drops the surface of a `cards` or `tiles` list so it sits on a card that already has one (no card in a card): the table's fill and padding go, tiles lose the list's border and corners (rows stay split by hairlines), cards lose their border and fill (one column stays split by hairlines) ([Cards and tiles](../guides/cards-and-tiles.md#inside-a-card)); the `table` layout ignores it |
|
|
100
101
|
| `renderCard` | `(row, { Title, Actions, Row, selected, locked, reason }) => ReactNode` | — | a card's content, required with `layout="cards"`; `Title` is the card's one link and its name; `Actions` is the trailing action slot (outside the link, at least 44px); `Row` (the compact record row) is also passed, laid out inside the card's own padding, with no height of its own |
|
|
101
102
|
| `renderTile` | `(row, { Title, Actions, Row, selected, locked, reason }) => ReactNode` | — | a tile's content, required with `layout="tiles"`; same `Title` as a card, or `Row`, the compact record row (title, subtitle, chips, trailing facts; see the cards and tiles guide) |
|
|
102
103
|
| `renderExpandedRow` | `(row) => ReactNode` | — | makes rows expandable; pair with the `expand` column |
|
|
@@ -82,7 +82,7 @@ phone's menu sheet pad clear of `env(safe-area-inset-*)`, as classes; see the
|
|
|
82
82
|
|
|
83
83
|
| Prop | Type | Default | Effect |
|
|
84
84
|
| --- | --- | --- | --- |
|
|
85
|
-
| `items` | `MenuItem[]` | — | `label` (already translated), `url`, `icon`, `footer`, `display` (`'icon'`: a round icon-only button, the label as tooltip and name, in the rail and the expanded sidebar; the phone's menu sheet always shows icon and label; see the [app shell guide](../guides/app-shell.md)), `badge` (`true` a dot, a number a count up to "99+"), `badgeLabel` (see [Badges](../guides/app-shell.md#badges)), and `children` (read by `navigation="top"`, which opens them in a dropdown under a parent that is then only a trigger; by `navigation="two-level"`, which lists them in the panel beside the rail, one level deep; by the phone's menu sheet and the expanded sidebar, which nest them under the parent's own link, unless the entry sets `childrenIn: 'sidebar'`, which keeps them to the sidebar and the top dropdown), `childrenIn`, `defaultExpanded` (the expanded sidebar folds the entry's children from a chevron button, open at first when `true`, folded when `false`; unset, they are always listed), `group`, `bar`, `priority` for the navigation presets that read them (the drawer reads `group`, the bar `bar` and `priority`; the floating toolbar, not drawn yet, is the only preset still to read them) |
|
|
85
|
+
| `items` | `MenuItem[]` | — | `label` (already translated), `url`, `icon`, `footer`, `display` (`'icon'`: a round icon-only button, the label as tooltip and name, in the rail and the expanded sidebar; the phone's menu sheet always shows icon and label; see the [app shell guide](../guides/app-shell.md)), `badge` (`true` a dot, a number a count up to "99+"), `badgeLabel` (see [Badges](../guides/app-shell.md#badges)), and `children` (read by `navigation="top"`, which opens them in a dropdown under a parent that is then only a trigger; by `navigation="two-level"`, which lists them in the panel beside the rail, one level deep; by the phone's menu sheet and the expanded sidebar, which nest them under the parent's own link, unless the entry sets `childrenIn: 'sidebar'`, which keeps them to the sidebar and the top dropdown), `childrenIn`, `defaultExpanded` (the expanded sidebar folds the entry's children from a chevron button, open at first when `true`, folded when `false`; unset, they are always listed), `persistKey` (remembers a collapsible group's fold state in this browser: a string key, or `true` to derive it from `navigation.persistKey` and the `url`), `badgeWhen` (`'collapsed'`: a collapsible group's own `badge` shows only while it is folded), `group`, `bar`, `priority` for the navigation presets that read them (the drawer reads `group`, the bar `bar` and `priority`; the floating toolbar, not drawn yet, is the only preset still to read them) |
|
|
86
86
|
| `linkComponent` | `AppShellLinkComponent` | React Router `Link` | The link each menu entry renders, given `href`; see the [app shell guide](../guides/app-shell.md). Defaults to the [`LinkComponentProvider`](./primitives.md#linkcomponentprovider)'s link when one is set. |
|
|
87
87
|
| `logo`, `name` | `AppLogo` (`ReactNode \| string \| AppLogoImage`, `AppLogoImage` = `{ src, alt? }`), `string` | — | the app's logo alone in the collapsed rail, named by `name` (also its tooltip); logo and name side by side in the phone's menu sheet |
|
|
88
88
|
| `context` | `ReactNode` | — | a line at the top of the phone's menu sheet, above the brand: the current tenant's name; `name` stays the app's brand; `AppHeader` and `AppSidebar` take it too (see the [app shell guide](../guides/app-shell.md#the-brand-logo-and-name)) |
|
package/docs/guides/app-shell.md
CHANGED
|
@@ -129,6 +129,8 @@ type MenuItem = {
|
|
|
129
129
|
`badge` marks an entry that has something new (the Material 3 navigation
|
|
130
130
|
badge):
|
|
131
131
|
|
|
132
|
+
(A collapsible sidebar group can show its own `badge` only while folded: see `badgeWhen` with `defaultExpanded`, below.)
|
|
133
|
+
|
|
132
134
|
```tsx
|
|
133
135
|
const items: MenuItem[] = [
|
|
134
136
|
{ label: 'Home', url: '/', icon: 'house', badge: true }, // a dot
|
|
@@ -418,8 +420,26 @@ its `url`, with its badge, for a parent page that already lists them. Unset
|
|
|
418
420
|
chevron button after the entry (named "Collapse the group" / "Expand the group",
|
|
419
421
|
`material.navigation.group-collapse` and `group-expand`) shows and hides them,
|
|
420
422
|
`true` opening them at first and `false` folding them (a folded group still opens at first when the current page is one of its children). It is ignored with `display: 'icon'`. Unset, they are always
|
|
421
|
-
listed, as before. The entry stays a link to its `url
|
|
422
|
-
|
|
423
|
+
listed, as before. The entry stays a link to its `url`, and the phone's menu sheet and the other presets ignore it.
|
|
424
|
+
|
|
425
|
+
By default the fold state is local and resets on reload. `persistKey` remembers it
|
|
426
|
+
in this browser: a string is the storage key, `true` derives the key from
|
|
427
|
+
`navigation.persistKey` and the entry's `url` (nothing is saved without that key).
|
|
428
|
+
Like the sidebar's own collapse, the saved choice is read after hydration, so a
|
|
429
|
+
server render and the first client render both follow `defaultExpanded`; a saved
|
|
430
|
+
choice wins over the "current page is a child" opening. `badgeWhen: 'collapsed'`
|
|
431
|
+
draws the parent's `badge` only while the group is folded, so its children's own
|
|
432
|
+
badges are not signalled twice (default `'always'`).
|
|
433
|
+
|
|
434
|
+
```tsx
|
|
435
|
+
{
|
|
436
|
+
label: 'Groups', url: '/groups', icon: 'users', badge: true,
|
|
437
|
+
children: [{ label: 'Item A', url: '/a', badge: 2 }],
|
|
438
|
+
defaultExpanded: true,
|
|
439
|
+
persistKey: true, // under navigation.persistKey + '/groups'
|
|
440
|
+
badgeWhen: 'collapsed', // the dot shows only while folded
|
|
441
|
+
}
|
|
442
|
+
```
|
|
423
443
|
|
|
424
444
|
```tsx
|
|
425
445
|
{
|
|
@@ -302,6 +302,26 @@ on the list or an ancestor to tune it. The default `comfortable` keeps the one,
|
|
|
302
302
|
two, three columns above, whatever the token; tiles ignore `cardDensity`. It is
|
|
303
303
|
independent of `density`, which also tightens a card's padding and gap.
|
|
304
304
|
|
|
305
|
+
## Inside a card
|
|
306
|
+
|
|
307
|
+
A list draws its own surface: tiles are one bordered, filled box, cards each have
|
|
308
|
+
a border and a fill. Inside a page card or a `PanelCard` that is a card in a card.
|
|
309
|
+
`surface="none"` leaves it out:
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
<PanelCard title="Team">
|
|
313
|
+
<DataTable layout="tiles" surface="none" renderTile={…} … />
|
|
314
|
+
</PanelCard>
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
The table's own fill and padding go, tiles lose the list's border and rounded
|
|
318
|
+
corners (the rows stay split by hairlines), and cards lose their border and fill (in
|
|
319
|
+
one column they are split by hairlines). Hover and selected tints, the padding and
|
|
320
|
+
the focus ring are unchanged, so the rows sit directly on the parent card. The
|
|
321
|
+
default (`'card'`) is unchanged, and the `table` layout ignores it. `ServerTable`
|
|
322
|
+
has its own `surface` (for its root, with the tiles keeping their border) and does
|
|
323
|
+
not pass this one on.
|
|
324
|
+
|
|
305
325
|
## States
|
|
306
326
|
|
|
307
327
|
- **First load** (`loading` with no row): placeholder cards (or tiles), hidden from
|
|
@@ -13,6 +13,15 @@
|
|
|
13
13
|
border: 1px solid var(--item-border);
|
|
14
14
|
border-radius: var(--item-radius);
|
|
15
15
|
}
|
|
16
|
+
/* `surface="none"`: no surface of its own, for a list inside a card. The
|
|
17
|
+
* rows keep their hairlines; the tints still mix over the parent. */
|
|
18
|
+
[data-slot="data-table-tiles"][data-surface="none"] {
|
|
19
|
+
--item-surface: transparent;
|
|
20
|
+
margin: 0;
|
|
21
|
+
background: none;
|
|
22
|
+
border: 0;
|
|
23
|
+
border-radius: 0;
|
|
24
|
+
}
|
|
16
25
|
/* A ServerTable on a phone has no panel of its own: the tile list sits at
|
|
17
26
|
* the page gutter, in line with the heading (#2292). */
|
|
18
27
|
@media (max-width: 767.98px) {
|
|
@@ -52,6 +61,11 @@
|
|
|
52
61
|
border-end-start-radius: calc(var(--item-radius) - 1px);
|
|
53
62
|
border-end-end-radius: calc(var(--item-radius) - 1px);
|
|
54
63
|
}
|
|
64
|
+
/* `surface="none"`: no rounded first and last row either. */
|
|
65
|
+
[data-slot="data-table-tiles"][data-surface="none"]
|
|
66
|
+
> [data-slot="data-table-item"] {
|
|
67
|
+
border-radius: 0;
|
|
68
|
+
}
|
|
55
69
|
[data-slot="data-table-tiles"][data-selectable]
|
|
56
70
|
> [data-slot="data-table-item"] {
|
|
57
71
|
padding-inline-start: 3.25rem;
|
|
@@ -73,6 +73,12 @@
|
|
|
73
73
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
+
/* `surface="none"`: the list sits on its parent, with no padding of the
|
|
77
|
+
* table's own to take the ring room's 4px back from. */
|
|
78
|
+
[data-slot="table-wrapper"]:has(> [data-surface="none"]) {
|
|
79
|
+
margin-inline: 0;
|
|
80
|
+
width: 100% !important;
|
|
81
|
+
}
|
|
76
82
|
[data-slot="data-table-cards"][data-density="compact"] {
|
|
77
83
|
gap: var(--nxgt-cards-gap, 0.5rem);
|
|
78
84
|
}
|
|
@@ -120,6 +126,22 @@
|
|
|
120
126
|
> [data-slot="data-table-item"] {
|
|
121
127
|
padding: 0.75rem;
|
|
122
128
|
}
|
|
129
|
+
/* `surface="none"`: a card draws no border or fill of its own, for a list
|
|
130
|
+
* inside a card. In one column the cards are split by hairlines. */
|
|
131
|
+
[data-slot="data-table-cards"][data-surface="none"] {
|
|
132
|
+
--item-surface: transparent;
|
|
133
|
+
}
|
|
134
|
+
[data-slot="data-table-cards"][data-surface="none"]
|
|
135
|
+
> [data-slot="data-table-item"] {
|
|
136
|
+
border-color: transparent;
|
|
137
|
+
}
|
|
138
|
+
@container (max-width: 35.999rem) {
|
|
139
|
+
[data-slot="data-table-cards"][data-surface="none"]
|
|
140
|
+
> [data-slot="data-table-item"]
|
|
141
|
+
+ [data-slot="data-table-item"] {
|
|
142
|
+
border-top-color: var(--item-border);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
123
145
|
[data-slot="data-table-item"] a[data-slot="data-table-item-link"],
|
|
124
146
|
[data-slot="data-table-item"] button[data-slot="data-table-item-link"] {
|
|
125
147
|
color: inherit;
|