ps-helix 6.2.1 → 6.2.2
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 +3 -3
- package/fesm2022/ps-helix.mjs +36 -16
- package/fesm2022/ps-helix.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ps-helix.d.ts +21 -14
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
|
-
[](https://www.npmjs.com/package/ps-helix)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
[](https://angular.dev/)
|
|
8
8
|
[](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.
|
|
109
|
+
"ps-helix": "^6.2.2"
|
|
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.
|
|
1185
|
+
**Version**: 6.2.2
|
|
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
|
package/fesm2022/ps-helix.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, output, computed, ChangeDetectionStrategy, Component, model, inject, ElementRef, signal, PLATFORM_ID, ViewEncapsulation, InjectionToken, viewChild,
|
|
2
|
+
import { input, output, computed, ChangeDetectionStrategy, Component, model, inject, ElementRef, signal, PLATFORM_ID, ViewEncapsulation, InjectionToken, viewChild, isDevMode, Injectable, DestroyRef, Directive, ViewContainerRef, ChangeDetectorRef, effect, ViewChild, Injector, afterNextRender, HostListener, Renderer2, contentChild, linkedSignal, EventEmitter, Output, Input, contentChildren } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule, DOCUMENT, isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
|
|
5
5
|
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
|
|
@@ -1210,6 +1210,9 @@ class PshCheckboxComponent {
|
|
|
1210
1210
|
this.config = inject(CHECKBOX_CONFIG);
|
|
1211
1211
|
this.checkboxInput = viewChild('checkboxInput', /* @ts-ignore */
|
|
1212
1212
|
...(ngDevMode ? [{ debugName: "checkboxInput" }] : /* istanbul ignore next */ []));
|
|
1213
|
+
/** Holds the `label` input or the projected content — whichever provides the visible label. */
|
|
1214
|
+
this.labelSlot = viewChild('labelSlot', /* @ts-ignore */
|
|
1215
|
+
...(ngDevMode ? [{ debugName: "labelSlot" }] : /* istanbul ignore next */ []));
|
|
1213
1216
|
this.uniqueId = `psh-cb-${++checkboxIdCounter}`;
|
|
1214
1217
|
this.onChange = (_) => { };
|
|
1215
1218
|
this.onTouched = () => { };
|
|
@@ -1261,11 +1264,17 @@ class PshCheckboxComponent {
|
|
|
1261
1264
|
return this.checked() ? 'checked' : 'unchecked';
|
|
1262
1265
|
}, /* @ts-ignore */
|
|
1263
1266
|
...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1267
|
+
}
|
|
1268
|
+
ngAfterViewInit() {
|
|
1269
|
+
if (!isDevMode())
|
|
1270
|
+
return;
|
|
1271
|
+
// Read the rendered label slot rather than the `label` input alone: a projected
|
|
1272
|
+
// label (`<psh-checkbox>Accept terms</psh-checkbox>`) is just as accessible, and
|
|
1273
|
+
// `contentChild` cannot see a bare text node. Checked once, after the first render.
|
|
1274
|
+
const hasVisibleLabel = !!this.labelSlot()?.nativeElement.textContent?.trim();
|
|
1275
|
+
if (!hasVisibleLabel && !this.ariaLabel()) {
|
|
1276
|
+
console.warn('[psh-checkbox] No accessible label provided. Please use label input, ariaLabel input, or projected content.');
|
|
1277
|
+
}
|
|
1269
1278
|
}
|
|
1270
1279
|
toggle() {
|
|
1271
1280
|
if (!this.disabled()) {
|
|
@@ -1296,7 +1305,7 @@ class PshCheckboxComponent {
|
|
|
1296
1305
|
provide: NG_VALUE_ACCESSOR,
|
|
1297
1306
|
useExisting: PshCheckboxComponent,
|
|
1298
1307
|
multi: true
|
|
1299
|
-
}], viewQueries: [{ propertyName: "checkboxInput", first: true, predicate: ["checkboxInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"checkbox-container\">\r\n <label class=\"checkbox-label\" [class.label-left]=\"labelPosition() === 'left'\">\r\n <input\r\n #checkboxInput\r\n type=\"checkbox\"\r\n class=\"checkbox-input\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [attr.aria-label]=\"computedAriaLabel()\"\r\n [attr.aria-checked]=\"ariaChecked()\"\r\n [attr.aria-required]=\"required() || null\"\r\n [attr.aria-invalid]=\"error() ? 'true' : null\"\r\n [attr.aria-describedby]=\"ariaDescribedBy()\"\r\n (change)=\"toggle()\"\r\n (keydown)=\"handleKeydown($event)\"\r\n />\r\n \r\n <span class=\"checkbox-control\">\r\n @if (checked() && !indeterminate()) {\r\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\r\n }\r\n @if (indeterminate()) {\r\n <i class=\"ph ph-minus\" aria-hidden=\"true\"></i>\r\n }\r\n </span>\r\n\r\n <span class=\"checkbox-text\">\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]=\"uniqueId + '-error'\" class=\"checkbox-message error\" role=\"alert\">\r\n {{ error() }}\r\n </div>\r\n } @else if (success()) {\r\n <div [id]=\"uniqueId + '-success'\" class=\"checkbox-message success\" role=\"status\">\r\n {{ success() }}\r\n </div>\r\n }\r\n</div>", styles: [":host{display:inline-flex;flex-direction:column}.checkbox-container{display:flex;flex-direction:column;gap:var(--form-field-gap)}.checkbox-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)}.checkbox-label.label-left{flex-direction:row-reverse;justify-content:space-between}.checkbox-input{position:absolute;opacity:0;width:0;height:0}.checkbox-control{display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border:.125rem solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);color:#fff;position:relative;flex-shrink:0}:host.checkbox-checked .checkbox-control,:host.checkbox-indeterminate .checkbox-control{background:var(--primary-color);border-color:var(--primary-color)}.checkbox-input:focus-visible+.checkbox-control{outline:.125rem solid var(--focus-outline-color);outline-offset:.125rem}.checkbox-control i{font-size:.875rem;line-height:1}:host.checkbox-small .checkbox-control{width:1rem;height:1rem}:host.checkbox-large .checkbox-control{width:1.5rem;height:1.5rem}:host.checkbox-error .checkbox-control{border-color:var(--danger-color)}:host.checkbox-error.checkbox-checked .checkbox-control{background:var(--danger-color)}:host.checkbox-success .checkbox-control{border-color:var(--success-color)}:host.checkbox-success.checkbox-checked .checkbox-control{background:var(--success-color)}:host.checkbox-disabled{opacity:var(--opacity-disabled);cursor:not-allowed}:host.checkbox-disabled .checkbox-label{cursor:not-allowed}.checkbox-message{font-size:.875rem}.checkbox-message.error{color:var(--danger-color)}.checkbox-message.success{color:var(--success-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1308
|
+
}], viewQueries: [{ propertyName: "checkboxInput", first: true, predicate: ["checkboxInput"], descendants: true, isSignal: true }, { propertyName: "labelSlot", first: true, predicate: ["labelSlot"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"checkbox-container\">\r\n <label class=\"checkbox-label\" [class.label-left]=\"labelPosition() === 'left'\">\r\n <input\r\n #checkboxInput\r\n type=\"checkbox\"\r\n class=\"checkbox-input\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [attr.aria-label]=\"computedAriaLabel()\"\r\n [attr.aria-checked]=\"ariaChecked()\"\r\n [attr.aria-required]=\"required() || null\"\r\n [attr.aria-invalid]=\"error() ? 'true' : null\"\r\n [attr.aria-describedby]=\"ariaDescribedBy()\"\r\n (change)=\"toggle()\"\r\n (keydown)=\"handleKeydown($event)\"\r\n />\r\n \r\n <span class=\"checkbox-control\">\r\n @if (checked() && !indeterminate()) {\r\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\r\n }\r\n @if (indeterminate()) {\r\n <i class=\"ph ph-minus\" aria-hidden=\"true\"></i>\r\n }\r\n </span>\r\n\r\n <span class=\"checkbox-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]=\"uniqueId + '-error'\" class=\"checkbox-message error\" role=\"alert\">\r\n {{ error() }}\r\n </div>\r\n } @else if (success()) {\r\n <div [id]=\"uniqueId + '-success'\" class=\"checkbox-message success\" role=\"status\">\r\n {{ success() }}\r\n </div>\r\n }\r\n</div>", styles: [":host{display:inline-flex;flex-direction:column}.checkbox-container{display:flex;flex-direction:column;gap:var(--form-field-gap)}.checkbox-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)}.checkbox-label.label-left{flex-direction:row-reverse;justify-content:space-between}.checkbox-input{position:absolute;opacity:0;width:0;height:0}.checkbox-control{display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border:.125rem solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);color:#fff;position:relative;flex-shrink:0}:host.checkbox-checked .checkbox-control,:host.checkbox-indeterminate .checkbox-control{background:var(--primary-color);border-color:var(--primary-color)}.checkbox-input:focus-visible+.checkbox-control{outline:.125rem solid var(--focus-outline-color);outline-offset:.125rem}.checkbox-control i{font-size:.875rem;line-height:1}:host.checkbox-small .checkbox-control{width:1rem;height:1rem}:host.checkbox-large .checkbox-control{width:1.5rem;height:1.5rem}:host.checkbox-error .checkbox-control{border-color:var(--danger-color)}:host.checkbox-error.checkbox-checked .checkbox-control{background:var(--danger-color)}:host.checkbox-success .checkbox-control{border-color:var(--success-color)}:host.checkbox-success.checkbox-checked .checkbox-control{background:var(--success-color)}:host.checkbox-disabled{opacity:var(--opacity-disabled);cursor:not-allowed}:host.checkbox-disabled .checkbox-label{cursor:not-allowed}.checkbox-message{font-size:.875rem}.checkbox-message.error{color:var(--danger-color)}.checkbox-message.success{color:var(--success-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1300
1309
|
}
|
|
1301
1310
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: PshCheckboxComponent, decorators: [{
|
|
1302
1311
|
type: Component,
|
|
@@ -1314,8 +1323,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
1314
1323
|
'[class.checkbox-indeterminate]': 'indeterminate()',
|
|
1315
1324
|
'[attr.data-state]': 'state()',
|
|
1316
1325
|
'[attr.aria-checked]': 'ariaChecked()'
|
|
1317
|
-
}, template: "<div class=\"checkbox-container\">\r\n <label class=\"checkbox-label\" [class.label-left]=\"labelPosition() === 'left'\">\r\n <input\r\n #checkboxInput\r\n type=\"checkbox\"\r\n class=\"checkbox-input\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [attr.aria-label]=\"computedAriaLabel()\"\r\n [attr.aria-checked]=\"ariaChecked()\"\r\n [attr.aria-required]=\"required() || null\"\r\n [attr.aria-invalid]=\"error() ? 'true' : null\"\r\n [attr.aria-describedby]=\"ariaDescribedBy()\"\r\n (change)=\"toggle()\"\r\n (keydown)=\"handleKeydown($event)\"\r\n />\r\n \r\n <span class=\"checkbox-control\">\r\n @if (checked() && !indeterminate()) {\r\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\r\n }\r\n @if (indeterminate()) {\r\n <i class=\"ph ph-minus\" aria-hidden=\"true\"></i>\r\n }\r\n </span>\r\n\r\n <span class=\"checkbox-text\">\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]=\"uniqueId + '-error'\" class=\"checkbox-message error\" role=\"alert\">\r\n {{ error() }}\r\n </div>\r\n } @else if (success()) {\r\n <div [id]=\"uniqueId + '-success'\" class=\"checkbox-message success\" role=\"status\">\r\n {{ success() }}\r\n </div>\r\n }\r\n</div>", styles: [":host{display:inline-flex;flex-direction:column}.checkbox-container{display:flex;flex-direction:column;gap:var(--form-field-gap)}.checkbox-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)}.checkbox-label.label-left{flex-direction:row-reverse;justify-content:space-between}.checkbox-input{position:absolute;opacity:0;width:0;height:0}.checkbox-control{display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border:.125rem solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);color:#fff;position:relative;flex-shrink:0}:host.checkbox-checked .checkbox-control,:host.checkbox-indeterminate .checkbox-control{background:var(--primary-color);border-color:var(--primary-color)}.checkbox-input:focus-visible+.checkbox-control{outline:.125rem solid var(--focus-outline-color);outline-offset:.125rem}.checkbox-control i{font-size:.875rem;line-height:1}:host.checkbox-small .checkbox-control{width:1rem;height:1rem}:host.checkbox-large .checkbox-control{width:1.5rem;height:1.5rem}:host.checkbox-error .checkbox-control{border-color:var(--danger-color)}:host.checkbox-error.checkbox-checked .checkbox-control{background:var(--danger-color)}:host.checkbox-success .checkbox-control{border-color:var(--success-color)}:host.checkbox-success.checkbox-checked .checkbox-control{background:var(--success-color)}:host.checkbox-disabled{opacity:var(--opacity-disabled);cursor:not-allowed}:host.checkbox-disabled .checkbox-label{cursor:not-allowed}.checkbox-message{font-size:.875rem}.checkbox-message.error{color:var(--danger-color)}.checkbox-message.success{color:var(--success-color)}\n"] }]
|
|
1318
|
-
}],
|
|
1326
|
+
}, template: "<div class=\"checkbox-container\">\r\n <label class=\"checkbox-label\" [class.label-left]=\"labelPosition() === 'left'\">\r\n <input\r\n #checkboxInput\r\n type=\"checkbox\"\r\n class=\"checkbox-input\"\r\n [checked]=\"checked()\"\r\n [disabled]=\"disabled()\"\r\n [required]=\"required()\"\r\n [attr.aria-label]=\"computedAriaLabel()\"\r\n [attr.aria-checked]=\"ariaChecked()\"\r\n [attr.aria-required]=\"required() || null\"\r\n [attr.aria-invalid]=\"error() ? 'true' : null\"\r\n [attr.aria-describedby]=\"ariaDescribedBy()\"\r\n (change)=\"toggle()\"\r\n (keydown)=\"handleKeydown($event)\"\r\n />\r\n \r\n <span class=\"checkbox-control\">\r\n @if (checked() && !indeterminate()) {\r\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\r\n }\r\n @if (indeterminate()) {\r\n <i class=\"ph ph-minus\" aria-hidden=\"true\"></i>\r\n }\r\n </span>\r\n\r\n <span class=\"checkbox-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]=\"uniqueId + '-error'\" class=\"checkbox-message error\" role=\"alert\">\r\n {{ error() }}\r\n </div>\r\n } @else if (success()) {\r\n <div [id]=\"uniqueId + '-success'\" class=\"checkbox-message success\" role=\"status\">\r\n {{ success() }}\r\n </div>\r\n }\r\n</div>", styles: [":host{display:inline-flex;flex-direction:column}.checkbox-container{display:flex;flex-direction:column;gap:var(--form-field-gap)}.checkbox-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)}.checkbox-label.label-left{flex-direction:row-reverse;justify-content:space-between}.checkbox-input{position:absolute;opacity:0;width:0;height:0}.checkbox-control{display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border:.125rem solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);color:#fff;position:relative;flex-shrink:0}:host.checkbox-checked .checkbox-control,:host.checkbox-indeterminate .checkbox-control{background:var(--primary-color);border-color:var(--primary-color)}.checkbox-input:focus-visible+.checkbox-control{outline:.125rem solid var(--focus-outline-color);outline-offset:.125rem}.checkbox-control i{font-size:.875rem;line-height:1}:host.checkbox-small .checkbox-control{width:1rem;height:1rem}:host.checkbox-large .checkbox-control{width:1.5rem;height:1.5rem}:host.checkbox-error .checkbox-control{border-color:var(--danger-color)}:host.checkbox-error.checkbox-checked .checkbox-control{background:var(--danger-color)}:host.checkbox-success .checkbox-control{border-color:var(--success-color)}:host.checkbox-success.checkbox-checked .checkbox-control{background:var(--success-color)}:host.checkbox-disabled{opacity:var(--opacity-disabled);cursor:not-allowed}:host.checkbox-disabled .checkbox-label{cursor:not-allowed}.checkbox-message{font-size:.875rem}.checkbox-message.error{color:var(--danger-color)}.checkbox-message.success{color:var(--success-color)}\n"] }]
|
|
1327
|
+
}], propDecorators: { checkboxInput: [{ type: i0.ViewChild, args: ['checkboxInput', { isSignal: true }] }], labelSlot: [{ type: i0.ViewChild, args: ['labelSlot', { isSignal: true }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }, { type: i0.Output, args: ["indeterminateChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], success: [{ type: i0.Input, args: [{ isSignal: true, alias: "success", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }] } });
|
|
1319
1328
|
|
|
1320
1329
|
class PshCollapseComponent {
|
|
1321
1330
|
constructor() {
|
|
@@ -1325,14 +1334,18 @@ class PshCollapseComponent {
|
|
|
1325
1334
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
1326
1335
|
this.variant = input('default', { ...(ngDevMode ? { debugName: "variant" } : /* istanbul ignore next */ {}), transform: (value) => {
|
|
1327
1336
|
if (!['default', 'outline'].includes(value)) {
|
|
1328
|
-
|
|
1337
|
+
if (isDevMode()) {
|
|
1338
|
+
console.warn(`[psh-collapse] Invalid variant "${value}", falling back to "default"`);
|
|
1339
|
+
}
|
|
1329
1340
|
return 'default';
|
|
1330
1341
|
}
|
|
1331
1342
|
return value;
|
|
1332
1343
|
} });
|
|
1333
1344
|
this.size = input('medium', { ...(ngDevMode ? { debugName: "size" } : /* istanbul ignore next */ {}), transform: (value) => {
|
|
1334
1345
|
if (!['small', 'medium', 'large'].includes(value)) {
|
|
1335
|
-
|
|
1346
|
+
if (isDevMode()) {
|
|
1347
|
+
console.warn(`[psh-collapse] Invalid size "${value}", falling back to "medium"`);
|
|
1348
|
+
}
|
|
1336
1349
|
return 'medium';
|
|
1337
1350
|
}
|
|
1338
1351
|
return value;
|
|
@@ -3890,11 +3903,13 @@ class PshRadioComponent {
|
|
|
3890
3903
|
// so aria-describedby references whichever message is actually rendered.
|
|
3891
3904
|
this.ariaDescribedBy = computed(() => this.errorMessageId() ?? this.successMessageId(), /* @ts-ignore */
|
|
3892
3905
|
...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : /* istanbul ignore next */ []));
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
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
|
+
});
|
|
3912
|
+
}
|
|
3898
3913
|
}
|
|
3899
3914
|
getState() {
|
|
3900
3915
|
if (this.disabled())
|
|
@@ -3905,6 +3920,11 @@ class PshRadioComponent {
|
|
|
3905
3920
|
return 'success';
|
|
3906
3921
|
return this.checked() ? 'checked' : 'unchecked';
|
|
3907
3922
|
}
|
|
3923
|
+
/**
|
|
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.
|
|
3927
|
+
*/
|
|
3908
3928
|
updateProjectedContent(hasContent) {
|
|
3909
3929
|
this.hasProjectedContent.set(hasContent);
|
|
3910
3930
|
}
|