ng-primitives 0.123.0 → 0.124.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.
@@ -1,47 +1,91 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, booleanAttribute, Directive, computed, HostListener } from '@angular/core';
3
- import { ngpFormControl } from 'ng-primitives/form-field';
4
- import * as i1 from 'ng-primitives/roving-focus';
5
- import { injectRovingFocusGroupState, NgpRovingFocusGroup, NgpRovingFocusItem } from 'ng-primitives/roving-focus';
2
+ import { signal, input, output, booleanAttribute, Directive, computed } from '@angular/core';
3
+ import { ngpRovingFocusGroup, provideRovingFocusGroupState, ngpRovingFocusItem, provideRovingFocusItemState } from 'ng-primitives/roving-focus';
6
4
  import { uniqueId } from 'ng-primitives/utils';
7
- import { createStateToken, createStateProvider, createStateInjector, createState } from 'ng-primitives/state';
8
- import * as i2 from 'ng-primitives/interactions';
9
- import { NgpHover, NgpPress, NgpFocusVisible } from 'ng-primitives/interactions';
5
+ import { ngpFormControl } from 'ng-primitives/form-field';
6
+ import { injectElementRef } from 'ng-primitives/internal';
7
+ import { createPrimitive, controlled, controlledState, attrBinding, dataBinding, deprecatedSetter, listener } from 'ng-primitives/state';
8
+ import { ngpInteractions } from 'ng-primitives/interactions';
10
9
 
11
- /**
12
- * The state token for the RadioGroup primitive.
13
- */
14
- const NgpRadioGroupStateToken = createStateToken('RadioGroup');
15
- /**
16
- * Provides the RadioGroup state.
17
- */
18
- const provideRadioGroupState = createStateProvider(NgpRadioGroupStateToken);
10
+ const [NgpRadioGroupStateToken, ngpRadioGroup, _injectRadioGroupState, provideRadioGroupState,] = createPrimitive('NgpRadioGroup', ({ id = signal(uniqueId('ngp-radio-group')), value: _value = signal(undefined), defaultValue: _defaultValue, disabled: _disabled = signal(false), orientation: _orientation = signal('horizontal'), compareWith = signal((a, b) => a === b), onValueChange, }) => {
11
+ const element = injectElementRef();
12
+ const disabled = controlled(_disabled, false);
13
+ const orientation = controlled(_orientation, 'horizontal');
14
+ const defaultValue = controlled(_defaultValue, null);
15
+ const [value, setValueInternal, valueChange] = controlledState({
16
+ value: _value,
17
+ defaultValue,
18
+ onChange: onValueChange,
19
+ });
20
+ // Own the roving focus group so it shares the group's `disabled` and
21
+ // `orientation` signals directly. This keeps keyboard navigation in sync
22
+ // with programmatic/form-driven changes (e.g. `setDisabled`, `setOrientation`)
23
+ // without needing to re-push each value across a directive boundary.
24
+ // `wrap` is always on to match the ARIA radio pattern (arrow keys cycle).
25
+ ngpRovingFocusGroup({ orientation, disabled, wrap: signal(true) });
26
+ ngpFormControl({ id, disabled });
27
+ // Host bindings
28
+ attrBinding(element, 'role', 'radiogroup');
29
+ attrBinding(element, 'id', id);
30
+ attrBinding(element, 'aria-orientation', orientation);
31
+ dataBinding(element, 'data-orientation', orientation);
32
+ dataBinding(element, 'data-disabled', disabled);
33
+ function setValue(newValue, options) {
34
+ setValueInternal(newValue, options);
35
+ }
36
+ function select(newValue) {
37
+ // Guard on disabled and dedupe by the comparator so that re-selecting an
38
+ // equal value (by `compareWith`, not just reference) is a no-op.
39
+ if (disabled() || compareWith()(value(), newValue)) {
40
+ return;
41
+ }
42
+ setValue(newValue);
43
+ }
44
+ function setDisabled(isDisabled) {
45
+ disabled.set(isDisabled);
46
+ }
47
+ function setOrientation(newOrientation) {
48
+ // The roving focus group shares this signal, so it stays in sync.
49
+ orientation.set(newOrientation);
50
+ }
51
+ return {
52
+ id,
53
+ value: deprecatedSetter(value, 'setValue', newValue => setValue(newValue)),
54
+ disabled: deprecatedSetter(disabled, 'setDisabled'),
55
+ orientation: deprecatedSetter(orientation, 'setOrientation', setOrientation),
56
+ compareWith,
57
+ valueChange,
58
+ select,
59
+ setValue,
60
+ setDefaultValue: defaultValue.set,
61
+ setDisabled,
62
+ setOrientation,
63
+ };
64
+ });
19
65
  /**
20
66
  * Injects the RadioGroup state.
21
67
  */
22
- const injectRadioGroupState = createStateInjector(NgpRadioGroupStateToken);
23
- /**
24
- * The RadioGroup state registration function.
25
- */
26
- const radioGroupState = createState(NgpRadioGroupStateToken);
68
+ function injectRadioGroupState(options) {
69
+ return _injectRadioGroupState(options);
70
+ }
27
71
 
28
72
  /**
29
73
  * Apply the `ngpRadioGroup` directive to an element that represents the group of radio items.
30
74
  */
31
75
  class NgpRadioGroup {
32
76
  constructor() {
33
- /**
34
- * Access the roving focus group state.
35
- */
36
- this.rovingFocusGroupState = injectRovingFocusGroupState();
37
77
  /**
38
78
  * The id of the radio group. If not provided, a unique id will be generated.
39
79
  */
40
80
  this.id = input(uniqueId('ngp-radio-group'), ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
41
81
  /**
42
- * The value of the radio group.
82
+ * The value of the radio group. Leave unset for uncontrolled usage.
83
+ */
84
+ this.value = input(undefined, { ...(ngDevMode ? { debugName: "value" } : /* istanbul ignore next */ {}), alias: 'ngpRadioGroupValue' });
85
+ /**
86
+ * The default value of the radio group for uncontrolled usage.
43
87
  */
44
- this.value = input(null, { ...(ngDevMode ? { debugName: "value" } : /* istanbul ignore next */ {}), alias: 'ngpRadioGroupValue' });
88
+ this.defaultValue = input(null, { ...(ngDevMode ? { debugName: "defaultValue" } : /* istanbul ignore next */ {}), alias: 'ngpRadioGroupDefaultValue' });
45
89
  /**
46
90
  * Event emitted when the radio group value changes.
47
91
  */
@@ -65,91 +109,94 @@ class NgpRadioGroup {
65
109
  this.compareWith = input((a, b) => a === b, { ...(ngDevMode ? { debugName: "compareWith" } : /* istanbul ignore next */ {}), alias: 'ngpRadioGroupCompareWith' });
66
110
  /**
67
111
  * The state of the radio group.
68
- * @internal
69
112
  */
70
- this.state = radioGroupState(this);
71
- ngpFormControl({ id: this.state.id, disabled: this.state.disabled });
72
- }
73
- ngOnInit() {
74
- // the roving focus group defaults to vertical orientation whereas we want to default to vertical
75
- this.rovingFocusGroupState()?.setOrientation(this.state.orientation());
113
+ this.state = ngpRadioGroup({
114
+ id: this.id,
115
+ value: this.value,
116
+ defaultValue: this.defaultValue,
117
+ disabled: this.disabled,
118
+ orientation: this.orientation,
119
+ compareWith: this.compareWith,
120
+ onValueChange: value => this.valueChange.emit(value),
121
+ });
76
122
  }
77
123
  /**
78
124
  * Select a radio item.
79
125
  * @param value The value of the radio item to select.
80
126
  */
81
127
  select(value) {
82
- // if the value is already selected, do nothing
83
- if (this.state.compareWith()(this.state.value(), value)) {
84
- return;
85
- }
86
- this.state.value.set(value);
87
- this.valueChange.emit(value);
128
+ this.state.select(value);
129
+ }
130
+ /**
131
+ * Set the default value of the radio group.
132
+ */
133
+ setDefaultValue(value) {
134
+ this.state.setDefaultValue(value);
135
+ }
136
+ /**
137
+ * Set the orientation of the radio group.
138
+ */
139
+ setOrientation(orientation) {
140
+ this.state.setOrientation(orientation);
88
141
  }
89
142
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgpRadioGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
90
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgpRadioGroup, isStandalone: true, selector: "[ngpRadioGroup]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "ngpRadioGroupValue", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpRadioGroupDisabled", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "ngpRadioGroupOrientation", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "ngpRadioGroupCompareWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "ngpRadioGroupValueChange" }, host: { attributes: { "role": "radiogroup" }, properties: { "id": "id()", "attr.aria-orientation": "state.orientation()", "attr.data-orientation": "state.orientation()", "attr.data-disabled": "state.disabled() ? \"\" : null" } }, providers: [provideRadioGroupState()], hostDirectives: [{ directive: i1.NgpRovingFocusGroup, inputs: ["ngpRovingFocusGroupOrientation", "ngpRadioGroupOrientation", "ngpRovingFocusGroupDisabled", "ngpRadioGroupDisabled"] }], ngImport: i0 }); }
143
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgpRadioGroup, isStandalone: true, selector: "[ngpRadioGroup]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "ngpRadioGroupValue", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "ngpRadioGroupDefaultValue", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpRadioGroupDisabled", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "ngpRadioGroupOrientation", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "ngpRadioGroupCompareWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "ngpRadioGroupValueChange" }, providers: [provideRadioGroupState(), provideRovingFocusGroupState()], ngImport: i0 }); }
91
144
  }
92
145
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgpRadioGroup, decorators: [{
93
146
  type: Directive,
94
147
  args: [{
95
148
  selector: '[ngpRadioGroup]',
96
- providers: [provideRadioGroupState()],
97
- hostDirectives: [
98
- {
99
- directive: NgpRovingFocusGroup,
100
- inputs: [
101
- 'ngpRovingFocusGroupOrientation:ngpRadioGroupOrientation',
102
- 'ngpRovingFocusGroupDisabled:ngpRadioGroupDisabled',
103
- ],
104
- },
105
- ],
106
- host: {
107
- role: 'radiogroup',
108
- '[id]': 'id()',
109
- '[attr.aria-orientation]': 'state.orientation()',
110
- '[attr.data-orientation]': 'state.orientation()',
111
- '[attr.data-disabled]': 'state.disabled() ? "" : null',
112
- },
149
+ providers: [provideRadioGroupState(), provideRovingFocusGroupState()],
113
150
  }]
114
- }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioGroupValue", required: false }] }], valueChange: [{ type: i0.Output, args: ["ngpRadioGroupValueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioGroupDisabled", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioGroupOrientation", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioGroupCompareWith", required: false }] }] } });
151
+ }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioGroupValue", required: false }] }], defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioGroupDefaultValue", required: false }] }], valueChange: [{ type: i0.Output, args: ["ngpRadioGroupValueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioGroupDisabled", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioGroupOrientation", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioGroupCompareWith", required: false }] }] } });
115
152
 
116
- /**
117
- * The state token for the RadioItem primitive.
118
- */
119
- const NgpRadioItemStateToken = createStateToken('RadioItem');
120
- /**
121
- * Provides the RadioItem state.
122
- */
123
- const provideRadioItemState = createStateProvider(NgpRadioItemStateToken);
153
+ const [NgpRadioItemStateToken, ngpRadioItem, _injectRadioItemState, provideRadioItemState] = createPrimitive('NgpRadioItem', ({ value, disabled = signal(false) }) => {
154
+ const element = injectElementRef();
155
+ const radioGroup = injectRadioGroupState();
156
+ const checked = computed(() => radioGroup().compareWith()(radioGroup().value(), value()), ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
157
+ // Setup interactions
158
+ ngpInteractions({ hover: true, press: true, focusVisible: true, disabled });
159
+ // Host bindings
160
+ attrBinding(element, 'role', 'radio');
161
+ attrBinding(element, 'aria-checked', () => (checked() ? 'true' : 'false'));
162
+ attrBinding(element, 'aria-disabled', disabled);
163
+ dataBinding(element, 'data-disabled', disabled);
164
+ dataBinding(element, 'data-checked', checked);
165
+ function select() {
166
+ if (disabled()) {
167
+ return;
168
+ }
169
+ radioGroup().select(value());
170
+ }
171
+ // Event listeners
172
+ listener(element, 'focus', select);
173
+ listener(element, 'click', select);
174
+ return { value, disabled, checked };
175
+ });
124
176
  /**
125
177
  * Injects the RadioItem state.
126
178
  */
127
- const injectRadioItemState = createStateInjector(NgpRadioItemStateToken);
128
- /**
129
- * The RadioItem state registration function.
130
- */
131
- const radioItemState = createState(NgpRadioItemStateToken);
179
+ function injectRadioItemState(options) {
180
+ return _injectRadioItemState(options);
181
+ }
132
182
 
133
183
  /**
134
184
  * Apply the `ngpRadioIndicator` directive to an element that represents the radio indicator (i.e. the dot).
135
185
  */
136
186
  class NgpRadioIndicator {
137
187
  constructor() {
138
- /**
139
- * Access the radio group state.
140
- */
141
- this.radioGroupState = injectRadioGroupState();
142
188
  /**
143
189
  * Access the radio group item state
144
190
  */
145
191
  this.radioItemState = injectRadioItemState();
146
192
  /**
147
- * Determine if the radio indicator is checked.
193
+ * Determine if the radio indicator is checked. Delegates to the item's
194
+ * checked state so it honours the group's `compareWith` comparator.
148
195
  */
149
- this.checked = computed(() => this.radioGroupState().value() === this.radioItemState().value(), ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
196
+ this.checked = computed(() => this.radioItemState().checked(), ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
150
197
  }
151
198
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgpRadioIndicator, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
152
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.14", type: NgpRadioIndicator, isStandalone: true, selector: "[ngpRadioIndicator]", host: { properties: { "attr.data-checked": "checked() ? \"\" : null", "attr.data-disabled": "radioItemState().disabled() ? \"\" : null" } }, hostDirectives: [{ directive: i2.NgpHover }, { directive: i2.NgpPress }], ngImport: i0 }); }
199
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.14", type: NgpRadioIndicator, isStandalone: true, selector: "[ngpRadioIndicator]", host: { properties: { "attr.data-checked": "checked() ? \"\" : null", "attr.data-disabled": "radioItemState().disabled() ? \"\" : null" } }, ngImport: i0 }); }
153
200
  }
154
201
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgpRadioIndicator, decorators: [{
155
202
  type: Directive,
@@ -159,7 +206,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
159
206
  '[attr.data-checked]': 'checked() ? "" : null',
160
207
  '[attr.data-disabled]': 'radioItemState().disabled() ? "" : null',
161
208
  },
162
- hostDirectives: [NgpHover, NgpPress],
163
209
  }]
164
210
  }] });
165
211
 
@@ -168,10 +214,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
168
214
  */
169
215
  class NgpRadioItem {
170
216
  constructor() {
171
- /**
172
- * Access the radio group state.
173
- */
174
- this.radioGroupState = injectRadioGroupState();
175
217
  /**
176
218
  * The value of the radio item.
177
219
  * @required
@@ -183,67 +225,31 @@ class NgpRadioItem {
183
225
  */
184
226
  this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), alias: 'ngpRadioItemDisabled',
185
227
  transform: booleanAttribute });
186
- /**
187
- * Whether the radio item is checked.
188
- */
189
- this.checked = computed(() => this.radioGroupState().compareWith()(this.radioGroupState().value(), this.state.value()), ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
190
- /**
191
- * The state of the radio item.
192
- */
193
- this.state = radioItemState(this);
228
+ ngpRadioItem({
229
+ value: this.value,
230
+ disabled: this.disabled,
231
+ });
232
+ ngpRovingFocusItem({ disabled: this.disabled });
194
233
  }
195
234
  ngOnInit() {
196
- if (this.state.value() === undefined) {
235
+ if (this.value() === undefined) {
197
236
  throw new Error('The `ngpRadioItem` directive requires a `value` input.');
198
237
  }
199
238
  }
200
- /**
201
- * When the item receives focus, select it.
202
- * @internal
203
- */
204
- onFocus() {
205
- if (this.state.disabled()) {
206
- return;
207
- }
208
- this.radioGroupState().select(this.state.value());
209
- }
210
- /**
211
- * When the item receives a click, select it.
212
- * @internal
213
- */
214
- onClick() {
215
- if (this.state.disabled()) {
216
- return;
217
- }
218
- this.radioGroupState().select(this.state.value());
219
- }
220
239
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgpRadioItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
221
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgpRadioItem, isStandalone: true, selector: "[ngpRadioItem]", inputs: { value: { classPropertyName: "value", publicName: "ngpRadioItemValue", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpRadioItemDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "radio" }, listeners: { "focus": "onFocus()", "click": "onClick()" }, properties: { "attr.aria-checked": "checked() ? \"true\" : \"false\"", "attr.data-disabled": "state.disabled() ? \"\" : null", "attr.data-checked": "checked() ? \"\" : null" } }, providers: [provideRadioItemState()], hostDirectives: [{ directive: i1.NgpRovingFocusItem }, { directive: i2.NgpHover }, { directive: i2.NgpFocusVisible }, { directive: i2.NgpPress }], ngImport: i0 }); }
240
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.14", type: NgpRadioItem, isStandalone: true, selector: "[ngpRadioItem]", inputs: { value: { classPropertyName: "value", publicName: "ngpRadioItemValue", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ngpRadioItemDisabled", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideRadioItemState(), provideRovingFocusItemState()], ngImport: i0 }); }
222
241
  }
223
242
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NgpRadioItem, decorators: [{
224
243
  type: Directive,
225
244
  args: [{
226
245
  selector: '[ngpRadioItem]',
227
- hostDirectives: [NgpRovingFocusItem, NgpHover, NgpFocusVisible, NgpPress],
228
- providers: [provideRadioItemState()],
229
- host: {
230
- role: 'radio',
231
- '[attr.aria-checked]': 'checked() ? "true" : "false"',
232
- '[attr.data-disabled]': 'state.disabled() ? "" : null',
233
- '[attr.data-checked]': 'checked() ? "" : null',
234
- },
246
+ providers: [provideRadioItemState(), provideRovingFocusItemState()],
235
247
  }]
236
- }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioItemValue", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioItemDisabled", required: false }] }], onFocus: [{
237
- type: HostListener,
238
- args: ['focus']
239
- }], onClick: [{
240
- type: HostListener,
241
- args: ['click']
242
- }] } });
248
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioItemValue", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngpRadioItemDisabled", required: false }] }] } });
243
249
 
244
250
  /**
245
251
  * Generated bundle index. Do not edit.
246
252
  */
247
253
 
248
- export { NgpRadioGroup, NgpRadioIndicator, NgpRadioItem, injectRadioGroupState, injectRadioItemState, provideRadioGroupState, provideRadioItemState };
254
+ export { NgpRadioGroup, NgpRadioIndicator, NgpRadioItem, injectRadioGroupState, injectRadioItemState, ngpRadioGroup, ngpRadioItem, provideRadioGroupState, provideRadioItemState };
249
255
  //# sourceMappingURL=ng-primitives-radio.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ng-primitives-radio.mjs","sources":["../../../../packages/ng-primitives/radio/src/radio-group/radio-group-state.ts","../../../../packages/ng-primitives/radio/src/radio-group/radio-group.ts","../../../../packages/ng-primitives/radio/src/radio-item/radio-item-state.ts","../../../../packages/ng-primitives/radio/src/radio-indicator/radio-indicator.ts","../../../../packages/ng-primitives/radio/src/radio-item/radio-item.ts","../../../../packages/ng-primitives/radio/src/ng-primitives-radio.ts"],"sourcesContent":["import {\n createState,\n createStateInjector,\n createStateProvider,\n createStateToken,\n InjectedState,\n} from 'ng-primitives/state';\nimport type { NgpRadioGroup } from './radio-group';\n\n/**\n * The state token for the RadioGroup primitive.\n */\nexport const NgpRadioGroupStateToken = createStateToken<NgpRadioGroup<unknown>>('RadioGroup');\n\n/**\n * Provides the RadioGroup state.\n */\nexport const provideRadioGroupState = createStateProvider(NgpRadioGroupStateToken);\n\n/**\n * Injects the RadioGroup state.\n */\nexport const injectRadioGroupState = createStateInjector<NgpRadioGroup<unknown>>(\n NgpRadioGroupStateToken,\n) as <T>() => InjectedState<NgpRadioGroup<T>>;\n\n/**\n * The RadioGroup state registration function.\n */\nexport const radioGroupState = createState(NgpRadioGroupStateToken);\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { booleanAttribute, Directive, input, OnInit, output } from '@angular/core';\nimport { NgpOrientation } from 'ng-primitives/common';\nimport { ngpFormControl } from 'ng-primitives/form-field';\nimport { injectRovingFocusGroupState, NgpRovingFocusGroup } from 'ng-primitives/roving-focus';\nimport { uniqueId } from 'ng-primitives/utils';\nimport { provideRadioGroupState, radioGroupState } from './radio-group-state';\n\n/**\n * Apply the `ngpRadioGroup` directive to an element that represents the group of radio items.\n */\n@Directive({\n selector: '[ngpRadioGroup]',\n providers: [provideRadioGroupState()],\n hostDirectives: [\n {\n directive: NgpRovingFocusGroup,\n inputs: [\n 'ngpRovingFocusGroupOrientation:ngpRadioGroupOrientation',\n 'ngpRovingFocusGroupDisabled:ngpRadioGroupDisabled',\n ],\n },\n ],\n host: {\n role: 'radiogroup',\n '[id]': 'id()',\n '[attr.aria-orientation]': 'state.orientation()',\n '[attr.data-orientation]': 'state.orientation()',\n '[attr.data-disabled]': 'state.disabled() ? \"\" : null',\n },\n})\nexport class NgpRadioGroup<T> implements OnInit {\n /**\n * Access the roving focus group state.\n */\n private readonly rovingFocusGroupState = injectRovingFocusGroupState();\n\n /**\n * The id of the radio group. If not provided, a unique id will be generated.\n */\n readonly id = input<string>(uniqueId('ngp-radio-group'));\n\n /**\n * The value of the radio group.\n */\n readonly value = input<T | null>(null, { alias: 'ngpRadioGroupValue' });\n\n /**\n * Event emitted when the radio group value changes.\n */\n readonly valueChange = output<T | null>({\n alias: 'ngpRadioGroupValueChange',\n });\n\n /**\n * Whether the radio group is disabled.\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpRadioGroupDisabled',\n transform: booleanAttribute,\n });\n\n /**\n * The orientation of the radio group.\n * @default 'horizontal'\n */\n readonly orientation = input<NgpOrientation>('horizontal', {\n alias: 'ngpRadioGroupOrientation',\n });\n\n /**\n * The comparator function for the radio group. This is useful if values are objects and you want to compare them by value, not by reference.\n * @default (a, b) => a === b\n */\n readonly compareWith = input<(a: T | null, b: T | null) => boolean>((a, b) => a === b, {\n alias: 'ngpRadioGroupCompareWith',\n });\n\n /**\n * The state of the radio group.\n * @internal\n */\n protected readonly state = radioGroupState<NgpRadioGroup<T>>(this);\n\n constructor() {\n ngpFormControl({ id: this.state.id, disabled: this.state.disabled });\n }\n\n ngOnInit(): void {\n // the roving focus group defaults to vertical orientation whereas we want to default to vertical\n this.rovingFocusGroupState()?.setOrientation(this.state.orientation());\n }\n\n /**\n * Select a radio item.\n * @param value The value of the radio item to select.\n */\n select(value: T): void {\n // if the value is already selected, do nothing\n if (this.state.compareWith()(this.state.value(), value)) {\n return;\n }\n\n this.state.value.set(value);\n this.valueChange.emit(value);\n }\n}\n","import {\n createState,\n createStateInjector,\n createStateProvider,\n createStateToken,\n InjectedState,\n} from 'ng-primitives/state';\nimport type { NgpRadioItem } from './radio-item';\n\n/**\n * The state token for the RadioItem primitive.\n */\nexport const NgpRadioItemStateToken = createStateToken<NgpRadioItem<unknown>>('RadioItem');\n\n/**\n * Provides the RadioItem state.\n */\nexport const provideRadioItemState = createStateProvider(NgpRadioItemStateToken);\n\n/**\n * Injects the RadioItem state.\n */\nexport const injectRadioItemState = createStateInjector<NgpRadioItem<unknown>>(\n NgpRadioItemStateToken,\n) as <T>() => InjectedState<NgpRadioItem<T>>;\n\n/**\n * The RadioItem state registration function.\n */\nexport const radioItemState = createState(NgpRadioItemStateToken);\n","import { Directive, computed } from '@angular/core';\nimport { NgpHover, NgpPress } from 'ng-primitives/interactions';\nimport { injectRadioGroupState } from '../radio-group/radio-group-state';\nimport { injectRadioItemState } from '../radio-item/radio-item-state';\n\n/**\n * Apply the `ngpRadioIndicator` directive to an element that represents the radio indicator (i.e. the dot).\n */\n@Directive({\n selector: '[ngpRadioIndicator]',\n host: {\n '[attr.data-checked]': 'checked() ? \"\" : null',\n '[attr.data-disabled]': 'radioItemState().disabled() ? \"\" : null',\n },\n hostDirectives: [NgpHover, NgpPress],\n})\nexport class NgpRadioIndicator<T> {\n /**\n * Access the radio group state.\n */\n protected readonly radioGroupState = injectRadioGroupState<T>();\n\n /**\n * Access the radio group item state\n */\n protected readonly radioItemState = injectRadioItemState<T>();\n\n /**\n * Determine if the radio indicator is checked.\n */\n protected readonly checked = computed(\n () => this.radioGroupState().value() === this.radioItemState().value(),\n );\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { Directive, HostListener, OnInit, booleanAttribute, computed, input } from '@angular/core';\nimport { NgpFocusVisible, NgpHover, NgpPress } from 'ng-primitives/interactions';\nimport { NgpRovingFocusItem } from 'ng-primitives/roving-focus';\nimport { injectRadioGroupState } from '../radio-group/radio-group-state';\nimport { provideRadioItemState, radioItemState } from './radio-item-state';\n\n/**\n * Apply the `ngpRadioItem` directive to an element that represents a radio item. This would typically be a `button` element.\n */\n@Directive({\n selector: '[ngpRadioItem]',\n hostDirectives: [NgpRovingFocusItem, NgpHover, NgpFocusVisible, NgpPress],\n providers: [provideRadioItemState()],\n host: {\n role: 'radio',\n '[attr.aria-checked]': 'checked() ? \"true\" : \"false\"',\n '[attr.data-disabled]': 'state.disabled() ? \"\" : null',\n '[attr.data-checked]': 'checked() ? \"\" : null',\n },\n})\nexport class NgpRadioItem<T> implements OnInit {\n /**\n * Access the radio group state.\n */\n private readonly radioGroupState = injectRadioGroupState<T>();\n\n /**\n * The value of the radio item.\n * @required\n */\n readonly value = input<T>(undefined, { alias: 'ngpRadioItemValue' });\n\n /**\n * Whether the radio item is disabled.\n * @default false\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpRadioItemDisabled',\n transform: booleanAttribute,\n });\n\n /**\n * Whether the radio item is checked.\n */\n readonly checked = computed(() =>\n this.radioGroupState().compareWith()(this.radioGroupState().value(), this.state.value()!),\n );\n\n /**\n * The state of the radio item.\n */\n protected readonly state = radioItemState<NgpRadioItem<T>>(this);\n\n ngOnInit(): void {\n if (this.state.value() === undefined) {\n throw new Error('The `ngpRadioItem` directive requires a `value` input.');\n }\n }\n\n /**\n * When the item receives focus, select it.\n * @internal\n */\n @HostListener('focus')\n protected onFocus(): void {\n if (this.state.disabled()) {\n return;\n }\n this.radioGroupState().select(this.state.value()!);\n }\n\n /**\n * When the item receives a click, select it.\n * @internal\n */\n @HostListener('click')\n protected onClick(): void {\n if (this.state.disabled()) {\n return;\n }\n this.radioGroupState().select(this.state.value()!);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1"],"mappings":"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"}
1
+ {"version":3,"file":"ng-primitives-radio.mjs","sources":["../../../../packages/ng-primitives/radio/src/radio-group/radio-group-state.ts","../../../../packages/ng-primitives/radio/src/radio-group/radio-group.ts","../../../../packages/ng-primitives/radio/src/radio-item/radio-item-state.ts","../../../../packages/ng-primitives/radio/src/radio-indicator/radio-indicator.ts","../../../../packages/ng-primitives/radio/src/radio-item/radio-item.ts","../../../../packages/ng-primitives/radio/src/ng-primitives-radio.ts"],"sourcesContent":["import { Signal, signal, WritableSignal } from '@angular/core';\nimport { NgpOrientation } from 'ng-primitives/common';\nimport { ngpFormControl } from 'ng-primitives/form-field';\nimport { injectElementRef } from 'ng-primitives/internal';\nimport { ngpRovingFocusGroup } from 'ng-primitives/roving-focus';\nimport {\n attrBinding,\n controlled,\n controlledState,\n createPrimitive,\n dataBinding,\n deprecatedSetter,\n SetterOptions,\n StateInjectionOptions,\n} from 'ng-primitives/state';\nimport { uniqueId } from 'ng-primitives/utils';\nimport { Observable } from 'rxjs';\n\n/**\n * Public state surface for the RadioGroup primitive.\n */\nexport interface NgpRadioGroupState<T> {\n /**\n * The id of the radio group.\n */\n readonly id: Signal<string>;\n /**\n * The selected value of the radio group.\n */\n readonly value: WritableSignal<T | null>;\n /**\n * Whether the radio group is disabled.\n */\n readonly disabled: WritableSignal<boolean>;\n /**\n * The orientation of the radio group.\n */\n readonly orientation: WritableSignal<NgpOrientation>;\n /**\n * The comparator function used to compare values.\n */\n readonly compareWith: Signal<(a: T | null, b: T | null) => boolean>;\n /**\n * Emits when the selected value changes.\n */\n readonly valueChange: Observable<T | null>;\n /**\n * Select a value in the radio group.\n */\n select(value: T): void;\n /**\n * Set the value of the radio group. Fires `onValueChange` and emits on the\n * `valueChange` observable by default. Pass `{ emit: false }` for cases like\n * form `writeValue` where the internal state should sync without notifying.\n */\n setValue(value: T | null, options?: SetterOptions): void;\n /**\n * Set the default value used for uncontrolled usage.\n */\n setDefaultValue(value: T | null): void;\n /**\n * Set the disabled value.\n */\n setDisabled(value: boolean): void;\n /**\n * Set the orientation of the radio group.\n */\n setOrientation(value: NgpOrientation): void;\n}\n\n/**\n * Inputs for configuring the RadioGroup primitive.\n */\nexport interface NgpRadioGroupProps<T> {\n /**\n * The id of the radio group.\n */\n readonly id?: Signal<string>;\n /**\n * The selected value of the radio group. Leave `undefined` for uncontrolled\n * usage (the group manages its own value from `defaultValue`).\n */\n readonly value?: Signal<T | null | undefined>;\n /**\n * The default value for uncontrolled usage.\n */\n readonly defaultValue?: Signal<T | null>;\n /**\n * Whether the radio group is disabled.\n */\n readonly disabled?: Signal<boolean>;\n /**\n * The orientation of the radio group.\n */\n readonly orientation?: Signal<NgpOrientation>;\n /**\n * The comparator function used to compare values.\n */\n readonly compareWith?: Signal<(a: T | null, b: T | null) => boolean>;\n /**\n * Callback fired when the selected value changes.\n */\n readonly onValueChange?: (value: T | null) => void;\n}\n\nexport const [\n NgpRadioGroupStateToken,\n ngpRadioGroup,\n _injectRadioGroupState,\n provideRadioGroupState,\n] = createPrimitive(\n 'NgpRadioGroup',\n <T>({\n id = signal(uniqueId('ngp-radio-group')),\n value: _value = signal<T | null | undefined>(undefined),\n defaultValue: _defaultValue,\n disabled: _disabled = signal(false),\n orientation: _orientation = signal<NgpOrientation>('horizontal'),\n compareWith = signal<(a: T | null, b: T | null) => boolean>((a, b) => a === b),\n onValueChange,\n }: NgpRadioGroupProps<T>): NgpRadioGroupState<T> => {\n const element = injectElementRef();\n const disabled = controlled(_disabled, false);\n const orientation = controlled(_orientation, 'horizontal');\n const defaultValue = controlled(_defaultValue, null);\n const [value, setValueInternal, valueChange] = controlledState<T | null>({\n value: _value,\n defaultValue,\n onChange: onValueChange,\n });\n\n // Own the roving focus group so it shares the group's `disabled` and\n // `orientation` signals directly. This keeps keyboard navigation in sync\n // with programmatic/form-driven changes (e.g. `setDisabled`, `setOrientation`)\n // without needing to re-push each value across a directive boundary.\n // `wrap` is always on to match the ARIA radio pattern (arrow keys cycle).\n ngpRovingFocusGroup({ orientation, disabled, wrap: signal(true) });\n\n ngpFormControl({ id, disabled });\n\n // Host bindings\n attrBinding(element, 'role', 'radiogroup');\n attrBinding(element, 'id', id);\n attrBinding(element, 'aria-orientation', orientation);\n dataBinding(element, 'data-orientation', orientation);\n dataBinding(element, 'data-disabled', disabled);\n\n function setValue(newValue: T | null, options?: SetterOptions): void {\n setValueInternal(newValue, options);\n }\n\n function select(newValue: T): void {\n // Guard on disabled and dedupe by the comparator so that re-selecting an\n // equal value (by `compareWith`, not just reference) is a no-op.\n if (disabled() || compareWith()(value(), newValue)) {\n return;\n }\n\n setValue(newValue);\n }\n\n function setDisabled(isDisabled: boolean): void {\n disabled.set(isDisabled);\n }\n\n function setOrientation(newOrientation: NgpOrientation): void {\n // The roving focus group shares this signal, so it stays in sync.\n orientation.set(newOrientation);\n }\n\n return {\n id,\n value: deprecatedSetter(value, 'setValue', newValue => setValue(newValue)),\n disabled: deprecatedSetter(disabled, 'setDisabled'),\n orientation: deprecatedSetter(orientation, 'setOrientation', setOrientation),\n compareWith,\n valueChange,\n select,\n setValue,\n setDefaultValue: defaultValue.set,\n setDisabled,\n setOrientation,\n } satisfies NgpRadioGroupState<T>;\n },\n);\n\n/**\n * Injects the RadioGroup state.\n */\nexport function injectRadioGroupState<T>(\n options?: StateInjectionOptions,\n): Signal<NgpRadioGroupState<T>> {\n return _injectRadioGroupState(options) as Signal<NgpRadioGroupState<T>>;\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { booleanAttribute, Directive, input, output } from '@angular/core';\nimport { NgpOrientation } from 'ng-primitives/common';\nimport { provideRovingFocusGroupState } from 'ng-primitives/roving-focus';\nimport { uniqueId } from 'ng-primitives/utils';\nimport { ngpRadioGroup, provideRadioGroupState } from './radio-group-state';\n\n/**\n * Apply the `ngpRadioGroup` directive to an element that represents the group of radio items.\n */\n@Directive({\n selector: '[ngpRadioGroup]',\n providers: [provideRadioGroupState(), provideRovingFocusGroupState()],\n})\nexport class NgpRadioGroup<T> {\n /**\n * The id of the radio group. If not provided, a unique id will be generated.\n */\n readonly id = input<string>(uniqueId('ngp-radio-group'));\n\n /**\n * The value of the radio group. Leave unset for uncontrolled usage.\n */\n readonly value = input<T | null | undefined>(undefined, { alias: 'ngpRadioGroupValue' });\n\n /**\n * The default value of the radio group for uncontrolled usage.\n */\n readonly defaultValue = input<T | null>(null, { alias: 'ngpRadioGroupDefaultValue' });\n\n /**\n * Event emitted when the radio group value changes.\n */\n readonly valueChange = output<T | null>({\n alias: 'ngpRadioGroupValueChange',\n });\n\n /**\n * Whether the radio group is disabled.\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpRadioGroupDisabled',\n transform: booleanAttribute,\n });\n\n /**\n * The orientation of the radio group.\n * @default 'horizontal'\n */\n readonly orientation = input<NgpOrientation>('horizontal', {\n alias: 'ngpRadioGroupOrientation',\n });\n\n /**\n * The comparator function for the radio group. This is useful if values are objects and you want to compare them by value, not by reference.\n * @default (a, b) => a === b\n */\n readonly compareWith = input<(a: T | null, b: T | null) => boolean>((a, b) => a === b, {\n alias: 'ngpRadioGroupCompareWith',\n });\n\n /**\n * The state of the radio group.\n */\n protected readonly state = ngpRadioGroup({\n id: this.id,\n value: this.value,\n defaultValue: this.defaultValue,\n disabled: this.disabled,\n orientation: this.orientation,\n compareWith: this.compareWith,\n onValueChange: value => this.valueChange.emit(value),\n });\n\n /**\n * Select a radio item.\n * @param value The value of the radio item to select.\n */\n select(value: T): void {\n this.state.select(value);\n }\n\n /**\n * Set the default value of the radio group.\n */\n setDefaultValue(value: T | null): void {\n this.state.setDefaultValue(value);\n }\n\n /**\n * Set the orientation of the radio group.\n */\n setOrientation(orientation: NgpOrientation): void {\n this.state.setOrientation(orientation);\n }\n}\n","import { computed, Signal, signal } from '@angular/core';\nimport { ngpInteractions } from 'ng-primitives/interactions';\nimport { injectElementRef } from 'ng-primitives/internal';\nimport {\n attrBinding,\n createPrimitive,\n dataBinding,\n listener,\n StateInjectionOptions,\n} from 'ng-primitives/state';\nimport { injectRadioGroupState } from '../radio-group/radio-group-state';\n\n/**\n * Public state surface for the RadioItem primitive.\n */\nexport interface NgpRadioItemState<T> {\n /**\n * The value of the radio item.\n */\n readonly value: Signal<T>;\n /**\n * Whether the radio item is disabled.\n */\n readonly disabled: Signal<boolean>;\n /**\n * Whether the radio item is checked.\n */\n readonly checked: Signal<boolean>;\n}\n\n/**\n * Inputs for configuring the RadioItem primitive.\n */\nexport interface NgpRadioItemProps<T> {\n /**\n * The value of the radio item.\n */\n readonly value: Signal<T>;\n /**\n * Whether the radio item is disabled.\n */\n readonly disabled?: Signal<boolean>;\n}\n\nexport const [NgpRadioItemStateToken, ngpRadioItem, _injectRadioItemState, provideRadioItemState] =\n createPrimitive(\n 'NgpRadioItem',\n <T>({ value, disabled = signal(false) }: NgpRadioItemProps<T>): NgpRadioItemState<T> => {\n const element = injectElementRef();\n const radioGroup = injectRadioGroupState<T>();\n\n const checked = computed(() => radioGroup().compareWith()(radioGroup().value(), value()));\n\n // Setup interactions\n ngpInteractions({ hover: true, press: true, focusVisible: true, disabled });\n\n // Host bindings\n attrBinding(element, 'role', 'radio');\n attrBinding(element, 'aria-checked', () => (checked() ? 'true' : 'false'));\n attrBinding(element, 'aria-disabled', disabled);\n dataBinding(element, 'data-disabled', disabled);\n dataBinding(element, 'data-checked', checked);\n\n function select(): void {\n if (disabled()) {\n return;\n }\n\n radioGroup().select(value());\n }\n\n // Event listeners\n listener(element, 'focus', select);\n listener(element, 'click', select);\n\n return { value, disabled, checked } satisfies NgpRadioItemState<T>;\n },\n );\n\n/**\n * Injects the RadioItem state.\n */\nexport function injectRadioItemState<T>(\n options?: StateInjectionOptions,\n): Signal<NgpRadioItemState<T>> {\n return _injectRadioItemState(options) as Signal<NgpRadioItemState<T>>;\n}\n","import { Directive, computed } from '@angular/core';\nimport { injectRadioItemState } from '../radio-item/radio-item-state';\n\n/**\n * Apply the `ngpRadioIndicator` directive to an element that represents the radio indicator (i.e. the dot).\n */\n@Directive({\n selector: '[ngpRadioIndicator]',\n host: {\n '[attr.data-checked]': 'checked() ? \"\" : null',\n '[attr.data-disabled]': 'radioItemState().disabled() ? \"\" : null',\n },\n})\nexport class NgpRadioIndicator<T> {\n /**\n * Access the radio group item state\n */\n protected readonly radioItemState = injectRadioItemState<T>();\n\n /**\n * Determine if the radio indicator is checked. Delegates to the item's\n * checked state so it honours the group's `compareWith` comparator.\n */\n protected readonly checked = computed(() => this.radioItemState().checked());\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { booleanAttribute, Directive, input, OnInit, Signal } from '@angular/core';\nimport { ngpRovingFocusItem, provideRovingFocusItemState } from 'ng-primitives/roving-focus';\nimport { ngpRadioItem, provideRadioItemState } from './radio-item-state';\n\n/**\n * Apply the `ngpRadioItem` directive to an element that represents a radio item. This would typically be a `button` element.\n */\n@Directive({\n selector: '[ngpRadioItem]',\n providers: [provideRadioItemState(), provideRovingFocusItemState()],\n})\nexport class NgpRadioItem<T> implements OnInit {\n /**\n * The value of the radio item.\n * @required\n */\n readonly value = input<T>(undefined, { alias: 'ngpRadioItemValue' });\n\n /**\n * Whether the radio item is disabled.\n * @default false\n */\n readonly disabled = input<boolean, BooleanInput>(false, {\n alias: 'ngpRadioItemDisabled',\n transform: booleanAttribute,\n });\n\n constructor() {\n ngpRadioItem({\n value: this.value as Signal<T>,\n disabled: this.disabled,\n });\n ngpRovingFocusItem({ disabled: this.disabled });\n }\n\n ngOnInit(): void {\n if (this.value() === undefined) {\n throw new Error('The `ngpRadioItem` directive requires a `value` input.');\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, inject, computed, signal, input, booleanAttribute, Directive, output } from '@angular/core';
3
- import { ngpRovingFocusItem, provideRovingFocusItemState, ngpRovingFocusGroup, provideRovingFocusGroupState } from 'ng-primitives/roving-focus';
3
+ import { ngpRovingFocusGroup, ngpRovingFocusItem, provideRovingFocusItemState, provideRovingFocusGroupState } from 'ng-primitives/roving-focus';
4
4
  import { injectElementRef } from 'ng-primitives/internal';
5
5
  import { createPrimitive, controlled, controlledState, attrBinding, dataBinding, deprecatedSetter, listener } from 'ng-primitives/state';
6
6
 
@@ -32,18 +32,24 @@ function injectToggleGroupConfig() {
32
32
  return inject(NgpToggleGroupConfigToken, { optional: true }) ?? defaultToggleGroupConfig;
33
33
  }
34
34
 
35
- const [NgpToggleGroupStateToken, ngpToggleGroup, injectToggleGroupState, provideToggleGroupState,] = createPrimitive('NgpToggleGroup', ({ rovingFocusGroup, orientation: _orientation, allowDeselection: _allowDeselection, type: _type, value: _value, defaultValue: _defaultValue, disabled: _disabled, onValueChange, }) => {
35
+ const [NgpToggleGroupStateToken, ngpToggleGroup, injectToggleGroupState, provideToggleGroupState,] = createPrimitive('NgpToggleGroup', ({ orientation: _orientation, wrap: _wrap, allowDeselection: _allowDeselection, type: _type, value: _value, defaultValue: _defaultValue, disabled: _disabled, onValueChange, }) => {
36
36
  const element = injectElementRef();
37
37
  const allowDeselection = controlled(_allowDeselection, true);
38
38
  const type = controlled(_type, 'single');
39
39
  const disabled = controlled(_disabled, false);
40
40
  const orientation = controlled(_orientation, 'horizontal');
41
+ const wrap = controlled(_wrap, true);
41
42
  const defaultValue = controlled(_defaultValue, []);
42
43
  const [value, setValueInternal, valueChange] = controlledState({
43
44
  value: _value,
44
45
  defaultValue,
45
46
  onChange: onValueChange,
46
47
  });
48
+ // Own the roving focus group so it shares the group's `disabled` and
49
+ // `orientation` signals directly. This keeps keyboard navigation in sync
50
+ // with programmatic/form-driven changes (e.g. `setDisabled`, `setOrientation`)
51
+ // without needing to re-push each value across a directive boundary.
52
+ ngpRovingFocusGroup({ orientation, disabled, wrap });
47
53
  // Host bindings
48
54
  attrBinding(element, 'role', 'group');
49
55
  dataBinding(element, 'data-orientation', orientation);
@@ -101,8 +107,8 @@ const [NgpToggleGroupStateToken, ngpToggleGroup, injectToggleGroupState, provide
101
107
  disabled.set(isDisabled);
102
108
  }
103
109
  function setOrientation(newOrientation) {
110
+ // The roving focus group shares this signal, so it stays in sync.
104
111
  orientation.set(newOrientation);
105
- rovingFocusGroup.setOrientation(newOrientation);
106
112
  }
107
113
  return {
108
114
  select,
@@ -228,12 +234,8 @@ class NgpToggleGroup {
228
234
  * The state of the toggle group.
229
235
  */
230
236
  this.state = ngpToggleGroup({
231
- rovingFocusGroup: ngpRovingFocusGroup({
232
- orientation: this.orientation,
233
- disabled: this.disabled,
234
- wrap: this.wrap,
235
- }),
236
237
  orientation: this.orientation,
238
+ wrap: this.wrap,
237
239
  allowDeselection: this.allowDeselection,
238
240
  type: this.type,
239
241
  value: this.value,