ngwr 12.1.0 → 13.0.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/README.md +11 -1
- package/alert/styles/_index.scss +11 -4
- package/badge/styles/_index.scss +30 -0
- package/badge/styles/_tag.scss +15 -1
- package/border-glow/border-glow.scss +1 -1
- package/border-glow/styles/_index.scss +15 -233
- package/border-glow/styles/_rules.scss +228 -0
- package/breadcrumbs/breadcrumbs.scss +1 -1
- package/breadcrumbs/styles/_index.scss +15 -78
- package/breadcrumbs/styles/_rules.scss +84 -0
- package/card/card.scss +1 -1
- package/card/styles/_index.scss +15 -96
- package/card/styles/_rules.scss +96 -0
- package/cascader/cascader.scss +1 -1
- package/cascader/styles/_index.scss +15 -244
- package/cascader/styles/_rules.scss +261 -0
- package/checkbox/styles/_index.scss +7 -0
- package/circular-text/circular-text.scss +1 -1
- package/circular-text/styles/_index.scss +15 -63
- package/circular-text/styles/_rules.scss +58 -0
- package/color-picker/styles/_index.scss +8 -0
- package/descriptions/styles/_index.scss +13 -3
- package/drag-drop/sortable-list.scss +1 -1
- package/drag-drop/styles/_index.scss +14 -143
- package/drag-drop/styles/_rules.scss +151 -0
- package/drawer/styles/_index.scss +95 -1
- package/falling-text/falling-text.scss +1 -1
- package/falling-text/styles/_index.scss +15 -36
- package/falling-text/styles/_rules.scss +31 -0
- package/fesm2022/ngwr-border-glow.mjs +2 -2
- package/fesm2022/ngwr-border-glow.mjs.map +1 -1
- package/fesm2022/ngwr-breadcrumbs.mjs +2 -2
- package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
- package/fesm2022/ngwr-card.mjs +2 -2
- package/fesm2022/ngwr-card.mjs.map +1 -1
- package/fesm2022/ngwr-cascader.mjs +27 -9
- package/fesm2022/ngwr-cascader.mjs.map +1 -1
- package/fesm2022/ngwr-checkbox.mjs +86 -8
- package/fesm2022/ngwr-checkbox.mjs.map +1 -1
- package/fesm2022/ngwr-circular-text.mjs +2 -2
- package/fesm2022/ngwr-circular-text.mjs.map +1 -1
- package/fesm2022/ngwr-color-picker.mjs +57 -7
- package/fesm2022/ngwr-color-picker.mjs.map +1 -1
- package/fesm2022/ngwr-date-picker.mjs +8 -0
- package/fesm2022/ngwr-date-picker.mjs.map +1 -1
- package/fesm2022/ngwr-drag-drop.mjs +2 -2
- package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
- package/fesm2022/ngwr-drawer.mjs +6 -0
- package/fesm2022/ngwr-drawer.mjs.map +1 -1
- package/fesm2022/ngwr-falling-text.mjs +2 -2
- package/fesm2022/ngwr-falling-text.mjs.map +1 -1
- package/fesm2022/ngwr-file-upload.mjs +29 -8
- package/fesm2022/ngwr-file-upload.mjs.map +1 -1
- package/fesm2022/ngwr-form.mjs +48 -1
- package/fesm2022/ngwr-form.mjs.map +1 -1
- package/fesm2022/ngwr-glitch-text.mjs +2 -2
- package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
- package/fesm2022/ngwr-gradient-text.mjs +2 -2
- package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
- package/fesm2022/ngwr-input-otp.mjs +41 -3
- package/fesm2022/ngwr-input-otp.mjs.map +1 -1
- package/fesm2022/ngwr-knob.mjs +17 -2
- package/fesm2022/ngwr-knob.mjs.map +1 -1
- package/fesm2022/ngwr-lightbox.mjs +2 -2
- package/fesm2022/ngwr-lightbox.mjs.map +1 -1
- package/fesm2022/ngwr-list.mjs +2 -2
- package/fesm2022/ngwr-list.mjs.map +1 -1
- package/fesm2022/ngwr-loading-bar.mjs +2 -2
- package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
- package/fesm2022/ngwr-marquee.mjs +2 -2
- package/fesm2022/ngwr-marquee.mjs.map +1 -1
- package/fesm2022/ngwr-pagination.mjs +1 -1
- package/fesm2022/ngwr-pagination.mjs.map +1 -1
- package/fesm2022/ngwr-radio.mjs +63 -8
- package/fesm2022/ngwr-radio.mjs.map +1 -1
- package/fesm2022/ngwr-rating.mjs +17 -2
- package/fesm2022/ngwr-rating.mjs.map +1 -1
- package/fesm2022/ngwr-segmented.mjs +22 -3
- package/fesm2022/ngwr-segmented.mjs.map +1 -1
- package/fesm2022/ngwr-select.mjs +59 -15
- package/fesm2022/ngwr-select.mjs.map +1 -1
- package/fesm2022/ngwr-shiny-text.mjs +2 -2
- package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
- package/fesm2022/ngwr-slider.mjs +21 -6
- package/fesm2022/ngwr-slider.mjs.map +1 -1
- package/fesm2022/ngwr-spotlight-card.mjs +2 -2
- package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
- package/fesm2022/ngwr-star-border.mjs +2 -2
- package/fesm2022/ngwr-star-border.mjs.map +1 -1
- package/fesm2022/ngwr-switch.mjs +44 -4
- package/fesm2022/ngwr-switch.mjs.map +1 -1
- package/fesm2022/ngwr-table.mjs +1 -1
- package/fesm2022/ngwr-table.mjs.map +1 -1
- package/fesm2022/ngwr-textarea.mjs +5 -2
- package/fesm2022/ngwr-textarea.mjs.map +1 -1
- package/fesm2022/ngwr-theme.mjs +41 -1
- package/fesm2022/ngwr-theme.mjs.map +1 -1
- package/fesm2022/ngwr-tilt-card.mjs +2 -2
- package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
- package/fesm2022/ngwr-transfer.mjs +38 -6
- package/fesm2022/ngwr-transfer.mjs.map +1 -1
- package/fesm2022/ngwr-tree.mjs +33 -7
- package/fesm2022/ngwr-tree.mjs.map +1 -1
- package/fesm2022/ngwr-typewriter.mjs +2 -2
- package/fesm2022/ngwr-typewriter.mjs.map +1 -1
- package/fesm2022/ngwr-version.mjs +1 -1
- package/fesm2022/ngwr-version.mjs.map +1 -1
- package/fesm2022/ngwr-virtual-scroll.mjs +2 -2
- package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
- package/fesm2022/ngwr-waves.mjs +2 -2
- package/fesm2022/ngwr-waves.mjs.map +1 -1
- package/file-upload/styles/_index.scss +6 -0
- package/glitch-text/glitch-text.scss +1 -1
- package/glitch-text/styles/_index.scss +14 -164
- package/glitch-text/styles/_rules.scss +160 -0
- package/gradient-text/gradient-text.scss +1 -1
- package/gradient-text/styles/_index.scss +15 -118
- package/gradient-text/styles/_rules.scss +113 -0
- package/input/styles/_index.scss +13 -0
- package/input-otp/styles/_index.scss +8 -0
- package/lightbox/lightbox.scss +1 -1
- package/lightbox/styles/_index.scss +15 -191
- package/lightbox/styles/_rules.scss +198 -0
- package/list/list.scss +1 -1
- package/list/styles/_index.scss +15 -101
- package/list/styles/_rules.scss +108 -0
- package/llms-full.txt +3 -3
- package/loading-bar/loading-bar.scss +1 -1
- package/loading-bar/styles/_index.scss +15 -33
- package/loading-bar/styles/_rules.scss +28 -0
- package/marquee/marquee.scss +1 -1
- package/marquee/styles/_index.scss +15 -155
- package/marquee/styles/_rules.scss +150 -0
- package/overlay/styles/_arrow.scss +243 -0
- package/package.json +1 -1
- package/popconfirm/styles/_index.scss +17 -0
- package/popover/styles/_index.scss +49 -207
- package/segmented/styles/_index.scss +8 -0
- package/select/styles/_index.scss +47 -5
- package/shiny-text/shiny-text.scss +1 -1
- package/shiny-text/styles/_index.scss +14 -105
- package/shiny-text/styles/_rules.scss +101 -0
- package/sidebar/styles/_index.scss +4 -1
- package/slider/styles/_index.scss +8 -0
- package/spotlight-card/spotlight-card.scss +1 -1
- package/spotlight-card/styles/_index.scss +15 -52
- package/spotlight-card/styles/_rules.scss +47 -0
- package/star-border/star-border.scss +1 -1
- package/star-border/styles/_index.scss +15 -125
- package/star-border/styles/_rules.scss +120 -0
- package/stepper/styles/_index.scss +44 -5
- package/switch/styles/_index.scss +7 -0
- package/theme/styles/_dark.scss +81 -4
- package/theme/styles/_index.scss +1 -0
- package/theme/styles/_mixins.scss +10 -0
- package/theme/styles/_motion.scss +94 -0
- package/tilt-card/styles/_index.scss +15 -45
- package/tilt-card/styles/_rules.scss +40 -0
- package/tilt-card/tilt-card.scss +1 -1
- package/tree/styles/_index.scss +25 -3
- package/types/ngwr-cascader.d.ts +17 -1
- package/types/ngwr-checkbox.d.ts +51 -3
- package/types/ngwr-color-picker.d.ts +19 -1
- package/types/ngwr-file-upload.d.ts +18 -1
- package/types/ngwr-form.d.ts +51 -2
- package/types/ngwr-input-otp.d.ts +23 -1
- package/types/ngwr-knob.d.ts +14 -0
- package/types/ngwr-radio.d.ts +37 -2
- package/types/ngwr-rating.d.ts +14 -0
- package/types/ngwr-segmented.d.ts +18 -1
- package/types/ngwr-select.d.ts +29 -3
- package/types/ngwr-slider.d.ts +14 -1
- package/types/ngwr-switch.d.ts +26 -2
- package/types/ngwr-textarea.d.ts +3 -0
- package/types/ngwr-theme.d.ts +24 -0
- package/types/ngwr-transfer.d.ts +17 -1
- package/types/ngwr-tree.d.ts +21 -1
- package/types/ngwr-version.d.ts +1 -1
- package/typewriter/styles/_index.scss +15 -38
- package/typewriter/styles/_rules.scss +33 -0
- package/typewriter/typewriter.scss +1 -1
- package/virtual-scroll/styles/_index.scss +15 -32
- package/virtual-scroll/styles/_rules.scss +27 -0
- package/virtual-scroll/virtual-scroll.scss +1 -1
- package/waves/styles/_index.scss +15 -50
- package/waves/styles/_rules.scss +45 -0
- package/waves/waves.scss +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// `prefers-reduced-motion` for the always-on chrome.
|
|
2
|
+
//
|
|
3
|
+
// Why this lives in the theme layer rather than in each component. The
|
|
4
|
+
// animation catalogue (`ngwr/glitch-text`, `ngwr/gradient-text`, …) guards
|
|
5
|
+
// itself, component by component — those are opt-in effects, and each one knows
|
|
6
|
+
// what its own stillness should look like. The ten blocks below are the
|
|
7
|
+
// opposite: chrome nobody opted into. A spinner and a skeleton animate on
|
|
8
|
+
// essentially every page of every app, and four of the animations here never
|
|
9
|
+
// stop at all (`wr-spinner-rotate`, `wr-spinner-dash`, `wr-skeleton-shimmer`,
|
|
10
|
+
// `wr-card-spin`, `wr-lightbox-shimmer`), which is the case vestibular guidance
|
|
11
|
+
// is most emphatic about. Collecting them in one place is what makes the set
|
|
12
|
+
// reviewable — the gap this closes existed because nine separate stylesheets
|
|
13
|
+
// each forgot, and nine separate stylesheets can each forget again.
|
|
14
|
+
//
|
|
15
|
+
// **Every declaration here is `!important`, and that is structural rather than
|
|
16
|
+
// lazy.** The theme layer is loaded first — `styles.scss` forwards it before any
|
|
17
|
+
// component, and a standalone `@use 'ngwr/spinner'` pulls it in ahead of the
|
|
18
|
+
// spinner's own rules — so at equal specificity the component always wins on
|
|
19
|
+
// source order. `!important` is the only lever a stylesheet that must come first
|
|
20
|
+
// has. `.wr-overlay-sheet` needs one more: its animation is itself `!important`
|
|
21
|
+
// (it has to beat four components' panel sizing), so the class is doubled here
|
|
22
|
+
// to out-specify it.
|
|
23
|
+
//
|
|
24
|
+
// What reduced motion MEANS is decided per animation, not globally:
|
|
25
|
+
//
|
|
26
|
+
// - An ENTER animation is removed. The panel still arrives, it just does not
|
|
27
|
+
// travel to get there. Every keyframe set below animates from a transparent,
|
|
28
|
+
// offset or scaled-down state TO the element's resting one, with no
|
|
29
|
+
// `forwards`, so removing it lands on exactly the frame the animation was
|
|
30
|
+
// heading for. Nothing in the library waits on `animationend`, so nothing
|
|
31
|
+
// is left un-dismissed.
|
|
32
|
+
// - A decorative INFINITE loop is removed outright — a skeleton's shimmer and
|
|
33
|
+
// a lightbox's shimmer say nothing the static placeholder does not.
|
|
34
|
+
// - A SPINNER is slowed, not stopped. Its rotation IS the message: a frozen
|
|
35
|
+
// spinner does not read as "reduced motion", it reads as "hung". So the
|
|
36
|
+
// rotation stays at half speed and the pulsing arc — the part that carries
|
|
37
|
+
// no information — is frozen at a fixed sweep. Same call Bootstrap makes,
|
|
38
|
+
// and the same reading as WCAG 2.3.3, which is about non-essential motion.
|
|
39
|
+
// - The TOAST progress bar is deliberately left alone. It is a countdown: it
|
|
40
|
+
// is the only thing on screen saying how long is left before the toast
|
|
41
|
+
// leaves, and freezing it would not remove information, it would state a
|
|
42
|
+
// falsehood — a full bar that never drains. It is also 2px tall and moves
|
|
43
|
+
// along one axis at constant speed, the mildest shape motion sensitivity
|
|
44
|
+
// takes. If that trade is ever revisited, revisit it here.
|
|
45
|
+
|
|
46
|
+
@media (prefers-reduced-motion: reduce) {
|
|
47
|
+
// Overlay enter choreography — dialog, dropdown, popconfirm, toast, lightbox
|
|
48
|
+
// viewer, and all four drawer edges.
|
|
49
|
+
.wr-dialog-panel,
|
|
50
|
+
.wr-dropdown-menu,
|
|
51
|
+
.wr-popconfirm-overlay > .wr-popconfirm,
|
|
52
|
+
.wr-toast,
|
|
53
|
+
.wr-lightbox-viewer,
|
|
54
|
+
.wr-drawer__panel--left,
|
|
55
|
+
.wr-drawer__panel--right,
|
|
56
|
+
.wr-drawer__panel--top,
|
|
57
|
+
.wr-drawer__panel--bottom {
|
|
58
|
+
animation: none !important;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// The responsive bottom sheet, which slides a full panel height up the
|
|
62
|
+
// screen — the largest single translation the library performs. Doubled
|
|
63
|
+
// class: `overlay/styles/_index.scss` sets this animation `!important`, and it
|
|
64
|
+
// is loaded after this file.
|
|
65
|
+
.wr-overlay-sheet.wr-overlay-sheet {
|
|
66
|
+
animation: none !important;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Decorative loading shimmers. Both ride a pseudo-element whose resting
|
|
70
|
+
// position is off-screen or at its gradient origin, so stopping them leaves a
|
|
71
|
+
// plain tinted placeholder rather than a half-drawn band.
|
|
72
|
+
.wr-skeleton--animated::after,
|
|
73
|
+
.wr-lightbox--loading::after {
|
|
74
|
+
animation: none !important;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Spinners. The rotation survives at half speed; the arc stops pulsing and
|
|
78
|
+
// holds the sweep the dash animation spends most of its cycle at, so the
|
|
79
|
+
// shape stays a recognisable spinner instead of collapsing to the 1-unit dot
|
|
80
|
+
// its first keyframe starts from.
|
|
81
|
+
.wr-spinner svg {
|
|
82
|
+
animation-duration: 4s !important;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.wr-spinner__path {
|
|
86
|
+
animation: none !important;
|
|
87
|
+
stroke-dasharray: 90, 150 !important;
|
|
88
|
+
stroke-dashoffset: 0 !important;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.wr-card__spinner {
|
|
92
|
+
animation-duration: 1.4s !important;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -1,45 +1,15 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
background: var(--wr-color-surface);
|
|
17
|
-
color: var(--wr-color-on-surface);
|
|
18
|
-
box-shadow: 0 1px 2px rgba(var(--wr-color-backdrop-rgb), 0.06);
|
|
19
|
-
// Card itself doesn't need overflow:hidden by default — the directive
|
|
20
|
-
// toggles overflow when glare is enabled. Authors can opt in.
|
|
21
|
-
transform-style: preserve-3d;
|
|
22
|
-
transition: transform 0.15s ease-out;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Glare overlay (appended by `[wrTilt]` when `[glare]="true"`)
|
|
26
|
-
// Lives in this package so the visual lives with the card chrome.
|
|
27
|
-
.wr-tilt-glare {
|
|
28
|
-
position: absolute;
|
|
29
|
-
inset: 0;
|
|
30
|
-
pointer-events: none;
|
|
31
|
-
// Light surfaces: glare reads as a soft moving shade. Dark theme flips
|
|
32
|
-
// to the classic white sheen below.
|
|
33
|
-
background: radial-gradient(
|
|
34
|
-
circle at var(--wr-tilt-glare-x, 50%) var(--wr-tilt-glare-y, 50%),
|
|
35
|
-
var(--wr-tilt-glare-color, rgba(var(--wr-color-on-surface-rgb), 0.12)),
|
|
36
|
-
transparent 60%
|
|
37
|
-
);
|
|
38
|
-
mix-blend-mode: multiply;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
[data-theme='dark'] .wr-tilt-glare {
|
|
42
|
-
--wr-tilt-glare-color: rgb(255 255 255 / 25%);
|
|
43
|
-
|
|
44
|
-
mix-blend-mode: overlay;
|
|
45
|
-
}
|
|
1
|
+
// Public Sass entry for `@use 'ngwr/tilt-card'`.
|
|
2
|
+
//
|
|
3
|
+
// Pulls the whole theme so a standalone import still brings in every design
|
|
4
|
+
// token these rules reference, then loads the rules themselves from `_rules`.
|
|
5
|
+
//
|
|
6
|
+
// The split is what keeps the token layer out of the JavaScript bundle.
|
|
7
|
+
// `tilt-card.scss` is the component's `styleUrl`, and a component stylesheet is
|
|
8
|
+
// its OWN Sass compilation — `@use` only deduplicates within one. So while the
|
|
9
|
+
// umbrella sheet emits the theme once, forwarding it from here would inline a
|
|
10
|
+
// second, byte-identical copy of `:root`, `[data-theme='dark']` and the
|
|
11
|
+
// box-sizing reset into the compiled component styles, which ng-packagr then
|
|
12
|
+
// embeds in the FESM bundle as a string. `tilt-card.scss` forwards `_rules`
|
|
13
|
+
// instead, so it carries this component's own CSS and nothing else.
|
|
14
|
+
@use '../../theme/styles';
|
|
15
|
+
@forward 'rules';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// 3D mouse-tilt card. The transform is set imperatively by `[wrTilt]`,
|
|
2
|
+
// so this stylesheet just covers the card chrome + the optional glare
|
|
3
|
+
// overlay that the directive appends when `[glare]="true"`.
|
|
4
|
+
|
|
5
|
+
.wr-tilt-card {
|
|
6
|
+
display: block;
|
|
7
|
+
position: relative;
|
|
8
|
+
padding: 1.5rem;
|
|
9
|
+
border-radius: 0.75rem;
|
|
10
|
+
border: 1px solid var(--wr-color-outline);
|
|
11
|
+
background: var(--wr-color-surface);
|
|
12
|
+
color: var(--wr-color-on-surface);
|
|
13
|
+
box-shadow: 0 1px 2px rgba(var(--wr-color-backdrop-rgb), 0.06);
|
|
14
|
+
// Card itself doesn't need overflow:hidden by default — the directive
|
|
15
|
+
// toggles overflow when glare is enabled. Authors can opt in.
|
|
16
|
+
transform-style: preserve-3d;
|
|
17
|
+
transition: transform 0.15s ease-out;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Glare overlay (appended by `[wrTilt]` when `[glare]="true"`)
|
|
21
|
+
// Lives in this package so the visual lives with the card chrome.
|
|
22
|
+
.wr-tilt-glare {
|
|
23
|
+
position: absolute;
|
|
24
|
+
inset: 0;
|
|
25
|
+
pointer-events: none;
|
|
26
|
+
// Light surfaces: glare reads as a soft moving shade. Dark theme flips
|
|
27
|
+
// to the classic white sheen below.
|
|
28
|
+
background: radial-gradient(
|
|
29
|
+
circle at var(--wr-tilt-glare-x, 50%) var(--wr-tilt-glare-y, 50%),
|
|
30
|
+
var(--wr-tilt-glare-color, rgba(var(--wr-color-on-surface-rgb), 0.12)),
|
|
31
|
+
transparent 60%
|
|
32
|
+
);
|
|
33
|
+
mix-blend-mode: multiply;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
[data-theme='dark'] .wr-tilt-glare {
|
|
37
|
+
--wr-tilt-glare-color: rgb(255 255 255 / 25%);
|
|
38
|
+
|
|
39
|
+
mix-blend-mode: overlay;
|
|
40
|
+
}
|
package/tilt-card/tilt-card.scss
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@forward './styles';
|
|
1
|
+
@forward './styles/rules';
|
package/tree/styles/_index.scss
CHANGED
|
@@ -122,6 +122,15 @@
|
|
|
122
122
|
white-space: nowrap;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
// A read-only tree still expands, still takes focus and still submits its
|
|
126
|
+
// value, so it keeps the visual and only stops inviting the click that would
|
|
127
|
+
// change the selection. The trigger is covered by the same rule in combobox
|
|
128
|
+
// mode, where the whole panel is refused.
|
|
129
|
+
&--readonly &__row,
|
|
130
|
+
&--readonly &__trigger {
|
|
131
|
+
cursor: default;
|
|
132
|
+
}
|
|
133
|
+
|
|
125
134
|
&--disabled {
|
|
126
135
|
opacity: var(--wr-disabled-opacity);
|
|
127
136
|
pointer-events: none;
|
|
@@ -145,6 +154,11 @@
|
|
|
145
154
|
--wr-tree-trigger-font-size: var(--wr-control-font-size-md);
|
|
146
155
|
--wr-tree-trigger-line-height: var(--wr-control-line-height-md);
|
|
147
156
|
--wr-tree-panel-max-height: 18rem;
|
|
157
|
+
// Trigger width floor — hooked for the same reason as `--wr-select-min-width`:
|
|
158
|
+
// in a narrow grid column the literal wins over `minmax(0, 1fr)` and the
|
|
159
|
+
// trigger overhangs its cell, and the only escape was overriding
|
|
160
|
+
// `.wr-tree__trigger` from outside. Set it to 0 to defer to the layout.
|
|
161
|
+
--wr-tree-trigger-min-width: 12rem;
|
|
148
162
|
|
|
149
163
|
display: inline-flex;
|
|
150
164
|
vertical-align: middle;
|
|
@@ -160,7 +174,7 @@
|
|
|
160
174
|
align-items: center;
|
|
161
175
|
gap: 0.5rem;
|
|
162
176
|
width: 100%;
|
|
163
|
-
min-width:
|
|
177
|
+
min-width: var(--wr-tree-trigger-min-width);
|
|
164
178
|
appearance: none;
|
|
165
179
|
background: var(--wr-tree-trigger-bg);
|
|
166
180
|
color: var(--wr-tree-trigger-color);
|
|
@@ -270,7 +284,10 @@
|
|
|
270
284
|
// Roomier on the label side, tighter where the remove (×) sits.
|
|
271
285
|
padding-block: 0.125rem;
|
|
272
286
|
padding-inline: 0.5rem 0.25rem;
|
|
273
|
-
|
|
287
|
+
// Not a pill: a chip is a shape nested INSIDE the trigger, so it repeats the
|
|
288
|
+
// trigger's own corner instead of deciding one for itself — and an override
|
|
289
|
+
// of `--wr-tree-trigger-radius` carries the chips with it.
|
|
290
|
+
border-radius: var(--wr-tree-trigger-radius);
|
|
274
291
|
background: var(--wr-color-primary-soft);
|
|
275
292
|
// The chip wraps a label, so this paints text on the chip's own tint.
|
|
276
293
|
color: var(--wr-color-primary-ink);
|
|
@@ -292,7 +309,12 @@
|
|
|
292
309
|
justify-content: center;
|
|
293
310
|
width: 1rem;
|
|
294
311
|
height: 1rem;
|
|
295
|
-
|
|
312
|
+
// Concentric with the chip: inset from the chip's edge by its 2px block
|
|
313
|
+
// padding, and an inner corner only nests cleanly when it is the outer
|
|
314
|
+
// corner minus that inset. `max()` keeps the value legal for a consumer who
|
|
315
|
+
// sets `--wr-tree-trigger-radius: 0` — a negative radius invalidates the
|
|
316
|
+
// whole declaration.
|
|
317
|
+
border-radius: max(0px, calc(var(--wr-tree-trigger-radius) - 2px));
|
|
296
318
|
cursor: pointer;
|
|
297
319
|
transition: background 0.12s ease;
|
|
298
320
|
|
package/types/ngwr-cascader.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as ngwr_form from 'ngwr/form';
|
|
1
2
|
import * as _angular_core from '@angular/core';
|
|
2
3
|
import { TemplateRef } from '@angular/core';
|
|
3
4
|
import { FormValueControl } from '@angular/forms/signals';
|
|
@@ -73,6 +74,21 @@ declare class WrCascader<T = string> implements FormValueControl<unknown> {
|
|
|
73
74
|
* @default false
|
|
74
75
|
*/
|
|
75
76
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
77
|
+
/**
|
|
78
|
+
* Refuse changes while the trigger stays focusable and the path still submits.
|
|
79
|
+
* Bound automatically from the field's readonly state when used with
|
|
80
|
+
* `[formField]`.
|
|
81
|
+
*
|
|
82
|
+
* The panel is where every edit happens, so a read-only cascader simply does
|
|
83
|
+
* not open — there is nothing to browse that is not already on the trigger —
|
|
84
|
+
* and the clear button goes away with it. Mirrored as `aria-readonly`, which
|
|
85
|
+
* role `combobox` supports.
|
|
86
|
+
*
|
|
87
|
+
* @default false
|
|
88
|
+
*/
|
|
89
|
+
readonly readonly: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
90
|
+
/** The surrounding `<wr-form-field>`'s error state. @internal */
|
|
91
|
+
protected readonly fieldAria: ngwr_form.WrFormFieldAria;
|
|
76
92
|
/** Control size — shares the `--wr-control-*` contract. @default 'md' */
|
|
77
93
|
readonly size: _angular_core.InputSignal<WrCascaderSize>;
|
|
78
94
|
/** Show a clear-all (×) button on the trigger when a path is selected. @default true */
|
|
@@ -143,7 +159,7 @@ declare class WrCascader<T = string> implements FormValueControl<unknown> {
|
|
|
143
159
|
private focusPanelOption;
|
|
144
160
|
private closeOverlay;
|
|
145
161
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrCascader<any>, never>;
|
|
146
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrCascader<any>, "wr-cascader", never, { "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "changeOnSelect": { "alias": "changeOnSelect"; "required": false; "isSignal": true; }; "separator": { "alias": "separator"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, never, true, never>;
|
|
162
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrCascader<any>, "wr-cascader", never, { "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": true; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "changeOnSelect": { "alias": "changeOnSelect"; "required": false; "isSignal": true; }; "separator": { "alias": "separator"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, never, true, never>;
|
|
147
163
|
}
|
|
148
164
|
|
|
149
165
|
export { WrCascader };
|
package/types/ngwr-checkbox.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
2
|
import { InjectionToken, Signal } from '@angular/core';
|
|
3
3
|
import { FormCheckboxControl, FormValueControl } from '@angular/forms/signals';
|
|
4
|
+
import * as ngwr_form from 'ngwr/form';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Two-state checkbox.
|
|
@@ -35,7 +36,8 @@ import { FormCheckboxControl, FormValueControl } from '@angular/forms/signals';
|
|
|
35
36
|
type WrCheckboxSize = 'sm' | 'md' | 'lg';
|
|
36
37
|
declare class WrCheckbox implements FormCheckboxControl {
|
|
37
38
|
/**
|
|
38
|
-
* Stable id used to associate the native input with its label.
|
|
39
|
+
* Stable id used to associate the native input with its label. Lands on the
|
|
40
|
+
* inner `<input>`; the host never keeps it.
|
|
39
41
|
*
|
|
40
42
|
* @default Randomly generated
|
|
41
43
|
*/
|
|
@@ -70,6 +72,18 @@ declare class WrCheckbox implements FormCheckboxControl {
|
|
|
70
72
|
* @default false
|
|
71
73
|
*/
|
|
72
74
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
75
|
+
/**
|
|
76
|
+
* Refuse edits while staying focusable and submittable. Bound automatically
|
|
77
|
+
* from the field's readonly state when used with `[formField]`.
|
|
78
|
+
*
|
|
79
|
+
* A native `<input type="checkbox">` ignores the `readonly` attribute, so this
|
|
80
|
+
* cancels the click's activation behaviour instead — which covers Space too,
|
|
81
|
+
* since a checkbox turns Space into a click — and mirrors the state as
|
|
82
|
+
* `aria-readonly`, which role `checkbox` supports.
|
|
83
|
+
*
|
|
84
|
+
* @default false
|
|
85
|
+
*/
|
|
86
|
+
readonly readonly: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
73
87
|
/**
|
|
74
88
|
* Control size — shares the `--wr-control-*` contract. Unset falls back to the
|
|
75
89
|
* `checkbox.size` app default from `provideWrConfig()`. @default 'md'
|
|
@@ -96,11 +110,28 @@ declare class WrCheckbox implements FormCheckboxControl {
|
|
|
96
110
|
protected readonly isChecked: _angular_core.Signal<boolean>;
|
|
97
111
|
/** Effective disabled — the `disabled` input wins, then the group. */
|
|
98
112
|
protected readonly effectiveDisabled: _angular_core.Signal<boolean>;
|
|
113
|
+
/** Effective readonly — this box's own `readonly` input, or the group's. */
|
|
114
|
+
protected readonly effectiveReadonly: _angular_core.Signal<boolean>;
|
|
115
|
+
/**
|
|
116
|
+
* The surrounding `<wr-form-field>`'s error state, mirrored onto the native
|
|
117
|
+
* input. Inside a `<wr-checkbox-group>` the GROUP is the bound control and
|
|
118
|
+
* carries the state, so a grouped box shields itself and stays silent — nine
|
|
119
|
+
* boxes each announcing the group's one error is noise, not information.
|
|
120
|
+
*/
|
|
121
|
+
private readonly fieldAria;
|
|
122
|
+
protected readonly ariaInvalid: _angular_core.Signal<"true" | null>;
|
|
123
|
+
protected readonly describedBy: _angular_core.Signal<string | null>;
|
|
99
124
|
protected readonly classes: _angular_core.Signal<string>;
|
|
125
|
+
/**
|
|
126
|
+
* Cancel the toggle while readonly. `change` never fires for a click whose
|
|
127
|
+
* default was prevented, so this is the only guard the pointer and Space
|
|
128
|
+
* paths need; `onInputChange` keeps its own for a synthetic `change`.
|
|
129
|
+
*/
|
|
130
|
+
protected onInputClick(event: Event): void;
|
|
100
131
|
protected onInputChange(event: Event): void;
|
|
101
132
|
protected onInputBlur(): void;
|
|
102
133
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrCheckbox, never>;
|
|
103
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrCheckbox, "wr-checkbox", never, { "id": { "alias": "id"; "required": false; "isSignal": true; }; "checkboxValue": { "alias": "checkboxValue"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "touch": "touch"; }, never, ["*"], true, never>;
|
|
134
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrCheckbox, "wr-checkbox", never, { "id": { "alias": "id"; "required": false; "isSignal": true; }; "checkboxValue": { "alias": "checkboxValue"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "touch": "touch"; }, never, ["*"], true, never>;
|
|
104
135
|
}
|
|
105
136
|
|
|
106
137
|
/**
|
|
@@ -133,6 +164,8 @@ interface WrCheckboxGroupContext {
|
|
|
133
164
|
blurred(): void;
|
|
134
165
|
/** Whether the entire group is disabled. */
|
|
135
166
|
readonly isDisabled: Signal<boolean>;
|
|
167
|
+
/** Whether the entire group refuses edits while staying focusable. */
|
|
168
|
+
readonly isReadonly: Signal<boolean>;
|
|
136
169
|
}
|
|
137
170
|
/**
|
|
138
171
|
* Token a `<wr-checkbox>` injects to read selection state from — and
|
|
@@ -169,6 +202,19 @@ declare class WrCheckboxGroup implements FormValueControl<unknown[]>, WrCheckbox
|
|
|
169
202
|
* @default false
|
|
170
203
|
*/
|
|
171
204
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
205
|
+
/**
|
|
206
|
+
* Refuse edits on every child while they stay focusable and the value still
|
|
207
|
+
* submits. Bound automatically from the field's readonly state when used with
|
|
208
|
+
* `[formField]`.
|
|
209
|
+
*
|
|
210
|
+
* No `aria-readonly` on the host: role `group` does not support it (the state
|
|
211
|
+
* is not global), so each child box mirrors its own instead.
|
|
212
|
+
*
|
|
213
|
+
* @default false
|
|
214
|
+
*/
|
|
215
|
+
readonly readonly: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
216
|
+
/** The surrounding `<wr-form-field>`'s error state. @internal */
|
|
217
|
+
protected readonly fieldAria: ngwr_form.WrFormFieldAria;
|
|
172
218
|
/** The checked items' values. Bound by `[formField]`, or two-way via `[(value)]`. */
|
|
173
219
|
readonly value: _angular_core.ModelSignal<unknown[]>;
|
|
174
220
|
/** Emitted when a child toggles so a bound field can mark itself touched. */
|
|
@@ -176,12 +222,14 @@ declare class WrCheckboxGroup implements FormValueControl<unknown[]>, WrCheckbox
|
|
|
176
222
|
private readonly selected;
|
|
177
223
|
/** Effective disabled state (WrCheckboxGroupContext). */
|
|
178
224
|
readonly isDisabled: _angular_core.Signal<boolean>;
|
|
225
|
+
/** Effective readonly state (WrCheckboxGroupContext). */
|
|
226
|
+
readonly isReadonly: _angular_core.Signal<boolean>;
|
|
179
227
|
isSelected(value: unknown): boolean;
|
|
180
228
|
toggle(value: unknown): void;
|
|
181
229
|
/** @internal A child checkbox lost focus — see {@link WrCheckboxGroupContext.blurred}. */
|
|
182
230
|
blurred(): void;
|
|
183
231
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrCheckboxGroup, never>;
|
|
184
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrCheckboxGroup, "wr-checkbox-group", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, ["*"], true, never>;
|
|
232
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrCheckboxGroup, "wr-checkbox-group", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, ["*"], true, never>;
|
|
185
233
|
}
|
|
186
234
|
|
|
187
235
|
export { WR_CHECKBOX_GROUP, WrCheckbox, WrCheckboxGroup };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as ngwr_form from 'ngwr/form';
|
|
1
2
|
import * as _angular_core from '@angular/core';
|
|
2
3
|
import { FormValueControl } from '@angular/forms/signals';
|
|
3
4
|
import { WrSegmentedOption } from 'ngwr/segmented';
|
|
@@ -196,6 +197,23 @@ declare class WrColorPicker implements FormValueControl<string> {
|
|
|
196
197
|
readonly alpha: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
197
198
|
/** Disable interaction. @default false */
|
|
198
199
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
200
|
+
/**
|
|
201
|
+
* Refuse changes while every surface stays focusable and the colour still
|
|
202
|
+
* submits. Bound automatically from the field's readonly state when used with
|
|
203
|
+
* `[formField]`.
|
|
204
|
+
*
|
|
205
|
+
* The two sliders keep their tab stop and keep announcing `aria-valuenow` —
|
|
206
|
+
* they simply do not move — the hex / channel fields take the native
|
|
207
|
+
* `readonly` attribute, and the swatches go inert. Switching TABS still works:
|
|
208
|
+
* that changes which notation is displayed, not the colour. `aria-readonly` is
|
|
209
|
+
* mirrored on the sliders, which support it; the saturation surface is a
|
|
210
|
+
* `role="group"`, which does not, so it carries nothing.
|
|
211
|
+
*
|
|
212
|
+
* @default false
|
|
213
|
+
*/
|
|
214
|
+
readonly readonly: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
215
|
+
/** The surrounding `<wr-form-field>`'s error state. @internal */
|
|
216
|
+
protected readonly fieldAria: ngwr_form.WrFormFieldAria;
|
|
199
217
|
/**
|
|
200
218
|
* Format the control writes into `value`. See {@link WrColorFormat} — all
|
|
201
219
|
* three are accepted on the way in whichever one is set. @default 'hex'
|
|
@@ -283,7 +301,7 @@ declare class WrColorPicker implements FormValueControl<string> {
|
|
|
283
301
|
/** Push an RGB triple into the HSV source of truth. */
|
|
284
302
|
private applyRgb;
|
|
285
303
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrColorPicker, never>;
|
|
286
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrColorPicker, "wr-color-picker", never, { "alpha": { "alias": "alpha"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "swatches": { "alias": "swatches"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, never, true, never>;
|
|
304
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrColorPicker, "wr-color-picker", never, { "alpha": { "alias": "alpha"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "swatches": { "alias": "swatches"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, never, true, never>;
|
|
287
305
|
}
|
|
288
306
|
|
|
289
307
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as ngwr_form from 'ngwr/form';
|
|
1
2
|
import * as _angular_core from '@angular/core';
|
|
2
3
|
import { ElementRef } from '@angular/core';
|
|
3
4
|
import { FormValueControl } from '@angular/forms/signals';
|
|
@@ -57,6 +58,22 @@ declare class WrFileUpload implements FormValueControl<File | readonly File[] |
|
|
|
57
58
|
* @default false
|
|
58
59
|
*/
|
|
59
60
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
61
|
+
/**
|
|
62
|
+
* Refuse changes to the selection while the zone stays focusable and the files
|
|
63
|
+
* still submit. Bound automatically from the field's readonly state when used
|
|
64
|
+
* with `[formField]`.
|
|
65
|
+
*
|
|
66
|
+
* The zone stops opening the picker, a drop is refused and the per-file remove
|
|
67
|
+
* buttons go inert — but the list stays readable, which is the point. No
|
|
68
|
+
* `aria-readonly`: the zone is a `role="button"`, and ARIA does not define the
|
|
69
|
+
* state for that role, so `aria-disabled` would be the only mirror available
|
|
70
|
+
* and it would say the wrong thing.
|
|
71
|
+
*
|
|
72
|
+
* @default false
|
|
73
|
+
*/
|
|
74
|
+
readonly readonly: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
75
|
+
/** The surrounding `<wr-form-field>`'s error state. @internal */
|
|
76
|
+
protected readonly fieldAria: ngwr_form.WrFormFieldAria;
|
|
60
77
|
/** Primary call-to-action label. Falls back to `fileUpload.browse`. */
|
|
61
78
|
readonly pickLabel: _angular_core.InputSignal<string | null>;
|
|
62
79
|
/** Secondary instruction below the CTA. Falls back to `fileUpload.dropZone`. */
|
|
@@ -98,7 +115,7 @@ declare class WrFileUpload implements FormValueControl<File | readonly File[] |
|
|
|
98
115
|
private reject;
|
|
99
116
|
private emit;
|
|
100
117
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrFileUpload, never>;
|
|
101
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrFileUpload, "wr-file-upload", never, { "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "showList": { "alias": "showList"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "pickLabel": { "alias": "pickLabel"; "required": false; "isSignal": true; }; "dropLabel": { "alias": "dropLabel"; "required": false; "isSignal": true; }; "dropZoneLabel": { "alias": "dropZoneLabel"; "required": false; "isSignal": true; }; "removeFileLabel": { "alias": "removeFileLabel"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "rejected": "rejected"; "touch": "touch"; }, never, never, true, never>;
|
|
118
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrFileUpload, "wr-file-upload", never, { "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "showList": { "alias": "showList"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "pickLabel": { "alias": "pickLabel"; "required": false; "isSignal": true; }; "dropLabel": { "alias": "dropLabel"; "required": false; "isSignal": true; }; "dropZoneLabel": { "alias": "dropZoneLabel"; "required": false; "isSignal": true; }; "removeFileLabel": { "alias": "removeFileLabel"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "rejected": "rejected"; "touch": "touch"; }, never, never, true, never>;
|
|
102
119
|
}
|
|
103
120
|
|
|
104
121
|
export { WrFileUpload };
|
package/types/ngwr-form.d.ts
CHANGED
|
@@ -214,6 +214,55 @@ declare class WrFormField implements WrFormFieldContext {
|
|
|
214
214
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrFormField, "wr-form-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "optionalLabel": { "alias": "optionalLabel"; "required": false; "isSignal": true; }; "controlId": { "alias": "controlId"; "required": false; "isSignal": true; }; "autoErrors": { "alias": "autoErrors"; "required": false; "isSignal": true; }; }, {}, ["ngControl", "projectedErrors"], ["*", "wr-form-error"], true, never>;
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
/**
|
|
218
|
+
* @license
|
|
219
|
+
*
|
|
220
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
221
|
+
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
|
|
222
|
+
*/
|
|
223
|
+
|
|
224
|
+
/** What {@link useFormFieldAria} hands a control to bind on its own element. */
|
|
225
|
+
interface WrFormFieldAria {
|
|
226
|
+
/** Id of the field's message block, or `null` when it is showing none. */
|
|
227
|
+
readonly describedBy: Signal<string | null>;
|
|
228
|
+
/** `'true'` while the field is showing a message, `null` otherwise. */
|
|
229
|
+
readonly ariaInvalid: Signal<'true' | null>;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* The two attributes that make a `<wr-form-field>`'s visible error reach a
|
|
233
|
+
* screen reader — bind both on whichever element carries the control's role.
|
|
234
|
+
*
|
|
235
|
+
* Without them the messages the field renders are visible and nothing else: the
|
|
236
|
+
* control announces itself as valid, and the message is associated with nothing.
|
|
237
|
+
* No automated gate catches that — axe has no rule that a visible error must be
|
|
238
|
+
* programmatically associated with its control — so this helper exists to make
|
|
239
|
+
* the wiring one line per control rather than three, and the specs are the gate.
|
|
240
|
+
*
|
|
241
|
+
* `aria-invalid` is keyed on the message EXISTING rather than on `errorKeys()`,
|
|
242
|
+
* because the field only publishes an id once it is showing something —
|
|
243
|
+
* announcing "invalid" while pointing at nothing is worse than staying quiet.
|
|
244
|
+
*
|
|
245
|
+
* Must be called from an injection context (a field initialiser or a
|
|
246
|
+
* constructor). Returns inert signals outside a `<wr-form-field>`.
|
|
247
|
+
*
|
|
248
|
+
* Pass `skipSelf` from a COMPOSITE control — one whose own template renders
|
|
249
|
+
* other ngwr controls. Such a component shields its subtree by re-providing
|
|
250
|
+
* `WR_FORM_FIELD` as `null`, or the inner parts each announce the outer field's
|
|
251
|
+
* error as their own; a component sees its own providers, so it has to read the
|
|
252
|
+
* real field from one level up.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```ts
|
|
256
|
+
* protected readonly fieldAria = useFormFieldAria();
|
|
257
|
+
* ```
|
|
258
|
+
* ```html
|
|
259
|
+
* <input [attr.aria-invalid]="fieldAria.ariaInvalid()" [attr.aria-describedby]="fieldAria.describedBy()" />
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
declare function useFormFieldAria(options?: {
|
|
263
|
+
readonly skipSelf?: boolean;
|
|
264
|
+
}): WrFormFieldAria;
|
|
265
|
+
|
|
217
266
|
/**
|
|
218
267
|
* @license
|
|
219
268
|
*
|
|
@@ -275,5 +324,5 @@ declare function provideWrFormErrors(messages?: WrFormErrorMessages): Environmen
|
|
|
275
324
|
*/
|
|
276
325
|
declare const WR_FORM_ERROR_FALLBACKS: WrFormErrorMessages;
|
|
277
326
|
|
|
278
|
-
export { WR_FORM_ERRORS, WR_FORM_ERROR_FALLBACKS, WR_FORM_FIELD, WrFormError, WrFormField, WrFormItem, provideWrFormErrors };
|
|
279
|
-
export type { WrFormErrorContext, WrFormErrorMessage, WrFormErrorMessages, WrFormFieldContext };
|
|
327
|
+
export { WR_FORM_ERRORS, WR_FORM_ERROR_FALLBACKS, WR_FORM_FIELD, WrFormError, WrFormField, WrFormItem, provideWrFormErrors, useFormFieldAria };
|
|
328
|
+
export type { WrFormErrorContext, WrFormErrorMessage, WrFormErrorMessages, WrFormFieldAria, WrFormFieldContext };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as ngwr_form from 'ngwr/form';
|
|
1
2
|
import * as _angular_core from '@angular/core';
|
|
2
3
|
import { ElementRef } from '@angular/core';
|
|
3
4
|
import { FormValueControl } from '@angular/forms/signals';
|
|
@@ -72,6 +73,27 @@ declare class WrInputOtp implements FormValueControl<string> {
|
|
|
72
73
|
* @default false
|
|
73
74
|
*/
|
|
74
75
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
76
|
+
/**
|
|
77
|
+
* Refuse edits while every box stays focusable and the code still submits.
|
|
78
|
+
* Bound automatically from the field's readonly state when used with
|
|
79
|
+
* `[formField]`.
|
|
80
|
+
*
|
|
81
|
+
* Each box is a real text input, so this is the native `readonly` attribute —
|
|
82
|
+
* arrow keys, Home / End and selection keep working, which is the whole
|
|
83
|
+
* difference from `disabled`. Paste is cancelled too, since a `paste` still
|
|
84
|
+
* reaches a read-only input even though typing does not.
|
|
85
|
+
*
|
|
86
|
+
* @default false
|
|
87
|
+
*/
|
|
88
|
+
readonly readonly: _angular_core.InputSignalWithTransform<boolean, any>;
|
|
89
|
+
/**
|
|
90
|
+
* The surrounding `<wr-form-field>`'s error state — bound per BOX rather than
|
|
91
|
+
* on the `role="group"` host, because the box is what takes focus and a reader
|
|
92
|
+
* queries the focused element.
|
|
93
|
+
*
|
|
94
|
+
* @internal
|
|
95
|
+
*/
|
|
96
|
+
protected readonly fieldAria: ngwr_form.WrFormFieldAria;
|
|
75
97
|
/** Character shown in empty cells. @default '•' */
|
|
76
98
|
readonly placeholder: _angular_core.InputSignal<string>;
|
|
77
99
|
/** The entered code. Bound by `[formField]`, or two-way via `[(value)]`. */
|
|
@@ -116,7 +138,7 @@ declare class WrInputOtp implements FormValueControl<string> {
|
|
|
116
138
|
*/
|
|
117
139
|
private inlineKey;
|
|
118
140
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrInputOtp, never>;
|
|
119
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrInputOtp, "wr-input-otp", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "length": { "alias": "length"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "mask": { "alias": "mask"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "completed": "completed"; "touch": "touch"; }, never, never, true, never>;
|
|
141
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrInputOtp, "wr-input-otp", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "length": { "alias": "length"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "mask": { "alias": "mask"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "completed": "completed"; "touch": "touch"; }, never, never, true, never>;
|
|
120
142
|
}
|
|
121
143
|
|
|
122
144
|
export { WrInputOtp };
|
package/types/ngwr-knob.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as ngwr_form from 'ngwr/form';
|
|
1
2
|
import * as _angular_core from '@angular/core';
|
|
2
3
|
import { FormValueControl } from '@angular/forms/signals';
|
|
3
4
|
|
|
@@ -54,6 +55,19 @@ declare class WrKnob implements FormValueControl<number> {
|
|
|
54
55
|
readonly touch: _angular_core.OutputEmitterRef<void>;
|
|
55
56
|
private dragging;
|
|
56
57
|
protected readonly interactive: _angular_core.Signal<boolean>;
|
|
58
|
+
/**
|
|
59
|
+
* Whether the control keeps its tab stop — `disabled` only, never `readonly`.
|
|
60
|
+
*
|
|
61
|
+
* The two states differ precisely here: a disabled control leaves the tab
|
|
62
|
+
* order, a read-only one stays in it and keeps announcing `aria-valuenow`,
|
|
63
|
+
* because a keyboard user still has to be able to READ a value they cannot
|
|
64
|
+
* change. Driving `tabindex` off `interactive()` collapsed that distinction
|
|
65
|
+
* and made `readonly()` unreachable — with an `aria-describedby` pointing at
|
|
66
|
+
* an error message on an element nobody could focus.
|
|
67
|
+
*/
|
|
68
|
+
protected readonly focusable: _angular_core.Signal<boolean>;
|
|
69
|
+
/** The surrounding `<wr-form-field>`'s error state. @internal */
|
|
70
|
+
protected readonly fieldAria: ngwr_form.WrFormFieldAria;
|
|
57
71
|
protected readonly classes: _angular_core.Signal<string>;
|
|
58
72
|
protected readonly cx = 50;
|
|
59
73
|
protected readonly cy = 50;
|