ngwr 12.0.0 → 12.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +79 -20
  2. package/alert/styles/_index.scss +11 -4
  3. package/badge/styles/_index.scss +30 -0
  4. package/badge/styles/_tag.scss +15 -1
  5. package/descriptions/styles/_index.scss +13 -3
  6. package/drawer/styles/_index.scss +95 -1
  7. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  8. package/fesm2022/ngwr-affix.mjs +3 -3
  9. package/fesm2022/ngwr-alert.mjs +3 -3
  10. package/fesm2022/ngwr-anchor.mjs +3 -3
  11. package/fesm2022/ngwr-aurora.mjs +3 -3
  12. package/fesm2022/ngwr-avatar.mjs +3 -3
  13. package/fesm2022/ngwr-back-top.mjs +3 -3
  14. package/fesm2022/ngwr-badge.mjs +6 -6
  15. package/fesm2022/ngwr-bar-chart.mjs +3 -3
  16. package/fesm2022/ngwr-blur-text.mjs +3 -3
  17. package/fesm2022/ngwr-border-glow.mjs +3 -3
  18. package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
  19. package/fesm2022/ngwr-burger.mjs +3 -3
  20. package/fesm2022/ngwr-button.mjs +6 -6
  21. package/fesm2022/ngwr-calendar-heatmap.mjs +3 -3
  22. package/fesm2022/ngwr-calendar.mjs +3 -3
  23. package/fesm2022/ngwr-card.mjs +9 -9
  24. package/fesm2022/ngwr-carousel.mjs +6 -6
  25. package/fesm2022/ngwr-cascader.mjs +3 -3
  26. package/fesm2022/ngwr-checkbox.mjs +6 -6
  27. package/fesm2022/ngwr-circular-text.mjs +3 -3
  28. package/fesm2022/ngwr-click-spark.mjs +3 -3
  29. package/fesm2022/ngwr-clipboard.mjs +3 -3
  30. package/fesm2022/ngwr-collapse.mjs +9 -9
  31. package/fesm2022/ngwr-color-picker.mjs +6 -6
  32. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  33. package/fesm2022/ngwr-command-palette.mjs +3 -3
  34. package/fesm2022/ngwr-compare.mjs +3 -3
  35. package/fesm2022/ngwr-confetti.mjs +3 -3
  36. package/fesm2022/ngwr-context-menu.mjs +12 -12
  37. package/fesm2022/ngwr-cookie.mjs +3 -3
  38. package/fesm2022/ngwr-counter.mjs +6 -6
  39. package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
  40. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  41. package/fesm2022/ngwr-date-picker.mjs +18 -18
  42. package/fesm2022/ngwr-date.mjs +3 -3
  43. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  44. package/fesm2022/ngwr-density.mjs +6 -6
  45. package/fesm2022/ngwr-descriptions.mjs +6 -6
  46. package/fesm2022/ngwr-dialog.mjs +15 -15
  47. package/fesm2022/ngwr-directives.mjs +12 -12
  48. package/fesm2022/ngwr-divider.mjs +3 -3
  49. package/fesm2022/ngwr-donut-chart.mjs +3 -3
  50. package/fesm2022/ngwr-drag-drop.mjs +6 -6
  51. package/fesm2022/ngwr-drawer.mjs +24 -18
  52. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  53. package/fesm2022/ngwr-dropdown.mjs +9 -9
  54. package/fesm2022/ngwr-empty.mjs +3 -3
  55. package/fesm2022/ngwr-event-calendar.mjs +6 -6
  56. package/fesm2022/ngwr-falling-text.mjs +3 -3
  57. package/fesm2022/ngwr-file-upload.mjs +3 -3
  58. package/fesm2022/ngwr-form.mjs +9 -9
  59. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  60. package/fesm2022/ngwr-gauge.mjs +3 -3
  61. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  62. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  63. package/fesm2022/ngwr-hotkey.mjs +6 -6
  64. package/fesm2022/ngwr-i18n.mjs +9 -9
  65. package/fesm2022/ngwr-icon.mjs +6 -6
  66. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  67. package/fesm2022/ngwr-input-number.mjs +3 -3
  68. package/fesm2022/ngwr-input-otp.mjs +3 -3
  69. package/fesm2022/ngwr-input.mjs +15 -15
  70. package/fesm2022/ngwr-keyboard.mjs +3 -3
  71. package/fesm2022/ngwr-knob.mjs +3 -3
  72. package/fesm2022/ngwr-layout.mjs +15 -15
  73. package/fesm2022/ngwr-lightbox.mjs +3 -3
  74. package/fesm2022/ngwr-line-chart.mjs +3 -3
  75. package/fesm2022/ngwr-list.mjs +6 -6
  76. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  77. package/fesm2022/ngwr-markdown.mjs +6 -6
  78. package/fesm2022/ngwr-marquee.mjs +3 -3
  79. package/fesm2022/ngwr-media.mjs +3 -3
  80. package/fesm2022/ngwr-mention.mjs +6 -6
  81. package/fesm2022/ngwr-meta.mjs +6 -6
  82. package/fesm2022/ngwr-meter-group.mjs +3 -3
  83. package/fesm2022/ngwr-overlay.mjs +6 -6
  84. package/fesm2022/ngwr-page-header.mjs +3 -3
  85. package/fesm2022/ngwr-pagination.mjs +72 -9
  86. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  87. package/fesm2022/ngwr-pipes.mjs +21 -21
  88. package/fesm2022/ngwr-platform.mjs +9 -9
  89. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  90. package/fesm2022/ngwr-popover.mjs +6 -6
  91. package/fesm2022/ngwr-progress.mjs +3 -3
  92. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  93. package/fesm2022/ngwr-qr.mjs +3 -3
  94. package/fesm2022/ngwr-radio.mjs +6 -6
  95. package/fesm2022/ngwr-rating.mjs +3 -3
  96. package/fesm2022/ngwr-result.mjs +12 -12
  97. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  98. package/fesm2022/ngwr-scroll.mjs +3 -3
  99. package/fesm2022/ngwr-segmented-testing.mjs +71 -0
  100. package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
  101. package/fesm2022/ngwr-segmented.mjs +98 -8
  102. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  103. package/fesm2022/ngwr-select.mjs +22 -12
  104. package/fesm2022/ngwr-select.mjs.map +1 -1
  105. package/fesm2022/ngwr-shiny-text.mjs +6 -6
  106. package/fesm2022/ngwr-sidebar.mjs +3 -3
  107. package/fesm2022/ngwr-skeleton.mjs +3 -3
  108. package/fesm2022/ngwr-slider.mjs +3 -3
  109. package/fesm2022/ngwr-sparkline.mjs +3 -3
  110. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  111. package/fesm2022/ngwr-spinner.mjs +3 -3
  112. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  113. package/fesm2022/ngwr-split-text.mjs +3 -3
  114. package/fesm2022/ngwr-splitter.mjs +3 -3
  115. package/fesm2022/ngwr-spotlight-card.mjs +6 -6
  116. package/fesm2022/ngwr-squircle.mjs +6 -6
  117. package/fesm2022/ngwr-star-border.mjs +3 -3
  118. package/fesm2022/ngwr-statistic.mjs +9 -9
  119. package/fesm2022/ngwr-stepper.mjs +6 -6
  120. package/fesm2022/ngwr-storage.mjs +3 -3
  121. package/fesm2022/ngwr-switch.mjs +3 -3
  122. package/fesm2022/ngwr-table.mjs +18 -18
  123. package/fesm2022/ngwr-tabs.mjs +6 -6
  124. package/fesm2022/ngwr-textarea.mjs +3 -3
  125. package/fesm2022/ngwr-theme.mjs +3 -3
  126. package/fesm2022/ngwr-tilt-card.mjs +6 -6
  127. package/fesm2022/ngwr-timeline.mjs +6 -6
  128. package/fesm2022/ngwr-toast.mjs +9 -9
  129. package/fesm2022/ngwr-toolbar.mjs +3 -3
  130. package/fesm2022/ngwr-tour.mjs +6 -6
  131. package/fesm2022/ngwr-transfer.mjs +3 -3
  132. package/fesm2022/ngwr-tree.mjs +3 -3
  133. package/fesm2022/ngwr-typewriter.mjs +3 -3
  134. package/fesm2022/ngwr-typography.mjs +3 -3
  135. package/fesm2022/ngwr-version.mjs +1 -1
  136. package/fesm2022/ngwr-version.mjs.map +1 -1
  137. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  138. package/fesm2022/ngwr-waves.mjs +3 -3
  139. package/fesm2022/ngwr-window.mjs +12 -12
  140. package/llms-full.txt +1 -1
  141. package/llms.txt +24 -2
  142. package/overlay/styles/_arrow.scss +243 -0
  143. package/package.json +1 -1
  144. package/popconfirm/styles/_index.scss +17 -0
  145. package/popover/styles/_index.scss +49 -207
  146. package/select/styles/_index.scss +30 -4
  147. package/sidebar/styles/_index.scss +4 -1
  148. package/stepper/styles/_index.scss +44 -5
  149. package/theme/styles/_mixins.scss +10 -0
  150. package/tree/styles/_index.scss +10 -2
  151. package/types/ngwr-pagination.d.ts +11 -0
  152. package/types/ngwr-segmented-testing.d.ts +44 -0
  153. package/types/ngwr-segmented.d.ts +86 -4
  154. package/types/ngwr-select.d.ts +12 -2
  155. package/types/ngwr-version.d.ts +1 -1
@@ -1,4 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
+ import { FormValueControl } from '@angular/forms/signals';
2
3
  import { WrIconName } from 'ngwr/icon';
3
4
 
4
5
  /**
@@ -31,8 +32,25 @@ interface WrSegmentedOption<T = unknown> {
31
32
  * Single-choice picker rendered as a segmented control. Two-way binds
32
33
  * the selected `value`.
33
34
  *
35
+ * A signal-forms native control: it implements `FormValueControl<T | null>`, so
36
+ * `[formField]` binds straight to its `value` model — no
37
+ * `ControlValueAccessor` in between. `[(value)]` works standalone, and classic
38
+ * `[(ngModel)]` / reactive forms keep working through Angular's bridge.
39
+ *
40
+ * It stays a `role="group"` of `aria-pressed` toggle buttons rather than
41
+ * becoming a `radiogroup`: being a form control changes what the value is bound
42
+ * to, not what the widget is, and a radiogroup would owe a roving tab stop and
43
+ * arrow-key selection — a different keyboard contract for every consumer who
44
+ * already ships this. The group is what the field describes (`aria-describedby`
45
+ * / `aria-invalid` land on the host), while the `<label for>` has to name a
46
+ * labelable element, so the id goes on the first segment.
47
+ *
34
48
  * @example
35
49
  * ```html
50
+ * <!-- signal forms -->
51
+ * <wr-segmented [options]="ranges" [formField]="form.range" />
52
+ *
53
+ * <!-- standalone two-way binding -->
36
54
  * <wr-segmented
37
55
  * [options]="[
38
56
  * { value: 'day', label: 'Day' },
@@ -46,15 +64,68 @@ interface WrSegmentedOption<T = unknown> {
46
64
  * @see https://ngwr.dev/reference/components/segmented
47
65
  */
48
66
  type WrSegmentedSize = 'sm' | 'md' | 'lg';
49
- declare class WrSegmented<T = unknown> {
67
+ declare class WrSegmented<T = unknown> implements FormValueControl<T | null> {
50
68
  /** The segments to render. */
51
69
  readonly options: _angular_core.InputSignal<readonly WrSegmentedOption<T>[]>;
52
- /** Two-way bindable selected value. */
70
+ /**
71
+ * The picked segment's `value`, `null` when nothing is selected. Bound by
72
+ * `[formField]`, or two-way via `[(value)]`.
73
+ */
53
74
  readonly value: _angular_core.ModelSignal<T | null>;
54
- /** Disable the whole control. @default false */
75
+ /** Emitted when focus leaves the strip, so a bound field can mark itself touched. */
76
+ readonly touch: _angular_core.OutputEmitterRef<void>;
77
+ /**
78
+ * Disable the whole control. Bound automatically from the field's disabled
79
+ * state when used with `[formField]`.
80
+ *
81
+ * @default false
82
+ */
55
83
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, any>;
56
84
  /** Control size — shares the `--wr-control-*` contract. @default 'md' */
57
85
  readonly size: _angular_core.InputSignal<WrSegmentedSize>;
86
+ private readonly host;
87
+ private readonly field;
88
+ /**
89
+ * Id the surrounding `<wr-form-field>`'s `<label for>` points at, stamped on the
90
+ * FIRST segment.
91
+ *
92
+ * The field renders its label before it can see what was projected into it, so the
93
+ * id travels the other way and the control adopts it, exactly as `[wrInput]`,
94
+ * `wr-slider` and `wr-select` do. Without this the `for` named an element that was
95
+ * nowhere in the document: clicking the label did nothing.
96
+ *
97
+ * It cannot go on the host — only a labelable element can be a label's target, and
98
+ * `<wr-segmented>` is not one — and there is no single control to put it on, so it
99
+ * goes where clicking the label should land a user: the first segment, which is
100
+ * also the strip's first tab stop. The same choice `wr-slider` makes with its low
101
+ * thumb.
102
+ *
103
+ * What this does NOT change is that segment's NAME: it is named by its own label,
104
+ * and a `<label for>` cannot outrank text content in the accname order anyway.
105
+ *
106
+ * The one shape this reads wrong is a strip NESTED inside another control that is
107
+ * itself the field — `<wr-color-picker>`'s own format tabs are the only case in
108
+ * the library — where the id lands on a tab instead of on the picker. That is the
109
+ * same exposure `[wrInput]`, `wr-slider` and `wr-select` all carry, and the fix
110
+ * belongs to the outer control (shield its subtree by providing `WR_FORM_FIELD`
111
+ * as `null`), not to a strip that cannot tell whose field it is in.
112
+ */
113
+ protected readonly controlId: _angular_core.Signal<string | null>;
114
+ /**
115
+ * The field's error message, wired to the GROUP rather than to a segment.
116
+ *
117
+ * A segmented control is one field made of several buttons, so the description
118
+ * belongs to the thing the field describes — repeated on every segment it would be
119
+ * announced once per Tab. `role="group"` supports neither state as a role-specific
120
+ * attribute, but both are ARIA globals, so this is valid where an `aria-checked`
121
+ * would not be.
122
+ *
123
+ * `aria-invalid` is keyed on the message EXISTING rather than on `errorKeys()`,
124
+ * because the field only publishes an id once it is showing something — announcing
125
+ * "invalid" while pointing at nothing is worse than staying quiet.
126
+ */
127
+ protected readonly describedBy: _angular_core.Signal<string | null>;
128
+ protected readonly ariaInvalid: _angular_core.Signal<"true" | null>;
58
129
  /** Index of the selected option, or `-1` when nothing is selected. */
59
130
  protected readonly selectedIndex: _angular_core.Signal<number>;
60
131
  /** Flips true after the first paint so the thumb only animates user-driven changes, not the initial snap. */
@@ -86,8 +157,19 @@ declare class WrSegmented<T = unknown> {
86
157
  protected isSelected(option: WrSegmentedOption<T>): boolean;
87
158
  protected select(option: WrSegmentedOption<T>): void;
88
159
  protected trackByValue(_: number, option: WrSegmentedOption<T>): unknown;
160
+ /**
161
+ * A bound field learns it may show its validation copy from `touch`, and a click
162
+ * cannot be the source: a strip tabbed into and out of without a pick left the
163
+ * field untouched forever — which is exactly the case `touched` exists for.
164
+ *
165
+ * `wr-knob` and `wr-rating` bind `(blur)` on the one element they own; this
166
+ * component owns one button per option, so it listens for the bubbling `focusout`
167
+ * on its host instead — and ignores the one that only moves focus from one segment
168
+ * to the next, the way `wr-slider` ignores the hop between its two thumbs.
169
+ */
170
+ protected onFocusOut(event: FocusEvent): void;
89
171
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrSegmented<any>, never>;
90
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrSegmented<any>, "wr-segmented", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
172
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrSegmented<any>, "wr-segmented", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, never, true, never>;
91
173
  }
92
174
 
93
175
  export { WrSegmented };
@@ -444,8 +444,18 @@ declare class WrSelect implements FormValueControl<unknown>, WrSelectContext {
444
444
  /** Tag-mode draft (text currently typed in the inline input). @internal */
445
445
  protected readonly draft: _angular_core.WritableSignal<string>;
446
446
  /**
447
- * Show a clear-all (×) button at the end of the chip row when at
448
- * least one option is selected (multi mode only). @default true
447
+ * Show a clear (×) button once at least one option is selected.
448
+ *
449
+ * NOT multi-only, which this said for a long time and which the template
450
+ * refutes: only the button trigger gates on `isMulti()`, so the chips trigger
451
+ * AND a single `mode="search"` / `[searchable]` select carry it too. The
452
+ * wording mattered little while the default was `true`; it decides what a
453
+ * reader expects to lose now that it is not.
454
+ *
455
+ * The default changed from `true` to `false`: the affordance is opt-in, so a
456
+ * trigger that grew an × on its own no longer does — pass `clearable` to keep
457
+ * it. In `search` mode this also gates Backspace-to-clear on an empty field,
458
+ * since that key is the keyboard twin of this button. @default false
449
459
  */
450
460
  readonly clearable: _angular_core.InputSignalWithTransform<boolean, any>;
451
461
  /**
@@ -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 = "12.0.0";
19
+ declare const NGWR_VERSION = "12.2.0";
20
20
 
21
21
  /**
22
22
  * @license