@radix-ng/primitives 0.51.0 → 1.0.0-beta.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/fesm2022/radix-ng-primitives-accordion.mjs +105 -38
- package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs +221 -129
- package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-arrow.mjs +20 -4
- package/fesm2022/radix-ng-primitives-arrow.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-avatar.mjs +54 -61
- package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-button.mjs +123 -0
- package/fesm2022/radix-ng-primitives-button.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-calendar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +378 -54
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-collapsible.mjs +182 -81
- package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-collection.mjs +40 -57
- package/fesm2022/radix-ng-primitives-collection.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-config.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-context-menu.mjs +140 -424
- package/fesm2022/radix-ng-primitives-context-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +735 -744
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-cropper.mjs +1 -0
- package/fesm2022/radix-ng-primitives-cropper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +51 -45
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dialog.mjs +655 -327
- package/fesm2022/radix-ng-primitives-dialog.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs +70 -46
- package/fesm2022/radix-ng-primitives-dismissable-layer.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-drawer.mjs +1059 -0
- package/fesm2022/radix-ng-primitives-drawer.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-field.mjs +363 -0
- package/fesm2022/radix-ng-primitives-field.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-fieldset.mjs +79 -0
- package/fesm2022/radix-ng-primitives-fieldset.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-focus-scope.mjs +23 -8
- package/fesm2022/radix-ng-primitives-focus-scope.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-input.mjs +172 -0
- package/fesm2022/radix-ng-primitives-input.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-label.mjs +6 -6
- package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +1480 -344
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menubar.mjs +290 -162
- package/fesm2022/radix-ng-primitives-menubar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-meter.mjs +271 -0
- package/fesm2022/radix-ng-primitives-meter.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs +1052 -1553
- package/fesm2022/radix-ng-primitives-navigation-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-number-field.mjs +1102 -367
- package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-pagination.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popover.mjs +978 -989
- package/fesm2022/radix-ng-primitives-popover.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +91 -41
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-portal.mjs +34 -10
- package/fesm2022/radix-ng-primitives-portal.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-presence.mjs +134 -246
- package/fesm2022/radix-ng-primitives-presence.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-preview-card.mjs +997 -0
- package/fesm2022/radix-ng-primitives-preview-card.mjs.map +1 -0
- package/fesm2022/radix-ng-primitives-progress.mjs +223 -84
- package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-radio.mjs +191 -51
- package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-roving-focus.mjs +96 -50
- package/fesm2022/radix-ng-primitives-roving-focus.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +791 -509
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-separator.mjs +12 -35
- package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +969 -717
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-stepper.mjs +15 -19
- package/fesm2022/radix-ng-primitives-stepper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-switch.mjs +125 -113
- package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tabs.mjs +381 -108
- package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-time-field.mjs +55 -46
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +121 -247
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle.mjs +98 -61
- package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toolbar.mjs +303 -92
- package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-tooltip.mjs +690 -1071
- package/fesm2022/radix-ng-primitives-tooltip.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-visually-hidden.mjs +25 -66
- package/fesm2022/radix-ng-primitives-visually-hidden.mjs.map +1 -1
- package/meter/README.md +3 -0
- package/navigation-menu/README.md +2 -1
- package/package.json +31 -18
- package/portal/README.md +2 -0
- package/preview-card/README.md +3 -0
- package/schematics/collection.json +1 -0
- package/schematics/ng-add/index.d.ts +3 -2
- package/schematics/ng-add/index.js +62 -31
- package/schematics/ng-add/index.js.map +1 -1
- package/schematics/ng-add/package-config.d.ts +4 -2
- package/schematics/ng-add/package-config.js +10 -2
- package/schematics/ng-add/package-config.js.map +1 -1
- package/schematics/ng-add/schema.d.ts +3 -0
- package/schematics/ng-add/schema.js +3 -0
- package/schematics/ng-add/schema.js.map +1 -0
- package/schematics/ng-add/schema.json +14 -0
- package/select/README.md +2 -0
- package/types/radix-ng-primitives-accordion.d.ts +48 -14
- package/types/radix-ng-primitives-alert-dialog.d.ts +95 -38
- package/types/radix-ng-primitives-arrow.d.ts +1 -1
- package/types/radix-ng-primitives-aspect-ratio.d.ts +1 -1
- package/types/radix-ng-primitives-avatar.d.ts +7 -11
- package/types/radix-ng-primitives-button.d.ts +73 -0
- package/types/radix-ng-primitives-calendar.d.ts +1 -2
- package/types/radix-ng-primitives-checkbox.d.ts +201 -32
- package/types/radix-ng-primitives-collapsible.d.ts +112 -39
- package/types/radix-ng-primitives-collection.d.ts +38 -34
- package/types/radix-ng-primitives-config.d.ts +1 -1
- package/types/radix-ng-primitives-context-menu.d.ts +60 -116
- package/types/radix-ng-primitives-core.d.ts +307 -236
- package/types/radix-ng-primitives-cropper.d.ts +2 -2
- package/types/radix-ng-primitives-date-field.d.ts +38 -23
- package/types/radix-ng-primitives-dialog.d.ts +282 -165
- package/types/radix-ng-primitives-dismissable-layer.d.ts +15 -7
- package/types/radix-ng-primitives-drawer.d.ts +448 -0
- package/types/radix-ng-primitives-editable.d.ts +1 -1
- package/types/radix-ng-primitives-field.d.ts +373 -0
- package/types/radix-ng-primitives-fieldset.d.ts +48 -0
- package/types/radix-ng-primitives-focus-scope.d.ts +13 -5
- package/types/radix-ng-primitives-input.d.ts +87 -0
- package/types/radix-ng-primitives-label.d.ts +0 -1
- package/types/radix-ng-primitives-menu.d.ts +572 -99
- package/types/radix-ng-primitives-menubar.d.ts +60 -50
- package/types/radix-ng-primitives-meter.d.ts +193 -0
- package/types/radix-ng-primitives-navigation-menu.d.ts +422 -340
- package/types/radix-ng-primitives-number-field.d.ts +405 -145
- package/types/radix-ng-primitives-pagination.d.ts +2 -2
- package/types/radix-ng-primitives-popover.d.ts +365 -351
- package/types/radix-ng-primitives-popper.d.ts +49 -9
- package/types/radix-ng-primitives-portal.d.ts +14 -6
- package/types/radix-ng-primitives-presence.d.ts +28 -76
- package/types/radix-ng-primitives-preview-card.d.ts +359 -0
- package/types/radix-ng-primitives-progress.d.ts +174 -48
- package/types/radix-ng-primitives-radio.d.ts +55 -25
- package/types/radix-ng-primitives-roving-focus.d.ts +30 -21
- package/types/radix-ng-primitives-select.d.ts +475 -177
- package/types/radix-ng-primitives-separator.d.ts +7 -32
- package/types/radix-ng-primitives-slider.d.ts +315 -201
- package/types/radix-ng-primitives-stepper.d.ts +5 -7
- package/types/radix-ng-primitives-switch.d.ts +86 -71
- package/types/radix-ng-primitives-tabs.d.ts +213 -79
- package/types/radix-ng-primitives-time-field.d.ts +42 -27
- package/types/radix-ng-primitives-toggle-group.d.ts +85 -164
- package/types/radix-ng-primitives-toggle.d.ts +43 -53
- package/types/radix-ng-primitives-toolbar.d.ts +163 -38
- package/types/radix-ng-primitives-tooltip.d.ts +347 -384
- package/types/radix-ng-primitives-visually-hidden.d.ts +19 -19
- package/dropdown-menu/README.md +0 -1
- package/fesm2022/radix-ng-primitives-dropdown-menu.mjs +0 -581
- package/fesm2022/radix-ng-primitives-dropdown-menu.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-hover-card.mjs +0 -1238
- package/fesm2022/radix-ng-primitives-hover-card.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-select2.mjs +0 -897
- package/fesm2022/radix-ng-primitives-select2.mjs.map +0 -1
- package/fesm2022/radix-ng-primitives-tooltip2.mjs +0 -735
- package/fesm2022/radix-ng-primitives-tooltip2.mjs.map +0 -1
- package/hover-card/README.md +0 -3
- package/select2/README.md +0 -3
- package/tooltip2/README.md +0 -3
- package/types/radix-ng-primitives-dropdown-menu.d.ts +0 -171
- package/types/radix-ng-primitives-hover-card.d.ts +0 -471
- package/types/radix-ng-primitives-select2.d.ts +0 -511
- package/types/radix-ng-primitives-tooltip2.d.ts +0 -325
|
@@ -1,11 +1,219 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, model, input, booleanAttribute,
|
|
3
|
-
import { outputFromObservable, outputToObservable } from '@angular/core/rxjs-interop';
|
|
2
|
+
import { inject, model, input, booleanAttribute, output, signal, computed, effect, Directive, ElementRef, NgModule } from '@angular/core';
|
|
4
3
|
import * as i1 from '@radix-ng/primitives/core';
|
|
5
|
-
import {
|
|
4
|
+
import { createContext, provideValueAccessor, RdxControlValueAccessor } from '@radix-ng/primitives/core';
|
|
5
|
+
import { outputFromObservable, outputToObservable } from '@angular/core/rxjs-interop';
|
|
6
6
|
import * as i1$1 from '@radix-ng/primitives/presence';
|
|
7
7
|
import { provideRdxPresenceContext, RdxPresenceDirective } from '@radix-ng/primitives/presence';
|
|
8
8
|
|
|
9
|
+
const [injectCheckboxGroupContext, provideCheckboxGroupContext] = createContext('CheckboxGroupContext');
|
|
10
|
+
const groupContext = () => {
|
|
11
|
+
const group = inject(RdxCheckboxGroupDirective);
|
|
12
|
+
return {
|
|
13
|
+
value: group.value,
|
|
14
|
+
allValues: group.allValues,
|
|
15
|
+
disabled: group.disabledState,
|
|
16
|
+
parentState: group.parentState,
|
|
17
|
+
controlledIds: group.controlledIds,
|
|
18
|
+
controlId: (name) => group.controlId(name),
|
|
19
|
+
toggleValue: (name) => group.toggleValue(name),
|
|
20
|
+
toggleAll: () => group.toggleAll(),
|
|
21
|
+
registerChild: (name, disabled) => group.registerChild(name, disabled),
|
|
22
|
+
registerControl: (name, id) => group.registerControl(name, id)
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
let nextCheckboxGroupId = 0;
|
|
26
|
+
/**
|
|
27
|
+
* Groups a set of checkboxes that share a single array value (the names of the checked boxes).
|
|
28
|
+
*
|
|
29
|
+
* Each child `rdxCheckboxRoot` participates by its `name`. A child marked `parent` becomes a
|
|
30
|
+
* "select all" checkbox whose state is derived from `allValues`.
|
|
31
|
+
*/
|
|
32
|
+
class RdxCheckboxGroupDirective {
|
|
33
|
+
constructor() {
|
|
34
|
+
/** The names of the currently checked checkboxes. Use with `onValueChange` or `[(value)]`. */
|
|
35
|
+
this.value = model([], ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
36
|
+
/** The names checked initially when the group is uncontrolled. */
|
|
37
|
+
this.defaultValue = input(...(ngDevMode ? [undefined, { debugName: "defaultValue" }] : /* istanbul ignore next */ []));
|
|
38
|
+
/** All checkbox names in the group. Required for a `parent` (select-all) checkbox. */
|
|
39
|
+
this.allValues = input([], ...(ngDevMode ? [{ debugName: "allValues" }] : /* istanbul ignore next */ []));
|
|
40
|
+
/** Whether the whole group is disabled. */
|
|
41
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
42
|
+
/** Emits the new array of checked names whenever the value changes. */
|
|
43
|
+
this.onValueChange = output();
|
|
44
|
+
this.disabledByCva = signal(false, ...(ngDevMode ? [{ debugName: "disabledByCva" }] : /* istanbul ignore next */ []));
|
|
45
|
+
this.disabledState = computed(() => this.disabledByCva() || this.disabled(), ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
46
|
+
/** Derived state for a `parent` checkbox: `true` (all), `false` (none) or `'indeterminate'`. */
|
|
47
|
+
this.parentState = computed(() => {
|
|
48
|
+
const total = this.allValues().length;
|
|
49
|
+
const count = this.value().length;
|
|
50
|
+
if (total > 0 && count === total) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
return count > 0 ? 'indeterminate' : false;
|
|
54
|
+
}, ...(ngDevMode ? [{ debugName: "parentState" }] : /* istanbul ignore next */ []));
|
|
55
|
+
/**
|
|
56
|
+
* The value as last set directly by a child (or the initial value) — the "remembered" partial
|
|
57
|
+
* selection that a `parent` checkbox cycles back to, mirroring Base UI's `uncontrolledStateRef`.
|
|
58
|
+
*/
|
|
59
|
+
this.uncontrolledState = [];
|
|
60
|
+
this.seeded = false;
|
|
61
|
+
/** Where the parent is in its mixed → on → off cycle. Reset to `mixed` on any direct child change. */
|
|
62
|
+
this.parentStatus = 'mixed';
|
|
63
|
+
/** Per-name disabled signals, so the parent can preserve disabled-but-checked children. */
|
|
64
|
+
this.disabledByName = new Map();
|
|
65
|
+
/** Stable group id used to derive child control ids when the consumer sets none. */
|
|
66
|
+
this.elementId = `rdx-checkbox-group-${nextCheckboxGroupId++}`;
|
|
67
|
+
/** Registered control element ids, keyed by child name. */
|
|
68
|
+
this.controlIds = signal({}, ...(ngDevMode ? [{ debugName: "controlIds" }] : /* istanbul ignore next */ []));
|
|
69
|
+
/** The space-separated control ids in `allValues` order, for the parent's `aria-controls`. */
|
|
70
|
+
this.controlledIds = computed(() => {
|
|
71
|
+
const ids = this.controlIds();
|
|
72
|
+
const list = this.allValues()
|
|
73
|
+
.map((name) => ids[name])
|
|
74
|
+
.filter((id) => id !== undefined);
|
|
75
|
+
return list.length > 0 ? list.join(' ') : undefined;
|
|
76
|
+
}, ...(ngDevMode ? [{ debugName: "controlledIds" }] : /* istanbul ignore next */ []));
|
|
77
|
+
this.hasAppliedDefault = false;
|
|
78
|
+
this.onChange = () => {
|
|
79
|
+
/* Empty */
|
|
80
|
+
};
|
|
81
|
+
this.onTouched = () => {
|
|
82
|
+
/* Empty */
|
|
83
|
+
};
|
|
84
|
+
effect(() => {
|
|
85
|
+
const defaultValue = this.defaultValue();
|
|
86
|
+
if (!this.hasAppliedDefault && defaultValue !== undefined) {
|
|
87
|
+
this.hasAppliedDefault = true;
|
|
88
|
+
this.value.set(defaultValue);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** @ignore Register a child's disabled signal keyed by its name. */
|
|
93
|
+
registerChild(name, disabled) {
|
|
94
|
+
this.disabledByName.set(name, disabled);
|
|
95
|
+
return () => {
|
|
96
|
+
if (this.disabledByName.get(name) === disabled) {
|
|
97
|
+
this.disabledByName.delete(name);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/** A stable control id for a child, derived from the group id and the child name. */
|
|
102
|
+
controlId(name) {
|
|
103
|
+
return `${this.elementId}-${name}`;
|
|
104
|
+
}
|
|
105
|
+
/** @ignore Register a child's control element id so the parent can list it in `aria-controls`. */
|
|
106
|
+
registerControl(name, id) {
|
|
107
|
+
this.controlIds.update((ids) => ({ ...ids, [name]: id }));
|
|
108
|
+
return () => {
|
|
109
|
+
this.controlIds.update((ids) => {
|
|
110
|
+
if (ids[name] !== id) {
|
|
111
|
+
return ids;
|
|
112
|
+
}
|
|
113
|
+
const next = { ...ids };
|
|
114
|
+
delete next[name];
|
|
115
|
+
return next;
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Add/remove a single child name from the value (a direct child change). */
|
|
120
|
+
toggleValue(name) {
|
|
121
|
+
if (this.disabledState()) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const current = this.value();
|
|
125
|
+
const next = current.includes(name) ? current.filter((v) => v !== name) : [...current, name];
|
|
126
|
+
this.emit(next);
|
|
127
|
+
// A direct child change becomes the new "remembered" selection and resets the parent cycle.
|
|
128
|
+
this.seeded = true;
|
|
129
|
+
this.uncontrolledState = next;
|
|
130
|
+
this.parentStatus = 'mixed';
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Toggle from the `parent` checkbox. Mirrors Base UI's `useCheckboxGroupParent`:
|
|
134
|
+
*
|
|
135
|
+
* - When the remembered selection is all/none, this is a plain check-all ↔ uncheck-all toggle.
|
|
136
|
+
* - When it is a partial selection, clicks cycle: partial → all → none → partial → …, so the
|
|
137
|
+
* user's original partial choice is restored rather than lost.
|
|
138
|
+
*
|
|
139
|
+
* Disabled-but-checked children are always preserved (they cannot be toggled programmatically).
|
|
140
|
+
*/
|
|
141
|
+
toggleAll() {
|
|
142
|
+
if (this.disabledState()) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this.ensureSeeded();
|
|
146
|
+
const allValues = this.allValues();
|
|
147
|
+
const remembered = this.uncontrolledState;
|
|
148
|
+
// Disabled children that were checked stay checked through every transition.
|
|
149
|
+
const none = allValues.filter((name) => this.isNameDisabled(name) && remembered.includes(name));
|
|
150
|
+
const all = allValues.filter((name) => !this.isNameDisabled(name) || remembered.includes(name));
|
|
151
|
+
const rememberedIsAllOrNone = remembered.length === all.length || remembered.length === 0;
|
|
152
|
+
if (rememberedIsAllOrNone) {
|
|
153
|
+
this.emit(this.value().length === all.length ? none : all);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
let nextStatus = 'mixed';
|
|
157
|
+
let nextValue = remembered;
|
|
158
|
+
if (this.parentStatus === 'mixed') {
|
|
159
|
+
nextStatus = 'on';
|
|
160
|
+
nextValue = all;
|
|
161
|
+
}
|
|
162
|
+
else if (this.parentStatus === 'on') {
|
|
163
|
+
nextStatus = 'off';
|
|
164
|
+
nextValue = none;
|
|
165
|
+
}
|
|
166
|
+
this.emit(nextValue);
|
|
167
|
+
this.parentStatus = nextStatus;
|
|
168
|
+
}
|
|
169
|
+
isNameDisabled(name) {
|
|
170
|
+
return this.disabledByName.get(name)?.() ?? false;
|
|
171
|
+
}
|
|
172
|
+
/** Seed the remembered selection from the current value the first time the parent is used. */
|
|
173
|
+
ensureSeeded() {
|
|
174
|
+
if (!this.seeded) {
|
|
175
|
+
this.seeded = true;
|
|
176
|
+
this.uncontrolledState = this.value();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
emit(next) {
|
|
180
|
+
this.value.set(next);
|
|
181
|
+
this.onValueChange.emit(next);
|
|
182
|
+
this.onChange(next);
|
|
183
|
+
this.onTouched();
|
|
184
|
+
}
|
|
185
|
+
/** @ignore */
|
|
186
|
+
writeValue(value) {
|
|
187
|
+
this.value.set(value ?? []);
|
|
188
|
+
}
|
|
189
|
+
/** @ignore */
|
|
190
|
+
registerOnChange(fn) {
|
|
191
|
+
this.onChange = fn;
|
|
192
|
+
}
|
|
193
|
+
/** @ignore */
|
|
194
|
+
registerOnTouched(fn) {
|
|
195
|
+
this.onTouched = fn;
|
|
196
|
+
}
|
|
197
|
+
/** @ignore */
|
|
198
|
+
setDisabledState(isDisabled) {
|
|
199
|
+
this.disabledByCva.set(isDisabled);
|
|
200
|
+
}
|
|
201
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
202
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxCheckboxGroupDirective, isStandalone: true, selector: "[rdxCheckboxGroup]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, allValues: { classPropertyName: "allValues", publicName: "allValues", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", onValueChange: "onValueChange" }, host: { attributes: { "role": "group" }, properties: { "attr.data-disabled": "disabledState() ? \"\" : undefined" } }, providers: [provideValueAccessor(RdxCheckboxGroupDirective), provideCheckboxGroupContext(groupContext)], exportAs: ["rdxCheckboxGroup"], ngImport: i0 }); }
|
|
203
|
+
}
|
|
204
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxGroupDirective, decorators: [{
|
|
205
|
+
type: Directive,
|
|
206
|
+
args: [{
|
|
207
|
+
selector: '[rdxCheckboxGroup]',
|
|
208
|
+
exportAs: 'rdxCheckboxGroup',
|
|
209
|
+
providers: [provideValueAccessor(RdxCheckboxGroupDirective), provideCheckboxGroupContext(groupContext)],
|
|
210
|
+
host: {
|
|
211
|
+
role: 'group',
|
|
212
|
+
'[attr.data-disabled]': 'disabledState() ? "" : undefined'
|
|
213
|
+
}
|
|
214
|
+
}]
|
|
215
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], allValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "allValues", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], onValueChange: [{ type: i0.Output, args: ["onValueChange"] }] } });
|
|
216
|
+
|
|
9
217
|
function isIndeterminate(checked) {
|
|
10
218
|
return checked === 'indeterminate';
|
|
11
219
|
}
|
|
@@ -14,13 +222,16 @@ function getState(checked) {
|
|
|
14
222
|
}
|
|
15
223
|
const rootContext = () => {
|
|
16
224
|
const checkbox = inject(RdxCheckboxRootDirective);
|
|
17
|
-
|
|
225
|
+
// `checked`/`disabled` come from the directive so they reflect group membership when the
|
|
226
|
+
// checkbox is inside a `rdxCheckboxGroup`; otherwise they fall back to the CVA.
|
|
18
227
|
return {
|
|
19
|
-
checked:
|
|
20
|
-
|
|
228
|
+
checked: checkbox.checkedState,
|
|
229
|
+
indeterminate: checkbox.indeterminateState,
|
|
230
|
+
disabled: checkbox.disabledState,
|
|
21
231
|
required: checkbox.required,
|
|
22
|
-
value: checkbox.
|
|
232
|
+
value: checkbox.submitValue,
|
|
23
233
|
name: checkbox.name,
|
|
234
|
+
parent: checkbox.parent,
|
|
24
235
|
form: checkbox.form,
|
|
25
236
|
readonly: checkbox.readonly,
|
|
26
237
|
state: checkbox.state,
|
|
@@ -36,16 +247,41 @@ const [injectCheckboxRootContext, provideCheckboxRootContext] = createContext('C
|
|
|
36
247
|
class RdxCheckboxRootDirective {
|
|
37
248
|
constructor() {
|
|
38
249
|
this.controlValueAccessor = inject(RdxControlValueAccessor);
|
|
250
|
+
/** The group this checkbox belongs to, if it is rendered inside a `rdxCheckboxGroup`. */
|
|
251
|
+
this.group = injectCheckboxGroupContext(true);
|
|
252
|
+
/**
|
|
253
|
+
* @ignore
|
|
254
|
+
* Reflects the effective disabled state (CVA, covering reactive-forms `.disable()`, plus the
|
|
255
|
+
* group's disabled state), used for the `data-disabled` host attribute.
|
|
256
|
+
*/
|
|
257
|
+
this.isDisabled = computed(() => this.disabledState(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
39
258
|
/**
|
|
40
259
|
* The controlled checked state of the checkbox. Must be used in conjunction with onCheckedChange.
|
|
260
|
+
*
|
|
261
|
+
* Mixed state is no longer expressed through `checked` — use the separate
|
|
262
|
+
* `indeterminate` input (Base UI shape). This `boolean` model is what
|
|
263
|
+
* `RdxFormCheckboxControl` / Angular Signal Forms bind to.
|
|
41
264
|
* @group Props
|
|
42
265
|
*/
|
|
43
266
|
this.checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
267
|
+
/**
|
|
268
|
+
* Whether the checkbox is in a mixed state: neither ticked nor unticked.
|
|
269
|
+
* Orthogonal to `checked` and not part of the submitted form value. A user
|
|
270
|
+
* click resolves the checkbox to `checked` and clears `indeterminate`.
|
|
271
|
+
* @group Props
|
|
272
|
+
*/
|
|
273
|
+
this.indeterminate = model(false, ...(ngDevMode ? [{ debugName: "indeterminate" }] : /* istanbul ignore next */ []));
|
|
44
274
|
/**
|
|
45
275
|
* The value of the checkbox. This is what is submitted with the form when the checkbox is checked.
|
|
276
|
+
*
|
|
277
|
+
* Bound publicly as `[value]`; the TS member is named `submitValue` so the
|
|
278
|
+
* directive can satisfy `RdxFormCheckboxControl`, whose contract reserves a
|
|
279
|
+
* `value` member for `RdxFormValueControl` and forbids it on checkbox-style
|
|
280
|
+
* controls. (Checkbox is not yet marked `implements` — its `checked` is still
|
|
281
|
+
* `CheckedState`; see the `indeterminate` half of collision #1.)
|
|
46
282
|
* @group Props
|
|
47
283
|
*/
|
|
48
|
-
this.
|
|
284
|
+
this.submitValue = input('on', { ...(ngDevMode ? { debugName: "submitValue" } : /* istanbul ignore next */ {}), alias: 'value' });
|
|
49
285
|
/**
|
|
50
286
|
* Whether or not the checkbox button is disabled. This prevents the user from interacting with it.
|
|
51
287
|
* @group Props
|
|
@@ -62,10 +298,17 @@ class RdxCheckboxRootDirective {
|
|
|
62
298
|
*/
|
|
63
299
|
this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
64
300
|
/**
|
|
65
|
-
* Name of the form control. Submitted with the form as part of a name/value pair.
|
|
301
|
+
* Name of the form control. Submitted with the form as part of a name/value pair. Inside a
|
|
302
|
+
* `rdxCheckboxGroup` this also identifies the checkbox in the group's value array.
|
|
66
303
|
* @group Props
|
|
67
304
|
*/
|
|
68
305
|
this.name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : /* istanbul ignore next */ []));
|
|
306
|
+
/**
|
|
307
|
+
* When inside a `rdxCheckboxGroup`, marks this as the "select all" checkbox: its state is
|
|
308
|
+
* derived from the group's `allValues`, and toggling it checks or unchecks every child.
|
|
309
|
+
* @group Props
|
|
310
|
+
*/
|
|
311
|
+
this.parent = input(false, { ...(ngDevMode ? { debugName: "parent" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
69
312
|
/**
|
|
70
313
|
* Associates the control with a form element.
|
|
71
314
|
* @group Props
|
|
@@ -76,23 +319,74 @@ class RdxCheckboxRootDirective {
|
|
|
76
319
|
* @group Emits
|
|
77
320
|
*/
|
|
78
321
|
this.onCheckedChange = outputFromObservable(outputToObservable(this.controlValueAccessor.valueChange));
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
322
|
+
/**
|
|
323
|
+
* @ignore
|
|
324
|
+
* The effective checked state as a `boolean`. Inside a `rdxCheckboxGroup` it is derived from the
|
|
325
|
+
* group (a `parent` checkbox is checked only when every child is; a child from whether its `name`
|
|
326
|
+
* is in the group value); standalone it reads the CVA value.
|
|
327
|
+
*/
|
|
328
|
+
this.checkedState = computed(() => {
|
|
329
|
+
const group = this.group;
|
|
330
|
+
if (group) {
|
|
331
|
+
if (this.parent()) {
|
|
332
|
+
return group.parentState() === true;
|
|
333
|
+
}
|
|
334
|
+
const name = this.name();
|
|
335
|
+
if (name !== undefined) {
|
|
336
|
+
return group.value().includes(name);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return !!this.controlValueAccessor.value();
|
|
340
|
+
}, ...(ngDevMode ? [{ debugName: "checkedState" }] : /* istanbul ignore next */ []));
|
|
341
|
+
/**
|
|
342
|
+
* @ignore
|
|
343
|
+
* The effective mixed state. A `parent` checkbox is indeterminate when some — but not all —
|
|
344
|
+
* children are checked; otherwise it follows the `indeterminate` input.
|
|
345
|
+
*/
|
|
346
|
+
this.indeterminateState = computed(() => {
|
|
347
|
+
const group = this.group;
|
|
348
|
+
if (group && this.parent()) {
|
|
349
|
+
return group.parentState() === 'indeterminate';
|
|
350
|
+
}
|
|
351
|
+
return this.indeterminate();
|
|
352
|
+
}, ...(ngDevMode ? [{ debugName: "indeterminateState" }] : /* istanbul ignore next */ []));
|
|
353
|
+
/** @ignore The effective disabled state, including the group. */
|
|
354
|
+
this.disabledState = computed(() => this.controlValueAccessor.disabled() || (this.group?.disabled() ?? false), ...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
355
|
+
this.state = computed(() => this.indeterminateState() ? 'indeterminate' : this.checkedState() ? 'checked' : 'unchecked', ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
356
|
+
// Inside a group, register this child's name and its own disabled state so a `parent`
|
|
357
|
+
// checkbox can preserve disabled-but-checked children when selecting/deselecting all.
|
|
358
|
+
effect((onCleanup) => {
|
|
359
|
+
const group = this.group;
|
|
360
|
+
const name = this.name();
|
|
361
|
+
if (group && !this.parent() && name !== undefined) {
|
|
362
|
+
onCleanup(group.registerChild(name, this.controlValueAccessor.disabled));
|
|
83
363
|
}
|
|
84
|
-
|
|
85
|
-
}, ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
364
|
+
});
|
|
86
365
|
}
|
|
87
366
|
toggle() {
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
this.
|
|
367
|
+
const group = this.group;
|
|
368
|
+
if (group) {
|
|
369
|
+
if (this.parent()) {
|
|
370
|
+
group.toggleAll();
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const name = this.name();
|
|
374
|
+
if (name !== undefined) {
|
|
375
|
+
group.toggleValue(name);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
91
378
|
}
|
|
92
|
-
|
|
379
|
+
// From the indeterminate state a click resolves to checked (matching
|
|
380
|
+
// native + Base UI), otherwise it flips the boolean. A single setValue so
|
|
381
|
+
// onCheckedChange fires once; the `checked`/`indeterminate` models are
|
|
382
|
+
// kept in sync so `[(checked)]` / `[(indeterminate)]` reflect the change.
|
|
383
|
+
const next = this.indeterminateState() ? true : !this.checkedState();
|
|
384
|
+
this.indeterminate.set(false);
|
|
385
|
+
this.checked.set(next);
|
|
386
|
+
this.controlValueAccessor.setValue(next);
|
|
93
387
|
}
|
|
94
388
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
95
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxCheckboxRootDirective, isStandalone: true, selector: "[rdxCheckboxRoot]", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null },
|
|
389
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: RdxCheckboxRootDirective, isStandalone: true, selector: "[rdxCheckboxRoot]", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, submitValue: { classPropertyName: "submitValue", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, parent: { classPropertyName: "parent", publicName: "parent", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", indeterminate: "indeterminateChange", onCheckedChange: "onCheckedChange" }, host: { properties: { "attr.data-state": "state()", "attr.data-disabled": "isDisabled() ? \"\" : undefined", "attr.data-readonly": "readonly() ? \"\" : undefined", "attr.data-required": "required() ? \"\" : undefined" } }, providers: [provideCheckboxRootContext(rootContext)], hostDirectives: [{ directive: i1.RdxControlValueAccessor, inputs: ["value", "checked", "disabled", "disabled"] }], ngImport: i0 }); }
|
|
96
390
|
}
|
|
97
391
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxRootDirective, decorators: [{
|
|
98
392
|
type: Directive,
|
|
@@ -106,10 +400,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
106
400
|
}
|
|
107
401
|
],
|
|
108
402
|
host: {
|
|
109
|
-
'[attr.data-state]': 'state()'
|
|
403
|
+
'[attr.data-state]': 'state()',
|
|
404
|
+
'[attr.data-disabled]': 'isDisabled() ? "" : undefined',
|
|
405
|
+
'[attr.data-readonly]': 'readonly() ? "" : undefined',
|
|
406
|
+
'[attr.data-required]': 'required() ? "" : undefined'
|
|
110
407
|
}
|
|
111
408
|
}]
|
|
112
|
-
}], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }],
|
|
409
|
+
}], ctorParameters: () => [], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }, { type: i0.Output, args: ["indeterminateChange"] }], submitValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], parent: [{ type: i0.Input, args: [{ isSignal: true, alias: "parent", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], onCheckedChange: [{ type: i0.Output, args: ["onCheckedChange"] }] } });
|
|
113
410
|
|
|
114
411
|
/**
|
|
115
412
|
* Directive: rdxCheckboxButton
|
|
@@ -120,7 +417,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
120
417
|
class RdxCheckboxButtonDirective {
|
|
121
418
|
constructor() {
|
|
122
419
|
this.rootContext = injectCheckboxRootContext();
|
|
420
|
+
this.group = injectCheckboxGroupContext(true);
|
|
123
421
|
this.elementRef = inject(ElementRef);
|
|
422
|
+
/** A `parent` checkbox lists the ids of the children it controls. */
|
|
423
|
+
this.ariaControls = computed(() => this.group && this.rootContext.parent() ? this.group.controlledIds() : undefined, ...(ngDevMode ? [{ debugName: "ariaControls" }] : /* istanbul ignore next */ []));
|
|
424
|
+
// A child checkbox in a group exposes its control id so the parent can reference it via
|
|
425
|
+
// `aria-controls`. Use the consumer's id when present, otherwise derive a stable one.
|
|
426
|
+
effect((onCleanup) => {
|
|
427
|
+
const group = this.group;
|
|
428
|
+
const name = this.rootContext.name();
|
|
429
|
+
if (!group || this.rootContext.parent() || name === undefined) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
const el = this.elementRef.nativeElement;
|
|
433
|
+
if (!el.id) {
|
|
434
|
+
el.id = group.controlId(name);
|
|
435
|
+
}
|
|
436
|
+
onCleanup(group.registerControl(name, el.id));
|
|
437
|
+
});
|
|
124
438
|
}
|
|
125
439
|
clicked(event) {
|
|
126
440
|
if (event.defaultPrevented || this.rootContext.readonly()) {
|
|
@@ -135,7 +449,7 @@ class RdxCheckboxButtonDirective {
|
|
|
135
449
|
}
|
|
136
450
|
}
|
|
137
451
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxButtonDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
138
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxCheckboxButtonDirective, isStandalone: true, selector: "button[rdxCheckboxButton]", host: { attributes: { "type": "button", "role": "checkbox" }, listeners: { "click": "clicked($event)", "keydown.enter": "$event.preventDefault()" }, properties: { "attr.aria-checked": "rootContext.
|
|
452
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxCheckboxButtonDirective, isStandalone: true, selector: "button[rdxCheckboxButton]", host: { attributes: { "type": "button", "role": "checkbox" }, listeners: { "click": "clicked($event)", "keydown.enter": "$event.preventDefault()" }, properties: { "attr.aria-checked": "rootContext.indeterminate() ? \"mixed\" : rootContext.checked()", "attr.aria-controls": "ariaControls()", "attr.aria-required": "rootContext.required() || undefined", "attr.aria-readonly": "rootContext.readonly() || undefined", "attr.data-state": "rootContext.state()", "attr.data-disabled": "rootContext.disabled() ? \"\" : undefined", "attr.data-readonly": "rootContext.readonly() ? \"\" : undefined", "attr.disabled": "rootContext.disabled() ? \"\" : undefined", "attr.value": "rootContext.value()" } }, ngImport: i0 }); }
|
|
139
453
|
}
|
|
140
454
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxButtonDirective, decorators: [{
|
|
141
455
|
type: Directive,
|
|
@@ -144,12 +458,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
144
458
|
host: {
|
|
145
459
|
type: 'button',
|
|
146
460
|
role: 'checkbox',
|
|
147
|
-
'[attr.aria-checked]': 'rootContext.
|
|
461
|
+
'[attr.aria-checked]': 'rootContext.indeterminate() ? "mixed" : rootContext.checked()',
|
|
462
|
+
'[attr.aria-controls]': 'ariaControls()',
|
|
148
463
|
'[attr.aria-required]': 'rootContext.required() || undefined',
|
|
149
464
|
'[attr.aria-readonly]': 'rootContext.readonly() || undefined',
|
|
150
465
|
'[attr.data-state]': 'rootContext.state()',
|
|
151
|
-
'[attr.data-disabled]': 'rootContext.disabled()
|
|
152
|
-
'[attr.data-readonly]': 'rootContext.readonly()
|
|
466
|
+
'[attr.data-disabled]': 'rootContext.disabled() ? "" : undefined',
|
|
467
|
+
'[attr.data-readonly]': 'rootContext.readonly() ? "" : undefined',
|
|
153
468
|
'[attr.disabled]': 'rootContext.disabled() ? "" : undefined',
|
|
154
469
|
'[attr.value]': 'rootContext.value()',
|
|
155
470
|
'(click)': 'clicked($event)',
|
|
@@ -157,14 +472,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
157
472
|
'(keydown.enter)': '$event.preventDefault()'
|
|
158
473
|
}
|
|
159
474
|
}]
|
|
160
|
-
}] });
|
|
475
|
+
}], ctorParameters: () => [] });
|
|
161
476
|
|
|
162
477
|
class RdxCheckboxIndicatorDirective {
|
|
163
478
|
constructor() {
|
|
164
479
|
this.rootContext = injectCheckboxRootContext();
|
|
165
480
|
}
|
|
166
481
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxIndicatorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
167
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxCheckboxIndicatorDirective, isStandalone: true, selector: "[rdxCheckboxIndicator]", host: { properties: { "attr.data-state": "rootContext.state()", "attr.data-disabled": "rootContext.disabled() ? \"\" : undefined", "hidden": "!rootContext.checked()", "style.pointer-events": "\"none\"" } }, ngImport: i0 }); }
|
|
482
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxCheckboxIndicatorDirective, isStandalone: true, selector: "[rdxCheckboxIndicator]", host: { properties: { "attr.data-state": "rootContext.state()", "attr.data-disabled": "rootContext.disabled() ? \"\" : undefined", "hidden": "!rootContext.checked() && !rootContext.indeterminate()", "style.pointer-events": "\"none\"" } }, ngImport: i0 }); }
|
|
168
483
|
}
|
|
169
484
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxIndicatorDirective, decorators: [{
|
|
170
485
|
type: Directive,
|
|
@@ -173,7 +488,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
173
488
|
host: {
|
|
174
489
|
'[attr.data-state]': 'rootContext.state()',
|
|
175
490
|
'[attr.data-disabled]': 'rootContext.disabled() ? "" : undefined',
|
|
176
|
-
'[hidden]': '!rootContext.checked()',
|
|
491
|
+
'[hidden]': '!rootContext.checked() && !rootContext.indeterminate()',
|
|
177
492
|
'[style.pointer-events]': '"none"'
|
|
178
493
|
}
|
|
179
494
|
}]
|
|
@@ -185,7 +500,7 @@ class RdxCheckboxIndicatorPresenceDirective {
|
|
|
185
500
|
provideRdxPresenceContext(() => {
|
|
186
501
|
const rootContext = injectCheckboxRootContext();
|
|
187
502
|
return {
|
|
188
|
-
present: computed(() =>
|
|
503
|
+
present: computed(() => rootContext.checked() || rootContext.indeterminate())
|
|
189
504
|
};
|
|
190
505
|
})
|
|
191
506
|
], hostDirectives: [{ directive: i1$1.RdxPresenceDirective }], ngImport: i0 }); }
|
|
@@ -198,7 +513,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
198
513
|
provideRdxPresenceContext(() => {
|
|
199
514
|
const rootContext = injectCheckboxRootContext();
|
|
200
515
|
return {
|
|
201
|
-
present: computed(() =>
|
|
516
|
+
present: computed(() => rootContext.checked() || rootContext.indeterminate())
|
|
202
517
|
};
|
|
203
518
|
})
|
|
204
519
|
],
|
|
@@ -209,30 +524,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
209
524
|
class RdxCheckboxInputDirective {
|
|
210
525
|
constructor() {
|
|
211
526
|
this.rootContext = injectCheckboxRootContext();
|
|
212
|
-
this.
|
|
213
|
-
|
|
527
|
+
this.input = inject(ElementRef).nativeElement;
|
|
528
|
+
let isInitial = true;
|
|
214
529
|
/**
|
|
215
|
-
*
|
|
530
|
+
* Keeps the hidden native input in sync so form submission, native
|
|
531
|
+
* validation and form events reflect the checkbox state.
|
|
216
532
|
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
* -
|
|
220
|
-
*
|
|
221
|
-
*
|
|
533
|
+
* - `indeterminate` is a native property (not a submittable value), so we
|
|
534
|
+
* mirror it here rather than via an attribute.
|
|
535
|
+
* - On every change (but not the initial render) we emit bubbling
|
|
536
|
+
* `input`/`change` events so native form listeners react. We do NOT
|
|
537
|
+
* dispatch a `click`: a click on a checkbox runs the toggle activation
|
|
538
|
+
* behavior and would desync the input from the bound state.
|
|
222
539
|
*/
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
540
|
+
effect(() => {
|
|
541
|
+
// Track both so the native input mirrors the checkbox and emits change
|
|
542
|
+
// events when either the checked or indeterminate state moves.
|
|
543
|
+
this.rootContext.checked();
|
|
544
|
+
this.input.indeterminate = this.rootContext.indeterminate();
|
|
545
|
+
if (isInitial) {
|
|
546
|
+
isInitial = false;
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
this.input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
550
|
+
this.input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
232
551
|
});
|
|
233
552
|
}
|
|
234
553
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
235
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxCheckboxInputDirective, isStandalone: true, selector: "input[rdxCheckboxInput]", host: { attributes: { "type": "checkbox", "tabindex": "-1", "aria-hidden": "true" }, properties: { "attr.name": "rootContext.name() || undefined", "attr.checked": "rootContext.
|
|
554
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: RdxCheckboxInputDirective, isStandalone: true, selector: "input[rdxCheckboxInput]", host: { attributes: { "type": "checkbox", "tabindex": "-1", "aria-hidden": "true" }, properties: { "attr.name": "rootContext.name() || undefined", "attr.checked": "rootContext.state() === \"checked\" ? \"\" : undefined", "attr.form": "rootContext.form() || undefined", "attr.value": "rootContext.value()", "required": "rootContext.required() || undefined", "attr.disabled": "rootContext.disabled() ? \"\" : undefined", "style": "{\n position: 'absolute',\n pointerEvents: 'none',\n opacity: 0,\n margin: 0,\n inset: 0,\n transform: 'translateX(-100%)',\n }" } }, ngImport: i0 }); }
|
|
236
555
|
}
|
|
237
556
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxInputDirective, decorators: [{
|
|
238
557
|
type: Directive,
|
|
@@ -243,7 +562,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
243
562
|
tabindex: '-1',
|
|
244
563
|
'aria-hidden': 'true',
|
|
245
564
|
'[attr.name]': 'rootContext.name() || undefined',
|
|
246
|
-
|
|
565
|
+
// Only a truly checked box is submitted; `indeterminate` is a property
|
|
566
|
+
// (set below), never a submitted "checked" value.
|
|
567
|
+
'[attr.checked]': 'rootContext.state() === "checked" ? "" : undefined',
|
|
247
568
|
'[attr.form]': 'rootContext.form() || undefined',
|
|
248
569
|
'[attr.value]': 'rootContext.value()',
|
|
249
570
|
'[required]': 'rootContext.required() || undefined',
|
|
@@ -265,7 +586,8 @@ const checkboxImports = [
|
|
|
265
586
|
RdxCheckboxRootDirective,
|
|
266
587
|
RdxCheckboxButtonDirective,
|
|
267
588
|
RdxCheckboxIndicatorDirective,
|
|
268
|
-
RdxCheckboxIndicatorPresenceDirective
|
|
589
|
+
RdxCheckboxIndicatorPresenceDirective,
|
|
590
|
+
RdxCheckboxGroupDirective
|
|
269
591
|
];
|
|
270
592
|
class RdxCheckboxModule {
|
|
271
593
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
@@ -273,11 +595,13 @@ class RdxCheckboxModule {
|
|
|
273
595
|
RdxCheckboxRootDirective,
|
|
274
596
|
RdxCheckboxButtonDirective,
|
|
275
597
|
RdxCheckboxIndicatorDirective,
|
|
276
|
-
RdxCheckboxIndicatorPresenceDirective
|
|
598
|
+
RdxCheckboxIndicatorPresenceDirective,
|
|
599
|
+
RdxCheckboxGroupDirective], exports: [RdxCheckboxInputDirective,
|
|
277
600
|
RdxCheckboxRootDirective,
|
|
278
601
|
RdxCheckboxButtonDirective,
|
|
279
602
|
RdxCheckboxIndicatorDirective,
|
|
280
|
-
RdxCheckboxIndicatorPresenceDirective
|
|
603
|
+
RdxCheckboxIndicatorPresenceDirective,
|
|
604
|
+
RdxCheckboxGroupDirective] }); }
|
|
281
605
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxModule }); }
|
|
282
606
|
}
|
|
283
607
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: RdxCheckboxModule, decorators: [{
|
|
@@ -292,5 +616,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
|
|
|
292
616
|
* Generated bundle index. Do not edit.
|
|
293
617
|
*/
|
|
294
618
|
|
|
295
|
-
export { RdxCheckboxButtonDirective, RdxCheckboxIndicatorDirective, RdxCheckboxIndicatorPresenceDirective, RdxCheckboxInputDirective, RdxCheckboxModule, RdxCheckboxRootDirective, checkboxImports, getState, injectCheckboxRootContext, isIndeterminate, provideCheckboxRootContext };
|
|
619
|
+
export { RdxCheckboxButtonDirective, RdxCheckboxGroupDirective, RdxCheckboxIndicatorDirective, RdxCheckboxIndicatorPresenceDirective, RdxCheckboxInputDirective, RdxCheckboxModule, RdxCheckboxRootDirective, checkboxImports, getState, injectCheckboxGroupContext, injectCheckboxRootContext, isIndeterminate, provideCheckboxGroupContext, provideCheckboxRootContext };
|
|
296
620
|
//# sourceMappingURL=radix-ng-primitives-checkbox.mjs.map
|