ngx-com 0.1.16 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/fesm2022/ngx-com-components-alert-testing.mjs +80 -0
  2. package/fesm2022/ngx-com-components-alert-testing.mjs.map +1 -0
  3. package/fesm2022/ngx-com-components-calendar-testing.mjs +157 -0
  4. package/fesm2022/ngx-com-components-calendar-testing.mjs.map +1 -0
  5. package/fesm2022/ngx-com-components-carousel-testing.mjs +121 -0
  6. package/fesm2022/ngx-com-components-carousel-testing.mjs.map +1 -0
  7. package/fesm2022/ngx-com-components-checkbox-testing.mjs +113 -0
  8. package/fesm2022/ngx-com-components-checkbox-testing.mjs.map +1 -0
  9. package/fesm2022/ngx-com-components-checkbox.mjs +2 -2
  10. package/fesm2022/ngx-com-components-checkbox.mjs.map +1 -1
  11. package/fesm2022/ngx-com-components-code-block-testing.mjs +88 -0
  12. package/fesm2022/ngx-com-components-code-block-testing.mjs.map +1 -0
  13. package/fesm2022/ngx-com-components-collapsible-testing.mjs +104 -0
  14. package/fesm2022/ngx-com-components-collapsible-testing.mjs.map +1 -0
  15. package/fesm2022/ngx-com-components-confirm-testing.mjs +150 -0
  16. package/fesm2022/ngx-com-components-confirm-testing.mjs.map +1 -0
  17. package/fesm2022/ngx-com-components-datepicker-testing.mjs +137 -0
  18. package/fesm2022/ngx-com-components-datepicker-testing.mjs.map +1 -0
  19. package/fesm2022/ngx-com-components-dialog-testing.mjs +109 -0
  20. package/fesm2022/ngx-com-components-dialog-testing.mjs.map +1 -0
  21. package/fesm2022/ngx-com-components-dialog.mjs +18 -18
  22. package/fesm2022/ngx-com-components-dialog.mjs.map +1 -1
  23. package/fesm2022/ngx-com-components-dropdown.mjs +39 -0
  24. package/fesm2022/ngx-com-components-dropdown.mjs.map +1 -1
  25. package/fesm2022/ngx-com-components-form-field-testing.mjs +140 -0
  26. package/fesm2022/ngx-com-components-form-field-testing.mjs.map +1 -0
  27. package/fesm2022/ngx-com-components-form-field.mjs +5 -1
  28. package/fesm2022/ngx-com-components-form-field.mjs.map +1 -1
  29. package/fesm2022/ngx-com-components-menu-testing.mjs +298 -0
  30. package/fesm2022/ngx-com-components-menu-testing.mjs.map +1 -0
  31. package/fesm2022/ngx-com-components-paginator-testing.mjs +128 -0
  32. package/fesm2022/ngx-com-components-paginator-testing.mjs.map +1 -0
  33. package/fesm2022/ngx-com-components-popover-testing.mjs +115 -0
  34. package/fesm2022/ngx-com-components-popover-testing.mjs.map +1 -0
  35. package/fesm2022/ngx-com-components-radio-testing.mjs +157 -0
  36. package/fesm2022/ngx-com-components-radio-testing.mjs.map +1 -0
  37. package/fesm2022/ngx-com-components-radio.mjs +2 -2
  38. package/fesm2022/ngx-com-components-radio.mjs.map +1 -1
  39. package/fesm2022/ngx-com-components-segmented-control-testing.mjs +122 -0
  40. package/fesm2022/ngx-com-components-segmented-control-testing.mjs.map +1 -0
  41. package/fesm2022/ngx-com-components-sort-testing.mjs +108 -0
  42. package/fesm2022/ngx-com-components-sort-testing.mjs.map +1 -0
  43. package/fesm2022/ngx-com-components-switch-testing.mjs +103 -0
  44. package/fesm2022/ngx-com-components-switch-testing.mjs.map +1 -0
  45. package/fesm2022/ngx-com-components-switch.mjs +2 -2
  46. package/fesm2022/ngx-com-components-switch.mjs.map +1 -1
  47. package/fesm2022/ngx-com-components-table-testing.mjs +198 -0
  48. package/fesm2022/ngx-com-components-table-testing.mjs.map +1 -0
  49. package/fesm2022/ngx-com-components-tabs-testing.mjs +126 -0
  50. package/fesm2022/ngx-com-components-tabs-testing.mjs.map +1 -0
  51. package/fesm2022/ngx-com-components-timepicker-testing.mjs +117 -0
  52. package/fesm2022/ngx-com-components-timepicker-testing.mjs.map +1 -0
  53. package/fesm2022/ngx-com-components-toast-testing.mjs +172 -0
  54. package/fesm2022/ngx-com-components-toast-testing.mjs.map +1 -0
  55. package/fesm2022/ngx-com-components-toast.mjs +4 -4
  56. package/fesm2022/ngx-com-components-toast.mjs.map +1 -1
  57. package/fesm2022/ngx-com-components-tooltip-testing.mjs +117 -0
  58. package/fesm2022/ngx-com-components-tooltip-testing.mjs.map +1 -0
  59. package/package.json +89 -1
  60. package/types/ngx-com-components-alert-testing.d.ts +41 -0
  61. package/types/ngx-com-components-calendar-testing.d.ts +80 -0
  62. package/types/ngx-com-components-carousel-testing.d.ts +51 -0
  63. package/types/ngx-com-components-checkbox-testing.d.ts +56 -0
  64. package/types/ngx-com-components-code-block-testing.d.ts +45 -0
  65. package/types/ngx-com-components-collapsible-testing.d.ts +53 -0
  66. package/types/ngx-com-components-confirm-testing.d.ts +78 -0
  67. package/types/ngx-com-components-datepicker-testing.d.ts +61 -0
  68. package/types/ngx-com-components-dialog-testing.d.ts +57 -0
  69. package/types/ngx-com-components-dropdown.d.ts +12 -0
  70. package/types/ngx-com-components-form-field-testing.d.ts +61 -0
  71. package/types/ngx-com-components-menu-testing.d.ts +167 -0
  72. package/types/ngx-com-components-paginator-testing.d.ts +58 -0
  73. package/types/ngx-com-components-popover-testing.d.ts +63 -0
  74. package/types/ngx-com-components-radio-testing.d.ts +86 -0
  75. package/types/ngx-com-components-segmented-control-testing.d.ts +66 -0
  76. package/types/ngx-com-components-sort-testing.d.ts +62 -0
  77. package/types/ngx-com-components-switch-testing.d.ts +52 -0
  78. package/types/ngx-com-components-table-testing.d.ts +124 -0
  79. package/types/ngx-com-components-tabs-testing.d.ts +67 -0
  80. package/types/ngx-com-components-timepicker-testing.d.ts +53 -0
  81. package/types/ngx-com-components-toast-testing.d.ts +93 -0
  82. package/types/ngx-com-components-tooltip-testing.d.ts +57 -0
@@ -0,0 +1,157 @@
1
+ import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
2
+
3
+ /**
4
+ * Harness for interacting with a radio button in tests.
5
+ */
6
+ class ComRadioButtonHarness extends ComponentHarness {
7
+ static hostSelector = 'com-radio';
8
+ label = this.locatorFor('label');
9
+ input = this.locatorFor('input[type="radio"]');
10
+ labelText = this.locatorFor('.com-radio__label');
11
+ /**
12
+ * Gets a HarnessPredicate for matching radio buttons.
13
+ * @param options Filter options.
14
+ */
15
+ static with(options = {}) {
16
+ return new HarnessPredicate(ComRadioButtonHarness, options)
17
+ .addOption('label', options.label, async (harness, label) => {
18
+ const text = await harness.getLabelText();
19
+ return HarnessPredicate.stringMatches(text, label);
20
+ })
21
+ .addOption('value', options.value, async (harness, value) => {
22
+ const val = await harness.getValue();
23
+ return HarnessPredicate.stringMatches(val, value);
24
+ })
25
+ .addOption('disabled', options.disabled, async (harness, disabled) => {
26
+ return (await harness.isDisabled()) === disabled;
27
+ })
28
+ .addOption('checked', options.checked, async (harness, checked) => {
29
+ return (await harness.isChecked()) === checked;
30
+ });
31
+ }
32
+ /** Whether the radio button is checked. */
33
+ async isChecked() {
34
+ const inputEl = await this.input();
35
+ return inputEl.getProperty('checked');
36
+ }
37
+ /** Whether the radio button is disabled. */
38
+ async isDisabled() {
39
+ const inputEl = await this.input();
40
+ return inputEl.getProperty('disabled');
41
+ }
42
+ /** Gets the radio button's label text. */
43
+ async getLabelText() {
44
+ const el = await this.labelText();
45
+ return el.text();
46
+ }
47
+ /** Gets the radio button's value. */
48
+ async getValue() {
49
+ const inputEl = await this.input();
50
+ return inputEl.getProperty('value');
51
+ }
52
+ /** Checks the radio button if it is not already checked. */
53
+ async check() {
54
+ if (!(await this.isChecked())) {
55
+ const labelEl = await this.label();
56
+ return labelEl.click();
57
+ }
58
+ }
59
+ /** Focuses the radio button's input. */
60
+ async focus() {
61
+ const inputEl = await this.input();
62
+ return inputEl.focus();
63
+ }
64
+ /** Blurs the radio button's input. */
65
+ async blur() {
66
+ const inputEl = await this.input();
67
+ return inputEl.blur();
68
+ }
69
+ /** Whether the radio button's input is focused. */
70
+ async isFocused() {
71
+ const inputEl = await this.input();
72
+ return inputEl.isFocused();
73
+ }
74
+ }
75
+ /**
76
+ * Harness for interacting with a radio group in tests.
77
+ */
78
+ class ComRadioGroupHarness extends ComponentHarness {
79
+ static hostSelector = 'com-radio-group';
80
+ radioGroup = this.locatorFor('[role="radiogroup"]');
81
+ errorMessage = this.locatorForOptional('.com-radio-group__error');
82
+ /**
83
+ * Gets a HarnessPredicate for matching radio groups.
84
+ * @param options Filter options.
85
+ */
86
+ static with(options = {}) {
87
+ return new HarnessPredicate(ComRadioGroupHarness, options)
88
+ .addOption('name', options.name, async (harness, name) => {
89
+ const groupName = await harness.getName();
90
+ return HarnessPredicate.stringMatches(groupName, name);
91
+ })
92
+ .addOption('disabled', options.disabled, async (harness, disabled) => {
93
+ return (await harness.isDisabled()) === disabled;
94
+ });
95
+ }
96
+ /** Gets all radio buttons in the group, optionally filtered. */
97
+ async getRadioButtons(filters = {}) {
98
+ return this.locatorForAll(ComRadioButtonHarness.with(filters))();
99
+ }
100
+ /** Gets the checked radio button, or null if none is checked. */
101
+ async getCheckedRadioButton() {
102
+ const buttons = await this.getRadioButtons({ checked: true });
103
+ return buttons[0] ?? null;
104
+ }
105
+ /** Gets the value of the checked radio button, or null if none is checked. */
106
+ async getCheckedValue() {
107
+ const checked = await this.getCheckedRadioButton();
108
+ return checked ? checked.getValue() : null;
109
+ }
110
+ /** Gets the name attribute of the radio group from the first radio input. */
111
+ async getName() {
112
+ const firstInput = await this.locatorForOptional('input[type="radio"]')();
113
+ return firstInput ? firstInput.getAttribute('name') : null;
114
+ }
115
+ /** Whether the radio group is disabled. */
116
+ async isDisabled() {
117
+ const host = await this.host();
118
+ return host.hasClass('com-radio-group--disabled');
119
+ }
120
+ /** Whether the radio group is required. */
121
+ async isRequired() {
122
+ const groupEl = await this.radioGroup();
123
+ return (await groupEl.getAttribute('aria-required')) === 'true';
124
+ }
125
+ /** Whether the radio group has an error state. */
126
+ async hasError() {
127
+ const host = await this.host();
128
+ return host.hasClass('com-radio-group--error');
129
+ }
130
+ /** Gets the error message text, or null if no error is displayed. */
131
+ async getErrorMessage() {
132
+ const errorEl = await this.errorMessage();
133
+ return errorEl ? errorEl.text() : null;
134
+ }
135
+ /** Gets the aria-label of the radio group. */
136
+ async getAriaLabel() {
137
+ const groupEl = await this.radioGroup();
138
+ return groupEl.getAttribute('aria-label');
139
+ }
140
+ /** Checks a radio button matching the given filter. */
141
+ async checkRadioButton(filter = {}) {
142
+ const buttons = await this.getRadioButtons(filter);
143
+ if (buttons.length === 0) {
144
+ throw new Error(`Could not find radio button matching filter: ${JSON.stringify(filter)}`);
145
+ }
146
+ return buttons[0].check();
147
+ }
148
+ }
149
+
150
+ // Testing utilities for the radio component
151
+
152
+ /**
153
+ * Generated bundle index. Do not edit.
154
+ */
155
+
156
+ export { ComRadioButtonHarness, ComRadioGroupHarness };
157
+ //# sourceMappingURL=ngx-com-components-radio-testing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-com-components-radio-testing.mjs","sources":["../../../projects/com/components/radio/testing/radio.harness.ts","../../../projects/com/components/radio/testing/index.ts","../../../projects/com/components/radio/testing/ngx-com-components-radio-testing.ts"],"sourcesContent":["import {\n ComponentHarness,\n HarnessPredicate,\n} from '@angular/cdk/testing';\nimport type { BaseHarnessFilters } from '@angular/cdk/testing';\n\n/** Harness filters for ComRadioButtonHarness. */\nexport interface ComRadioButtonHarnessFilters extends BaseHarnessFilters {\n /** Filter by the radio button's label text. */\n label?: string | RegExp;\n /** Filter by the radio button's value. */\n value?: string | RegExp;\n /** Filter by whether the radio button is disabled. */\n disabled?: boolean;\n /** Filter by whether the radio button is checked. */\n checked?: boolean;\n}\n\n/** Harness filters for ComRadioGroupHarness. */\nexport interface ComRadioGroupHarnessFilters extends BaseHarnessFilters {\n /** Filter by the radio group's name. */\n name?: string | RegExp;\n /** Filter by whether the radio group is disabled. */\n disabled?: boolean;\n}\n\n/**\n * Harness for interacting with a radio button in tests.\n */\nexport class ComRadioButtonHarness extends ComponentHarness {\n static hostSelector = 'com-radio';\n\n private readonly label = this.locatorFor('label');\n private readonly input = this.locatorFor('input[type=\"radio\"]');\n private readonly labelText = this.locatorFor('.com-radio__label');\n\n /**\n * Gets a HarnessPredicate for matching radio buttons.\n * @param options Filter options.\n */\n static with(options: ComRadioButtonHarnessFilters = {}): HarnessPredicate<ComRadioButtonHarness> {\n return new HarnessPredicate(ComRadioButtonHarness, options)\n .addOption('label', options.label, async (harness, label) => {\n const text = await harness.getLabelText();\n return HarnessPredicate.stringMatches(text, label);\n })\n .addOption('value', options.value, async (harness, value) => {\n const val = await harness.getValue();\n return HarnessPredicate.stringMatches(val, value);\n })\n .addOption('disabled', options.disabled, async (harness, disabled) => {\n return (await harness.isDisabled()) === disabled;\n })\n .addOption('checked', options.checked, async (harness, checked) => {\n return (await harness.isChecked()) === checked;\n });\n }\n\n /** Whether the radio button is checked. */\n async isChecked(): Promise<boolean> {\n const inputEl = await this.input();\n return inputEl.getProperty<boolean>('checked');\n }\n\n /** Whether the radio button is disabled. */\n async isDisabled(): Promise<boolean> {\n const inputEl = await this.input();\n return inputEl.getProperty<boolean>('disabled');\n }\n\n /** Gets the radio button's label text. */\n async getLabelText(): Promise<string> {\n const el = await this.labelText();\n return el.text();\n }\n\n /** Gets the radio button's value. */\n async getValue(): Promise<string> {\n const inputEl = await this.input();\n return inputEl.getProperty<string>('value');\n }\n\n /** Checks the radio button if it is not already checked. */\n async check(): Promise<void> {\n if (!(await this.isChecked())) {\n const labelEl = await this.label();\n return labelEl.click();\n }\n }\n\n /** Focuses the radio button's input. */\n async focus(): Promise<void> {\n const inputEl = await this.input();\n return inputEl.focus();\n }\n\n /** Blurs the radio button's input. */\n async blur(): Promise<void> {\n const inputEl = await this.input();\n return inputEl.blur();\n }\n\n /** Whether the radio button's input is focused. */\n async isFocused(): Promise<boolean> {\n const inputEl = await this.input();\n return inputEl.isFocused();\n }\n}\n\n/**\n * Harness for interacting with a radio group in tests.\n */\nexport class ComRadioGroupHarness extends ComponentHarness {\n static hostSelector = 'com-radio-group';\n\n private readonly radioGroup = this.locatorFor('[role=\"radiogroup\"]');\n private readonly errorMessage = this.locatorForOptional('.com-radio-group__error');\n\n /**\n * Gets a HarnessPredicate for matching radio groups.\n * @param options Filter options.\n */\n static with(options: ComRadioGroupHarnessFilters = {}): HarnessPredicate<ComRadioGroupHarness> {\n return new HarnessPredicate(ComRadioGroupHarness, options)\n .addOption('name', options.name, async (harness, name) => {\n const groupName = await harness.getName();\n return HarnessPredicate.stringMatches(groupName, name);\n })\n .addOption('disabled', options.disabled, async (harness, disabled) => {\n return (await harness.isDisabled()) === disabled;\n });\n }\n\n /** Gets all radio buttons in the group, optionally filtered. */\n async getRadioButtons(filters: ComRadioButtonHarnessFilters = {}): Promise<ComRadioButtonHarness[]> {\n return this.locatorForAll(ComRadioButtonHarness.with(filters))();\n }\n\n /** Gets the checked radio button, or null if none is checked. */\n async getCheckedRadioButton(): Promise<ComRadioButtonHarness | null> {\n const buttons = await this.getRadioButtons({ checked: true });\n return buttons[0] ?? null;\n }\n\n /** Gets the value of the checked radio button, or null if none is checked. */\n async getCheckedValue(): Promise<string | null> {\n const checked = await this.getCheckedRadioButton();\n return checked ? checked.getValue() : null;\n }\n\n /** Gets the name attribute of the radio group from the first radio input. */\n async getName(): Promise<string | null> {\n const firstInput = await this.locatorForOptional('input[type=\"radio\"]')();\n return firstInput ? firstInput.getAttribute('name') : null;\n }\n\n /** Whether the radio group is disabled. */\n async isDisabled(): Promise<boolean> {\n const host = await this.host();\n return host.hasClass('com-radio-group--disabled');\n }\n\n /** Whether the radio group is required. */\n async isRequired(): Promise<boolean> {\n const groupEl = await this.radioGroup();\n return (await groupEl.getAttribute('aria-required')) === 'true';\n }\n\n /** Whether the radio group has an error state. */\n async hasError(): Promise<boolean> {\n const host = await this.host();\n return host.hasClass('com-radio-group--error');\n }\n\n /** Gets the error message text, or null if no error is displayed. */\n async getErrorMessage(): Promise<string | null> {\n const errorEl = await this.errorMessage();\n return errorEl ? errorEl.text() : null;\n }\n\n /** Gets the aria-label of the radio group. */\n async getAriaLabel(): Promise<string | null> {\n const groupEl = await this.radioGroup();\n return groupEl.getAttribute('aria-label');\n }\n\n /** Checks a radio button matching the given filter. */\n async checkRadioButton(filter: ComRadioButtonHarnessFilters = {}): Promise<void> {\n const buttons = await this.getRadioButtons(filter);\n if (buttons.length === 0) {\n throw new Error(`Could not find radio button matching filter: ${JSON.stringify(filter)}`);\n }\n return buttons[0]!.check();\n }\n}\n","// Testing utilities for the radio component\n\nexport {\n ComRadioButtonHarness,\n ComRadioGroupHarness,\n} from './radio.harness';\n\nexport type {\n ComRadioButtonHarnessFilters,\n ComRadioGroupHarnessFilters,\n} from './radio.harness';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -530,7 +530,7 @@ class ComRadio {
530
530
  this.changed.emit({ value: this.value(), source: this });
531
531
  }
532
532
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComRadio, deps: [], target: i0.ɵɵFactoryTarget.Component });
533
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.0", type: ComRadio, isStandalone: true, selector: "com-radio", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", changed: "changed" }, host: { properties: { "class.com-radio--disabled": "isDisabled()", "class.com-radio--checked": "isChecked()" }, classAttribute: "com-radio inline-block align-middle" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputElement"], descendants: true, isSignal: true }], exportAs: ["comRadio"], ngImport: i0, template: `
533
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.0", type: ComRadio, isStandalone: true, selector: "com-radio", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "aria-describedby", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", changed: "changed" }, host: { properties: { "class.com-radio--disabled": "isDisabled()", "class.com-radio--checked": "isChecked()" }, classAttribute: "com-radio inline-flex align-middle" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputElement"], descendants: true, isSignal: true }], exportAs: ["comRadio"], ngImport: i0, template: `
534
534
  <label
535
535
  class="group relative inline-flex items-center"
536
536
  [class.cursor-pointer]="!isDisabled()"
@@ -611,7 +611,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
611
611
  </span>
612
612
  </label>
613
613
  `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
614
- class: 'com-radio inline-block align-middle',
614
+ class: 'com-radio inline-flex align-middle',
615
615
  '[class.com-radio--disabled]': 'isDisabled()',
616
616
  '[class.com-radio--checked]': 'isChecked()',
617
617
  }, styles: [".sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-com-components-radio.mjs","sources":["../../../projects/com/components/radio/radio.variants.ts","../../../projects/com/components/radio/radio.utils.ts","../../../projects/com/components/radio/radio-group.component.ts","../../../projects/com/components/radio/radio.component.ts","../../../projects/com/components/radio/index.ts","../../../projects/com/components/radio/ngx-com-components-radio.ts"],"sourcesContent":["import { cva } from 'class-variance-authority';\n\n/** Radio size variants. */\nexport type RadioSize = 'sm' | 'md' | 'lg';\n\n/** Radio color variants. */\nexport type RadioVariant = 'primary' | 'accent' | 'warn';\n\n/** Radio group orientation. */\nexport type RadioOrientation = 'vertical' | 'horizontal';\n\n/**\n * CVA variants for the visual radio circle.\n *\n * Uses `peer` selectors to style based on native input state:\n * - `peer-checked:` for checked state\n * - `peer-focus-visible:` for keyboard focus\n * - `peer-disabled:` for disabled state\n *\n * @tokens `--color-border`, `--color-primary`, `--color-primary-hover`,\n * `--color-accent`, `--color-accent-hover`,\n * `--color-warn`, `--color-warn-hover`,\n * `--color-disabled`, `--color-ring`\n */\nexport const radioCircleVariants: (props?: {\n variant?: RadioVariant;\n size?: RadioSize;\n}) => string = cva(\n [\n 'com-radio__circle',\n 'inline-flex shrink-0 items-center justify-center',\n 'rounded-pill border-2 border-border',\n 'transition-colors duration-normal',\n 'peer-focus-visible:outline-[1px] peer-focus-visible:outline-offset-2 peer-focus-visible:outline-ring',\n 'peer-disabled:cursor-not-allowed peer-disabled:border-disabled peer-disabled:bg-disabled',\n ],\n {\n variants: {\n variant: {\n primary: [\n 'peer-checked:border-primary peer-checked:bg-primary peer-checked:text-primary-foreground',\n 'group-hover:border-primary-hover',\n 'peer-checked:group-hover:bg-primary-hover peer-checked:group-hover:border-primary-hover',\n ],\n accent: [\n 'peer-checked:border-accent peer-checked:bg-accent peer-checked:text-accent-foreground',\n 'group-hover:border-accent-hover',\n 'peer-checked:group-hover:bg-accent-hover peer-checked:group-hover:border-accent-hover',\n ],\n warn: [\n 'peer-checked:border-warn peer-checked:bg-warn peer-checked:text-warn-foreground',\n 'group-hover:border-warn-hover',\n 'peer-checked:group-hover:bg-warn-hover peer-checked:group-hover:border-warn-hover',\n ],\n },\n size: {\n sm: 'size-4',\n md: 'size-5',\n lg: 'size-6',\n },\n },\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n },\n }\n);\n\n/** Size-based classes for the inner dot indicator. */\nexport const RADIO_DOT_SIZES: Record<RadioSize, string> = {\n sm: 'size-1.5',\n md: 'size-2',\n lg: 'size-2.5',\n};\n\n/** Size-based classes for the label content. */\nexport const RADIO_LABEL_SIZES: Record<RadioSize, string> = {\n sm: 'text-sm ms-2',\n md: 'text-base ms-2.5',\n lg: 'text-lg ms-3',\n};\n\n/** Base classes for the radio group container. */\nconst RADIO_GROUP_BASE = 'com-radio-group__container flex';\n\n/** Orientation-based classes for the radio group container. */\nexport const RADIO_GROUP_ORIENTATIONS: Record<RadioOrientation, string> = {\n vertical: `${RADIO_GROUP_BASE} flex-col gap-2`,\n horizontal: `${RADIO_GROUP_BASE} flex-row flex-wrap gap-4`,\n};\n","/** Auto-incrementing ID counter for unique radio IDs. */\nlet nextRadioId = 0;\n\n/** Generates a unique radio ID. */\nexport function generateRadioId(): string {\n return `com-radio-${nextRadioId++}`;\n}\n\n/** Auto-incrementing ID counter for unique radio group IDs. */\nlet nextGroupId = 0;\n\n/** Generates a unique radio group ID. */\nexport function generateRadioGroupId(): string {\n return `com-radio-group-${nextGroupId++}`;\n}\n","import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n InjectionToken,\n input,\n linkedSignal,\n model,\n output,\n signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport type {\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n WritableSignal,\n} from '@angular/core';\nimport { FormGroupDirective, NgControl, NgForm } from '@angular/forms';\nimport type { ControlValueAccessor } from '@angular/forms';\nimport { ErrorStateMatcher } from 'ngx-com/components/form-field';\nimport { RADIO_GROUP_ORIENTATIONS } from './radio.variants';\nimport type { RadioOrientation, RadioSize, RadioVariant } from './radio.variants';\nimport { generateRadioGroupId } from './radio.utils';\n\n/** Event emitted when radio group value changes. */\nexport interface RadioGroupChange {\n value: string | null;\n}\n\n/** Interface for radio items that register with the group. */\nexport interface RadioItem {\n value: () => string;\n isDisabled: () => boolean;\n focus: () => void;\n}\n\n/** Context provided to child radio components via DI. */\nexport interface ComRadioGroupContext {\n name: Signal<string>;\n value: Signal<string | null>;\n disabled: Signal<boolean>;\n size: Signal<RadioSize>;\n variant: Signal<RadioVariant>;\n orientation: Signal<RadioOrientation>;\n focusedValue: Signal<string | null>;\n select: (value: string) => void;\n focusNext: (currentValue: string) => void;\n focusPrevious: (currentValue: string) => void;\n register: (radio: RadioItem) => void;\n unregister: (radio: RadioItem) => void;\n onTouched?: () => void;\n}\n\n/** Injection token for radio group context. */\nexport const COM_RADIO_GROUP: InjectionToken<ComRadioGroupContext> = new InjectionToken<ComRadioGroupContext>('COM_RADIO_GROUP');\n\n/**\n * Radio group component that manages a set of radio buttons.\n *\n * Provides mutual exclusion, shared name, and roving tabindex keyboard navigation.\n * Implements `ControlValueAccessor` for Reactive Forms integration.\n *\n * @tokens `--color-border`, `--color-primary`, `--color-primary-foreground`, `--color-primary-hover`,\n * `--color-accent`, `--color-accent-foreground`, `--color-accent-hover`,\n * `--color-warn`, `--color-warn-foreground`, `--color-warn-hover`,\n * `--color-disabled`, `--color-disabled-foreground`, `--color-ring`\n *\n * @example Basic usage\n * ```html\n * <com-radio-group [(value)]=\"selectedFruit\" aria-label=\"Select a fruit\">\n * <com-radio value=\"apple\">Apple</com-radio>\n * <com-radio value=\"banana\">Banana</com-radio>\n * <com-radio value=\"cherry\">Cherry</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example With reactive forms\n * ```html\n * <com-radio-group formControlName=\"size\" aria-label=\"Select size\">\n * <com-radio value=\"sm\">Small</com-radio>\n * <com-radio value=\"md\">Medium</com-radio>\n * <com-radio value=\"lg\">Large</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example Horizontal orientation\n * ```html\n * <com-radio-group [(value)]=\"color\" orientation=\"horizontal\">\n * <com-radio value=\"red\">Red</com-radio>\n * <com-radio value=\"green\">Green</com-radio>\n * <com-radio value=\"blue\">Blue</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example With variants\n * ```html\n * <com-radio-group [(value)]=\"priority\" variant=\"warn\" size=\"lg\">\n * <com-radio value=\"low\">Low</com-radio>\n * <com-radio value=\"medium\">Medium</com-radio>\n * <com-radio value=\"high\">High</com-radio>\n * </com-radio-group>\n * ```\n */\n@Component({\n selector: 'com-radio-group',\n exportAs: 'comRadioGroup',\n template: `\n <div\n role=\"radiogroup\"\n [class]=\"groupClasses()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"computedAriaDescribedby()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"errorState() || null\"\n >\n <ng-content />\n </div>\n @if (errorState() && errorMessage()) {\n <div\n [id]=\"errorId\"\n class=\"com-radio-group__error mt-1.5 text-sm text-warn\"\n role=\"alert\"\n >\n {{ errorMessage() }}\n </div>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n providers: [\n {\n provide: COM_RADIO_GROUP,\n useFactory: () => {\n const group = inject(ComRadioGroup);\n return group.createContext();\n },\n },\n ],\n host: {\n class: 'com-radio-group block',\n '[class.com-radio-group--disabled]': 'disabled()',\n '[class.com-radio-group--error]': 'errorState()',\n },\n})\nexport class ComRadioGroup implements ControlValueAccessor {\n /** Optional NgControl for reactive forms integration. */\n readonly ngControl: NgControl | null = inject(NgControl, { optional: true, self: true });\n\n /** Error state matcher for determining when to show validation errors. */\n private readonly defaultErrorStateMatcher: ErrorStateMatcher = inject(ErrorStateMatcher);\n private readonly parentForm: NgForm | null = inject(NgForm, { optional: true });\n private readonly parentFormGroup: FormGroupDirective | null = inject(FormGroupDirective, { optional: true });\n\n /** Unique ID for this radio group instance. */\n private readonly uniqueId: string = generateRadioGroupId();\n\n /** ID for the error message element. */\n readonly errorId: string = `${this.uniqueId}-error`;\n\n /** Registered radio items. */\n private readonly registeredRadios: WritableSignal<RadioItem[]> = signal([]);\n\n // Inputs\n readonly name: InputSignal<string> = input<string>(this.uniqueId);\n readonly value: ModelSignal<string | null> = model<string | null>(null);\n readonly disabled: ModelSignal<boolean> = model<boolean>(false);\n readonly required: InputSignalWithTransform<boolean, unknown> = input(false, {\n transform: booleanAttribute,\n });\n readonly orientation: InputSignal<RadioOrientation> = input<RadioOrientation>('vertical');\n readonly size: InputSignal<RadioSize> = input<RadioSize>('md');\n readonly variant: InputSignal<RadioVariant> = input<RadioVariant>('primary');\n readonly errorMessage: InputSignal<string> = input<string>('');\n readonly errorStateMatcher: InputSignal<ErrorStateMatcher | undefined> = input<ErrorStateMatcher>();\n\n /** Tracks touched state — writable by both CVA callback and Signal Forms [formField]. */\n readonly touched: ModelSignal<boolean> = model<boolean>(false);\n\n // Signal Forms inputs — set automatically by [formField] via setInputOnDirectives\n readonly invalid: InputSignal<boolean> = input<boolean>(false);\n readonly sfErrors: InputSignal<readonly unknown[]> = input<readonly unknown[]>([], { alias: 'errors' });\n\n readonly ariaLabel: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-label' });\n readonly ariaLabelledby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-labelledby' });\n readonly ariaDescribedby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-describedby' });\n\n // Outputs\n /** Emits when the selection changes, with full event details. */\n readonly selectionChange: OutputEmitterRef<RadioGroupChange> = output<RadioGroupChange>();\n\n /**\n * Tracks the currently focused radio value for roving tabindex.\n * Resets to the current selection (or first focusable) when value or radios change.\n */\n private readonly focusedValueSignal: WritableSignal<string | null> = linkedSignal({\n source: () => ({ value: this.value(), radios: this.registeredRadios() }),\n computation: ({ value, radios }) => {\n if (value && radios.some((r) => r.value() === value && !r.isDisabled())) {\n return value;\n }\n const firstFocusable = radios.find((r) => !r.isDisabled());\n return firstFocusable?.value() ?? null;\n },\n });\n\n // Computed\n /**\n * Computed error state derived from form validation.\n * Shows errors when control is invalid and touched/submitted.\n */\n readonly errorState: Signal<boolean> = computed(() => {\n if (!this.ngControl) {\n // Signal Forms: gate on invalid AND touched (mirrors ErrorStateMatcher default)\n return this.invalid() && this.touched();\n }\n // Reactive Forms: use ErrorStateMatcher (existing logic)\n this.touched();\n const matcher = this.errorStateMatcher() ?? this.defaultErrorStateMatcher;\n const form = this.parentFormGroup ?? this.parentForm;\n return matcher.isErrorState(this.ngControl.control ?? null, form);\n });\n\n readonly computedAriaDescribedby: Signal<string | null> = computed(() => {\n const userDescribedby = this.ariaDescribedby();\n if (this.errorState() && this.errorMessage()) {\n return userDescribedby ? `${userDescribedby} ${this.errorId}` : this.errorId;\n }\n return userDescribedby;\n });\n\n protected readonly groupClasses: Signal<string> = computed(() =>\n RADIO_GROUP_ORIENTATIONS[this.orientation()]\n );\n\n // CVA callbacks\n private onChange: (value: string | null) => void = () => {};\n private onTouchedCallback: () => void = () => {};\n\n constructor() {\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n /** Creates the context object for child radios. */\n createContext(): ComRadioGroupContext {\n return {\n name: this.name,\n value: this.value,\n disabled: this.disabled,\n size: this.size,\n variant: this.variant,\n orientation: this.orientation,\n focusedValue: this.focusedValueSignal,\n select: this.select.bind(this),\n focusNext: this.focusNext.bind(this),\n focusPrevious: this.focusPrevious.bind(this),\n register: this.register.bind(this),\n unregister: this.unregister.bind(this),\n onTouched: () => this.onTouchedCallback(),\n };\n }\n\n /** Register a radio item with the group. */\n private register(radio: RadioItem): void {\n this.registeredRadios.update((radios) => [...radios, radio]);\n }\n\n /** Unregister a radio item from the group. */\n private unregister(radio: RadioItem): void {\n this.registeredRadios.update((radios) => radios.filter((r) => r !== radio));\n }\n\n // ControlValueAccessor implementation\n writeValue(value: string | null): void {\n this.value.set(value);\n }\n\n registerOnChange(fn: (value: string | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouchedCallback = () => {\n this.touched.set(true);\n fn();\n };\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled.set(isDisabled);\n }\n\n // Public API\n /** Selects a radio by value. */\n select(newValue: string): void {\n if (this.disabled()) {\n return;\n }\n this.value.set(newValue);\n this.focusedValueSignal.set(newValue);\n this.onChange(newValue);\n this.selectionChange.emit({ value: newValue });\n }\n\n /** Focuses the next non-disabled radio (with cyclic wrap). */\n focusNext(currentValue: string): void {\n const allRadios = this.registeredRadios();\n const focusableRadios = allRadios.filter((r) => !r.isDisabled());\n\n if (focusableRadios.length === 0) {\n return;\n }\n\n const currentIndex = focusableRadios.findIndex((r) => r.value() === currentValue);\n const nextIndex = (currentIndex + 1) % focusableRadios.length;\n const nextRadio = focusableRadios[nextIndex];\n\n if (nextRadio) {\n this.focusedValueSignal.set(nextRadio.value());\n this.select(nextRadio.value());\n nextRadio.focus();\n }\n }\n\n /** Focuses the previous non-disabled radio (with cyclic wrap). */\n focusPrevious(currentValue: string): void {\n const allRadios = this.registeredRadios();\n const focusableRadios = allRadios.filter((r) => !r.isDisabled());\n\n if (focusableRadios.length === 0) {\n return;\n }\n\n const currentIndex = focusableRadios.findIndex((r) => r.value() === currentValue);\n const prevIndex = (currentIndex - 1 + focusableRadios.length) % focusableRadios.length;\n const prevRadio = focusableRadios[prevIndex];\n\n if (prevRadio) {\n this.focusedValueSignal.set(prevRadio.value());\n this.select(prevRadio.value());\n prevRadio.focus();\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n model,\n output,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport type {\n InputSignal,\n ModelSignal,\n OnInit,\n OutputEmitterRef,\n Signal,\n} from '@angular/core';\nimport {\n radioCircleVariants,\n RADIO_DOT_SIZES,\n RADIO_LABEL_SIZES,\n} from './radio.variants';\nimport type { RadioSize, RadioVariant } from './radio.variants';\nimport { generateRadioId } from './radio.utils';\nimport { COM_RADIO_GROUP, type ComRadioGroupContext, type RadioItem } from './radio-group.component';\n\n/** Event emitted when a radio is selected. */\nexport interface RadioChange {\n value: string;\n source: ComRadio;\n}\n\n/**\n * Production-grade radio component with full accessibility support.\n *\n * Uses a native `<input type=\"radio\">` for built-in keyboard handling,\n * `:checked` pseudo-class, and screen reader support.\n *\n * Must be used within a `ComRadioGroup` which manages the selected value\n * and provides the shared `name` attribute.\n *\n * @tokens `--color-border`, `--color-primary`, `--color-primary-foreground`, `--color-primary-hover`,\n * `--color-accent`, `--color-accent-foreground`, `--color-accent-hover`,\n * `--color-warn`, `--color-warn-foreground`, `--color-warn-hover`,\n * `--color-disabled`, `--color-disabled-foreground`, `--color-ring`\n *\n * @example Basic usage within a group\n * ```html\n * <com-radio-group [(value)]=\"selectedOption\">\n * <com-radio value=\"option1\">Option 1</com-radio>\n * <com-radio value=\"option2\">Option 2</com-radio>\n * <com-radio value=\"option3\">Option 3</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example Disabled option\n * ```html\n * <com-radio-group [(value)]=\"selected\">\n * <com-radio value=\"enabled\">Enabled option</com-radio>\n * <com-radio value=\"disabled\" [disabled]=\"true\">Disabled option</com-radio>\n * </com-radio-group>\n * ```\n */\n@Component({\n selector: 'com-radio',\n exportAs: 'comRadio',\n template: `\n <label\n class=\"group relative inline-flex items-center\"\n [class.cursor-pointer]=\"!isDisabled()\"\n [class.cursor-not-allowed]=\"isDisabled()\"\n >\n <span><input\n #inputElement\n type=\"radio\"\n class=\"peer sr-only\"\n [id]=\"inputId()\"\n [checked]=\"isChecked()\"\n [disabled]=\"isDisabled()\"\n [attr.name]=\"groupName()\"\n [attr.value]=\"value()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n [attr.tabindex]=\"tabIndex()\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeyDown($event)\"\n /></span>\n <div [class]=\"circleClasses()\">\n <div\n class=\"com-radio__dot rounded-pill bg-current transition-transform duration-normal peer-disabled:bg-disabled-foreground\"\n [class]=\"dotSizeClass()\"\n [class.scale-100]=\"isChecked()\"\n [class.scale-0]=\"!isChecked()\"\n ></div>\n </div>\n <span\n class=\"com-radio__label select-none peer-disabled:cursor-not-allowed peer-disabled:text-disabled-foreground\"\n [class]=\"labelSizeClass()\"\n >\n <ng-content />\n </span>\n </label>\n `,\n styles: `\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'com-radio inline-block align-middle',\n '[class.com-radio--disabled]': 'isDisabled()',\n '[class.com-radio--checked]': 'isChecked()',\n },\n})\nexport class ComRadio implements OnInit, RadioItem {\n /** Optional parent radio group context. */\n private readonly group: ComRadioGroupContext | null = inject(COM_RADIO_GROUP, {\n optional: true,\n });\n\n /** DestroyRef for cleanup. */\n private readonly destroyRef: DestroyRef = inject(DestroyRef);\n\n /** Reference to the native input element. */\n readonly inputRef: Signal<ElementRef<HTMLInputElement> | undefined> =\n viewChild<ElementRef<HTMLInputElement>>('inputElement');\n\n /** Unique ID for this radio instance. */\n private readonly uniqueId: string = generateRadioId();\n\n // Inputs\n readonly value: InputSignal<string> = input.required<string>();\n readonly size: InputSignal<RadioSize> = input<RadioSize>('md');\n readonly variant: InputSignal<RadioVariant> = input<RadioVariant>('primary');\n readonly disabled: ModelSignal<boolean> = model<boolean>(false);\n readonly id: InputSignal<string | undefined> = input<string>();\n readonly ariaLabel: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-label' });\n readonly ariaLabelledby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-labelledby' });\n readonly ariaDescribedby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-describedby' });\n\n // Outputs\n readonly changed: OutputEmitterRef<RadioChange> = output<RadioChange>();\n\n // Computed state\n readonly inputId: Signal<string> = computed(() => this.id() ?? this.uniqueId);\n\n /** Resolve size from group or local input. */\n readonly resolvedSize: Signal<RadioSize> = computed(\n () => this.group?.size() ?? this.size()\n );\n\n /** Resolve variant from group or local input. */\n readonly resolvedVariant: Signal<RadioVariant> = computed(\n () => this.group?.variant() ?? this.variant()\n );\n\n /** Whether this radio is checked based on group value. */\n readonly isChecked: Signal<boolean> = computed(() => {\n if (!this.group) {\n return false;\n }\n return this.group.value() === this.value();\n });\n\n /** Whether this radio is disabled (from local or group). */\n readonly isDisabled: Signal<boolean> = computed(\n () => this.disabled() || (this.group?.disabled() ?? false)\n );\n\n /** Get name from group. */\n readonly groupName: Signal<string | undefined> = computed(() => this.group?.name());\n\n /** Tab index for roving tabindex pattern. */\n readonly tabIndex: Signal<number> = computed(() => {\n if (this.isDisabled()) {\n return -1;\n }\n if (!this.group) {\n return 0;\n }\n // Roving tabindex: only the selected or first focusable item gets tabindex 0\n const isSelected = this.isChecked();\n const isFocusTarget = this.group.focusedValue() === this.value();\n\n if (isSelected || isFocusTarget) {\n return 0;\n }\n return -1;\n });\n\n protected readonly circleClasses: Signal<string> = computed(() =>\n radioCircleVariants({ variant: this.resolvedVariant(), size: this.resolvedSize() })\n );\n\n protected readonly dotSizeClass: Signal<string> = computed(() => RADIO_DOT_SIZES[this.resolvedSize()]);\n protected readonly labelSizeClass: Signal<string> = computed(() => RADIO_LABEL_SIZES[this.resolvedSize()]);\n\n ngOnInit(): void {\n // Register with the group\n this.group?.register(this);\n\n // Unregister on destroy\n this.destroyRef.onDestroy(() => {\n this.group?.unregister(this);\n });\n }\n\n // Event handlers\n protected onInputChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n if (input.checked && this.group) {\n this.group.select(this.value());\n this.changed.emit({ value: this.value(), source: this });\n }\n }\n\n protected onBlur(): void {\n this.group?.onTouched?.();\n }\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (!this.group) {\n return;\n }\n\n const { key } = event;\n const isVertical = this.group.orientation() === 'vertical';\n const isHorizontal = this.group.orientation() === 'horizontal';\n\n let handled = false;\n\n if (\n (isVertical && key === 'ArrowDown') ||\n (isHorizontal && key === 'ArrowRight')\n ) {\n this.group.focusNext(this.value());\n handled = true;\n } else if (\n (isVertical && key === 'ArrowUp') ||\n (isHorizontal && key === 'ArrowLeft')\n ) {\n this.group.focusPrevious(this.value());\n handled = true;\n } else if (key === ' ') {\n // Space selects the focused radio\n if (!this.isChecked()) {\n this.group.select(this.value());\n this.changed.emit({ value: this.value(), source: this });\n }\n handled = true;\n }\n\n if (handled) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n\n // Public API\n /** Focuses this radio's input element. */\n focus(): void {\n this.inputRef()?.nativeElement.focus();\n }\n\n /** Selects this radio programmatically. */\n select(): void {\n if (this.isDisabled() || !this.group) {\n return;\n }\n this.group.select(this.value());\n this.changed.emit({ value: this.value(), source: this });\n }\n}\n","// Public API for the radio component\n\n// Main components\nexport { ComRadio } from './radio.component';\nexport { ComRadioGroup, COM_RADIO_GROUP } from './radio-group.component';\n\n// Types\nexport type { RadioChange } from './radio.component';\nexport type { RadioGroupChange, ComRadioGroupContext, RadioItem } from './radio-group.component';\n\n// Variants (for advanced customization)\nexport {\n radioCircleVariants,\n RADIO_GROUP_ORIENTATIONS,\n RADIO_DOT_SIZES,\n RADIO_LABEL_SIZES,\n} from './radio.variants';\n\nexport type { RadioSize, RadioVariant, RadioOrientation } from './radio.variants';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-com-components-radio.mjs","sources":["../../../projects/com/components/radio/radio.variants.ts","../../../projects/com/components/radio/radio.utils.ts","../../../projects/com/components/radio/radio-group.component.ts","../../../projects/com/components/radio/radio.component.ts","../../../projects/com/components/radio/index.ts","../../../projects/com/components/radio/ngx-com-components-radio.ts"],"sourcesContent":["import { cva } from 'class-variance-authority';\n\n/** Radio size variants. */\nexport type RadioSize = 'sm' | 'md' | 'lg';\n\n/** Radio color variants. */\nexport type RadioVariant = 'primary' | 'accent' | 'warn';\n\n/** Radio group orientation. */\nexport type RadioOrientation = 'vertical' | 'horizontal';\n\n/**\n * CVA variants for the visual radio circle.\n *\n * Uses `peer` selectors to style based on native input state:\n * - `peer-checked:` for checked state\n * - `peer-focus-visible:` for keyboard focus\n * - `peer-disabled:` for disabled state\n *\n * @tokens `--color-border`, `--color-primary`, `--color-primary-hover`,\n * `--color-accent`, `--color-accent-hover`,\n * `--color-warn`, `--color-warn-hover`,\n * `--color-disabled`, `--color-ring`\n */\nexport const radioCircleVariants: (props?: {\n variant?: RadioVariant;\n size?: RadioSize;\n}) => string = cva(\n [\n 'com-radio__circle',\n 'inline-flex shrink-0 items-center justify-center',\n 'rounded-pill border-2 border-border',\n 'transition-colors duration-normal',\n 'peer-focus-visible:outline-[1px] peer-focus-visible:outline-offset-2 peer-focus-visible:outline-ring',\n 'peer-disabled:cursor-not-allowed peer-disabled:border-disabled peer-disabled:bg-disabled',\n ],\n {\n variants: {\n variant: {\n primary: [\n 'peer-checked:border-primary peer-checked:bg-primary peer-checked:text-primary-foreground',\n 'group-hover:border-primary-hover',\n 'peer-checked:group-hover:bg-primary-hover peer-checked:group-hover:border-primary-hover',\n ],\n accent: [\n 'peer-checked:border-accent peer-checked:bg-accent peer-checked:text-accent-foreground',\n 'group-hover:border-accent-hover',\n 'peer-checked:group-hover:bg-accent-hover peer-checked:group-hover:border-accent-hover',\n ],\n warn: [\n 'peer-checked:border-warn peer-checked:bg-warn peer-checked:text-warn-foreground',\n 'group-hover:border-warn-hover',\n 'peer-checked:group-hover:bg-warn-hover peer-checked:group-hover:border-warn-hover',\n ],\n },\n size: {\n sm: 'size-4',\n md: 'size-5',\n lg: 'size-6',\n },\n },\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n },\n }\n);\n\n/** Size-based classes for the inner dot indicator. */\nexport const RADIO_DOT_SIZES: Record<RadioSize, string> = {\n sm: 'size-1.5',\n md: 'size-2',\n lg: 'size-2.5',\n};\n\n/** Size-based classes for the label content. */\nexport const RADIO_LABEL_SIZES: Record<RadioSize, string> = {\n sm: 'text-sm ms-2',\n md: 'text-base ms-2.5',\n lg: 'text-lg ms-3',\n};\n\n/** Base classes for the radio group container. */\nconst RADIO_GROUP_BASE = 'com-radio-group__container flex';\n\n/** Orientation-based classes for the radio group container. */\nexport const RADIO_GROUP_ORIENTATIONS: Record<RadioOrientation, string> = {\n vertical: `${RADIO_GROUP_BASE} flex-col gap-2`,\n horizontal: `${RADIO_GROUP_BASE} flex-row flex-wrap gap-4`,\n};\n","/** Auto-incrementing ID counter for unique radio IDs. */\nlet nextRadioId = 0;\n\n/** Generates a unique radio ID. */\nexport function generateRadioId(): string {\n return `com-radio-${nextRadioId++}`;\n}\n\n/** Auto-incrementing ID counter for unique radio group IDs. */\nlet nextGroupId = 0;\n\n/** Generates a unique radio group ID. */\nexport function generateRadioGroupId(): string {\n return `com-radio-group-${nextGroupId++}`;\n}\n","import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n InjectionToken,\n input,\n linkedSignal,\n model,\n output,\n signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport type {\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n WritableSignal,\n} from '@angular/core';\nimport { FormGroupDirective, NgControl, NgForm } from '@angular/forms';\nimport type { ControlValueAccessor } from '@angular/forms';\nimport { ErrorStateMatcher } from 'ngx-com/components/form-field';\nimport { RADIO_GROUP_ORIENTATIONS } from './radio.variants';\nimport type { RadioOrientation, RadioSize, RadioVariant } from './radio.variants';\nimport { generateRadioGroupId } from './radio.utils';\n\n/** Event emitted when radio group value changes. */\nexport interface RadioGroupChange {\n value: string | null;\n}\n\n/** Interface for radio items that register with the group. */\nexport interface RadioItem {\n value: () => string;\n isDisabled: () => boolean;\n focus: () => void;\n}\n\n/** Context provided to child radio components via DI. */\nexport interface ComRadioGroupContext {\n name: Signal<string>;\n value: Signal<string | null>;\n disabled: Signal<boolean>;\n size: Signal<RadioSize>;\n variant: Signal<RadioVariant>;\n orientation: Signal<RadioOrientation>;\n focusedValue: Signal<string | null>;\n select: (value: string) => void;\n focusNext: (currentValue: string) => void;\n focusPrevious: (currentValue: string) => void;\n register: (radio: RadioItem) => void;\n unregister: (radio: RadioItem) => void;\n onTouched?: () => void;\n}\n\n/** Injection token for radio group context. */\nexport const COM_RADIO_GROUP: InjectionToken<ComRadioGroupContext> = new InjectionToken<ComRadioGroupContext>('COM_RADIO_GROUP');\n\n/**\n * Radio group component that manages a set of radio buttons.\n *\n * Provides mutual exclusion, shared name, and roving tabindex keyboard navigation.\n * Implements `ControlValueAccessor` for Reactive Forms integration.\n *\n * @tokens `--color-border`, `--color-primary`, `--color-primary-foreground`, `--color-primary-hover`,\n * `--color-accent`, `--color-accent-foreground`, `--color-accent-hover`,\n * `--color-warn`, `--color-warn-foreground`, `--color-warn-hover`,\n * `--color-disabled`, `--color-disabled-foreground`, `--color-ring`\n *\n * @example Basic usage\n * ```html\n * <com-radio-group [(value)]=\"selectedFruit\" aria-label=\"Select a fruit\">\n * <com-radio value=\"apple\">Apple</com-radio>\n * <com-radio value=\"banana\">Banana</com-radio>\n * <com-radio value=\"cherry\">Cherry</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example With reactive forms\n * ```html\n * <com-radio-group formControlName=\"size\" aria-label=\"Select size\">\n * <com-radio value=\"sm\">Small</com-radio>\n * <com-radio value=\"md\">Medium</com-radio>\n * <com-radio value=\"lg\">Large</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example Horizontal orientation\n * ```html\n * <com-radio-group [(value)]=\"color\" orientation=\"horizontal\">\n * <com-radio value=\"red\">Red</com-radio>\n * <com-radio value=\"green\">Green</com-radio>\n * <com-radio value=\"blue\">Blue</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example With variants\n * ```html\n * <com-radio-group [(value)]=\"priority\" variant=\"warn\" size=\"lg\">\n * <com-radio value=\"low\">Low</com-radio>\n * <com-radio value=\"medium\">Medium</com-radio>\n * <com-radio value=\"high\">High</com-radio>\n * </com-radio-group>\n * ```\n */\n@Component({\n selector: 'com-radio-group',\n exportAs: 'comRadioGroup',\n template: `\n <div\n role=\"radiogroup\"\n [class]=\"groupClasses()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"computedAriaDescribedby()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"errorState() || null\"\n >\n <ng-content />\n </div>\n @if (errorState() && errorMessage()) {\n <div\n [id]=\"errorId\"\n class=\"com-radio-group__error mt-1.5 text-sm text-warn\"\n role=\"alert\"\n >\n {{ errorMessage() }}\n </div>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n providers: [\n {\n provide: COM_RADIO_GROUP,\n useFactory: () => {\n const group = inject(ComRadioGroup);\n return group.createContext();\n },\n },\n ],\n host: {\n class: 'com-radio-group block',\n '[class.com-radio-group--disabled]': 'disabled()',\n '[class.com-radio-group--error]': 'errorState()',\n },\n})\nexport class ComRadioGroup implements ControlValueAccessor {\n /** Optional NgControl for reactive forms integration. */\n readonly ngControl: NgControl | null = inject(NgControl, { optional: true, self: true });\n\n /** Error state matcher for determining when to show validation errors. */\n private readonly defaultErrorStateMatcher: ErrorStateMatcher = inject(ErrorStateMatcher);\n private readonly parentForm: NgForm | null = inject(NgForm, { optional: true });\n private readonly parentFormGroup: FormGroupDirective | null = inject(FormGroupDirective, { optional: true });\n\n /** Unique ID for this radio group instance. */\n private readonly uniqueId: string = generateRadioGroupId();\n\n /** ID for the error message element. */\n readonly errorId: string = `${this.uniqueId}-error`;\n\n /** Registered radio items. */\n private readonly registeredRadios: WritableSignal<RadioItem[]> = signal([]);\n\n // Inputs\n readonly name: InputSignal<string> = input<string>(this.uniqueId);\n readonly value: ModelSignal<string | null> = model<string | null>(null);\n readonly disabled: ModelSignal<boolean> = model<boolean>(false);\n readonly required: InputSignalWithTransform<boolean, unknown> = input(false, {\n transform: booleanAttribute,\n });\n readonly orientation: InputSignal<RadioOrientation> = input<RadioOrientation>('vertical');\n readonly size: InputSignal<RadioSize> = input<RadioSize>('md');\n readonly variant: InputSignal<RadioVariant> = input<RadioVariant>('primary');\n readonly errorMessage: InputSignal<string> = input<string>('');\n readonly errorStateMatcher: InputSignal<ErrorStateMatcher | undefined> = input<ErrorStateMatcher>();\n\n /** Tracks touched state — writable by both CVA callback and Signal Forms [formField]. */\n readonly touched: ModelSignal<boolean> = model<boolean>(false);\n\n // Signal Forms inputs — set automatically by [formField] via setInputOnDirectives\n readonly invalid: InputSignal<boolean> = input<boolean>(false);\n readonly sfErrors: InputSignal<readonly unknown[]> = input<readonly unknown[]>([], { alias: 'errors' });\n\n readonly ariaLabel: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-label' });\n readonly ariaLabelledby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-labelledby' });\n readonly ariaDescribedby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-describedby' });\n\n // Outputs\n /** Emits when the selection changes, with full event details. */\n readonly selectionChange: OutputEmitterRef<RadioGroupChange> = output<RadioGroupChange>();\n\n /**\n * Tracks the currently focused radio value for roving tabindex.\n * Resets to the current selection (or first focusable) when value or radios change.\n */\n private readonly focusedValueSignal: WritableSignal<string | null> = linkedSignal({\n source: () => ({ value: this.value(), radios: this.registeredRadios() }),\n computation: ({ value, radios }) => {\n if (value && radios.some((r) => r.value() === value && !r.isDisabled())) {\n return value;\n }\n const firstFocusable = radios.find((r) => !r.isDisabled());\n return firstFocusable?.value() ?? null;\n },\n });\n\n // Computed\n /**\n * Computed error state derived from form validation.\n * Shows errors when control is invalid and touched/submitted.\n */\n readonly errorState: Signal<boolean> = computed(() => {\n if (!this.ngControl) {\n // Signal Forms: gate on invalid AND touched (mirrors ErrorStateMatcher default)\n return this.invalid() && this.touched();\n }\n // Reactive Forms: use ErrorStateMatcher (existing logic)\n this.touched();\n const matcher = this.errorStateMatcher() ?? this.defaultErrorStateMatcher;\n const form = this.parentFormGroup ?? this.parentForm;\n return matcher.isErrorState(this.ngControl.control ?? null, form);\n });\n\n readonly computedAriaDescribedby: Signal<string | null> = computed(() => {\n const userDescribedby = this.ariaDescribedby();\n if (this.errorState() && this.errorMessage()) {\n return userDescribedby ? `${userDescribedby} ${this.errorId}` : this.errorId;\n }\n return userDescribedby;\n });\n\n protected readonly groupClasses: Signal<string> = computed(() =>\n RADIO_GROUP_ORIENTATIONS[this.orientation()]\n );\n\n // CVA callbacks\n private onChange: (value: string | null) => void = () => {};\n private onTouchedCallback: () => void = () => {};\n\n constructor() {\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n /** Creates the context object for child radios. */\n createContext(): ComRadioGroupContext {\n return {\n name: this.name,\n value: this.value,\n disabled: this.disabled,\n size: this.size,\n variant: this.variant,\n orientation: this.orientation,\n focusedValue: this.focusedValueSignal,\n select: this.select.bind(this),\n focusNext: this.focusNext.bind(this),\n focusPrevious: this.focusPrevious.bind(this),\n register: this.register.bind(this),\n unregister: this.unregister.bind(this),\n onTouched: () => this.onTouchedCallback(),\n };\n }\n\n /** Register a radio item with the group. */\n private register(radio: RadioItem): void {\n this.registeredRadios.update((radios) => [...radios, radio]);\n }\n\n /** Unregister a radio item from the group. */\n private unregister(radio: RadioItem): void {\n this.registeredRadios.update((radios) => radios.filter((r) => r !== radio));\n }\n\n // ControlValueAccessor implementation\n writeValue(value: string | null): void {\n this.value.set(value);\n }\n\n registerOnChange(fn: (value: string | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouchedCallback = () => {\n this.touched.set(true);\n fn();\n };\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled.set(isDisabled);\n }\n\n // Public API\n /** Selects a radio by value. */\n select(newValue: string): void {\n if (this.disabled()) {\n return;\n }\n this.value.set(newValue);\n this.focusedValueSignal.set(newValue);\n this.onChange(newValue);\n this.selectionChange.emit({ value: newValue });\n }\n\n /** Focuses the next non-disabled radio (with cyclic wrap). */\n focusNext(currentValue: string): void {\n const allRadios = this.registeredRadios();\n const focusableRadios = allRadios.filter((r) => !r.isDisabled());\n\n if (focusableRadios.length === 0) {\n return;\n }\n\n const currentIndex = focusableRadios.findIndex((r) => r.value() === currentValue);\n const nextIndex = (currentIndex + 1) % focusableRadios.length;\n const nextRadio = focusableRadios[nextIndex];\n\n if (nextRadio) {\n this.focusedValueSignal.set(nextRadio.value());\n this.select(nextRadio.value());\n nextRadio.focus();\n }\n }\n\n /** Focuses the previous non-disabled radio (with cyclic wrap). */\n focusPrevious(currentValue: string): void {\n const allRadios = this.registeredRadios();\n const focusableRadios = allRadios.filter((r) => !r.isDisabled());\n\n if (focusableRadios.length === 0) {\n return;\n }\n\n const currentIndex = focusableRadios.findIndex((r) => r.value() === currentValue);\n const prevIndex = (currentIndex - 1 + focusableRadios.length) % focusableRadios.length;\n const prevRadio = focusableRadios[prevIndex];\n\n if (prevRadio) {\n this.focusedValueSignal.set(prevRadio.value());\n this.select(prevRadio.value());\n prevRadio.focus();\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n model,\n output,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport type {\n InputSignal,\n ModelSignal,\n OnInit,\n OutputEmitterRef,\n Signal,\n} from '@angular/core';\nimport {\n radioCircleVariants,\n RADIO_DOT_SIZES,\n RADIO_LABEL_SIZES,\n} from './radio.variants';\nimport type { RadioSize, RadioVariant } from './radio.variants';\nimport { generateRadioId } from './radio.utils';\nimport { COM_RADIO_GROUP, type ComRadioGroupContext, type RadioItem } from './radio-group.component';\n\n/** Event emitted when a radio is selected. */\nexport interface RadioChange {\n value: string;\n source: ComRadio;\n}\n\n/**\n * Production-grade radio component with full accessibility support.\n *\n * Uses a native `<input type=\"radio\">` for built-in keyboard handling,\n * `:checked` pseudo-class, and screen reader support.\n *\n * Must be used within a `ComRadioGroup` which manages the selected value\n * and provides the shared `name` attribute.\n *\n * @tokens `--color-border`, `--color-primary`, `--color-primary-foreground`, `--color-primary-hover`,\n * `--color-accent`, `--color-accent-foreground`, `--color-accent-hover`,\n * `--color-warn`, `--color-warn-foreground`, `--color-warn-hover`,\n * `--color-disabled`, `--color-disabled-foreground`, `--color-ring`\n *\n * @example Basic usage within a group\n * ```html\n * <com-radio-group [(value)]=\"selectedOption\">\n * <com-radio value=\"option1\">Option 1</com-radio>\n * <com-radio value=\"option2\">Option 2</com-radio>\n * <com-radio value=\"option3\">Option 3</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example Disabled option\n * ```html\n * <com-radio-group [(value)]=\"selected\">\n * <com-radio value=\"enabled\">Enabled option</com-radio>\n * <com-radio value=\"disabled\" [disabled]=\"true\">Disabled option</com-radio>\n * </com-radio-group>\n * ```\n */\n@Component({\n selector: 'com-radio',\n exportAs: 'comRadio',\n template: `\n <label\n class=\"group relative inline-flex items-center\"\n [class.cursor-pointer]=\"!isDisabled()\"\n [class.cursor-not-allowed]=\"isDisabled()\"\n >\n <span><input\n #inputElement\n type=\"radio\"\n class=\"peer sr-only\"\n [id]=\"inputId()\"\n [checked]=\"isChecked()\"\n [disabled]=\"isDisabled()\"\n [attr.name]=\"groupName()\"\n [attr.value]=\"value()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n [attr.tabindex]=\"tabIndex()\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeyDown($event)\"\n /></span>\n <div [class]=\"circleClasses()\">\n <div\n class=\"com-radio__dot rounded-pill bg-current transition-transform duration-normal peer-disabled:bg-disabled-foreground\"\n [class]=\"dotSizeClass()\"\n [class.scale-100]=\"isChecked()\"\n [class.scale-0]=\"!isChecked()\"\n ></div>\n </div>\n <span\n class=\"com-radio__label select-none peer-disabled:cursor-not-allowed peer-disabled:text-disabled-foreground\"\n [class]=\"labelSizeClass()\"\n >\n <ng-content />\n </span>\n </label>\n `,\n styles: `\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'com-radio inline-flex align-middle',\n '[class.com-radio--disabled]': 'isDisabled()',\n '[class.com-radio--checked]': 'isChecked()',\n },\n})\nexport class ComRadio implements OnInit, RadioItem {\n /** Optional parent radio group context. */\n private readonly group: ComRadioGroupContext | null = inject(COM_RADIO_GROUP, {\n optional: true,\n });\n\n /** DestroyRef for cleanup. */\n private readonly destroyRef: DestroyRef = inject(DestroyRef);\n\n /** Reference to the native input element. */\n readonly inputRef: Signal<ElementRef<HTMLInputElement> | undefined> =\n viewChild<ElementRef<HTMLInputElement>>('inputElement');\n\n /** Unique ID for this radio instance. */\n private readonly uniqueId: string = generateRadioId();\n\n // Inputs\n readonly value: InputSignal<string> = input.required<string>();\n readonly size: InputSignal<RadioSize> = input<RadioSize>('md');\n readonly variant: InputSignal<RadioVariant> = input<RadioVariant>('primary');\n readonly disabled: ModelSignal<boolean> = model<boolean>(false);\n readonly id: InputSignal<string | undefined> = input<string>();\n readonly ariaLabel: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-label' });\n readonly ariaLabelledby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-labelledby' });\n readonly ariaDescribedby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-describedby' });\n\n // Outputs\n readonly changed: OutputEmitterRef<RadioChange> = output<RadioChange>();\n\n // Computed state\n readonly inputId: Signal<string> = computed(() => this.id() ?? this.uniqueId);\n\n /** Resolve size from group or local input. */\n readonly resolvedSize: Signal<RadioSize> = computed(\n () => this.group?.size() ?? this.size()\n );\n\n /** Resolve variant from group or local input. */\n readonly resolvedVariant: Signal<RadioVariant> = computed(\n () => this.group?.variant() ?? this.variant()\n );\n\n /** Whether this radio is checked based on group value. */\n readonly isChecked: Signal<boolean> = computed(() => {\n if (!this.group) {\n return false;\n }\n return this.group.value() === this.value();\n });\n\n /** Whether this radio is disabled (from local or group). */\n readonly isDisabled: Signal<boolean> = computed(\n () => this.disabled() || (this.group?.disabled() ?? false)\n );\n\n /** Get name from group. */\n readonly groupName: Signal<string | undefined> = computed(() => this.group?.name());\n\n /** Tab index for roving tabindex pattern. */\n readonly tabIndex: Signal<number> = computed(() => {\n if (this.isDisabled()) {\n return -1;\n }\n if (!this.group) {\n return 0;\n }\n // Roving tabindex: only the selected or first focusable item gets tabindex 0\n const isSelected = this.isChecked();\n const isFocusTarget = this.group.focusedValue() === this.value();\n\n if (isSelected || isFocusTarget) {\n return 0;\n }\n return -1;\n });\n\n protected readonly circleClasses: Signal<string> = computed(() =>\n radioCircleVariants({ variant: this.resolvedVariant(), size: this.resolvedSize() })\n );\n\n protected readonly dotSizeClass: Signal<string> = computed(() => RADIO_DOT_SIZES[this.resolvedSize()]);\n protected readonly labelSizeClass: Signal<string> = computed(() => RADIO_LABEL_SIZES[this.resolvedSize()]);\n\n ngOnInit(): void {\n // Register with the group\n this.group?.register(this);\n\n // Unregister on destroy\n this.destroyRef.onDestroy(() => {\n this.group?.unregister(this);\n });\n }\n\n // Event handlers\n protected onInputChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n if (input.checked && this.group) {\n this.group.select(this.value());\n this.changed.emit({ value: this.value(), source: this });\n }\n }\n\n protected onBlur(): void {\n this.group?.onTouched?.();\n }\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (!this.group) {\n return;\n }\n\n const { key } = event;\n const isVertical = this.group.orientation() === 'vertical';\n const isHorizontal = this.group.orientation() === 'horizontal';\n\n let handled = false;\n\n if (\n (isVertical && key === 'ArrowDown') ||\n (isHorizontal && key === 'ArrowRight')\n ) {\n this.group.focusNext(this.value());\n handled = true;\n } else if (\n (isVertical && key === 'ArrowUp') ||\n (isHorizontal && key === 'ArrowLeft')\n ) {\n this.group.focusPrevious(this.value());\n handled = true;\n } else if (key === ' ') {\n // Space selects the focused radio\n if (!this.isChecked()) {\n this.group.select(this.value());\n this.changed.emit({ value: this.value(), source: this });\n }\n handled = true;\n }\n\n if (handled) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n\n // Public API\n /** Focuses this radio's input element. */\n focus(): void {\n this.inputRef()?.nativeElement.focus();\n }\n\n /** Selects this radio programmatically. */\n select(): void {\n if (this.isDisabled() || !this.group) {\n return;\n }\n this.group.select(this.value());\n this.changed.emit({ value: this.value(), source: this });\n }\n}\n","// Public API for the radio component\n\n// Main components\nexport { ComRadio } from './radio.component';\nexport { ComRadioGroup, COM_RADIO_GROUP } from './radio-group.component';\n\n// Types\nexport type { RadioChange } from './radio.component';\nexport type { RadioGroupChange, ComRadioGroupContext, RadioItem } from './radio-group.component';\n\n// Variants (for advanced customization)\nexport {\n radioCircleVariants,\n RADIO_GROUP_ORIENTATIONS,\n RADIO_DOT_SIZES,\n RADIO_LABEL_SIZES,\n} from './radio.variants';\n\nexport type { RadioSize, RadioVariant, RadioOrientation } from './radio.variants';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ import { ComponentHarness, HarnessPredicate, parallel } from '@angular/cdk/testing';
2
+
3
+ /**
4
+ * Harness for interacting with an individual segment button in tests.
5
+ */
6
+ class ComSegmentHarness extends ComponentHarness {
7
+ static hostSelector = 'button[role="radio"]';
8
+ /**
9
+ * Gets a HarnessPredicate for matching segments.
10
+ * @param options Filter options.
11
+ */
12
+ static with(options = {}) {
13
+ return new HarnessPredicate(ComSegmentHarness, options)
14
+ .addOption('label', options.label, async (harness, label) => {
15
+ const text = await harness.getLabel();
16
+ return HarnessPredicate.stringMatches(text, label);
17
+ })
18
+ .addOption('selected', options.selected, async (harness, selected) => {
19
+ return (await harness.isSelected()) === selected;
20
+ })
21
+ .addOption('disabled', options.disabled, async (harness, disabled) => {
22
+ return (await harness.isDisabled()) === disabled;
23
+ });
24
+ }
25
+ /** Gets the segment's label text. Uses aria-label if present, otherwise text content. */
26
+ async getLabel() {
27
+ const host = await this.host();
28
+ const ariaLabel = await host.getAttribute('aria-label');
29
+ if (ariaLabel) {
30
+ return ariaLabel;
31
+ }
32
+ return host.text();
33
+ }
34
+ /** Whether the segment is currently selected. */
35
+ async isSelected() {
36
+ const host = await this.host();
37
+ return (await host.getAttribute('aria-checked')) === 'true';
38
+ }
39
+ /** Whether the segment is disabled. */
40
+ async isDisabled() {
41
+ const host = await this.host();
42
+ return (await host.getAttribute('aria-disabled')) === 'true' ||
43
+ (await host.getProperty('disabled'));
44
+ }
45
+ /** Clicks the segment to select it. Throws if disabled. */
46
+ async select() {
47
+ if (await this.isDisabled()) {
48
+ throw new Error('Cannot select a disabled segment');
49
+ }
50
+ const host = await this.host();
51
+ return host.click();
52
+ }
53
+ /** Focuses the segment button. */
54
+ async focus() {
55
+ const host = await this.host();
56
+ return host.focus();
57
+ }
58
+ /** Blurs the segment button. */
59
+ async blur() {
60
+ const host = await this.host();
61
+ return host.blur();
62
+ }
63
+ /** Whether the segment button is focused. */
64
+ async isFocused() {
65
+ const host = await this.host();
66
+ return host.isFocused();
67
+ }
68
+ }
69
+ /**
70
+ * Harness for interacting with a ComSegmentedControl in tests.
71
+ */
72
+ class ComSegmentedControlHarness extends ComponentHarness {
73
+ static hostSelector = 'com-segmented-control';
74
+ radioGroup = this.locatorFor('div[role="radiogroup"]');
75
+ /**
76
+ * Gets a HarnessPredicate for matching segmented controls.
77
+ * @param options Filter options.
78
+ */
79
+ static with(options = {}) {
80
+ return new HarnessPredicate(ComSegmentedControlHarness, options)
81
+ .addOption('ariaLabel', options.ariaLabel, async (harness, ariaLabel) => {
82
+ const label = await harness.getAriaLabel();
83
+ return HarnessPredicate.stringMatches(label, ariaLabel);
84
+ });
85
+ }
86
+ /** Gets all segment buttons, optionally filtered. */
87
+ async getSegments(filters = {}) {
88
+ return this.locatorForAll(ComSegmentHarness.with(filters))();
89
+ }
90
+ /** Gets the currently selected segment, or null if none is selected. */
91
+ async getSelectedSegment() {
92
+ const segments = await this.getSegments({ selected: true });
93
+ return segments[0] ?? null;
94
+ }
95
+ /** Selects a segment matching the given filter. */
96
+ async selectSegment(filter) {
97
+ const segments = await this.getSegments(filter);
98
+ if (segments.length === 0) {
99
+ throw new Error(`Could not find segment matching filter: ${JSON.stringify(filter)}`);
100
+ }
101
+ return segments[0].select();
102
+ }
103
+ /** Gets all segment label texts. */
104
+ async getSegmentLabels() {
105
+ const segments = await this.getSegments();
106
+ return parallel(() => segments.map((s) => s.getLabel()));
107
+ }
108
+ /** Gets the radiogroup's aria-label. */
109
+ async getAriaLabel() {
110
+ const group = await this.radioGroup();
111
+ return group.getAttribute('aria-label');
112
+ }
113
+ }
114
+
115
+ // Testing utilities for the segmented-control component
116
+
117
+ /**
118
+ * Generated bundle index. Do not edit.
119
+ */
120
+
121
+ export { ComSegmentHarness, ComSegmentedControlHarness };
122
+ //# sourceMappingURL=ngx-com-components-segmented-control-testing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-com-components-segmented-control-testing.mjs","sources":["../../../projects/com/components/segmented-control/testing/segmented-control.harness.ts","../../../projects/com/components/segmented-control/testing/index.ts","../../../projects/com/components/segmented-control/testing/ngx-com-components-segmented-control-testing.ts"],"sourcesContent":["import {\n ComponentHarness,\n HarnessPredicate,\n parallel,\n} from '@angular/cdk/testing';\nimport type { BaseHarnessFilters } from '@angular/cdk/testing';\n\n/** Harness filters for ComSegmentHarness. */\nexport interface ComSegmentHarnessFilters extends BaseHarnessFilters {\n /** Filter by the segment's label text. */\n label?: string | RegExp;\n /** Filter by whether the segment is selected. */\n selected?: boolean;\n /** Filter by whether the segment is disabled. */\n disabled?: boolean;\n}\n\n/** Harness filters for ComSegmentedControlHarness. */\nexport interface ComSegmentedControlHarnessFilters extends BaseHarnessFilters {\n /** Filter by the control's aria-label. */\n ariaLabel?: string | RegExp;\n}\n\n/**\n * Harness for interacting with an individual segment button in tests.\n */\nexport class ComSegmentHarness extends ComponentHarness {\n static hostSelector = 'button[role=\"radio\"]';\n\n /**\n * Gets a HarnessPredicate for matching segments.\n * @param options Filter options.\n */\n static with(options: ComSegmentHarnessFilters = {}): HarnessPredicate<ComSegmentHarness> {\n return new HarnessPredicate(ComSegmentHarness, options)\n .addOption('label', options.label, async (harness, label) => {\n const text = await harness.getLabel();\n return HarnessPredicate.stringMatches(text, label);\n })\n .addOption('selected', options.selected, async (harness, selected) => {\n return (await harness.isSelected()) === selected;\n })\n .addOption('disabled', options.disabled, async (harness, disabled) => {\n return (await harness.isDisabled()) === disabled;\n });\n }\n\n /** Gets the segment's label text. Uses aria-label if present, otherwise text content. */\n async getLabel(): Promise<string> {\n const host = await this.host();\n const ariaLabel = await host.getAttribute('aria-label');\n if (ariaLabel) {\n return ariaLabel;\n }\n return host.text();\n }\n\n /** Whether the segment is currently selected. */\n async isSelected(): Promise<boolean> {\n const host = await this.host();\n return (await host.getAttribute('aria-checked')) === 'true';\n }\n\n /** Whether the segment is disabled. */\n async isDisabled(): Promise<boolean> {\n const host = await this.host();\n return (await host.getAttribute('aria-disabled')) === 'true' ||\n (await host.getProperty<boolean>('disabled'));\n }\n\n /** Clicks the segment to select it. Throws if disabled. */\n async select(): Promise<void> {\n if (await this.isDisabled()) {\n throw new Error('Cannot select a disabled segment');\n }\n const host = await this.host();\n return host.click();\n }\n\n /** Focuses the segment button. */\n async focus(): Promise<void> {\n const host = await this.host();\n return host.focus();\n }\n\n /** Blurs the segment button. */\n async blur(): Promise<void> {\n const host = await this.host();\n return host.blur();\n }\n\n /** Whether the segment button is focused. */\n async isFocused(): Promise<boolean> {\n const host = await this.host();\n return host.isFocused();\n }\n}\n\n/**\n * Harness for interacting with a ComSegmentedControl in tests.\n */\nexport class ComSegmentedControlHarness extends ComponentHarness {\n static hostSelector = 'com-segmented-control';\n\n private readonly radioGroup = this.locatorFor('div[role=\"radiogroup\"]');\n\n /**\n * Gets a HarnessPredicate for matching segmented controls.\n * @param options Filter options.\n */\n static with(options: ComSegmentedControlHarnessFilters = {}): HarnessPredicate<ComSegmentedControlHarness> {\n return new HarnessPredicate(ComSegmentedControlHarness, options)\n .addOption('ariaLabel', options.ariaLabel, async (harness, ariaLabel) => {\n const label = await harness.getAriaLabel();\n return HarnessPredicate.stringMatches(label, ariaLabel);\n });\n }\n\n /** Gets all segment buttons, optionally filtered. */\n async getSegments(filters: ComSegmentHarnessFilters = {}): Promise<ComSegmentHarness[]> {\n return this.locatorForAll(ComSegmentHarness.with(filters))();\n }\n\n /** Gets the currently selected segment, or null if none is selected. */\n async getSelectedSegment(): Promise<ComSegmentHarness | null> {\n const segments = await this.getSegments({ selected: true });\n return segments[0] ?? null;\n }\n\n /** Selects a segment matching the given filter. */\n async selectSegment(filter: ComSegmentHarnessFilters): Promise<void> {\n const segments = await this.getSegments(filter);\n if (segments.length === 0) {\n throw new Error(`Could not find segment matching filter: ${JSON.stringify(filter)}`);\n }\n return segments[0]!.select();\n }\n\n /** Gets all segment label texts. */\n async getSegmentLabels(): Promise<string[]> {\n const segments = await this.getSegments();\n return parallel(() => segments.map((s) => s.getLabel()));\n }\n\n /** Gets the radiogroup's aria-label. */\n async getAriaLabel(): Promise<string | null> {\n const group = await this.radioGroup();\n return group.getAttribute('aria-label');\n }\n}\n","// Testing utilities for the segmented-control component\n\nexport {\n ComSegmentHarness,\n ComSegmentedControlHarness,\n} from './segmented-control.harness';\n\nexport type {\n ComSegmentHarnessFilters,\n ComSegmentedControlHarnessFilters,\n} from './segmented-control.harness';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}