@nxgt/material-core 0.6.0 → 0.7.1
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 +16 -0
- package/README.md +38 -1
- package/dist/lib/toast-focus.d.ts +41 -0
- package/dist/lib/toast-focus.d.ts.map +1 -0
- package/dist/lib/toast-focus.js +41 -0
- package/dist/lib/toast-focus.js.map +10 -0
- package/docs/roadmap.md +28 -5
- package/package.json +8 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @nxgt/material-core
|
|
2
2
|
|
|
3
|
+
## 0.7.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#504](https://github.com/softistx/nxgt-material/pull/504) [`c6f76a1`](https://github.com/softistx/nxgt-material/commit/c6f76a179087bd6c8b9a3698040dd001f08d8bda) Thanks [@SteveGT96](https://github.com/SteveGT96)! - The roadmaps describe the coming redesign.
|
|
8
|
+
|
|
9
|
+
## 0.7.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#475](https://github.com/softistx/nxgt-material/pull/475) [`2fcfa35`](https://github.com/softistx/nxgt-material/commit/2fcfa35d5bff9d46392247440a82f0bc3638f104) Thanks [@SteveGT96](https://github.com/SteveGT96)! - New `/toast-focus` subpath: `focusOrigin(event, origin)` records where the focus was before it entered a toast, and `handFocusBack(origin)` gives it back there before the toast's action runs (or blurs the toast's control when that element has gone), so a dialog the action opens keeps the focus. `trackToasterOrigin()` records, per `Toaster`, where the focus entered it, so a toast reached from another toast hands the focus back to the same control. `TOASTER_SELECTOR` is `'[data-sonner-toaster]'`. Both libraries' toasts use it ([#473](https://github.com/softistx/nxgt-material/issues/473)).
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#476](https://github.com/softistx/nxgt-material/pull/476) [`464883e`](https://github.com/softistx/nxgt-material/commit/464883e825e4601f17395c9586d0ac01dd392162) Thanks [@SteveGT96](https://github.com/SteveGT96)! - The roadmap names the release that ships the toast action and focus fixes.
|
|
18
|
+
|
|
3
19
|
## 0.6.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -11,7 +11,8 @@ rule, a field's first reachable control (`/focus-control`) and its `aria-describ
|
|
|
11
11
|
(`/described-by`), the page behind a modal layer made inert
|
|
12
12
|
(`/inert-others`), Escape pressed while an overlay closes
|
|
13
13
|
(`/escape-forward`), the Toaster's guard against a tap's emulated hover
|
|
14
|
-
(`/touch-hover`), a
|
|
14
|
+
(`/touch-hover`), the focus a toast's action hands back (`/toast-focus`), a
|
|
15
|
+
table row's activation, the zod error map's issue
|
|
15
16
|
messages (`/zod-issue-messages`), the Vite plugin that bundles pdfkit's
|
|
16
17
|
standard fonts, and the Node-only resolution of those fonts that the Next.js
|
|
17
18
|
helper and the Nuxt module run at build time.
|
|
@@ -85,6 +86,7 @@ built-in.
|
|
|
85
86
|
| `/described-by` | `describedBy` — an `aria-describedby` value from the caller's ids and a field's help and error ids |
|
|
86
87
|
| `/inert-others` | `inertOthers`, `INERT_MARKER` — the rest of the page `inert` behind a modal layer, live regions kept, nested layers counted |
|
|
87
88
|
| `/touch-hover` | `ignoreTouchHover`, `TOASTER_PHONE_QUERY`, `TOASTER_PHONE_POSITION` — keeps a tap from hovering an element, so a toast a finger touched does not stay paused; where the `Toaster` puts toasts on a phone |
|
|
89
|
+
| `/toast-focus` | `focusOrigin`, `handFocusBack`, `trackToasterOrigin`, `TOASTER_SELECTOR` — where the focus was before it entered a toast, and handing it back there before the toast's action runs, so a dialog the action opens keeps the focus |
|
|
88
90
|
| `/zod-issue-messages` | `sizeMessage`, `invalidFormatMessage`, `IssueText` — the translated text of a zod `too_big` / `too_small` and `invalid_format` issue |
|
|
89
91
|
| `/row-activation` | `isRowActivation`, `followRowLink`, `ROW_CONTROL_SELECTOR`, `ROW_LINK_SELECTOR`, `RowClick` — whether a click on a table row follows its link, and following it |
|
|
90
92
|
| `/format-file-size` | `formatFileSize` — a byte count as `'1.5 KB'` |
|
|
@@ -613,6 +615,41 @@ It also holds the two constants both libraries' `Toaster` share: `TOASTER_PHONE_
|
|
|
613
615
|
screen) and `TOASTER_PHONE_POSITION` (`'top-center'`, where toasts go on a phone
|
|
614
616
|
when the caller names no `position`).
|
|
615
617
|
|
|
618
|
+
### The focus a toast's action hands back: `/toast-focus`
|
|
619
|
+
|
|
620
|
+
sonner focuses again the control that had the focus before it entered the
|
|
621
|
+
`Toaster` as soon as the focus leaves it, so an action that opened a dialog
|
|
622
|
+
saw the focus pulled back out of the dialog; and a dialog opened from a
|
|
623
|
+
toast's button gave the focus back, once closed, to a button that had gone
|
|
624
|
+
with its toast. Each toast records where the focus came from with
|
|
625
|
+
`focusOrigin(event, origin)` on its `focusin` (focus moving between toasts
|
|
626
|
+
keeps the first origin, or else the one its `Toaster` recorded), and its action calls `handFocusBack(origin)` before
|
|
627
|
+
running: it focuses `origin` (else the `Toaster`'s), or blurs the toast's control when `origin` has
|
|
628
|
+
gone, and does nothing when the focus is not in the `Toaster`
|
|
629
|
+
(`TOASTER_SELECTOR`, `'[data-sonner-toaster]'`). The list item around a
|
|
630
|
+
toast takes the focus first from the keyboard, and no toast hears it:
|
|
631
|
+
`trackToasterOrigin()` (once, when a toast mounts) listens on the document so
|
|
632
|
+
the `Toaster` knows the page control the focus left, and the next toast, which
|
|
633
|
+
never had the focus from the page, still hands it back there.
|
|
634
|
+
|
|
635
|
+
```ts
|
|
636
|
+
import {
|
|
637
|
+
focusOrigin,
|
|
638
|
+
handFocusBack,
|
|
639
|
+
trackToasterOrigin,
|
|
640
|
+
} from '@nxgt/material-core/toast-focus';
|
|
641
|
+
|
|
642
|
+
trackToasterOrigin();
|
|
643
|
+
let origin: Element | null = null;
|
|
644
|
+
toastElement.addEventListener('focusin', (event) => {
|
|
645
|
+
origin = focusOrigin(event, origin);
|
|
646
|
+
});
|
|
647
|
+
actionButton.addEventListener('click', () => {
|
|
648
|
+
handFocusBack(origin);
|
|
649
|
+
openDialog();
|
|
650
|
+
});
|
|
651
|
+
```
|
|
652
|
+
|
|
616
653
|
### Zod issue messages: `/zod-issue-messages`
|
|
617
654
|
|
|
618
655
|
The two libraries' zod error maps turn an issue into text in the language
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** The element sonner and vue-sonner render each toast list as. */
|
|
2
|
+
export declare const TOASTER_SELECTOR = "[data-sonner-toaster]";
|
|
3
|
+
/**
|
|
4
|
+
* Where the focus came from as it entered a toast, for a `focusin` heard on
|
|
5
|
+
* the toast: the element it left (`relatedTarget`), unless that was already
|
|
6
|
+
* in a Toaster, as when the focus moves from one toast to the next; then
|
|
7
|
+
* `origin`, what the toast had recorded so far, is kept, or else what the
|
|
8
|
+
* Toaster recorded when the focus first entered it (a toast that never had
|
|
9
|
+
* the focus from outside, as the next one in the list, still has an origin).
|
|
10
|
+
*/
|
|
11
|
+
export declare function focusOrigin(event: Pick<FocusEvent, 'relatedTarget'> & Partial<Pick<FocusEvent, 'target'>>, origin: Element | null): Element | null;
|
|
12
|
+
/**
|
|
13
|
+
* Records, for each Toaster, where the focus came from as it entered it.
|
|
14
|
+
* A toast hears the focus only once it reaches one of its own controls, and
|
|
15
|
+
* with a keyboard it first lands on the list item that wraps the toast
|
|
16
|
+
* (sonner's and vue-sonner's `li` take `tabindex="0"`), which no toast hears:
|
|
17
|
+
* this listens on the document, once, so the Toaster knows the page control
|
|
18
|
+
* the focus left. Call it when a toast mounts; calling it again does nothing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function trackToasterOrigin(doc?: Pick<Document, 'addEventListener'>): void;
|
|
21
|
+
/**
|
|
22
|
+
* Gives the focus back before a toast's action runs.
|
|
23
|
+
*
|
|
24
|
+
* sonner remembers the element focused before the focus entered its Toaster,
|
|
25
|
+
* and focuses it again the moment the focus leaves (the list's `onBlur`, and
|
|
26
|
+
* once more when the list unmounts). An action that opens a dialog moves the
|
|
27
|
+
* focus into the dialog, which counts as leaving: the restore pulled it back
|
|
28
|
+
* out, and the dialog lost the control it had focused (WCAG 2.4.3).
|
|
29
|
+
* vue-sonner does not restore (its `blur` does not bubble from the toast's
|
|
30
|
+
* buttons), so a dialog opened there gave the focus back, once closed, to a
|
|
31
|
+
* button that had gone with its toast.
|
|
32
|
+
*
|
|
33
|
+
* Called first by the action, it focuses `origin` (from {@link focusOrigin}),
|
|
34
|
+
* else the origin its Toaster recorded, or blurs the toast's control when
|
|
35
|
+
* neither is left (gone, or inert: `focus()` then silently does nothing).
|
|
36
|
+
* Only while the focus is in the Toaster: an action run from elsewhere leaves
|
|
37
|
+
* it alone. sonner then has nothing left to restore; the action moves the focus where it wants, and
|
|
38
|
+
* a dialog it opens returns the focus to `origin` when it closes.
|
|
39
|
+
*/
|
|
40
|
+
export declare function handFocusBack(origin: Element | null, doc?: Pick<Document, 'activeElement'>): void;
|
|
41
|
+
//# sourceMappingURL=toast-focus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast-focus.d.ts","sourceRoot":"","sources":["../../src/lib/toast-focus.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAoBxD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAC1B,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,EACpC,MAAM,EAAE,OAAO,GAAG,IAAI,GACpB,OAAO,GAAG,IAAI,CAQhB;AAID;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,GAAE,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAY,GAChD,IAAI,CAIN;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC5B,MAAM,EAAE,OAAO,GAAG,IAAI,EACtB,GAAG,GAAE,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAY,GAC7C,IAAI,CAUN"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// src/lib/toast-focus.ts
|
|
2
|
+
var TOASTER_SELECTOR = "[data-sonner-toaster]";
|
|
3
|
+
var asFocusable = (value) => typeof value?.closest === "function" && typeof value.focus === "function" ? value : null;
|
|
4
|
+
var toasterOrigins = new WeakMap;
|
|
5
|
+
function focusOrigin(event, origin) {
|
|
6
|
+
const toaster = asFocusable(event.target)?.closest(TOASTER_SELECTOR);
|
|
7
|
+
const from = asFocusable(event.relatedTarget);
|
|
8
|
+
if (from && !from.closest(TOASTER_SELECTOR)) {
|
|
9
|
+
if (toaster)
|
|
10
|
+
toasterOrigins.set(toaster, from);
|
|
11
|
+
return from;
|
|
12
|
+
}
|
|
13
|
+
return origin ?? (toaster ? toasterOrigins.get(toaster) ?? null : null);
|
|
14
|
+
}
|
|
15
|
+
var tracked = new WeakSet;
|
|
16
|
+
function trackToasterOrigin(doc = document) {
|
|
17
|
+
if (tracked.has(doc))
|
|
18
|
+
return;
|
|
19
|
+
tracked.add(doc);
|
|
20
|
+
doc.addEventListener("focusin", (event) => focusOrigin(event, null), true);
|
|
21
|
+
}
|
|
22
|
+
function handFocusBack(origin, doc = document) {
|
|
23
|
+
const active = asFocusable(doc.activeElement);
|
|
24
|
+
if (!active?.closest(TOASTER_SELECTOR))
|
|
25
|
+
return;
|
|
26
|
+
const toaster = active.closest(TOASTER_SELECTOR);
|
|
27
|
+
const candidates = [origin, toaster && toasterOrigins.get(toaster)];
|
|
28
|
+
const target = candidates.map(asFocusable).find((el) => el && el.isConnected !== false);
|
|
29
|
+
target?.focus({ preventScroll: true });
|
|
30
|
+
if (asFocusable(doc.activeElement) === active)
|
|
31
|
+
active.blur();
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
TOASTER_SELECTOR,
|
|
35
|
+
focusOrigin,
|
|
36
|
+
handFocusBack,
|
|
37
|
+
trackToasterOrigin
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
//# debugId=0763A78D43B386CF64756E2164756E21
|
|
41
|
+
//# sourceMappingURL=toast-focus.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lib/toast-focus.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/** The element sonner and vue-sonner render each toast list as. */\nexport const TOASTER_SELECTOR = '[data-sonner-toaster]';\n\n/** What these helpers read of an element: the DOM's own `HTMLElement` fits. */\ntype Focusable = Pick<HTMLElement, 'closest' | 'focus' | 'blur'> & {\n\treadonly isConnected?: boolean;\n};\n\nconst asFocusable = (value: unknown): Focusable | null =>\n\ttypeof (value as Focusable | null)?.closest === 'function' &&\n\ttypeof (value as Focusable).focus === 'function'\n\t\t? (value as Focusable)\n\t\t: null;\n\n/**\n * Where the focus was before it entered each Toaster, keyed by the Toaster's\n * element: a toast reached from another toast has no origin of its own, and\n * falls back to this one.\n */\nconst toasterOrigins = new WeakMap<Element, Element>();\n\n/**\n * Where the focus came from as it entered a toast, for a `focusin` heard on\n * the toast: the element it left (`relatedTarget`), unless that was already\n * in a Toaster, as when the focus moves from one toast to the next; then\n * `origin`, what the toast had recorded so far, is kept, or else what the\n * Toaster recorded when the focus first entered it (a toast that never had\n * the focus from outside, as the next one in the list, still has an origin).\n */\nexport function focusOrigin(\n\tevent: Pick<FocusEvent, 'relatedTarget'> &\n\t\tPartial<Pick<FocusEvent, 'target'>>,\n\torigin: Element | null,\n): Element | null {\n\tconst toaster = asFocusable(event.target)?.closest(TOASTER_SELECTOR);\n\tconst from = asFocusable(event.relatedTarget);\n\tif (from && !from.closest(TOASTER_SELECTOR)) {\n\t\tif (toaster) toasterOrigins.set(toaster, from as unknown as Element);\n\t\treturn from as unknown as Element;\n\t}\n\treturn origin ?? (toaster ? (toasterOrigins.get(toaster) ?? null) : null);\n}\n\nconst tracked = new WeakSet<object>();\n\n/**\n * Records, for each Toaster, where the focus came from as it entered it.\n * A toast hears the focus only once it reaches one of its own controls, and\n * with a keyboard it first lands on the list item that wraps the toast\n * (sonner's and vue-sonner's `li` take `tabindex=\"0\"`), which no toast hears:\n * this listens on the document, once, so the Toaster knows the page control\n * the focus left. Call it when a toast mounts; calling it again does nothing.\n */\nexport function trackToasterOrigin(\n\tdoc: Pick<Document, 'addEventListener'> = document,\n): void {\n\tif (tracked.has(doc)) return;\n\ttracked.add(doc);\n\tdoc.addEventListener('focusin', (event) => focusOrigin(event, null), true);\n}\n\n/**\n * Gives the focus back before a toast's action runs.\n *\n * sonner remembers the element focused before the focus entered its Toaster,\n * and focuses it again the moment the focus leaves (the list's `onBlur`, and\n * once more when the list unmounts). An action that opens a dialog moves the\n * focus into the dialog, which counts as leaving: the restore pulled it back\n * out, and the dialog lost the control it had focused (WCAG 2.4.3).\n * vue-sonner does not restore (its `blur` does not bubble from the toast's\n * buttons), so a dialog opened there gave the focus back, once closed, to a\n * button that had gone with its toast.\n *\n * Called first by the action, it focuses `origin` (from {@link focusOrigin}),\n * else the origin its Toaster recorded, or blurs the toast's control when\n * neither is left (gone, or inert: `focus()` then silently does nothing).\n * Only while the focus is in the Toaster: an action run from elsewhere leaves\n * it alone. sonner then has nothing left to restore; the action moves the focus where it wants, and\n * a dialog it opens returns the focus to `origin` when it closes.\n */\nexport function handFocusBack(\n\torigin: Element | null,\n\tdoc: Pick<Document, 'activeElement'> = document,\n): void {\n\tconst active = asFocusable(doc.activeElement);\n\tif (!active?.closest(TOASTER_SELECTOR)) return;\n\tconst toaster = active.closest(TOASTER_SELECTOR);\n\tconst candidates = [origin, toaster && toasterOrigins.get(toaster)];\n\tconst target = candidates\n\t\t.map(asFocusable)\n\t\t.find((el) => el && el.isConnected !== false);\n\ttarget?.focus({ preventScroll: true });\n\tif (asFocusable(doc.activeElement) === active) active.blur();\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AACO,IAAM,mBAAmB;AAOhC,IAAM,cAAc,CAAC,UACpB,OAAQ,OAA4B,YAAY,cAChD,OAAQ,MAAoB,UAAU,aAClC,QACD;AAOJ,IAAM,iBAAiB,IAAI;AAUpB,SAAS,WAAW,CAC1B,OAEA,QACiB;AAAA,EACjB,MAAM,UAAU,YAAY,MAAM,MAAM,GAAG,QAAQ,gBAAgB;AAAA,EACnE,MAAM,OAAO,YAAY,MAAM,aAAa;AAAA,EAC5C,IAAI,QAAQ,CAAC,KAAK,QAAQ,gBAAgB,GAAG;AAAA,IAC5C,IAAI;AAAA,MAAS,eAAe,IAAI,SAAS,IAA0B;AAAA,IACnE,OAAO;AAAA,EACR;AAAA,EACA,OAAO,WAAW,UAAW,eAAe,IAAI,OAAO,KAAK,OAAQ;AAAA;AAGrE,IAAM,UAAU,IAAI;AAUb,SAAS,kBAAkB,CACjC,MAA0C,UACnC;AAAA,EACP,IAAI,QAAQ,IAAI,GAAG;AAAA,IAAG;AAAA,EACtB,QAAQ,IAAI,GAAG;AAAA,EACf,IAAI,iBAAiB,WAAW,CAAC,UAAU,YAAY,OAAO,IAAI,GAAG,IAAI;AAAA;AAsBnE,SAAS,aAAa,CAC5B,QACA,MAAuC,UAChC;AAAA,EACP,MAAM,SAAS,YAAY,IAAI,aAAa;AAAA,EAC5C,IAAI,CAAC,QAAQ,QAAQ,gBAAgB;AAAA,IAAG;AAAA,EACxC,MAAM,UAAU,OAAO,QAAQ,gBAAgB;AAAA,EAC/C,MAAM,aAAa,CAAC,QAAQ,WAAW,eAAe,IAAI,OAAO,CAAC;AAAA,EAClE,MAAM,SAAS,WACb,IAAI,WAAW,EACf,KAAK,CAAC,OAAO,MAAM,GAAG,gBAAgB,KAAK;AAAA,EAC7C,QAAQ,MAAM,EAAE,eAAe,KAAK,CAAC;AAAA,EACrC,IAAI,YAAY,IAAI,aAAa,MAAM;AAAA,IAAQ,OAAO,KAAK;AAAA;",
|
|
8
|
+
"debugId": "0763A78D43B386CF64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/docs/roadmap.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Roadmap
|
|
2
2
|
|
|
3
|
-
Where `@nxgt/material-core` is going. A direction, not a commitment:
|
|
4
|
-
version
|
|
3
|
+
Where `@nxgt/material-core` is going. A direction, not a commitment: shipped
|
|
4
|
+
entries carry the version they shipped in, and planned entries may name the
|
|
5
|
+
major they target.
|
|
5
6
|
|
|
6
7
|
## Now
|
|
7
8
|
|
|
@@ -9,6 +10,20 @@ Nothing in progress right now; see Next.
|
|
|
9
10
|
|
|
10
11
|
## Next
|
|
11
12
|
|
|
13
|
+
- **The shared media player** — the player state machine (playback, queue and
|
|
14
|
+
shuffle, chapters, transcript sync, resume position, quality levels, Wake
|
|
15
|
+
Lock), its keyboard shortcuts and the shortcut-help list, so
|
|
16
|
+
`useMediaPlayer` behaves the same in React and Vue.
|
|
17
|
+
- **The PDF engine** — a framework-free engine on pdfkit that renders the
|
|
18
|
+
document model in Node, Bun and the browser, replacing `@react-pdf/renderer`:
|
|
19
|
+
`definePdfDocument`, the app theme and fonts, QR codes, barcodes and charts,
|
|
20
|
+
rich text and Markdown, tagged output (PDF/UA), PDF/A-3 and Factur-X
|
|
21
|
+
(EN 16931), and the helpers that read a generated PDF back in a test.
|
|
22
|
+
- **The PDF reader layers** — pdf.js used directly: the rendering, text and
|
|
23
|
+
annotation layers, the annotation model (JSON in and out, export into the
|
|
24
|
+
PDF through `pdf-lib`, loaded when used), AcroForm filling, the two-page and
|
|
25
|
+
scrolling layouts, read-aloud and the reflowed text mode, so each library
|
|
26
|
+
only draws the toolbar around them.
|
|
12
27
|
- **What the two libraries still keep twice.** The upload constraints (once
|
|
13
28
|
their translation function no longer names each library's own message
|
|
14
29
|
keys), pdf.js's inlined note icons (they need an asset build core does not
|
|
@@ -25,12 +40,20 @@ Nothing in progress right now; see Next.
|
|
|
25
40
|
|
|
26
41
|
- **Components.** This package stays framework-free: React components are in
|
|
27
42
|
`@nxgt/material`, Vue ones in `@nxgt/material-vue`.
|
|
28
|
-
- **
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
- **A fake DOM for tests.** The one the libraries' own tests use is the
|
|
44
|
+
repository's, in a private package that is never published.
|
|
45
|
+
- **Right-to-left and complex-script PDFs** — pdfkit does not lay out
|
|
46
|
+
right-to-left text or shape Arabic and Hebrew reliably, so the new engine
|
|
47
|
+
does not promise it. Render such a document as HTML and print it with a
|
|
48
|
+
browser.
|
|
49
|
+
- **Two PDF engines** — pdfkit replaces `@react-pdf/renderer`; they do not
|
|
50
|
+
coexist. One engine and one document model serve both libraries.
|
|
31
51
|
|
|
32
52
|
## Shipped
|
|
33
53
|
|
|
54
|
+
- **The focus a toast's action hands back** (`/toast-focus`) — where the
|
|
55
|
+
focus was before it entered a toast, given back before the action runs, so
|
|
56
|
+
a dialog the action opens keeps the focus in both libraries. 0.7.0.
|
|
34
57
|
- **A field's first reachable control** (`/focus-control`) — the control of a
|
|
35
58
|
field made of several a user can reach, and a stand-in a form library can
|
|
36
59
|
focus, so both libraries focus the first invalid field. 0.5.0.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/material-core",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The framework-free core of @nxgt/material and @nxgt/material-vue: the PDF document model and its react-pdf renderer, print formatters, PDF file helpers, the PDF viewer's pure modules, the currency digits, the file-size formatter, the field-blur layers, a field's first focusable control, the aria-describedby joiner, the inert background of a modal layer, Escape forwarded while an overlay closes, the Toaster's touch-hover guard, the zod issue messages, the date range presets, the file preview's kind detection and text reader, the pdfkit fonts Vite plugin and the Node-only pdfkit fonts resolution for Next.js and Nuxt builds",
|
|
3
|
+
"version": "0.7.1",
|
|
4
|
+
"description": "The framework-free core of @nxgt/material and @nxgt/material-vue: the PDF document model and its react-pdf renderer, print formatters, PDF file helpers, the PDF viewer's pure modules, the currency digits, the file-size formatter, the field-blur layers, a field's first focusable control, the aria-describedby joiner, the inert background of a modal layer, Escape forwarded while an overlay closes, the Toaster's touch-hover guard and its focus hand-back, the zod issue messages, the date range presets, the file preview's kind detection and text reader, the pdfkit fonts Vite plugin and the Node-only pdfkit fonts resolution for Next.js and Nuxt builds",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"email": "stevegires@gmail.com"
|
|
@@ -113,6 +113,11 @@
|
|
|
113
113
|
"import": "./dist/lib/touch-hover.js",
|
|
114
114
|
"default": "./dist/lib/touch-hover.js"
|
|
115
115
|
},
|
|
116
|
+
"./toast-focus": {
|
|
117
|
+
"types": "./dist/lib/toast-focus.d.ts",
|
|
118
|
+
"import": "./dist/lib/toast-focus.js",
|
|
119
|
+
"default": "./dist/lib/toast-focus.js"
|
|
120
|
+
},
|
|
116
121
|
"./zod-issue-messages": {
|
|
117
122
|
"types": "./dist/lib/zod-issue-messages.d.ts",
|
|
118
123
|
"import": "./dist/lib/zod-issue-messages.js",
|
|
@@ -216,6 +221,7 @@
|
|
|
216
221
|
"src/lib/escape-forward.ts",
|
|
217
222
|
"src/lib/described-by.ts",
|
|
218
223
|
"src/lib/touch-hover.ts",
|
|
224
|
+
"src/lib/toast-focus.ts",
|
|
219
225
|
"src/lib/zod-issue-messages.ts",
|
|
220
226
|
"src/lib/inert-others.ts",
|
|
221
227
|
"src/lib/row-activation.ts",
|