@nxgt/material 3.70.0 → 3.71.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 (125) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/README.md +8 -5
  3. package/dist/{alert-dialog-CBkWG32g.js → alert-dialog-y2pbowVh.js} +1 -1
  4. package/dist/{async-slice-CNZ3N55P.js → async-slice-CGfWBOaV.js} +1 -1
  5. package/dist/{button-D3qzqDY_.js → button-D54Hrjo0.js} +1 -1
  6. package/dist/charts.js +3 -3
  7. package/dist/{chip-CMTe4sQd.js → chip-B5MhXBfm.js} +2 -2
  8. package/dist/{code-editor-Cs7mz1J-.js → code-editor-mULs4SL8.js} +5 -5
  9. package/dist/code-editor.js +5 -5
  10. package/dist/{code-language-items-D_QMgjVy.js → code-language-items-BWDnqUqn.js} +2 -2
  11. package/dist/components/ui/collections/server-table/server-table-phone-row.css +6 -0
  12. package/dist/components/ui/display/code/code-moonlight.css +37 -0
  13. package/dist/{components-BbWcozcj.js → components-B_taYVcd.js} +19417 -18629
  14. package/dist/components.js +28 -28
  15. package/dist/{dialog-B3BSdRci.js → dialog-AjCYZ2Vz.js} +4 -4
  16. package/dist/dnd.js +1 -1
  17. package/dist/{dropdown-menu-BaupOWgS.js → dropdown-menu-LN60hu_3.js} +1 -1
  18. package/dist/editor.js +35 -35
  19. package/dist/{empty-state-B2Um5UpI.js → empty-state-Bo8G8W8G.js} +2 -2
  20. package/dist/{field-blur-1XLyxRPr.js → field-blur-Cnd6FfCH.js} +1 -1
  21. package/dist/{field-blur-context-XNvCDnMT.js → field-blur-context-bUFZj8iN.js} +1 -1
  22. package/dist/{hooks-BU21Jpaa.js → hooks-Dt4PkQiZ.js} +2 -2
  23. package/dist/hooks.js +3 -3
  24. package/dist/{hover-card-Bvm3svX9.js → hover-card-QtGnvsnc.js} +1 -1
  25. package/dist/i18n.js +3 -3
  26. package/dist/{icon-badge-wip9bfa2.js → icon-badge-DLbpCQIm.js} +3 -3
  27. package/dist/{icon-button-QwIeBTdw.js → icon-button-C59DqL7L.js} +1 -1
  28. package/dist/lib/components/ui/actions/fab/fab-dock-inset.d.ts +29 -0
  29. package/dist/lib/components/ui/actions/fab/fab-dock.d.ts +6 -1
  30. package/dist/lib/components/ui/collections/data-table/select-checkbox.d.ts +3 -2
  31. package/dist/lib/components/ui/collections/index.d.ts +1 -0
  32. package/dist/lib/components/ui/collections/record-actions-menu/index.d.ts +2 -0
  33. package/dist/lib/components/ui/collections/record-actions-menu/record-actions-dialogs.d.ts +15 -0
  34. package/dist/lib/components/ui/collections/record-actions-menu/record-actions-menu.d.ts +72 -0
  35. package/dist/lib/components/ui/collections/record-actions-menu/record-actions-rules.d.ts +68 -0
  36. package/dist/lib/components/ui/collections/record-actions-menu/record-actions-words.d.ts +52 -0
  37. package/dist/lib/components/ui/collections/record-actions-menu/use-record-actions.d.ts +51 -0
  38. package/dist/lib/components/ui/collections/record-actions-menu/use-record-flight.d.ts +16 -0
  39. package/dist/lib/components/ui/collections/row-menu/row-menu-column.d.ts +4 -0
  40. package/dist/lib/components/ui/collections/row-menu/row-menu.d.ts +1 -1
  41. package/dist/lib/components/ui/collections/server-table/partials/server-table-band-classes.d.ts +7 -5
  42. package/dist/lib/components/ui/collections/server-table/partials/server-table-column-sorting.d.ts +7 -0
  43. package/dist/lib/components/ui/collections/server-table/types.d.ts +3 -1
  44. package/dist/lib/components/ui/display/markdown/markdown.d.ts +12 -1
  45. package/dist/lib/components/ui/display/markdown/markdown.utils.d.ts +2 -0
  46. package/dist/lib/components/ui/display/markdown/mermaid-csp-scope.d.ts +8 -0
  47. package/dist/lib/components/ui/display/markdown/mermaid-markup.d.ts +20 -0
  48. package/dist/lib/components/ui/display/markdown/partials/markdown-code.d.ts +5 -1
  49. package/dist/lib/components/ui/feedback/confirm-dialog/action-refusal.d.ts +24 -0
  50. package/dist/lib/components/ui/feedback/confirm-dialog/confirm-alert.d.ts +17 -0
  51. package/dist/lib/components/ui/feedback/confirm-dialog/confirm-description.d.ts +10 -0
  52. package/dist/lib/components/ui/feedback/confirm-dialog/confirm-dialog.d.ts +24 -2
  53. package/dist/lib/components/ui/feedback/confirm-dialog/confirm-refusal.d.ts +7 -0
  54. package/dist/lib/components/ui/feedback/confirm-dialog/index.d.ts +1 -0
  55. package/dist/lib/components/ui/feedback/confirm-dialog/use-confirm-action.d.ts +6 -0
  56. package/dist/lib/components/ui/feedback/index.d.ts +1 -0
  57. package/dist/lib/components/ui/feedback/stale-notice/index.d.ts +1 -0
  58. package/dist/lib/components/ui/feedback/stale-notice/stale-notice.d.ts +15 -0
  59. package/dist/lib/components/ui/fields/contacts/placeholders.d.ts +1 -1
  60. package/dist/lib/components/ui/forms/index.d.ts +1 -0
  61. package/dist/lib/components/ui/forms/use-server-field-errors.d.ts +21 -0
  62. package/dist/lib/components/ui/layout/index.d.ts +1 -0
  63. package/dist/lib/components/ui/layout/record-page/index.d.ts +2 -0
  64. package/dist/lib/components/ui/layout/record-page/record-details.d.ts +40 -0
  65. package/dist/lib/components/ui/layout/record-page/record-page.d.ts +27 -0
  66. package/dist/lib/components/ui/widgets/chat/chat-conversation-item.d.ts +8 -2
  67. package/dist/lib/components/ui/widgets/chat/chat-markdown.d.ts +4 -0
  68. package/dist/lib/components/ui/widgets/chat/chat-message-list.d.ts +8 -1
  69. package/dist/lib/components/ui/widgets/chat/index.d.ts +2 -0
  70. package/dist/lib/components/ui/widgets/chat/partials/chat-conversation-item-text.d.ts +2 -1
  71. package/dist/lib/components/ui/widgets/chat/partials/chat-empty-thread.d.ts +2 -0
  72. package/dist/lib/components/ui/widgets/chat/proposal/chat-action-proposal-parts.d.ts +24 -0
  73. package/dist/lib/components/ui/widgets/chat/proposal/chat-action-proposal.d.ts +39 -0
  74. package/dist/lib/components/ui/widgets/chat/proposal/chat-action-proposal.rules.d.ts +17 -0
  75. package/dist/lib/components/ui/widgets/chat/proposal/chat-tool-activity.d.ts +16 -0
  76. package/dist/lib/i18n/resources/en/en.d.ts +40 -0
  77. package/dist/lib/i18n/resources/en/material.json.d.ts +40 -0
  78. package/dist/lib/i18n/resources/fr/fr.d.ts +40 -0
  79. package/dist/lib/i18n/resources/fr/material.json.d.ts +40 -0
  80. package/dist/lib/i18n/resources/resources.d.ts +80 -0
  81. package/dist/lib/i18n/translator.d.ts +1 -1
  82. package/dist/lib/print/output/to-pdf-element.d.ts +6 -0
  83. package/dist/lib.js +1 -1
  84. package/dist/main.js +42 -42
  85. package/dist/map.js +8 -8
  86. package/dist/material.css +1 -1
  87. package/dist/pdf-reader.js +1 -1
  88. package/dist/print.js +135 -131
  89. package/dist/{public-BuGgOtAl.js → public-BSaSCwy7.js} +9 -9
  90. package/dist/{rich-code-block-DdHqzzek.js → rich-code-block-BFVj1GWz.js} +5 -5
  91. package/dist/{sortable-provider-DMyaSfZZ.js → sortable-provider-REwyjiOZ.js} +2 -2
  92. package/dist/{spinner-ByYdcukU.js → spinner-BFZxqdWC.js} +1 -1
  93. package/dist/theme-picker.js +2 -2
  94. package/dist/{theme-toggle-DB3aZZnO.js → theme-toggle-BHi6miz-.js} +1 -1
  95. package/dist/{toolbar-items-DbzIKjo7.js → toolbar-items-BTtoKVlx.js} +3 -3
  96. package/dist/{translate-material-Dh7MYkHT.js → translate-material-R-uLthBy.js} +1 -1
  97. package/dist/{translator-Byhohi1S.js → translator-ClbXOGQO.js} +80 -0
  98. package/dist/{typography-rUf0mE5a.js → typography-v-PJ4Zco.js} +1 -1
  99. package/dist/{use-chat-composer-uUUTRB3Z.js → use-chat-composer-Rhan4Xv0.js} +107 -107
  100. package/dist/{use-heading-spy-CVzW2NM3.js → use-heading-spy-CJnBkCY0.js} +179 -87
  101. package/dist/{use-material-translation-BAYyZOcH.js → use-material-translation-CCWUeiEn.js} +1 -1
  102. package/dist/{use-return-focus-CQAuk9kh.js → use-return-focus-Duk40DZI.js} +1 -1
  103. package/docs/components/buttons-and-actions.md +24 -0
  104. package/docs/components/data-display.md +33 -0
  105. package/docs/components/data-table-filter-and-lists.md +117 -5
  106. package/docs/components/feedback-and-status.md +58 -2
  107. package/docs/components/navigation-and-layout.md +58 -0
  108. package/docs/components/rich-widgets.md +35 -2
  109. package/docs/guides/cards-and-tiles.md +4 -2
  110. package/docs/guides/csp.md +44 -6
  111. package/docs/guides/forms.md +51 -4
  112. package/docs/guides/i18n.md +6 -5
  113. package/docs/guides/printing.md +17 -7
  114. package/docs/previews/data-table-filter-lists-recordactionsmenu.webp +0 -0
  115. package/docs/previews/feedback-status-stalenotice.webp +0 -0
  116. package/docs/previews/media-files-networkuploadfield.webp +0 -0
  117. package/docs/previews/media-files-s3uploadfield.webp +0 -0
  118. package/docs/previews/media-files-uploadfield.webp +0 -0
  119. package/docs/previews/navigation-layout-recordpage.webp +0 -0
  120. package/docs/previews/rich-widgets-chat-action-proposal.webp +0 -0
  121. package/docs/roadmap.md +11 -1
  122. package/docs/troubleshooting.md +47 -7
  123. package/lib/components/ui/collections/server-table/server-table-phone-row.css +6 -0
  124. package/lib/components/ui/display/code/code-moonlight.css +37 -0
  125. package/package.json +2 -2
@@ -236,7 +236,7 @@ the camera's button, toggle and image (`material.camera.capture`, `captured`,
236
236
  barcode accessible names, the calendar's navigation tooltips
237
237
  (`material.calendar.*`), the data table's selection checkboxes, the filter's
238
238
  presets and `Min`/`Max` fields, the `variant="4"` spinner's label,
239
- `ScrollToTop`, the network upload field's `Retry`/`Remove`, the map's
239
+ `ScrollToTop`, the network upload field's `Retry` and `Remove {name}`, the map's
240
240
  `You are here` and zoom buttons, and the icon-only close button of
241
241
  `DialogClose`, `DrawerClose`, `SheetClose` and `SheetContent`'s
242
242
  `withCloseButton`. A range `Slider`'s readout inputs read
@@ -320,9 +320,9 @@ those words as an optional third argument); the `aria-label` of `Breadcrumb`
320
320
  and `Pagination` and the breadcrumb ellipsis's "More"
321
321
  (`material.breadcrumb.*`, `material.pagination.label`), and `DocHeader`'s
322
322
  breadcrumb (`material.doc.breadcrumb`); `MessageCard`'s "Unread"
323
- (`material.cards.unread`); the network upload field's "Replace {name}", "Upload
323
+ (`material.cards.unread`); the network upload field's "Replace {name}", "Remove {name}", "Upload
324
324
  failed", its type, size and count errors (`material.upload.replace-named`,
325
- `failed`, `invalid-type`, `too-large`, `max-files`; an error keeps the language
325
+ `remove-named`, `failed`, `invalid-type`, `too-large`, `max-files`; an error keeps the language
326
326
  it was raised in) and the drop zone's "Max {size}" and "Up to {count} files"
327
327
  (`material.upload.dropzone.max-size` / `max-files`); the editor's
328
328
  placeholder, which follows a language change without rebuilding the editor,
@@ -485,8 +485,9 @@ and description and against the English ones, ignoring accents: in French,
485
485
 
486
486
  Some strings are still English in every language, among them the filter's
487
487
  validation messages, the camera's error messages, the editor's callout type
488
- names and default block content. File sizes (`2 KB`) and the filter chips' dates are not formatted for
489
- the provider's language.
488
+ names and default block content. The filter chips' dates, and file sizes outside the upload field (`2 KB`),
489
+ are not formatted for the provider's language; the upload field writes its
490
+ size in it (`10,4 ko`).
490
491
 
491
492
  The emoji picker's category tabs are icon-only; their name, read by screen
492
493
  readers and shown as a tooltip, comes from `material.emoji.groups.<group>`.
@@ -1013,7 +1013,7 @@ it:
1013
1013
  | `heading` | `heading(text, level?)` | A title, level `1`, `2` or `3` |
1014
1014
  | `text` | `text(content, { variant?, style? })` | A paragraph: a string, or runs `{ text, bold?, italic?, color?, href? }`; `variant` is `'body'`, `'muted'`, `'caption'` or `'label'` |
1015
1015
  | `stack` / `row` | `stack(children, { gap?, style?, keepTogether? })`, `row(children, { gap?, align?, justify?, style? })` | Children one under the other, or side by side |
1016
- | `section` | `section(title, children, { keepTogether? })` | A titled block, as `PrintSection`; `keepTogether` as on a `stack` |
1016
+ | `section` | `section(title, children, { keepTogether? })` | A titled block, as `PrintSection`; `keepTogether` as on a `stack`; a block taller than a page breaks normally, see [Keeping a block on one page](#keeping-a-block-on-one-page) |
1017
1017
  | `table` | `table({ columns, rows, footer?, labelTotals?, striped?, repeatHeader?, keepRowsWhole?, emptyText?, hideWhenEmpty? })`, or `dataTable(columns, rows, options?)` from [column definitions](#tables-from-column-definitions-datatable-and-keyvalueof) | A table of `PrintValue`s, as `PrintDataTable`; a row or a cell may carry a `style`, see [Row and cell styles](#row-and-cell-styles-in-a-table); with `labelTotals`, an empty first cell of a `footer` row reads "Total" in the document's language |
1018
1018
  | `keyValue` | `keyValue(items, { columns?, keepEmpty? })`, or `keyValueOf(fields, data, options?)` from column definitions | Label and value pairs, as `PrintKeyValue` |
1019
1019
  | `totals` | `totals(rows)` | Label and value rows; `emphasis` makes one bold |
@@ -1140,12 +1140,22 @@ section(group.title, rows, { keepTogether: true });
1140
1140
  stack([heading('Result'), table(result)], { keepTogether: true });
1141
1141
  ```
1142
1142
 
1143
- Use it on a block you know is shorter than a page. react-pdf cannot split a
1144
- block that opted out of wrapping: a block taller than the page area is not
1145
- broken, it overflows the page and is cut off at the edge (react-pdf logs
1146
- "can't wrap between pages and it's bigger than available page height").
1147
- Leave `keepTogether` off for a block that may grow past a page, and use
1148
- `keepRowsWhole` and `repeatHeader` on a long table instead.
1143
+ A block taller than a page breaks normally. react-pdf cannot split a block
1144
+ that opted out of wrapping (it overflows and is cut off at the edge), and
1145
+ cannot measure ahead, so for a document as data `renderPdfBuffer`,
1146
+ `renderPdfBlob`, `renderPdfStream`, `downloadPdf`, `openPdf` and `pdfResponse`
1147
+ first render each `keepTogether` block alone, on a page like the one it sits
1148
+ on, and drop the option of those that need more than one page. A block that
1149
+ fits keeps it, so its output does not change; a document with no
1150
+ `keepTogether` pays for no extra pass. The measure is made at the page's
1151
+ width: a block inside a `row` is measured with that row, but a parent's padding or narrower style is not applied.
1152
+
1153
+ This holds for a document as data only. `<PrintSection keepTogether>` in a
1154
+ `PrintDocument` element, and a document you render yourself with
1155
+ `renderPdfElement`, are not measured: use `keepTogether` there on a block
1156
+ shorter than a page, or call `resolveKeepTogether(doc)` from
1157
+ `@nxgt/material-core/pdf/render` first and render its result. For a long
1158
+ table, `keepRowsWhole` and `repeatHeader` keep the rows apart from each other.
1149
1159
 
1150
1160
  ### Row and cell styles in a table
1151
1161
 
package/docs/roadmap.md CHANGED
@@ -6,6 +6,8 @@ version they shipped in, and planned entries may name the major they target.
6
6
 
7
7
  ## Now
8
8
 
9
+ - **Calculator** — `@nxgt/material/calculator` adds `Calculator`, in six variants (Standard, Scientific, point of sale, Financial, Unit conversion, Programmer) chosen by `variant` or by its own switcher, and `CalculatorField` / `CalculatorFormField`, a number field whose button opens it in a popover, or a bottom sheet on a phone. Every variant shows the whole expression above the result, honours operator precedence and computes in exact decimals (0.1 + 0.2 = 0.3) without `eval`, so a strict CSP holds. A history tape (persisted, with an opt-out), memory keys, the physical keyboard, copy and paste, locale formatting and screen-reader announcements come with each; haptic and sound feedback are opt-in. Point of sale charges through `onCharge(total)`; currency rates come from the app. React only for now; the Vue port is tracked in [#2100](https://github.com/softistx/nxgt-material/issues/2100). Tracked in [#2101](https://github.com/softistx/nxgt-material/issues/2101).
10
+
9
11
  - **Barcodes and label sheets** — `@nxgt/material/barcode` draws Code 128
10
12
  and Data Matrix as accessible SVG (themed, dark-aware, black on white in
11
13
  print) and lays labels out on a sheet to print: label size, columns, rows,
@@ -15,6 +17,10 @@ version they shipped in, and planned entries may name the major they target.
15
17
  - **Toast texts follow app translations** — the toast presets read the
16
18
  app's `I18nProvider` `resources`, so an override under `material.*`
17
19
  changes their wording ([#1855](https://github.com/softistx/nxgt-material/issues/1855)).
20
+ - **A record page layout** — `RecordPage` and `RecordDetails` lay out one
21
+ record: a header card, the content, and its facts as a side panel from `xl`
22
+ that stacks after or before the content, with a created / updated line
23
+ ([#1689](https://github.com/softistx/nxgt-material/issues/1689)).
18
24
  - **A decision bar for phone pages** — `StickyActionBar` holds a long page's
19
25
  main decision at the bottom of a phone, above the keyboard and clear of the
20
26
  safe areas, and inline from `md`
@@ -157,6 +163,8 @@ version they shipped in, and planned entries may name the major they target.
157
163
 
158
164
  ## Next
159
165
 
166
+ - **Layouts: adaptive navigation, headers and page layouts** — `ActivityLayout` takes `navigation` (a bottom bar, a rail with a FAB, standard and modal drawers, a collapsible sidebar, a top navigation with dropdowns, two-level navigation or a floating toolbar, chosen for phone, tablet and desktop) and `header` (small, center-aligned, medium and large collapsing on scroll, a search bar with full-screen search on a phone, sticky tabs, hide on scroll); each piece is also exported. Page layouts grow with it: an inspector pane and URL state for `ListDetailsLayout`, phone modes for `PaneLayout`, spans and masonry for `ResponsiveGrid`, tabs for `Kanban` on a phone, and new settings, dashboard (rearranging tiles), editor and landing layouts, each with a screen recipe. Everything is opt-in; the shell's default is unchanged. Tracked in [#2103](https://github.com/softistx/nxgt-material/issues/2103).
167
+
160
168
  - **FilterBar "Add a filter" stays on its row** — the button no longer wraps
161
169
  alone onto a second row on a desktop screen ([#1752](https://github.com/softistx/nxgt-material/issues/1752)).
162
170
 
@@ -241,7 +249,6 @@ version they shipped in, and planned entries may name the major they target.
241
249
  slot; the bar's `views` slot is planned with it. They are meant to replace
242
250
  the legacy `FilterPresets`. Tracked in [#1876](https://github.com/softistx/nxgt-material/issues/1876).
243
251
 
244
- - **RecordActionsMenu** — one menu for a record's lifecycle: archive with an Undo toast (or confirm first with `archivePolicy="confirm"`), restore, and delete that always confirms and shows the backend's refusal, with `ConfirmDialog` gaining `details` and `refusal` slots.
245
252
  - **Cursor trail cap** — `ServerTable` and `PageFooter` keep cursor URLs short: the trail is encoded once and capped by `maxTrail` (20 by default) with an exact page count, and `totalCount` becomes optional for APIs that do not count.
246
253
 
247
254
  ## Later
@@ -364,6 +371,9 @@ version they shipped in, and planned entries may name the major they target.
364
371
 
365
372
  ## Shipped
366
373
 
374
+ - **RecordActionsMenu (next minor)** — one menu for a record's lifecycle: archive with an Undo toast (or confirm first with `archivePolicy="confirm"`), restore, and delete that always confirms and shows the backend's refusal, with `ConfirmDialog` gaining `details` and `refusal` slots.
375
+ - **Assistant approval card (next minor)** — `ChatActionProposal` shows an action an assistant proposes, with its status, deadline and Confirm / Reject, and `ChatToolActivity` is a compact row for a tool step in a chat thread ([#2134](https://github.com/softistx/nxgt-material/issues/2134)).
376
+
367
377
  - **Link navigation (3.66.0)** — `TabsNav` and `SegmentedNav` render route tabs and segmented navigation as a `nav` of links with `aria-current="page"`, looking like Tabs and the segmented ToggleGroup, plus `useTabParam`, `skipTabChange` and `tabIds` to keep the current tab in the URL. Tracked in [#2029](https://github.com/softistx/nxgt-material/issues/2029).
368
378
 
369
379
  - **Smaller, easier-to-read components (3.58.0)** — the library's own source
@@ -66,6 +66,7 @@ words in your error.
66
66
  - [A Button's label overflows a card on a phone](#a-buttons-label-overflows-a-card-on-a-phone)
67
67
  - [A ResponsiveButton no longer shows its tooltip next to its visible label](#a-responsivebutton-no-longer-shows-its-tooltip-next-to-its-visible-label)
68
68
  - [An input now has `placeholder=" "` in the DOM](#an-input-now-has-placeholder--in-the-dom)
69
+ - ["Select all" runs under the sort, "Filters" or the actions in a cards or tiles list on a phone](#select-all-runs-under-the-sort-filters-or-the-actions-in-a-cards-or-tiles-list-on-a-phone)
69
70
  - [A dialog or sheet scrolls, or clips a child, after upgrading](#a-dialog-or-sheet-scrolls-or-clips-a-child-after-upgrading)
70
71
  - [A form's fields no longer scroll in their own box after upgrading](#a-forms-fields-no-longer-scroll-in-their-own-box-after-upgrading)
71
72
  - [My activity content lost its side padding, or the rail's entries moved up](#my-activity-content-lost-its-side-padding-or-the-rails-entries-moved-up)
@@ -1427,6 +1428,18 @@ your own through `className`. With `asChild`, put the label in a `<span>` (on a
1427
1428
  </Button>
1428
1429
  ```
1429
1430
 
1431
+ ### "Select all" runs under the sort, "Filters" or the actions in a cards or tiles list on a phone
1432
+
1433
+ **When:** below 768px, a `ServerTable` in `cards` or `tiles` with `filter` and
1434
+ `actions` draws "Select all" over the sort menu and "Filters (N)" when an action
1435
+ has a long label ("Add a measurement unit").
1436
+ **Why:** up to 3.70.0, the label of row 2 neither shrank nor truncated, and the
1437
+ end group (sort, "Filters (N)", actions) never gave up its width.
1438
+ **Fix:** update. The "Select all" text now ends in "…" (the box keeps its name,
1439
+ "Select all on this page"), and an end group too wide for the row wraps to its
1440
+ own line under it. Until then, use a `Fab` for the create action on phones, or
1441
+ a short or icon-only label.
1442
+
1430
1443
  ### A dialog or sheet scrolls, or clips a child, after upgrading
1431
1444
 
1432
1445
  **When:** after upgrading, a tall `DialogContent`, `AlertDialogContent` or
@@ -2128,6 +2141,12 @@ settles, with `focusRef` on the table. It matches the row by id, not by label.
2128
2141
  See "Handing the focus back to a row" in
2129
2142
  [RowMenu](components/data-table-filter-and-lists.md#handing-the-focus-back-to-a-row).
2130
2143
 
2144
+ ### A `RecordActionsMenu` or `ConfirmDialog` refusal shows no action, or its link reloads the page
2145
+
2146
+ **When:** `send` rejects (or a `ConfirmDialog`'s `onConfirm` throws) with an error that should offer a link, but the dialog or toast shows only the message; or the link of a toast action reloads the whole app.
2147
+ **Why:** only an `ActionRefusal` carries an action (a plain `Error`, or a rethrown copy of its message, does not). A toast's `href` is a plain navigation (`window.location.assign`), since a toast is outside your router.
2148
+ **Fix:** reject with `new ActionRefusal(message, { action: { label, href } })` and keep it as thrown (do not wrap it in another `Error`). For a client-side navigation use `action: { label, onAction: () => navigate(...) }`. A `ConfirmDialog` renders it by default; a `refusal` prop of your own replaces that rendering, so it must show the details and the action itself. See [ConfirmDialog](components/feedback-and-status.md#confirmdialog) and [RecordActionsMenu](components/data-table-filter-and-lists.md#recordactionsmenu).
2149
+
2131
2150
  ### A `ConfirmationDialog` reopened with new content blocks clicks
2132
2151
 
2133
2152
  **When:** a `ConfirmationDialog` or a `ConfirmDialog` (or a `Dialog`,
@@ -3649,6 +3668,26 @@ fill is now left empty, and the title stays centred.
3649
3668
  <PrintHeader title="Invoice" logoText="LOGO" />
3650
3669
  ```
3651
3670
 
3671
+ ### A `keepTogether` block is cut off at the bottom of the page
3672
+
3673
+ **When:** the console shows `Node of type VIEW can't wrap between pages and
3674
+ it's bigger than available page height` and the rows of a `PrintSection` or
3675
+ a `section` / `stack` with `keepTogether` run past the page edge.
3676
+ **Why:** react-pdf keeps a block whole with `wrap={false}` and cannot split
3677
+ one taller than a page, nor measure it ahead.
3678
+ **Fix:** for a document as data, render it with `renderPdfBuffer`,
3679
+ `renderPdfBlob`, `renderPdfStream`, `downloadPdf` or `pdfResponse`: they
3680
+ measure each `keepTogether` block and let a too-tall one break normally. For a
3681
+ `<PrintSection keepTogether>` in a `PrintDocument`, or your own call to
3682
+ `renderPdfElement`, remove `keepTogether` from blocks that can outgrow a page,
3683
+ or resolve the document first:
3684
+
3685
+ ```ts
3686
+ import { resolveKeepTogether } from '@nxgt/material-core/pdf/render';
3687
+
3688
+ const element = renderPdfElement(await resolveKeepTogether(doc));
3689
+ ```
3690
+
3652
3691
  ### French amounts print with a slash, as in `1/234,50`
3653
3692
 
3654
3693
  **When:** before 2.2.0, `formatAmount(1234.5, 'EUR', { locale: 'fr-FR' })`
@@ -5142,7 +5181,7 @@ such as `getByRole('navigation', { name: 'pagination' })`,
5142
5181
  | `No filters available`, `+2 more` | `Aucun filtre disponible`, `+2 de plus` | `filter.empty`, `filter.more` |
5143
5182
  | `Yes` / `No`, `From 5`, `Until …`, `Up to 9` (filter chips) | `Oui` / `Non`, `À partir de 5`, `Jusqu'au …`, `Jusqu'à 9` | `filter.value.*` |
5144
5183
  | `Unread` (`MessageCard`) | `Non lu` | `cards.unread` |
5145
- | `Replace {name}`, `Upload failed` | `Remplacer {name}`, `Échec de l'envoi` | `upload.replace-named`, `upload.failed` |
5184
+ | `Replace {name}`, `Remove {name}`, `Upload failed` | `Remplacer {name}`, `Supprimer {name}`, `Échec de l'envoi` | `upload.replace-named`, `upload.remove-named`, `upload.failed` |
5146
5185
  | `File type not accepted`, `File exceeds maximum size of …`, `Maximum of 3 files reached` | `Type de fichier non accepté`, `Le fichier dépasse la taille maximale de …`, `Maximum de 3 fichiers atteint` | `upload.invalid-type`, `upload.too-large`, `upload.max-files` |
5147
5186
  | `Write something …`, `Insert {name} emoji` (editor) | `Écrire quelque chose…`, `Insérer l'emoji {name}` | `rich-text-editor.placeholder`, `rich-text-editor.insert-emoji` |
5148
5187
  | `Progress: 40%` | `Progression : 40 %` | `circular-progress.label` |
@@ -7748,8 +7787,13 @@ one. The usual sources are the components listed in
7748
7787
  [the guide](guides/csp.md#style-elements-the-components-inject).
7749
7788
  `ScrollArea`, `Select`, `RichTextEditor` and the scroll lock of dialogs and
7750
7789
  sheets take the nonce from `NonceProvider`, and report this when the app has
7751
- none (or gives it another nonce than the header's). A `<style>` in mermaid's
7752
- SVG is a [known gap](guides/csp.md#known-gaps). `Toaster`, `Drawer`,
7790
+ none (or gives it another nonce than the header's). Mermaid and KaTeX
7791
+ need none of this on a client render
7792
+ ([Markdown under a strict CSP](guides/csp.md#markdown-katex-mermaid-and-code-under-a-strict-csp));
7793
+ the two left are a server-rendered page with math (KaTeX's `style` attributes
7794
+ need `style-src-attr 'unsafe-inline'`) and the `<style>` cytoscape adds to
7795
+ `<head>` for mermaid's mindmap and architecture diagrams.
7796
+ `Toaster`, `Drawer`,
7753
7797
  `InputOTP`, `ImageCropper`, `Spinner` and `PdfReader` create none: their CSS is in the stylesheet, so if one of them looks unstyled, the
7754
7798
  app imports neither `styles.css` nor `dist/material.css`.
7755
7799
  **Fix:** for `style-src-attr`, allow attributes: they cannot be nonced.
@@ -7770,10 +7814,6 @@ import { NonceProvider } from '@nxgt/material';
7770
7814
  </NonceProvider>;
7771
7815
  ```
7772
7816
 
7773
- For a mermaid diagram, serve that route with `'unsafe-inline'` in
7774
- `style-src-elem` instead of the nonce (a nonce in the same directive makes
7775
- browsers ignore `'unsafe-inline'`).
7776
-
7777
7817
  Once a page has a header-delivered CSP, browsers blank the `nonce` attribute, so React's development build may warn of an attribute mismatch when it hydrates a server-rendered `<style nonce>`. The warning is harmless.
7778
7818
 
7779
7819
  ### `Refused to load the font 'data:font/woff2…' because it violates the following Content Security Policy directive: "font-src 'self'"`
@@ -187,3 +187,9 @@
187
187
  gap: 0.75rem;
188
188
  }
189
189
  }
190
+ /* A wide action (#2168): the actions may shrink within the row, so a long
191
+ * label ends in "..." (the button's own ellipsis) instead of overflowing. */
192
+ [data-slot="server-table-phone-row-end"] > [data-slot="server-table-actions"] {
193
+ flex-shrink: 1;
194
+ min-width: 0;
195
+ }
@@ -1,3 +1,40 @@
1
+ /* The scheme's colours as custom properties on the block: classes of the
2
+ stylesheet, never an inline `style` (strict CSP). Same values as
3
+ moonlight-tokens.ts; code-block-scheme.test.ts keeps them equal. */
4
+ [data-slot="code-block"][data-scheme="dark"] {
5
+ --code-bg: #222436;
6
+ --code-fg: #c8d3f5;
7
+ --code-comment: #7a88cf;
8
+ --code-blue: #82aaff;
9
+ --code-cyan: #86e1fc;
10
+ --code-green: #c3e88d;
11
+ --code-orange: #ff966c;
12
+ --code-yellow: #ffc777;
13
+ --code-red: #ff757f;
14
+ --code-magenta: #c099ff;
15
+ --code-pink: #fca7ea;
16
+ --code-selection: #2f334d;
17
+ }
18
+
19
+ [data-slot="code-block"][data-scheme="light"] {
20
+ --code-bg: #f5f7ff;
21
+ --code-fg: #383a51;
22
+ --code-comment: #7a88cf;
23
+ --code-blue: #3e68d7;
24
+ --code-cyan: #0b8ec2;
25
+ --code-green: #4db380;
26
+ --code-orange: #c44c22;
27
+ --code-yellow: #ac8300;
28
+ --code-red: #c53b40;
29
+ --code-magenta: #7a5af5;
30
+ --code-pink: #b04d9a;
31
+ --code-selection: #d4daf0;
32
+ }
33
+
34
+ [data-slot="code-block"] [data-code-scroll] {
35
+ max-height: var(--code-max-height, none);
36
+ }
37
+
1
38
  [data-slot="code-block"] {
2
39
  background: var(--code-bg);
3
40
  color: var(--code-fg);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxgt/material",
3
- "version": "3.70.0",
3
+ "version": "3.71.0",
4
4
  "license": "MIT",
5
5
  "bugs": {
6
6
  "email": "stevegires@gmail.com"
@@ -372,7 +372,7 @@
372
372
  "docs:previews": "rm -rf node_modules/.cache/nxgt-preview-free/missing && NXGT_PREVIEW_FREE=1 vitest run --project previews && bun .storybook/preview-free-report.ts"
373
373
  },
374
374
  "dependencies": {
375
- "@nxgt/material-core": "^0.45.1",
375
+ "@nxgt/material-core": "^0.46.0",
376
376
  "@base-ui/react": "^1.6.0",
377
377
  "@dnd-kit/core": "^6.3.1",
378
378
  "@dnd-kit/sortable": "^10.0.0",