ps-helix 6.2.2 → 6.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A comprehensive Angular component library built with Angular 22+ featuring modern design patterns, accessibility-first development, and optimal developer experience.
4
4
 
5
- [![npm version](https://img.shields.io/badge/npm-6.2.2-blue.svg)](https://www.npmjs.com/package/ps-helix)
5
+ [![npm version](https://img.shields.io/badge/npm-6.2.3-blue.svg)](https://www.npmjs.com/package/ps-helix)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
  [![Angular](https://img.shields.io/badge/Angular-22.0.0-red.svg)](https://angular.dev/)
8
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-6.0.0-blue.svg)](https://www.typescriptlang.org/)
@@ -106,7 +106,7 @@ After installation, verify that ps-helix is in your `package.json`:
106
106
  ```json
107
107
  {
108
108
  "dependencies": {
109
- "ps-helix": "^6.2.2"
109
+ "ps-helix": "^6.2.3"
110
110
  }
111
111
  }
112
112
  ```
@@ -1182,7 +1182,7 @@ Copyright (c) 2025 PACK Solutions
1182
1182
 
1183
1183
  ---
1184
1184
 
1185
- **Version**: 6.2.2
1185
+ **Version**: 6.2.3
1186
1186
  **Built with**: Angular 22.0.0, TypeScript 6.0.0, Phosphor Icons 2.0.3
1187
1187
  **Author**: Fabrice PEREZ | Design Engineer at PACK Solutions
1188
1188
  **Last Updated**: January 2026
@@ -3841,12 +3841,13 @@ const RADIO_STYLES = new InjectionToken('RADIO_STYLES', {
3841
3841
  */
3842
3842
  let radioIdCounter = 0;
3843
3843
  class PshRadioComponent {
3844
- set checkedInput(v) { this.checked.set(v); }
3845
- set disabledInput(v) { this.disabled.set(v); }
3846
3844
  constructor() {
3847
3845
  this.config = inject(RADIO_CONFIG);
3848
3846
  this.styles = inject(RADIO_STYLES, { optional: true }) ?? [];
3849
3847
  this.uniqueId = `radio-${++radioIdCounter}`;
3848
+ /** Holds the `label` input or the projected content — whichever provides the visible label. */
3849
+ this.labelSlot = viewChild('labelSlot', /* @ts-ignore */
3850
+ ...(ngDevMode ? [{ debugName: "labelSlot" }] : /* istanbul ignore next */ []));
3850
3851
  // Plain signals + manual @Input/@Output to prevent auto-emission
3851
3852
  // when parent sets [checked] or [disabled] via template binding.
3852
3853
  // model() would auto-emit checkedChange/disabledChange on .set().
@@ -3892,7 +3893,10 @@ class PshRadioComponent {
3892
3893
  const labelText = this.label();
3893
3894
  if (labelText)
3894
3895
  return labelText;
3895
- return this.hasProjectedContent() ? undefined : 'Radio';
3896
+ // No `aria-label` at all when nothing is declared: the `<label>` wrapping the input
3897
+ // already names it from a projected label. A hard-coded fallback would override that
3898
+ // visible text for screen readers (WCAG 2.5.3 "Label in Name").
3899
+ return undefined;
3896
3900
  }, /* @ts-ignore */
3897
3901
  ...(ngDevMode ? [{ debugName: "computedAriaLabel" }] : /* istanbul ignore next */ []));
3898
3902
  this.errorMessageId = computed(() => this.error() ? `${this.uniqueId}-error` : undefined, /* @ts-ignore */
@@ -3903,12 +3907,18 @@ class PshRadioComponent {
3903
3907
  // so aria-describedby references whichever message is actually rendered.
3904
3908
  this.ariaDescribedBy = computed(() => this.errorMessageId() ?? this.successMessageId(), /* @ts-ignore */
3905
3909
  ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : /* istanbul ignore next */ []));
3906
- if (isDevMode()) {
3907
- effect(() => {
3908
- if (!this.label() && !this.ariaLabel() && !this.hasProjectedContent()) {
3909
- console.warn('[psh-radio] No accessible label provided. Please use label input, ariaLabel input, or projected content.');
3910
- }
3911
- });
3910
+ }
3911
+ set checkedInput(v) { this.checked.set(v); }
3912
+ set disabledInput(v) { this.disabled.set(v); }
3913
+ ngAfterViewInit() {
3914
+ if (!isDevMode())
3915
+ return;
3916
+ // Read the rendered label slot rather than the `label` input alone: a projected
3917
+ // label (`<psh-radio>Accept terms</psh-radio>`) is just as accessible, and
3918
+ // `contentChild` cannot see a bare text node. Checked once, after the first render.
3919
+ const hasVisibleLabel = !!this.labelSlot()?.nativeElement.textContent?.trim();
3920
+ if (!hasVisibleLabel && !this.ariaLabel() && !this.hasProjectedContent()) {
3921
+ console.warn('[psh-radio] No accessible label provided. Please use label input, ariaLabel input, or projected content.');
3912
3922
  }
3913
3923
  }
3914
3924
  getState() {
@@ -3921,9 +3931,9 @@ class PshRadioComponent {
3921
3931
  return this.checked() ? 'checked' : 'unchecked';
3922
3932
  }
3923
3933
  /**
3924
- * Declares whether a label is projected (`<psh-radio>Label</psh-radio>`). Not detected
3925
- * automatically yet: until a consumer calls this, a projected label still triggers the
3926
- * dev-only accessibility warning and `aria-label="Radio"` overrides the visible text.
3934
+ * Declares whether a label is projected. No longer required — projected content is now
3935
+ * detected from the rendered label slot. Kept for backwards compatibility: calling it
3936
+ * with `true` still suppresses the dev-only accessibility warning.
3927
3937
  */
3928
3938
  updateProjectedContent(hasContent) {
3929
3939
  this.hasProjectedContent.set(hasContent);
@@ -3969,7 +3979,7 @@ class PshRadioComponent {
3969
3979
  // Implementation requires radio group context
3970
3980
  }
3971
3981
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PshRadioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3972
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: PshRadioComponent, isStandalone: true, selector: "psh-radio", inputs: { checkedInput: { classPropertyName: "checkedInput", publicName: "checked", isSignal: false, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, success: { classPropertyName: "success", publicName: "success", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "checkedChange", disabledChange: "disabledChange", valueChange: "valueChange" }, host: { properties: { "class.radio-disabled": "disabled()", "class.radio-error": "!!error()", "class.radio-success": "!!success()", "class.radio-small": "size() === \"small\"", "class.radio-large": "size() === \"large\"", "attr.data-state": "state()" } }, ngImport: i0, template: "<div class=\"radio-container\">\r\n <label class=\"radio-label\" [class.label-left]=\"labelPosition() === 'left'\">\r\n <input\r\n type=\"radio\"\r\n class=\"radio-input\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [name]=\"name()\"\r\n [attr.value]=\"value()\"\r\n [attr.aria-label]=\"computedAriaLabel()\"\r\n [attr.aria-required]=\"required() || null\"\r\n [attr.aria-invalid]=\"error() ? 'true' : null\"\r\n [attr.aria-checked]=\"checked()\"\r\n [attr.aria-describedby]=\"ariaDescribedBy()\"\r\n (change)=\"handleChange()\"\r\n (keydown)=\"handleKeydown($event)\"\r\n />\r\n <span \r\n class=\"radio-control\"\r\n [class.error]=\"!!error()\"\r\n [class.success]=\"!!success()\"\r\n >\r\n <span class=\"radio-dot\"></span>\r\n </span>\r\n <span class=\"radio-text\">\r\n @if (label()) {\r\n {{ label() }}\r\n } @else {\r\n <ng-content>Radio</ng-content>\r\n }\r\n </span>\r\n </label>\r\n\r\n @if (error()) {\r\n <div [id]=\"errorMessageId()\" class=\"radio-error\" role=\"alert\">\r\n {{ error() }}\r\n </div>\r\n } @else if (success()) {\r\n <div [id]=\"successMessageId()\" class=\"radio-success\" role=\"status\">\r\n {{ success() }}\r\n </div>\r\n }\r\n</div>", styles: [".radio-container{display:inline-flex;flex-direction:column;gap:var(--form-field-gap)}.radio-label{display:inline-flex;align-items:center;gap:var(--form-label-gap);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--text-color)}.radio-label.label-left{flex-direction:row-reverse;justify-content:space-between}.radio-input{position:absolute;opacity:0;width:0;height:0}.radio-control{display:flex;align-items:center;justify-content:center;width:var(--size-5);height:var(--size-5);min-width:var(--size-5);min-height:var(--size-5);border:var(--border-width-2) solid var(--surface-border);border-radius:var(--radius-full);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);flex-shrink:0}.radio-dot{width:var(--size-2);height:var(--size-2);border-radius:var(--radius-full);background:var(--primary-color-text);opacity:0;transform:scale(.8);transition:all var(--animation-duration-fast) var(--animation-easing-default)}.radio-input:checked+.radio-control{background:var(--primary-color);border-color:var(--primary-color)}.radio-input:checked+.radio-control .radio-dot{opacity:1;transform:scale(1)}.radio-input:focus-visible+.radio-control{box-shadow:0 0 0 var(--focus-outline-width) var(--focus-ring-color)}:host(.radio-disabled) .radio-label{opacity:var(--opacity-disabled);cursor:not-allowed}:host(.radio-error) .radio-control{border-color:var(--danger-color)}:host(.radio-error) .radio-input:checked+.radio-control{background:var(--danger-color);border-color:var(--danger-color)}:host(.radio-success) .radio-control{border-color:var(--success-color)}:host(.radio-success) .radio-input:checked+.radio-control{background:var(--success-color);border-color:var(--success-color)}.radio-error{font-size:var(--font-size-sm);color:var(--danger-color)}.radio-success{font-size:var(--font-size-sm);color:var(--success-color)}:host(.radio-small) .radio-control{width:var(--size-4);height:var(--size-4);min-width:var(--size-4);min-height:var(--size-4)}:host(.radio-small) .radio-dot{width:var(--size-1-5);height:var(--size-1-5)}:host(.radio-small) .radio-text{font-size:var(--font-size-sm)}:host(.radio-large) .radio-control{width:var(--size-6);height:var(--size-6);min-width:var(--size-6);min-height:var(--size-6)}:host(.radio-large) .radio-dot{width:var(--size-3);height:var(--size-3)}:host(.radio-large) .radio-text{font-size:var(--font-size-lg)}.radio-text{color:var(--text-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3982
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: PshRadioComponent, isStandalone: true, selector: "psh-radio", inputs: { checkedInput: { classPropertyName: "checkedInput", publicName: "checked", isSignal: false, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, success: { classPropertyName: "success", publicName: "success", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "checkedChange", disabledChange: "disabledChange", valueChange: "valueChange" }, host: { properties: { "class.radio-disabled": "disabled()", "class.radio-error": "!!error()", "class.radio-success": "!!success()", "class.radio-small": "size() === \"small\"", "class.radio-large": "size() === \"large\"", "attr.data-state": "state()" } }, viewQueries: [{ propertyName: "labelSlot", first: true, predicate: ["labelSlot"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"radio-container\">\r\n <label class=\"radio-label\" [class.label-left]=\"labelPosition() === 'left'\">\r\n <input\r\n type=\"radio\"\r\n class=\"radio-input\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [name]=\"name()\"\r\n [attr.value]=\"value()\"\r\n [attr.aria-label]=\"computedAriaLabel()\"\r\n [attr.aria-required]=\"required() || null\"\r\n [attr.aria-invalid]=\"error() ? 'true' : null\"\r\n [attr.aria-checked]=\"checked()\"\r\n [attr.aria-describedby]=\"ariaDescribedBy()\"\r\n (change)=\"handleChange()\"\r\n (keydown)=\"handleKeydown($event)\"\r\n />\r\n <span \r\n class=\"radio-control\"\r\n [class.error]=\"!!error()\"\r\n [class.success]=\"!!success()\"\r\n >\r\n <span class=\"radio-dot\"></span>\r\n </span>\r\n <span class=\"radio-text\" #labelSlot>\r\n @if (label()) {\r\n {{ label() }}\r\n } @else {\r\n <ng-content></ng-content>\r\n }\r\n </span>\r\n </label>\r\n\r\n @if (error()) {\r\n <div [id]=\"errorMessageId()\" class=\"radio-error\" role=\"alert\">\r\n {{ error() }}\r\n </div>\r\n } @else if (success()) {\r\n <div [id]=\"successMessageId()\" class=\"radio-success\" role=\"status\">\r\n {{ success() }}\r\n </div>\r\n }\r\n</div>", styles: [".radio-container{display:inline-flex;flex-direction:column;gap:var(--form-field-gap)}.radio-label{display:inline-flex;align-items:center;gap:var(--form-label-gap);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--text-color)}.radio-label.label-left{flex-direction:row-reverse;justify-content:space-between}.radio-input{position:absolute;opacity:0;width:0;height:0}.radio-control{display:flex;align-items:center;justify-content:center;width:var(--size-5);height:var(--size-5);min-width:var(--size-5);min-height:var(--size-5);border:var(--border-width-2) solid var(--surface-border);border-radius:var(--radius-full);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);flex-shrink:0}.radio-dot{width:var(--size-2);height:var(--size-2);border-radius:var(--radius-full);background:var(--primary-color-text);opacity:0;transform:scale(.8);transition:all var(--animation-duration-fast) var(--animation-easing-default)}.radio-input:checked+.radio-control{background:var(--primary-color);border-color:var(--primary-color)}.radio-input:checked+.radio-control .radio-dot{opacity:1;transform:scale(1)}.radio-input:focus-visible+.radio-control{box-shadow:0 0 0 var(--focus-outline-width) var(--focus-ring-color)}:host(.radio-disabled) .radio-label{opacity:var(--opacity-disabled);cursor:not-allowed}:host(.radio-error) .radio-control{border-color:var(--danger-color)}:host(.radio-error) .radio-input:checked+.radio-control{background:var(--danger-color);border-color:var(--danger-color)}:host(.radio-success) .radio-control{border-color:var(--success-color)}:host(.radio-success) .radio-input:checked+.radio-control{background:var(--success-color);border-color:var(--success-color)}.radio-error{font-size:var(--font-size-sm);color:var(--danger-color)}.radio-success{font-size:var(--font-size-sm);color:var(--success-color)}:host(.radio-small) .radio-control{width:var(--size-4);height:var(--size-4);min-width:var(--size-4);min-height:var(--size-4)}:host(.radio-small) .radio-dot{width:var(--size-1-5);height:var(--size-1-5)}:host(.radio-small) .radio-text{font-size:var(--font-size-sm)}:host(.radio-large) .radio-control{width:var(--size-6);height:var(--size-6);min-width:var(--size-6);min-height:var(--size-6)}:host(.radio-large) .radio-dot{width:var(--size-3);height:var(--size-3)}:host(.radio-large) .radio-text{font-size:var(--font-size-lg)}.radio-text{color:var(--text-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3973
3983
  }
3974
3984
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PshRadioComponent, decorators: [{
3975
3985
  type: Component,
@@ -3980,8 +3990,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
3980
3990
  '[class.radio-small]': 'size() === "small"',
3981
3991
  '[class.radio-large]': 'size() === "large"',
3982
3992
  '[attr.data-state]': 'state()'
3983
- }, template: "<div class=\"radio-container\">\r\n <label class=\"radio-label\" [class.label-left]=\"labelPosition() === 'left'\">\r\n <input\r\n type=\"radio\"\r\n class=\"radio-input\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [name]=\"name()\"\r\n [attr.value]=\"value()\"\r\n [attr.aria-label]=\"computedAriaLabel()\"\r\n [attr.aria-required]=\"required() || null\"\r\n [attr.aria-invalid]=\"error() ? 'true' : null\"\r\n [attr.aria-checked]=\"checked()\"\r\n [attr.aria-describedby]=\"ariaDescribedBy()\"\r\n (change)=\"handleChange()\"\r\n (keydown)=\"handleKeydown($event)\"\r\n />\r\n <span \r\n class=\"radio-control\"\r\n [class.error]=\"!!error()\"\r\n [class.success]=\"!!success()\"\r\n >\r\n <span class=\"radio-dot\"></span>\r\n </span>\r\n <span class=\"radio-text\">\r\n @if (label()) {\r\n {{ label() }}\r\n } @else {\r\n <ng-content>Radio</ng-content>\r\n }\r\n </span>\r\n </label>\r\n\r\n @if (error()) {\r\n <div [id]=\"errorMessageId()\" class=\"radio-error\" role=\"alert\">\r\n {{ error() }}\r\n </div>\r\n } @else if (success()) {\r\n <div [id]=\"successMessageId()\" class=\"radio-success\" role=\"status\">\r\n {{ success() }}\r\n </div>\r\n }\r\n</div>", styles: [".radio-container{display:inline-flex;flex-direction:column;gap:var(--form-field-gap)}.radio-label{display:inline-flex;align-items:center;gap:var(--form-label-gap);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--text-color)}.radio-label.label-left{flex-direction:row-reverse;justify-content:space-between}.radio-input{position:absolute;opacity:0;width:0;height:0}.radio-control{display:flex;align-items:center;justify-content:center;width:var(--size-5);height:var(--size-5);min-width:var(--size-5);min-height:var(--size-5);border:var(--border-width-2) solid var(--surface-border);border-radius:var(--radius-full);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);flex-shrink:0}.radio-dot{width:var(--size-2);height:var(--size-2);border-radius:var(--radius-full);background:var(--primary-color-text);opacity:0;transform:scale(.8);transition:all var(--animation-duration-fast) var(--animation-easing-default)}.radio-input:checked+.radio-control{background:var(--primary-color);border-color:var(--primary-color)}.radio-input:checked+.radio-control .radio-dot{opacity:1;transform:scale(1)}.radio-input:focus-visible+.radio-control{box-shadow:0 0 0 var(--focus-outline-width) var(--focus-ring-color)}:host(.radio-disabled) .radio-label{opacity:var(--opacity-disabled);cursor:not-allowed}:host(.radio-error) .radio-control{border-color:var(--danger-color)}:host(.radio-error) .radio-input:checked+.radio-control{background:var(--danger-color);border-color:var(--danger-color)}:host(.radio-success) .radio-control{border-color:var(--success-color)}:host(.radio-success) .radio-input:checked+.radio-control{background:var(--success-color);border-color:var(--success-color)}.radio-error{font-size:var(--font-size-sm);color:var(--danger-color)}.radio-success{font-size:var(--font-size-sm);color:var(--success-color)}:host(.radio-small) .radio-control{width:var(--size-4);height:var(--size-4);min-width:var(--size-4);min-height:var(--size-4)}:host(.radio-small) .radio-dot{width:var(--size-1-5);height:var(--size-1-5)}:host(.radio-small) .radio-text{font-size:var(--font-size-sm)}:host(.radio-large) .radio-control{width:var(--size-6);height:var(--size-6);min-width:var(--size-6);min-height:var(--size-6)}:host(.radio-large) .radio-dot{width:var(--size-3);height:var(--size-3)}:host(.radio-large) .radio-text{font-size:var(--font-size-lg)}.radio-text{color:var(--text-color)}\n"] }]
3984
- }], ctorParameters: () => [], propDecorators: { checkedInput: [{
3993
+ }, template: "<div class=\"radio-container\">\r\n <label class=\"radio-label\" [class.label-left]=\"labelPosition() === 'left'\">\r\n <input\r\n type=\"radio\"\r\n class=\"radio-input\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [name]=\"name()\"\r\n [attr.value]=\"value()\"\r\n [attr.aria-label]=\"computedAriaLabel()\"\r\n [attr.aria-required]=\"required() || null\"\r\n [attr.aria-invalid]=\"error() ? 'true' : null\"\r\n [attr.aria-checked]=\"checked()\"\r\n [attr.aria-describedby]=\"ariaDescribedBy()\"\r\n (change)=\"handleChange()\"\r\n (keydown)=\"handleKeydown($event)\"\r\n />\r\n <span \r\n class=\"radio-control\"\r\n [class.error]=\"!!error()\"\r\n [class.success]=\"!!success()\"\r\n >\r\n <span class=\"radio-dot\"></span>\r\n </span>\r\n <span class=\"radio-text\" #labelSlot>\r\n @if (label()) {\r\n {{ label() }}\r\n } @else {\r\n <ng-content></ng-content>\r\n }\r\n </span>\r\n </label>\r\n\r\n @if (error()) {\r\n <div [id]=\"errorMessageId()\" class=\"radio-error\" role=\"alert\">\r\n {{ error() }}\r\n </div>\r\n } @else if (success()) {\r\n <div [id]=\"successMessageId()\" class=\"radio-success\" role=\"status\">\r\n {{ success() }}\r\n </div>\r\n }\r\n</div>", styles: [".radio-container{display:inline-flex;flex-direction:column;gap:var(--form-field-gap)}.radio-label{display:inline-flex;align-items:center;gap:var(--form-label-gap);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--text-color)}.radio-label.label-left{flex-direction:row-reverse;justify-content:space-between}.radio-input{position:absolute;opacity:0;width:0;height:0}.radio-control{display:flex;align-items:center;justify-content:center;width:var(--size-5);height:var(--size-5);min-width:var(--size-5);min-height:var(--size-5);border:var(--border-width-2) solid var(--surface-border);border-radius:var(--radius-full);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);flex-shrink:0}.radio-dot{width:var(--size-2);height:var(--size-2);border-radius:var(--radius-full);background:var(--primary-color-text);opacity:0;transform:scale(.8);transition:all var(--animation-duration-fast) var(--animation-easing-default)}.radio-input:checked+.radio-control{background:var(--primary-color);border-color:var(--primary-color)}.radio-input:checked+.radio-control .radio-dot{opacity:1;transform:scale(1)}.radio-input:focus-visible+.radio-control{box-shadow:0 0 0 var(--focus-outline-width) var(--focus-ring-color)}:host(.radio-disabled) .radio-label{opacity:var(--opacity-disabled);cursor:not-allowed}:host(.radio-error) .radio-control{border-color:var(--danger-color)}:host(.radio-error) .radio-input:checked+.radio-control{background:var(--danger-color);border-color:var(--danger-color)}:host(.radio-success) .radio-control{border-color:var(--success-color)}:host(.radio-success) .radio-input:checked+.radio-control{background:var(--success-color);border-color:var(--success-color)}.radio-error{font-size:var(--font-size-sm);color:var(--danger-color)}.radio-success{font-size:var(--font-size-sm);color:var(--success-color)}:host(.radio-small) .radio-control{width:var(--size-4);height:var(--size-4);min-width:var(--size-4);min-height:var(--size-4)}:host(.radio-small) .radio-dot{width:var(--size-1-5);height:var(--size-1-5)}:host(.radio-small) .radio-text{font-size:var(--font-size-sm)}:host(.radio-large) .radio-control{width:var(--size-6);height:var(--size-6);min-width:var(--size-6);min-height:var(--size-6)}:host(.radio-large) .radio-dot{width:var(--size-3);height:var(--size-3)}:host(.radio-large) .radio-text{font-size:var(--font-size-lg)}.radio-text{color:var(--text-color)}\n"] }]
3994
+ }], propDecorators: { labelSlot: [{ type: i0.ViewChild, args: ['labelSlot', { isSignal: true }] }], checkedInput: [{
3985
3995
  type: Input,
3986
3996
  args: ['checked']
3987
3997
  }], disabledInput: [{