ngwr 14.0.0 → 14.0.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/README.md +57 -8
- package/aurora/aurora.scss +1 -1
- package/aurora/styles/_dark.scss +21 -0
- package/aurora/styles/_index.scss +11 -30
- package/aurora/styles/_rules.scss +25 -0
- package/border-glow/styles/_dark.scss +46 -0
- package/border-glow/styles/_index.scss +5 -0
- package/border-glow/styles/_rules.scss +0 -31
- package/button/styles/_index.scss +16 -0
- package/event-calendar/styles/_index.scss +15 -0
- package/fesm2022/ngwr-action-sheet.mjs +3 -3
- package/fesm2022/ngwr-affix.mjs +3 -3
- package/fesm2022/ngwr-alert.mjs +3 -3
- package/fesm2022/ngwr-anchor.mjs +3 -3
- package/fesm2022/ngwr-aurora.mjs +4 -4
- package/fesm2022/ngwr-aurora.mjs.map +1 -1
- package/fesm2022/ngwr-avatar.mjs +3 -3
- package/fesm2022/ngwr-back-top.mjs +3 -3
- package/fesm2022/ngwr-badge.mjs +6 -6
- package/fesm2022/ngwr-bar-chart.mjs +3 -3
- package/fesm2022/ngwr-blur-text.mjs +3 -3
- package/fesm2022/ngwr-border-glow.mjs +4 -4
- package/fesm2022/ngwr-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +7 -7
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-burger.mjs +3 -3
- package/fesm2022/ngwr-button.mjs +86 -8
- package/fesm2022/ngwr-button.mjs.map +1 -1
- package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
- package/fesm2022/ngwr-calendar.mjs +3 -3
- package/fesm2022/ngwr-card.mjs +9 -9
- package/fesm2022/ngwr-carousel.mjs +6 -6
- package/fesm2022/ngwr-cascader.mjs +4 -4
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +6 -6
- package/fesm2022/ngwr-circular-text.mjs +3 -3
- package/fesm2022/ngwr-click-spark.mjs +3 -3
- package/fesm2022/ngwr-clipboard.mjs +3 -3
- package/fesm2022/ngwr-collapse.mjs +9 -9
- package/fesm2022/ngwr-color-picker.mjs +6 -6
- package/fesm2022/ngwr-command-palette.mjs +3 -3
- package/fesm2022/ngwr-compare.mjs +3 -3
- package/fesm2022/ngwr-confetti.mjs +3 -3
- package/fesm2022/ngwr-context-menu.mjs +12 -12
- package/fesm2022/ngwr-cookie.mjs +3 -3
- package/fesm2022/ngwr-counter.mjs +6 -6
- package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
- package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
- package/fesm2022/ngwr-date-picker.mjs +18 -18
- package/fesm2022/ngwr-date.mjs +3 -3
- package/fesm2022/ngwr-decrypt-text.mjs +3 -3
- package/fesm2022/ngwr-density.mjs +6 -6
- package/fesm2022/ngwr-descriptions.mjs +6 -6
- package/fesm2022/ngwr-dialog.mjs +15 -15
- package/fesm2022/ngwr-directives.mjs +12 -12
- package/fesm2022/ngwr-divider.mjs +3 -3
- package/fesm2022/ngwr-donut-chart.mjs +3 -3
- package/fesm2022/ngwr-drag-drop.mjs +7 -7
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-drawer.mjs +18 -18
- package/fesm2022/ngwr-dropdown.mjs +28 -12
- package/fesm2022/ngwr-dropdown.mjs.map +1 -1
- package/fesm2022/ngwr-empty.mjs +3 -3
- package/fesm2022/ngwr-event-calendar.mjs +6 -6
- package/fesm2022/ngwr-falling-text.mjs +3 -3
- package/fesm2022/ngwr-file-upload.mjs +3 -3
- package/fesm2022/ngwr-form-testing.mjs +13 -7
- package/fesm2022/ngwr-form-testing.mjs.map +1 -1
- package/fesm2022/ngwr-form.mjs +44 -25
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
- package/fesm2022/ngwr-gauge.mjs +3 -3
- package/fesm2022/ngwr-glitch-text.mjs +3 -3
- package/fesm2022/ngwr-gradient-text.mjs +3 -3
- package/fesm2022/ngwr-hotkey.mjs +6 -6
- package/fesm2022/ngwr-i18n.mjs +9 -9
- package/fesm2022/ngwr-icon.mjs +6 -6
- package/fesm2022/ngwr-image-cropper.mjs +3 -3
- package/fesm2022/ngwr-input-number.mjs +3 -3
- package/fesm2022/ngwr-input-otp.mjs +3 -3
- package/fesm2022/ngwr-input.mjs +24 -20
- package/fesm2022/ngwr-input.mjs.map +1 -1
- package/fesm2022/ngwr-keyboard.mjs +3 -3
- package/fesm2022/ngwr-knob.mjs +3 -3
- package/fesm2022/ngwr-layout.mjs +15 -15
- package/fesm2022/ngwr-lightbox.mjs +4 -4
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-line-chart.mjs +3 -3
- package/fesm2022/ngwr-list.mjs +7 -7
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar.mjs +6 -6
- package/fesm2022/ngwr-markdown.mjs +6 -6
- package/fesm2022/ngwr-marquee.mjs +3 -3
- package/fesm2022/ngwr-media.mjs +3 -3
- package/fesm2022/ngwr-mention.mjs +6 -6
- package/fesm2022/ngwr-meta.mjs +6 -6
- package/fesm2022/ngwr-meter-group.mjs +3 -3
- package/fesm2022/ngwr-overlay.mjs +6 -6
- package/fesm2022/ngwr-page-header.mjs +3 -3
- package/fesm2022/ngwr-pagination.mjs +3 -3
- package/fesm2022/ngwr-pipes.mjs +21 -21
- package/fesm2022/ngwr-platform.mjs +9 -9
- package/fesm2022/ngwr-popconfirm.mjs +6 -6
- package/fesm2022/ngwr-popover.mjs +6 -6
- package/fesm2022/ngwr-progress.mjs +3 -3
- package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
- package/fesm2022/ngwr-qr.mjs +3 -3
- package/fesm2022/ngwr-radio.mjs +6 -6
- package/fesm2022/ngwr-rating.mjs +48 -22
- package/fesm2022/ngwr-rating.mjs.map +1 -1
- package/fesm2022/ngwr-result.mjs +12 -12
- package/fesm2022/ngwr-rotating-text.mjs +3 -3
- package/fesm2022/ngwr-scroll.mjs +3 -3
- package/fesm2022/ngwr-segmented.mjs +12 -8
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +125 -26
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text.mjs +7 -7
- package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
- package/fesm2022/ngwr-sidebar.mjs +3 -3
- package/fesm2022/ngwr-skeleton.mjs +3 -3
- package/fesm2022/ngwr-slider.mjs +12 -8
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-sparkline.mjs +3 -3
- package/fesm2022/ngwr-speed-dial.mjs +3 -3
- package/fesm2022/ngwr-spinner.mjs +3 -3
- package/fesm2022/ngwr-splash-cursor.mjs +3 -3
- package/fesm2022/ngwr-split-text.mjs +3 -3
- package/fesm2022/ngwr-splitter.mjs +3 -3
- package/fesm2022/ngwr-spotlight-card.mjs +7 -7
- package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-squircle.mjs +6 -6
- package/fesm2022/ngwr-star-border.mjs +4 -4
- package/fesm2022/ngwr-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-statistic.mjs +9 -9
- package/fesm2022/ngwr-stepper.mjs +6 -6
- package/fesm2022/ngwr-storage.mjs +11 -3
- package/fesm2022/ngwr-storage.mjs.map +1 -1
- package/fesm2022/ngwr-switch.mjs +3 -3
- package/fesm2022/ngwr-table.mjs +18 -18
- package/fesm2022/ngwr-tabs-router.mjs +3 -3
- package/fesm2022/ngwr-tabs.mjs +6 -6
- package/fesm2022/ngwr-textarea.mjs +26 -5
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-theme.mjs +90 -4
- package/fesm2022/ngwr-theme.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card.mjs +7 -7
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-timeline.mjs +6 -6
- package/fesm2022/ngwr-toast.mjs +116 -11
- package/fesm2022/ngwr-toast.mjs.map +1 -1
- package/fesm2022/ngwr-toolbar.mjs +3 -3
- package/fesm2022/ngwr-tour.mjs +6 -6
- package/fesm2022/ngwr-transfer.mjs +3 -3
- package/fesm2022/ngwr-tree.mjs +18 -11
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter.mjs +3 -3
- package/fesm2022/ngwr-typography.mjs +3 -3
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
- package/fesm2022/ngwr-waves.mjs +4 -4
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/fesm2022/ngwr-window.mjs +12 -12
- package/llms-full.txt +9 -9
- package/llms.txt +82 -11
- package/package.json +1 -1
- package/shiny-text/styles/_dark.scss +20 -0
- package/shiny-text/styles/_index.scss +5 -0
- package/shiny-text/styles/_rules.scss +0 -4
- package/spotlight-card/styles/_dark.scss +21 -0
- package/spotlight-card/styles/_index.scss +5 -0
- package/spotlight-card/styles/_rules.scss +0 -6
- package/star-border/styles/_dark.scss +21 -0
- package/star-border/styles/_index.scss +5 -0
- package/star-border/styles/_rules.scss +0 -5
- package/theme/styles/_colors.scss +102 -0
- package/theme/styles/_focus.scss +31 -1
- package/tilt-card/styles/_dark.scss +21 -0
- package/tilt-card/styles/_index.scss +5 -0
- package/tilt-card/styles/_rules.scss +0 -5
- package/types/ngwr-button.d.ts +43 -0
- package/types/ngwr-dropdown.d.ts +17 -1
- package/types/ngwr-form-testing.d.ts +13 -7
- package/types/ngwr-form.d.ts +47 -12
- package/types/ngwr-input.d.ts +2 -1
- package/types/ngwr-rating.d.ts +25 -4
- package/types/ngwr-segmented.d.ts +1 -0
- package/types/ngwr-select.d.ts +45 -9
- package/types/ngwr-slider.d.ts +1 -0
- package/types/ngwr-storage.d.ts +39 -1
- package/types/ngwr-textarea.d.ts +20 -0
- package/types/ngwr-theme.d.ts +92 -2
- package/types/ngwr-toast.d.ts +53 -0
- package/types/ngwr-tree.d.ts +3 -2
- package/types/ngwr-version.d.ts +1 -1
- package/waves/styles/_dark.scss +19 -0
- package/waves/styles/_index.scss +5 -0
- package/waves/styles/_rules.scss +0 -3
package/types/ngwr-select.d.ts
CHANGED
|
@@ -227,15 +227,17 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
227
227
|
*/
|
|
228
228
|
protected readonly controlId: _angular_core.Signal<string | null>;
|
|
229
229
|
/**
|
|
230
|
-
* The field's error message, wired to the same
|
|
230
|
+
* The field's error message — or, failing that, its hint — wired to the same
|
|
231
|
+
* element, plus the invalid flag.
|
|
231
232
|
*
|
|
232
|
-
* Without it the
|
|
233
|
-
*
|
|
234
|
-
* message says. `
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*/
|
|
233
|
+
* Without it the copy `<wr-form-field>` renders is visible and nothing else: a
|
|
234
|
+
* screen reader on the trigger never learns the field is invalid, nor what the
|
|
235
|
+
* message says. Composed by `useFormFieldAria()` rather than read off the field
|
|
236
|
+
* here, so the trigger picks up the hint the same way the other value controls
|
|
237
|
+
* do and `aria-invalid` stays keyed on the error rather than on "is anything
|
|
238
|
+
* describing me".
|
|
239
|
+
*/
|
|
240
|
+
private readonly fieldAria;
|
|
239
241
|
protected readonly describedBy: _angular_core.Signal<string | null>;
|
|
240
242
|
protected readonly ariaInvalid: _angular_core.Signal<"true" | null>;
|
|
241
243
|
/**
|
|
@@ -605,8 +607,41 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
605
607
|
protected virtualRowId(i: number): string;
|
|
606
608
|
/** The virtual scroll container inside the overlay panel, if attached. */
|
|
607
609
|
private get vlistElement();
|
|
608
|
-
/**
|
|
610
|
+
/** The scrolling listbox inside the overlay panel, if attached. */
|
|
611
|
+
private get panelElement();
|
|
612
|
+
/**
|
|
613
|
+
* Scroll the ordered index `i` just into view. Two implementations, because the
|
|
614
|
+
* two panels scroll different elements and know the row geometry in different
|
|
615
|
+
* ways — the virtual list is index maths against a measured row height, the
|
|
616
|
+
* projected list has to read the row it is moving to.
|
|
617
|
+
*
|
|
618
|
+
* The non-virtual half is not an optimisation, it is the whole keyboard
|
|
619
|
+
* contract: `activeIndex` drives `aria-activedescendant`, and NOTHING else
|
|
620
|
+
* moves a projected panel, because the rows never take DOM focus. Without it
|
|
621
|
+
* End on a 250-option `mode="search"` panel announced Zimbabwe while the panel
|
|
622
|
+
* sat at `scrollTop` 0 with the cursor 9 218 px below the fold, and Enter then
|
|
623
|
+
* committed a row the user could not see.
|
|
624
|
+
*/
|
|
609
625
|
private ensureVisible;
|
|
626
|
+
/**
|
|
627
|
+
* Scroll the projected row at ordered index `i` just into view.
|
|
628
|
+
*
|
|
629
|
+
* Geometry is READ rather than computed: projected `<wr-option>` rows are
|
|
630
|
+
* consumer content, so they are not a uniform height the way a virtual row is
|
|
631
|
+
* — a row with a description, an icon or a wrapped label is taller than its
|
|
632
|
+
* neighbours, and index maths would land the panel next to the cursor instead
|
|
633
|
+
* of on it. The offset is taken relative to the panel's own scroll content
|
|
634
|
+
* (`rect.top` difference plus the current `scrollTop`) rather than from
|
|
635
|
+
* `offsetTop`, which is measured against whichever ancestor happens to be
|
|
636
|
+
* positioned.
|
|
637
|
+
*
|
|
638
|
+
* `scrollTop` is written directly instead of `scrollTo`, so the write is
|
|
639
|
+
* observable in a spec — jsdom implements the property and does not implement
|
|
640
|
+
* the method. It still reads as a no-op there, since every jsdom rect is 0×0:
|
|
641
|
+
* a spec asserting a scroll has to stub `getBoundingClientRect` and
|
|
642
|
+
* `clientHeight` on the panel and the row, which `select.spec.ts` does.
|
|
643
|
+
*/
|
|
644
|
+
private ensureRowVisible;
|
|
610
645
|
/**
|
|
611
646
|
* Count of registered options that pass the current search filter.
|
|
612
647
|
* Hides the noResults state when the panel has at least one visible row.
|
|
@@ -674,6 +709,7 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
|
|
|
674
709
|
private readonly scrollStrategies;
|
|
675
710
|
private readonly destroyRef;
|
|
676
711
|
private readonly platformId;
|
|
712
|
+
private readonly injector;
|
|
677
713
|
private overlayRef;
|
|
678
714
|
constructor();
|
|
679
715
|
isSelected(value: unknown): boolean;
|
package/types/ngwr-slider.d.ts
CHANGED
|
@@ -137,6 +137,7 @@ declare class WrSlider implements FormValueControl<WrSliderValue> {
|
|
|
137
137
|
* showing something — announcing "invalid" while pointing at nothing is worse
|
|
138
138
|
* than staying quiet.
|
|
139
139
|
*/
|
|
140
|
+
private readonly fieldAria;
|
|
140
141
|
protected readonly describedBy: _angular_core.Signal<string | null>;
|
|
141
142
|
protected readonly ariaInvalid: _angular_core.Signal<"true" | null>;
|
|
142
143
|
/**
|
package/types/ngwr-storage.d.ts
CHANGED
|
@@ -14,6 +14,9 @@ import * as ngwr_storage from 'ngwr/storage';
|
|
|
14
14
|
* lazily on the next `get` / `watch` read.
|
|
15
15
|
* - **Reactive watch** — `watch(key)` returns a `Signal` that updates on
|
|
16
16
|
* local writes and cross-tab `storage` events.
|
|
17
|
+
* - **On-disk format** — values are wrapped in a {@link WrStorageEnvelope}
|
|
18
|
+
* (`{"v":…,"e":…}`) while `json` is on. Anything reading the same key from
|
|
19
|
+
* outside Angular has to unwrap it.
|
|
17
20
|
*
|
|
18
21
|
* SSR-safe: the default engine factory returns an in-memory shim when
|
|
19
22
|
* `localStorage` is unavailable, so reads always work.
|
|
@@ -60,6 +63,11 @@ declare class WrStorage {
|
|
|
60
63
|
/**
|
|
61
64
|
* Write `value` at `key`. Per-call `ttl` (ms) overrides the config
|
|
62
65
|
* default. JSON-serializable values only when `json` is on (the default).
|
|
66
|
+
*
|
|
67
|
+
* What lands in the engine is a {@link WrStorageEnvelope} —
|
|
68
|
+
* `{"v":<value>}`, plus `"e"` when a TTL applies — not the bare value. Code
|
|
69
|
+
* outside Angular that reads the same key has to unwrap it; see the envelope's
|
|
70
|
+
* own docs for the exact format.
|
|
63
71
|
*/
|
|
64
72
|
set<T = unknown>(key: string, value: T, opts?: {
|
|
65
73
|
ttl?: number;
|
|
@@ -118,6 +126,36 @@ interface WrStorageConfig {
|
|
|
118
126
|
}
|
|
119
127
|
/** Fully-resolved config (all defaults filled). @internal */
|
|
120
128
|
type WrStorageConfigResolved = Required<WrStorageConfig>;
|
|
129
|
+
/**
|
|
130
|
+
* The **on-disk format** `WrStorage` writes while `json` is on (the default).
|
|
131
|
+
*
|
|
132
|
+
* Public because it is a wire format, not an implementation detail: the value in
|
|
133
|
+
* `localStorage` is `JSON.stringify(envelope)`, so anything reading the same key
|
|
134
|
+
* from outside Angular — a pre-paint theme script in `index.html`, a service
|
|
135
|
+
* worker, a native shell, another framework on the same origin — has to know
|
|
136
|
+
* that a stored `'dark'` is spelled `{"v":"dark"}` and not `"dark"`. Left
|
|
137
|
+
* undocumented, the only way to learn that was to read the bundle.
|
|
138
|
+
*
|
|
139
|
+
* `e` is an absolute expiry in epoch milliseconds, written only when a TTL
|
|
140
|
+
* applies; a value past it reads as absent and is removed on the next `get`.
|
|
141
|
+
* A key holding anything else — a bare JSON value, or a string that is not JSON
|
|
142
|
+
* at all — is returned as it stands, so keys written by non-ngwr code keep
|
|
143
|
+
* working.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```jsonc
|
|
147
|
+
* // localStorage['wr-theme']
|
|
148
|
+
* { "v": "dark" }
|
|
149
|
+
* // localStorage['cart'], written with { ttl: 60_000 }
|
|
150
|
+
* { "v": [{ "sku": "a1" }], "e": 1767225600000 }
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
interface WrStorageEnvelope<T = unknown> {
|
|
154
|
+
/** The stored value, as handed to `set()`. */
|
|
155
|
+
readonly v: T;
|
|
156
|
+
/** Absolute expiry, epoch ms. Absent when the write carried no TTL. */
|
|
157
|
+
readonly e?: number;
|
|
158
|
+
}
|
|
121
159
|
|
|
122
160
|
declare const DEFAULT_WR_STORAGE_CONFIG: WrStorageConfigResolved;
|
|
123
161
|
declare const WR_STORAGE_CONFIG: InjectionToken<Required<ngwr_storage.WrStorageConfig>>;
|
|
@@ -185,4 +223,4 @@ interface ProvideWrStorageOptions extends WrStorageConfig {
|
|
|
185
223
|
declare function provideWrStorage(options?: ProvideWrStorageOptions): EnvironmentProviders;
|
|
186
224
|
|
|
187
225
|
export { DEFAULT_WR_STORAGE_CONFIG, WR_STORAGE_CONFIG, WR_STORAGE_ENGINE, WrStorage, createMemoryStorage, provideWrStorage };
|
|
188
|
-
export type { ProvideWrStorageOptions, WrStorageConfig, WrStorageConfigResolved, WrStorageEngine };
|
|
226
|
+
export type { ProvideWrStorageOptions, WrStorageConfig, WrStorageConfigResolved, WrStorageEngine, WrStorageEnvelope };
|
package/types/ngwr-textarea.d.ts
CHANGED
|
@@ -71,6 +71,26 @@ declare class WrTextarea implements FormValueControl<string> {
|
|
|
71
71
|
protected readonly effectiveResize: _angular_core.Signal<WrTextareaResize>;
|
|
72
72
|
/** The surrounding `<wr-form-field>`'s error state. @internal */
|
|
73
73
|
protected readonly fieldAria: ngwr_form.WrFormFieldAria;
|
|
74
|
+
private readonly field;
|
|
75
|
+
/**
|
|
76
|
+
* Id the surrounding `<wr-form-field>`'s `<label for>` points at.
|
|
77
|
+
*
|
|
78
|
+
* The field renders its label before it can see what was projected into it, so
|
|
79
|
+
* the id travels the other way and the control adopts it, exactly as
|
|
80
|
+
* `[wrInput]` and `wr-select` do. Without it the `for` named an element that
|
|
81
|
+
* was nowhere in the document: clicking the label did nothing, and the field
|
|
82
|
+
* was, to a screen reader, an unlabelled block.
|
|
83
|
+
*
|
|
84
|
+
* It lands on the native `<textarea>` rather than on the host, because only a
|
|
85
|
+
* labelable element can be a label's target and `<wr-textarea>` is not one.
|
|
86
|
+
*
|
|
87
|
+
* What it does NOT change is the NAME: `aria-label` outranks a `<label>` in
|
|
88
|
+
* the accname order and `resolvedAriaLabel()` still wins, the same call
|
|
89
|
+
* `wr-select` and `wr-slider` make — the field renders a label only when its
|
|
90
|
+
* `label` input is set, so it cannot promise a name to fall back on. Set
|
|
91
|
+
* `[ariaLabel]` to the field's label where the two should read alike.
|
|
92
|
+
*/
|
|
93
|
+
protected readonly controlId: _angular_core.Signal<string | null>;
|
|
74
94
|
protected readonly classes: _angular_core.Signal<string>;
|
|
75
95
|
/** Show the corner grip (hidden when direction is 'none' / autosize / disabled). */
|
|
76
96
|
protected readonly showHandle: _angular_core.Signal<boolean>;
|
package/types/ngwr-theme.d.ts
CHANGED
|
@@ -164,6 +164,15 @@ declare const WR_THEME_CONFIG: InjectionToken<WrThemeConfig>;
|
|
|
164
164
|
* `@use 'ngwr' with ($theme-attribute: '...')`. In dev mode the service compares
|
|
165
165
|
* the two and warns when they disagree.
|
|
166
166
|
*
|
|
167
|
+
* **Under SSR or prerendering this service cannot prevent a flash of the wrong
|
|
168
|
+
* theme, and nothing inside the application can.** The server has no
|
|
169
|
+
* `localStorage` and no `prefers-color-scheme`, so every rendered page ships the
|
|
170
|
+
* same attribute (`light` under the default config); by the time the client
|
|
171
|
+
* bundle boots and the effect below corrects it, the browser has already
|
|
172
|
+
* painted. Closing that window takes a script that runs before first paint —
|
|
173
|
+
* {@link wrThemePrePaintScript} emits one that reads the persisted mode exactly
|
|
174
|
+
* the way this service does.
|
|
175
|
+
*
|
|
167
176
|
* @example
|
|
168
177
|
* ```ts
|
|
169
178
|
* const theme = inject(WrTheme);
|
|
@@ -237,5 +246,86 @@ declare class WrTheme {
|
|
|
237
246
|
*/
|
|
238
247
|
declare function provideWrTheme(config?: Partial<WrThemeConfig>): EnvironmentProviders;
|
|
239
248
|
|
|
240
|
-
|
|
241
|
-
|
|
249
|
+
/**
|
|
250
|
+
* @license
|
|
251
|
+
*
|
|
252
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
253
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
/** Options for {@link wrThemePrePaintScript}. All optional — defaults mirror the services. */
|
|
257
|
+
interface WrThemePrePaintOptions {
|
|
258
|
+
/**
|
|
259
|
+
* The key {@link WrTheme} persists the mode under — `provideWrTheme({ storageKey })`.
|
|
260
|
+
* @default 'wr-theme'
|
|
261
|
+
*/
|
|
262
|
+
readonly storageKey?: string;
|
|
263
|
+
/**
|
|
264
|
+
* The attribute written on `<html>` — `provideWrTheme({ attribute })`, which
|
|
265
|
+
* has to agree with `@use 'ngwr' with ($theme-attribute: '…')`.
|
|
266
|
+
* @default 'data-theme'
|
|
267
|
+
*/
|
|
268
|
+
readonly attribute?: string;
|
|
269
|
+
/**
|
|
270
|
+
* What to resolve when nothing is persisted — `provideWrTheme({ defaultMode })`.
|
|
271
|
+
* @default 'auto'
|
|
272
|
+
*/
|
|
273
|
+
readonly defaultMode?: WrThemeMode;
|
|
274
|
+
/**
|
|
275
|
+
* `WrStorage`'s key prefix — `provideWrStorage({ prefix })`. The script reads
|
|
276
|
+
* the raw key, so a prefixed app has to pass the same string here.
|
|
277
|
+
* @default ''
|
|
278
|
+
*/
|
|
279
|
+
readonly storagePrefix?: string;
|
|
280
|
+
/**
|
|
281
|
+
* Whether `WrStorage` wraps values in its JSON envelope —
|
|
282
|
+
* `provideWrStorage({ json })`. The emitted reader accepts both shapes either
|
|
283
|
+
* way; this only decides which one it tries first, and is here so the option
|
|
284
|
+
* cannot be silently forgotten when an app turns the envelope off.
|
|
285
|
+
* @default true
|
|
286
|
+
*/
|
|
287
|
+
readonly json?: boolean;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Source of the blocking script that resolves the theme BEFORE first paint.
|
|
291
|
+
*
|
|
292
|
+
* A server has no `localStorage` and no `prefers-color-scheme`, so every
|
|
293
|
+
* server-rendered or prerendered page ships the same attribute — `light` under
|
|
294
|
+
* the default config — and a dark-mode visitor sees a white page until the
|
|
295
|
+
* client bundle boots and {@link WrTheme}'s effect corrects it. That window is
|
|
296
|
+
* milliseconds on localhost and seconds on a slow connection, and it is not
|
|
297
|
+
* something the service can close from inside the application: by the time
|
|
298
|
+
* Angular runs, the paint has happened.
|
|
299
|
+
*
|
|
300
|
+
* The only fix is a script that runs before the first paint, and the only thing
|
|
301
|
+
* it needs to know is how {@link WrTheme} and `WrStorage` agree to spell the
|
|
302
|
+
* persisted mode. That agreement — the key, the prefix, the JSON envelope
|
|
303
|
+
* `{ v, e }`, the expiry, the `auto` fallback — is what this function writes
|
|
304
|
+
* out, so an app never has to re-derive it from the bundle and never has to keep
|
|
305
|
+
* a hand-copied version in step with a library upgrade.
|
|
306
|
+
*
|
|
307
|
+
* Returns the JS source WITHOUT a `<script>` wrapper, so it can be inlined into
|
|
308
|
+
* `index.html`, emitted from an SSR template, or hashed for a CSP
|
|
309
|
+
* `script-src 'sha256-…'`. It is plain ES5 with no dependency on the app bundle,
|
|
310
|
+
* and every step is wrapped so a blocked `localStorage` (private mode, a
|
|
311
|
+
* sandboxed iframe) leaves the prerendered default in place rather than throwing
|
|
312
|
+
* before anything has rendered.
|
|
313
|
+
*
|
|
314
|
+
* Pass the same values given to `provideWrTheme()` / `provideWrStorage()`; the
|
|
315
|
+
* defaults here are the defaults there.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```ts
|
|
319
|
+
* // Build step / SSR template:
|
|
320
|
+
* const html = template.replace('<!--theme-->', `<script>${wrThemePrePaintScript()}</script>`);
|
|
321
|
+
*
|
|
322
|
+
* // Or paste the output straight into <head>, above every stylesheet:
|
|
323
|
+
* // <script>(function(){ … })();</script>
|
|
324
|
+
* ```
|
|
325
|
+
*
|
|
326
|
+
* @see https://ngwr.dev/reference/services/theme
|
|
327
|
+
*/
|
|
328
|
+
declare function wrThemePrePaintScript(options?: WrThemePrePaintOptions): string;
|
|
329
|
+
|
|
330
|
+
export { DEFAULT_WR_THEME_CONFIG, WR_COLORS, WR_THEME_CONFIG, WrTheme, provideWrTheme, wrContrastFor, wrIntentTokens, wrThemePrePaintScript, wrThemeTokens };
|
|
331
|
+
export type { WrColor, WrResolvedTheme, WrThemeConfig, WrThemeMode, WrThemePrePaintOptions };
|
package/types/ngwr-toast.d.ts
CHANGED
|
@@ -166,6 +166,8 @@ declare class WrToast {
|
|
|
166
166
|
private readonly config;
|
|
167
167
|
private overlayRef;
|
|
168
168
|
private hostRef;
|
|
169
|
+
/** Watches the overlay container for overlays opened after the host. */
|
|
170
|
+
private containerObserver;
|
|
169
171
|
private currentPosition;
|
|
170
172
|
private currentMode;
|
|
171
173
|
private nextId;
|
|
@@ -187,6 +189,49 @@ declare class WrToast {
|
|
|
187
189
|
private startTimer;
|
|
188
190
|
private pauseTimer;
|
|
189
191
|
private ensureHost;
|
|
192
|
+
/**
|
|
193
|
+
* Put the host back on top of the browser's top layer.
|
|
194
|
+
*
|
|
195
|
+
* The stacking rule here is not a z-index and cannot be fixed with one. CDK 22
|
|
196
|
+
* promotes every overlay by calling `showPopover()` on its host element, and
|
|
197
|
+
* the top layer is ordered by the MOMENT of promotion — a popover shown later
|
|
198
|
+
* paints over one shown earlier no matter what either element's z-index, DOM
|
|
199
|
+
* order or containing block says. The toast host is created once and kept
|
|
200
|
+
* alive until the last toast leaves, so its place in that order is frozen at
|
|
201
|
+
* whenever the first toast of the run appeared. Every dialog and drawer opened
|
|
202
|
+
* after that sits above it.
|
|
203
|
+
*
|
|
204
|
+
* The symptom was as bad as the mechanism is quiet: a toast raised from inside
|
|
205
|
+
* an open dialog rendered UNDER the dialog's backdrop, dimmed by it and
|
|
206
|
+
* hit-tested as it — so the close button was unreachable and clicking where it
|
|
207
|
+
* appeared closed the dialog instead. Nothing threw, and a toast with
|
|
208
|
+
* `duration: 0` never went away on its own.
|
|
209
|
+
*
|
|
210
|
+
* Hiding and re-showing moves the host to the end of the top layer. Both calls
|
|
211
|
+
* happen in one task, so there is no frame in which the host is `display:
|
|
212
|
+
* none` and nothing re-runs a toast's enter animation.
|
|
213
|
+
*
|
|
214
|
+
* Skipped while focus is inside the host: Chromium keeps focus across this
|
|
215
|
+
* pair, but the hide-popover algorithm is specified to restore focus to the
|
|
216
|
+
* previously focused element, and a host the user is already tabbing through
|
|
217
|
+
* is by definition reachable. In practice the two never coincide — a modal
|
|
218
|
+
* traps focus, so focus inside the host means nothing is above it to escape.
|
|
219
|
+
*/
|
|
220
|
+
private raiseHost;
|
|
221
|
+
/**
|
|
222
|
+
* Re-raise the host whenever another overlay joins the container.
|
|
223
|
+
*
|
|
224
|
+
* `show()` covers the reported order (toast raised while a dialog is up). This
|
|
225
|
+
* covers the mirror image, which is the same defect seen from the other side:
|
|
226
|
+
* a toast already on screen when the dialog opens is left under it, unclickable
|
|
227
|
+
* for the rest of its duration, and no further `show()` is coming to fix it.
|
|
228
|
+
*
|
|
229
|
+
* Observing the host's own parent rather than a container resolved from the
|
|
230
|
+
* injector keeps this correct whether or not `provideWrOverlay()` is installed
|
|
231
|
+
* — the host is in whichever container it was actually appended to. Re-showing
|
|
232
|
+
* a popover moves nothing in the DOM, so this cannot re-trigger itself.
|
|
233
|
+
*/
|
|
234
|
+
private watchForNewerOverlays;
|
|
190
235
|
/** Fill any free stack slots from the queue (FIFO), starting each promoted
|
|
191
236
|
* toast's auto-dismiss timer only as it becomes visible. */
|
|
192
237
|
private promoteFromQueue;
|
|
@@ -222,6 +267,14 @@ declare class WrToast {
|
|
|
222
267
|
* ],
|
|
223
268
|
* });
|
|
224
269
|
* ```
|
|
270
|
+
*
|
|
271
|
+
* **Bootstrap only, and the three ngwr providers differ here.** {@link WrToast}
|
|
272
|
+
* is root-provided, so it reads this token once from the ROOT injector — a
|
|
273
|
+
* `provideWrToastConfig()` in a route's `providers` is never seen, and used to
|
|
274
|
+
* be ignored in silence. It now warns in dev mode instead. By contrast
|
|
275
|
+
* `provideWrConfig()` IS read per route, because components resolve it from
|
|
276
|
+
* their own injector, and `provideWrIcons()` works at any level and chains, so
|
|
277
|
+
* a route may add icons to the set its parent registered.
|
|
225
278
|
*/
|
|
226
279
|
declare function provideWrToastConfig(config: Partial<Omit<WrToastConfig, 'labels'>> & {
|
|
227
280
|
readonly labels?: Partial<WrToastConfig['labels']>;
|
package/types/ngwr-tree.d.ts
CHANGED
|
@@ -165,8 +165,9 @@ declare class WrTree<TId = string> implements FormValueControl<unknown> {
|
|
|
165
165
|
/**
|
|
166
166
|
* Form value — the current selection as seen by a bound field. Bound by
|
|
167
167
|
* `[formField]`, or two-way via `[(value)]`. Shape follows `selectionMode`:
|
|
168
|
-
* `TId | null` in single mode, `readonly TId[]` in multi mode.
|
|
169
|
-
* `
|
|
168
|
+
* `TId | null` in single mode, `readonly TId[]` in multi mode. Works in both
|
|
169
|
+
* `openOn` modes; `[(selected)]` stays the inline-native API and always
|
|
170
|
+
* carries an array, whatever the selection mode.
|
|
170
171
|
*/
|
|
171
172
|
readonly value: _angular_core.ModelSignal<unknown>;
|
|
172
173
|
/** Emitted on blur so a bound field can mark itself touched. */
|
package/types/ngwr-version.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { InjectionToken } from '@angular/core';
|
|
|
16
16
|
* Distinct from `Version` exported by `@angular/core`, which reports the
|
|
17
17
|
* loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.
|
|
18
18
|
*/
|
|
19
|
-
declare const NGWR_VERSION = "14.0.
|
|
19
|
+
declare const NGWR_VERSION = "14.0.1";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* @license
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Dark theme.
|
|
2
|
+
//
|
|
3
|
+
// Keyed on `theme.dark-selector()`, never on a literal `[data-theme='dark']`.
|
|
4
|
+
// The attribute is renameable — `@use 'ngwr' with ($theme-attribute: '…')`
|
|
5
|
+
// alongside `provideWrTheme({ attribute: '…' })` — and a hand-written literal
|
|
6
|
+
// misses the rename in both directions: this block stops firing under the
|
|
7
|
+
// configured name, and it keeps firing under `data-theme`, which is the
|
|
8
|
+
// attribute a foreign design system owns and the rename exists to escape.
|
|
9
|
+
//
|
|
10
|
+
// It lives outside the `styleUrl` closure for the same reason. A component
|
|
11
|
+
// stylesheet is compiled when the LIBRARY is built, where `$theme-attribute` can
|
|
12
|
+
// only ever be the default, and Angular appends that copy after the app's linked
|
|
13
|
+
// sheet — so an inlined literal would not merely be dead, it would outrank the
|
|
14
|
+
// correctly-named rule beside it.
|
|
15
|
+
@use '../../theme/styles' as theme;
|
|
16
|
+
|
|
17
|
+
#{theme.dark-selector()} .wr-waves {
|
|
18
|
+
--wr-waves-line-color: rgb(255 255 255 / 14%);
|
|
19
|
+
}
|
package/waves/styles/_index.scss
CHANGED
|
@@ -11,5 +11,10 @@
|
|
|
11
11
|
// box-sizing reset into the compiled component styles, which ng-packagr then
|
|
12
12
|
// embeds in the FESM bundle as a string. `waves.scss` forwards `_rules`
|
|
13
13
|
// instead, so it carries this component's own CSS and nothing else.
|
|
14
|
+
//
|
|
15
|
+
// `_dark` is loaded from HERE for a second reason: its selector is built out of
|
|
16
|
+
// `$theme-attribute`, which only a stylesheet compiled by the consuming app can
|
|
17
|
+
// configure, so a copy inside the bundle could only ever carry the default name.
|
|
14
18
|
@use '../../theme/styles';
|
|
15
19
|
@forward 'rules';
|
|
20
|
+
@forward 'dark';
|