@colletdev/angular 0.1.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.
Files changed (53) hide show
  1. package/README.md +60 -0
  2. package/package.json +43 -0
  3. package/src/accordion.component.ts +97 -0
  4. package/src/activity-group.component.ts +61 -0
  5. package/src/alert.component.ts +75 -0
  6. package/src/autocomplete.component.ts +196 -0
  7. package/src/avatar.component.ts +59 -0
  8. package/src/backdrop.component.ts +51 -0
  9. package/src/badge.component.ts +67 -0
  10. package/src/breadcrumb.component.ts +77 -0
  11. package/src/button.component.ts +74 -0
  12. package/src/card.component.ts +72 -0
  13. package/src/carousel.component.ts +96 -0
  14. package/src/chat-input.component.ts +116 -0
  15. package/src/checkbox.component.ts +121 -0
  16. package/src/code-block.component.ts +67 -0
  17. package/src/collapsible.component.ts +72 -0
  18. package/src/date-picker.component.ts +159 -0
  19. package/src/dialog.component.ts +67 -0
  20. package/src/drawer.component.ts +67 -0
  21. package/src/fab.component.ts +70 -0
  22. package/src/file-upload.component.ts +77 -0
  23. package/src/index.ts +99 -0
  24. package/src/listbox.component.ts +121 -0
  25. package/src/menu.component.ts +99 -0
  26. package/src/message-bubble.component.ts +67 -0
  27. package/src/message-group.component.ts +77 -0
  28. package/src/message-part.component.ts +47 -0
  29. package/src/pagination.component.ts +67 -0
  30. package/src/popover.component.ts +77 -0
  31. package/src/profile-menu.component.ts +87 -0
  32. package/src/progress.component.ts +60 -0
  33. package/src/radio-group.component.ts +138 -0
  34. package/src/scrollbar.component.ts +59 -0
  35. package/src/search-bar.component.ts +127 -0
  36. package/src/select.component.ts +181 -0
  37. package/src/sidebar.component.ts +91 -0
  38. package/src/skeleton.component.ts +57 -0
  39. package/src/slider.component.ts +134 -0
  40. package/src/speed-dial.component.ts +100 -0
  41. package/src/spinner.component.ts +53 -0
  42. package/src/split-button.component.ts +97 -0
  43. package/src/stepper.component.ts +83 -0
  44. package/src/switch.component.ts +123 -0
  45. package/src/table.component.ts +219 -0
  46. package/src/tabs.component.ts +82 -0
  47. package/src/text-input.component.ts +158 -0
  48. package/src/text.component.ts +73 -0
  49. package/src/thinking.component.ts +57 -0
  50. package/src/toast.component.ts +72 -0
  51. package/src/toggle-group.component.ts +123 -0
  52. package/src/tooltip.component.ts +61 -0
  53. package/src/types.ts +334 -0
@@ -0,0 +1,134 @@
1
+ // Auto-generated by scripts/generate-angular.mjs — DO NOT EDIT
2
+ // Angular wrapper for <cx-slider>
3
+ import {
4
+ Component,
5
+ CUSTOM_ELEMENTS_SCHEMA,
6
+ ChangeDetectionStrategy,
7
+ ChangeDetectorRef,
8
+ ElementRef,
9
+ ViewChild,
10
+ Input,
11
+ Output,
12
+ EventEmitter,
13
+ AfterViewInit,
14
+ forwardRef,
15
+ } from '@angular/core';
16
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
17
+ import type { FocusDetail, KeyboardDetail, SliderDetail } from './types.js';
18
+
19
+ @Component({
20
+ selector: 'cx-slider[collet]',
21
+ standalone: true,
22
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
23
+ changeDetection: ChangeDetectionStrategy.OnPush,
24
+ providers: [{
25
+ provide: NG_VALUE_ACCESSOR,
26
+ useExisting: forwardRef(() => CxSlider),
27
+ multi: true,
28
+ }],
29
+ template: `
30
+ <cx-slider
31
+ [attr.id]="id"
32
+ [attr.label]="label"
33
+ [attr.aria-label]="ariaLabel"
34
+ [attr.value]="value"
35
+ [attr.min]="min"
36
+ [attr.max]="max"
37
+ [attr.step]="step"
38
+ [attr.orientation]="orientation"
39
+ [attr.shape]="shape"
40
+ [attr.intent]="intent"
41
+ [attr.size]="size"
42
+ [attr.show-value]="showValue || null"
43
+ [attr.value-text]="valueText"
44
+ [attr.helper-text]="helperText"
45
+ [attr.error-text]="errorText"
46
+ [attr.disabled]="disabled || null"
47
+ [attr.unlabeled]="unlabeled || null"
48
+ #el
49
+ ><ng-content /></cx-slider>
50
+ `,
51
+ })
52
+ export class CxSlider implements AfterViewInit, ControlValueAccessor {
53
+ @ViewChild('el', { static: true }) el!: ElementRef<HTMLElement>;
54
+
55
+ @Input() id?: string = undefined;
56
+ @Input() label?: string = undefined;
57
+ @Input() ariaLabel?: string = undefined;
58
+ @Input() value?: number = undefined;
59
+ @Input() min?: number = undefined;
60
+ @Input() max?: number = undefined;
61
+ @Input() step?: number = undefined;
62
+ @Input() orientation?: 'horizontal' | 'vertical' = undefined;
63
+ @Input() shape?: 'sharp' | 'rounded' | 'pill' = undefined;
64
+ @Input() intent?: 'neutral' | 'primary' | 'info' | 'success' | 'warning' | 'danger' = undefined;
65
+ @Input() size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = undefined;
66
+ @Input() showValue?: boolean = undefined;
67
+ @Input() valueText?: string = undefined;
68
+ @Input() helperText?: string = undefined;
69
+ @Input() errorText?: string = undefined;
70
+ @Input() disabled?: boolean = undefined;
71
+ @Input() unlabeled?: boolean = undefined;
72
+
73
+ @Output() cxInput = new EventEmitter<CustomEvent<SliderDetail>>();
74
+ @Output() cxChange = new EventEmitter<CustomEvent>();
75
+ @Output() cxFocus = new EventEmitter<CustomEvent<FocusDetail>>();
76
+ @Output() cxBlur = new EventEmitter<CustomEvent<FocusDetail>>();
77
+ @Output() cxKeydown = new EventEmitter<CustomEvent<KeyboardDetail>>();
78
+ @Output() cxKeyup = new EventEmitter<CustomEvent<KeyboardDetail>>();
79
+
80
+ constructor(private c: ChangeDetectorRef) {
81
+ c.detach();
82
+ }
83
+
84
+ ngAfterViewInit(): void {
85
+ this.el.nativeElement.addEventListener('cx-input', (e: Event) => {
86
+ this.cxInput.emit(e as CustomEvent);
87
+ });
88
+ this.el.nativeElement.addEventListener('cx-change', (e: Event) => {
89
+ this.cxChange.emit(e as CustomEvent);
90
+ });
91
+ this.el.nativeElement.addEventListener('cx-focus', (e: Event) => {
92
+ this.cxFocus.emit(e as CustomEvent);
93
+ });
94
+ this.el.nativeElement.addEventListener('cx-blur', (e: Event) => {
95
+ this.cxBlur.emit(e as CustomEvent);
96
+ });
97
+ this.el.nativeElement.addEventListener('cx-keydown', (e: Event) => {
98
+ this.cxKeydown.emit(e as CustomEvent);
99
+ });
100
+ this.el.nativeElement.addEventListener('cx-keyup', (e: Event) => {
101
+ this.cxKeyup.emit(e as CustomEvent);
102
+ });
103
+ // CVA: sync CE value changes back to Angular forms
104
+ this.el.nativeElement.addEventListener('cx-change', (e: Event) => {
105
+ this._onChange((e as CustomEvent).detail?.value);
106
+ });
107
+ this.el.nativeElement.addEventListener('focusout', () => {
108
+ this._onTouched();
109
+ });
110
+ }
111
+
112
+
113
+
114
+ /** Focuses the range input. */
115
+ focus(): void { (this.el.nativeElement as any).focus(); }
116
+
117
+ // ── ControlValueAccessor ──
118
+ private _onChange: (value: any) => void = () => {};
119
+ private _onTouched: () => void = () => {};
120
+
121
+ writeValue(value: any): void {
122
+ if (this.el) (this.el.nativeElement as any).value = value ?? '';
123
+ }
124
+
125
+ registerOnChange(fn: (value: any) => void): void { this._onChange = fn; }
126
+ registerOnTouched(fn: () => void): void { this._onTouched = fn; }
127
+
128
+ setDisabledState(isDisabled: boolean): void {
129
+ if (this.el) {
130
+ if (isDisabled) this.el.nativeElement.setAttribute('disabled', '');
131
+ else this.el.nativeElement.removeAttribute('disabled');
132
+ }
133
+ }
134
+ }
@@ -0,0 +1,100 @@
1
+ // Auto-generated by scripts/generate-angular.mjs — DO NOT EDIT
2
+ // Angular wrapper for <cx-speed-dial>
3
+ import {
4
+ Component,
5
+ CUSTOM_ELEMENTS_SCHEMA,
6
+ ChangeDetectionStrategy,
7
+ ChangeDetectorRef,
8
+ ElementRef,
9
+ ViewChild,
10
+ Input,
11
+ Output,
12
+ EventEmitter,
13
+ OnChanges,
14
+ SimpleChanges,
15
+ AfterViewInit,
16
+ } from '@angular/core';
17
+ import type { CollapsibleDetail, MenuActionDetail, SpeedDialAction } from './types.js';
18
+
19
+ @Component({
20
+ selector: 'cx-speed-dial[collet]',
21
+ standalone: true,
22
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
23
+ changeDetection: ChangeDetectionStrategy.OnPush,
24
+ template: `
25
+ <cx-speed-dial
26
+ [attr.id]="id"
27
+ [attr.icon]="icon"
28
+ [attr.aria-label]="ariaLabel"
29
+ [attr.close-icon]="closeIcon"
30
+ [actions]="_serialize_actions()"
31
+ [attr.variant]="variant"
32
+ [attr.shape]="shape"
33
+ [attr.size]="size"
34
+ [attr.direction]="direction"
35
+ [attr.backdrop]="backdrop || null"
36
+ [attr.tooltips]="tooltips || null"
37
+ [attr.disabled]="disabled || null"
38
+ #el
39
+ ><ng-content /></cx-speed-dial>
40
+ `,
41
+ })
42
+ export class CxSpeedDial implements AfterViewInit, OnChanges {
43
+ @ViewChild('el', { static: true }) el!: ElementRef<HTMLElement>;
44
+
45
+ @Input() id!: string;
46
+ @Input() icon!: string;
47
+ @Input() ariaLabel?: string = undefined;
48
+ @Input() closeIcon?: string = undefined;
49
+ @Input() actions?: SpeedDialAction[] | string = undefined;
50
+ @Input() variant?: 'filled' | 'outline' | 'ghost' = undefined;
51
+ @Input() shape?: 'rounded' | 'pill' = undefined;
52
+ @Input() size?: 'sm' | 'md' | 'lg' = undefined;
53
+ @Input() direction?: 'up' | 'down' | 'left' | 'right' = undefined;
54
+ @Input() backdrop?: boolean = undefined;
55
+ @Input() tooltips?: boolean = undefined;
56
+ @Input() disabled?: boolean = undefined;
57
+
58
+ @Output() cxAction = new EventEmitter<CustomEvent<MenuActionDetail>>();
59
+ @Output() cxChange = new EventEmitter<CustomEvent<CollapsibleDetail>>();
60
+
61
+ constructor(private c: ChangeDetectorRef) {
62
+ c.detach();
63
+ }
64
+
65
+ ngAfterViewInit(): void {
66
+ this.el.nativeElement.addEventListener('cx-action', (e: Event) => {
67
+ this.cxAction.emit(e as CustomEvent);
68
+ });
69
+ this.el.nativeElement.addEventListener('cx-change', (e: Event) => {
70
+ this.cxChange.emit(e as CustomEvent);
71
+ });
72
+ }
73
+
74
+ ngOnChanges(changes: SimpleChanges): void {
75
+ if (changes['actions'] && this.el) {
76
+ const val = this.actions;
77
+ if (val != null) {
78
+ this.el.nativeElement.setAttribute('actions', typeof val === 'object' ? JSON.stringify(val) : String(val));
79
+ } else {
80
+ this.el.nativeElement.removeAttribute('actions');
81
+ }
82
+ }
83
+ }
84
+
85
+ _serialize_actions(): string | null {
86
+ const val = this.actions;
87
+ if (val == null) return null;
88
+ return typeof val === 'object' ? JSON.stringify(val) : String(val);
89
+ }
90
+
91
+ /** Opens the speed dial action menu. */
92
+ open(): void { (this.el.nativeElement as any).open(); }
93
+
94
+ /** Closes the speed dial action menu. */
95
+ close(): void { (this.el.nativeElement as any).close(); }
96
+
97
+ /** Toggles the speed dial action menu. */
98
+ toggle(): void { (this.el.nativeElement as any).toggle(); }
99
+
100
+ }
@@ -0,0 +1,53 @@
1
+ // Auto-generated by scripts/generate-angular.mjs — DO NOT EDIT
2
+ // Angular wrapper for <cx-spinner>
3
+ import {
4
+ Component,
5
+ CUSTOM_ELEMENTS_SCHEMA,
6
+ ChangeDetectionStrategy,
7
+ ChangeDetectorRef,
8
+ ElementRef,
9
+ ViewChild,
10
+ Input,
11
+ Output,
12
+ EventEmitter,
13
+ AfterViewInit,
14
+ } from '@angular/core';
15
+
16
+ @Component({
17
+ selector: 'cx-spinner[collet]',
18
+ standalone: true,
19
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
20
+ changeDetection: ChangeDetectionStrategy.OnPush,
21
+ template: `
22
+ <cx-spinner
23
+ [attr.id]="id"
24
+ [attr.variant]="variant"
25
+ [attr.label]="label"
26
+ [attr.size]="size"
27
+ #el
28
+ ><ng-content /></cx-spinner>
29
+ `,
30
+ })
31
+ export class CxSpinner implements AfterViewInit {
32
+ @ViewChild('el', { static: true }) el!: ElementRef<HTMLElement>;
33
+
34
+ @Input() id?: string = undefined;
35
+ @Input() variant?: 'circle' | 'square' = undefined;
36
+ @Input() label?: string = undefined;
37
+ @Input() size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = undefined;
38
+
39
+
40
+
41
+ constructor(private c: ChangeDetectorRef) {
42
+ c.detach();
43
+ }
44
+
45
+ ngAfterViewInit(): void {
46
+
47
+ }
48
+
49
+
50
+
51
+
52
+
53
+ }
@@ -0,0 +1,97 @@
1
+ // Auto-generated by scripts/generate-angular.mjs — DO NOT EDIT
2
+ // Angular wrapper for <cx-split-button>
3
+ import {
4
+ Component,
5
+ CUSTOM_ELEMENTS_SCHEMA,
6
+ ChangeDetectionStrategy,
7
+ ChangeDetectorRef,
8
+ ElementRef,
9
+ ViewChild,
10
+ Input,
11
+ Output,
12
+ EventEmitter,
13
+ OnChanges,
14
+ SimpleChanges,
15
+ AfterViewInit,
16
+ } from '@angular/core';
17
+ import type { ClickDetail, MenuActionDetail, SplitMenuEntry } from './types.js';
18
+
19
+ @Component({
20
+ selector: 'cx-split-button[collet]',
21
+ standalone: true,
22
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
23
+ changeDetection: ChangeDetectionStrategy.OnPush,
24
+ template: `
25
+ <cx-split-button
26
+ [attr.id]="id"
27
+ [attr.label]="label"
28
+ [entries]="_serialize_entries()"
29
+ [attr.variant]="variant"
30
+ [attr.intent]="intent"
31
+ [attr.shape]="shape"
32
+ [attr.size]="size"
33
+ [attr.icon-leading]="iconLeading"
34
+ [attr.disabled]="disabled || null"
35
+ [attr.primary-disabled]="primaryDisabled || null"
36
+ [attr.trigger-disabled]="triggerDisabled || null"
37
+ [attr.trigger-label]="triggerLabel"
38
+ #el
39
+ ><ng-content /></cx-split-button>
40
+ `,
41
+ })
42
+ export class CxSplitButton implements AfterViewInit, OnChanges {
43
+ @ViewChild('el', { static: true }) el!: ElementRef<HTMLElement>;
44
+
45
+ @Input() id!: string;
46
+ @Input() label!: string;
47
+ @Input() entries?: SplitMenuEntry[] | string = undefined;
48
+ @Input() variant?: 'filled' | 'outline' | 'ghost' = undefined;
49
+ @Input() intent?: 'neutral' | 'primary' | 'info' | 'success' | 'warning' | 'danger' = undefined;
50
+ @Input() shape?: 'sharp' | 'rounded' | 'pill' = undefined;
51
+ @Input() size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = undefined;
52
+ @Input() iconLeading?: string = undefined;
53
+ @Input() disabled?: boolean = undefined;
54
+ @Input() primaryDisabled?: boolean = undefined;
55
+ @Input() triggerDisabled?: boolean = undefined;
56
+ @Input() triggerLabel?: string = undefined;
57
+
58
+ @Output() cxClick = new EventEmitter<CustomEvent<ClickDetail>>();
59
+ @Output() cxAction = new EventEmitter<CustomEvent<MenuActionDetail>>();
60
+
61
+ constructor(private c: ChangeDetectorRef) {
62
+ c.detach();
63
+ }
64
+
65
+ ngAfterViewInit(): void {
66
+ this.el.nativeElement.addEventListener('cx-click', (e: Event) => {
67
+ this.cxClick.emit(e as CustomEvent);
68
+ });
69
+ this.el.nativeElement.addEventListener('cx-action', (e: Event) => {
70
+ this.cxAction.emit(e as CustomEvent);
71
+ });
72
+ }
73
+
74
+ ngOnChanges(changes: SimpleChanges): void {
75
+ if (changes['entries'] && this.el) {
76
+ const val = this.entries;
77
+ if (val != null) {
78
+ this.el.nativeElement.setAttribute('entries', typeof val === 'object' ? JSON.stringify(val) : String(val));
79
+ } else {
80
+ this.el.nativeElement.removeAttribute('entries');
81
+ }
82
+ }
83
+ }
84
+
85
+ _serialize_entries(): string | null {
86
+ const val = this.entries;
87
+ if (val == null) return null;
88
+ return typeof val === 'object' ? JSON.stringify(val) : String(val);
89
+ }
90
+
91
+ /** Opens the dropdown menu. */
92
+ open(): void { (this.el.nativeElement as any).open(); }
93
+
94
+ /** Closes the dropdown menu. */
95
+ close(): void { (this.el.nativeElement as any).close(); }
96
+
97
+ }
@@ -0,0 +1,83 @@
1
+ // Auto-generated by scripts/generate-angular.mjs — DO NOT EDIT
2
+ // Angular wrapper for <cx-stepper>
3
+ import {
4
+ Component,
5
+ CUSTOM_ELEMENTS_SCHEMA,
6
+ ChangeDetectionStrategy,
7
+ ChangeDetectorRef,
8
+ ElementRef,
9
+ ViewChild,
10
+ Input,
11
+ Output,
12
+ EventEmitter,
13
+ OnChanges,
14
+ SimpleChanges,
15
+ AfterViewInit,
16
+ } from '@angular/core';
17
+ import type { SelectDetail, StepperStep } from './types.js';
18
+
19
+ @Component({
20
+ selector: 'cx-stepper[collet]',
21
+ standalone: true,
22
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
23
+ changeDetection: ChangeDetectionStrategy.OnPush,
24
+ template: `
25
+ <cx-stepper
26
+ [attr.id]="id"
27
+ [attr.label]="label"
28
+ [steps]="_serialize_steps()"
29
+ [attr.current]="current"
30
+ [attr.variant]="variant"
31
+ [attr.shape]="shape"
32
+ [attr.orientation]="orientation"
33
+ [attr.size]="size"
34
+ [attr.linear]="linear || null"
35
+ #el
36
+ ><ng-content /></cx-stepper>
37
+ `,
38
+ })
39
+ export class CxStepper implements AfterViewInit, OnChanges {
40
+ @ViewChild('el', { static: true }) el!: ElementRef<HTMLElement>;
41
+
42
+ @Input() id?: string = undefined;
43
+ @Input() label?: string = undefined;
44
+ @Input() steps?: StepperStep[] | string = undefined;
45
+ @Input() current?: number = undefined;
46
+ @Input() variant?: 'outline' | 'filled' | 'ghost' = undefined;
47
+ @Input() shape?: 'sharp' | 'rounded' = undefined;
48
+ @Input() orientation?: 'horizontal' | 'vertical' = undefined;
49
+ @Input() size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = undefined;
50
+ @Input() linear?: boolean = undefined;
51
+
52
+ @Output() cxChange = new EventEmitter<CustomEvent<SelectDetail>>();
53
+
54
+ constructor(private c: ChangeDetectorRef) {
55
+ c.detach();
56
+ }
57
+
58
+ ngAfterViewInit(): void {
59
+ this.el.nativeElement.addEventListener('cx-change', (e: Event) => {
60
+ this.cxChange.emit(e as CustomEvent);
61
+ });
62
+ }
63
+
64
+ ngOnChanges(changes: SimpleChanges): void {
65
+ if (changes['steps'] && this.el) {
66
+ const val = this.steps;
67
+ if (val != null) {
68
+ this.el.nativeElement.setAttribute('steps', typeof val === 'object' ? JSON.stringify(val) : String(val));
69
+ } else {
70
+ this.el.nativeElement.removeAttribute('steps');
71
+ }
72
+ }
73
+ }
74
+
75
+ _serialize_steps(): string | null {
76
+ const val = this.steps;
77
+ if (val == null) return null;
78
+ return typeof val === 'object' ? JSON.stringify(val) : String(val);
79
+ }
80
+
81
+
82
+
83
+ }
@@ -0,0 +1,123 @@
1
+ // Auto-generated by scripts/generate-angular.mjs — DO NOT EDIT
2
+ // Angular wrapper for <cx-switch>
3
+ import {
4
+ Component,
5
+ CUSTOM_ELEMENTS_SCHEMA,
6
+ ChangeDetectionStrategy,
7
+ ChangeDetectorRef,
8
+ ElementRef,
9
+ ViewChild,
10
+ Input,
11
+ Output,
12
+ EventEmitter,
13
+ AfterViewInit,
14
+ forwardRef,
15
+ } from '@angular/core';
16
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
17
+ import type { CheckedDetail, FocusDetail, KeyboardDetail } from './types.js';
18
+
19
+ @Component({
20
+ selector: 'cx-switch[collet]',
21
+ standalone: true,
22
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
23
+ changeDetection: ChangeDetectionStrategy.OnPush,
24
+ providers: [{
25
+ provide: NG_VALUE_ACCESSOR,
26
+ useExisting: forwardRef(() => CxSwitch),
27
+ multi: true,
28
+ }],
29
+ template: `
30
+ <cx-switch
31
+ [attr.id]="id"
32
+ [attr.label]="label"
33
+ [attr.shape]="shape"
34
+ [attr.size]="size"
35
+ [attr.checked]="checked || null"
36
+ [attr.disabled]="disabled || null"
37
+ [attr.required]="required || null"
38
+ [attr.helper-text]="helperText"
39
+ [attr.error]="error"
40
+ [attr.description]="description"
41
+ [attr.unlabeled]="unlabeled || null"
42
+ #el
43
+ ><ng-content /></cx-switch>
44
+ `,
45
+ })
46
+ export class CxSwitch implements AfterViewInit, ControlValueAccessor {
47
+ @ViewChild('el', { static: true }) el!: ElementRef<HTMLElement>;
48
+
49
+ @Input() id?: string = undefined;
50
+ @Input() label?: string = undefined;
51
+ @Input() shape?: 'sharp' | 'rounded' | 'pill' = undefined;
52
+ @Input() size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' = undefined;
53
+ /** Boolean checked state (unlike Checkbox, which uses a string). */
54
+ @Input() checked?: boolean = undefined;
55
+ @Input() disabled?: boolean = undefined;
56
+ @Input() required?: boolean = undefined;
57
+ @Input() helperText?: string = undefined;
58
+ @Input() error?: string = undefined;
59
+ @Input() description?: string = undefined;
60
+ @Input() unlabeled?: boolean = undefined;
61
+
62
+ @Output() cxInput = new EventEmitter<CustomEvent<CheckedDetail>>();
63
+ @Output() cxChange = new EventEmitter<CustomEvent<CheckedDetail>>();
64
+ @Output() cxFocus = new EventEmitter<CustomEvent<FocusDetail>>();
65
+ @Output() cxBlur = new EventEmitter<CustomEvent<FocusDetail>>();
66
+ @Output() cxKeydown = new EventEmitter<CustomEvent<KeyboardDetail>>();
67
+ @Output() cxKeyup = new EventEmitter<CustomEvent<KeyboardDetail>>();
68
+
69
+ constructor(private c: ChangeDetectorRef) {
70
+ c.detach();
71
+ }
72
+
73
+ ngAfterViewInit(): void {
74
+ this.el.nativeElement.addEventListener('cx-input', (e: Event) => {
75
+ this.cxInput.emit(e as CustomEvent);
76
+ });
77
+ this.el.nativeElement.addEventListener('cx-change', (e: Event) => {
78
+ this.cxChange.emit(e as CustomEvent);
79
+ });
80
+ this.el.nativeElement.addEventListener('cx-focus', (e: Event) => {
81
+ this.cxFocus.emit(e as CustomEvent);
82
+ });
83
+ this.el.nativeElement.addEventListener('cx-blur', (e: Event) => {
84
+ this.cxBlur.emit(e as CustomEvent);
85
+ });
86
+ this.el.nativeElement.addEventListener('cx-keydown', (e: Event) => {
87
+ this.cxKeydown.emit(e as CustomEvent);
88
+ });
89
+ this.el.nativeElement.addEventListener('cx-keyup', (e: Event) => {
90
+ this.cxKeyup.emit(e as CustomEvent);
91
+ });
92
+ // CVA: sync CE value changes back to Angular forms
93
+ this.el.nativeElement.addEventListener('cx-change', (e: Event) => {
94
+ this._onChange((e as CustomEvent).detail?.checked);
95
+ });
96
+ this.el.nativeElement.addEventListener('focusout', () => {
97
+ this._onTouched();
98
+ });
99
+ }
100
+
101
+
102
+
103
+ /** Focuses the switch input. */
104
+ focus(): void { (this.el.nativeElement as any).focus(); }
105
+
106
+ // ── ControlValueAccessor ──
107
+ private _onChange: (value: any) => void = () => {};
108
+ private _onTouched: () => void = () => {};
109
+
110
+ writeValue(value: any): void {
111
+ if (this.el) (this.el.nativeElement as any).checked = value ?? false;
112
+ }
113
+
114
+ registerOnChange(fn: (value: any) => void): void { this._onChange = fn; }
115
+ registerOnTouched(fn: () => void): void { this._onTouched = fn; }
116
+
117
+ setDisabledState(isDisabled: boolean): void {
118
+ if (this.el) {
119
+ if (isDisabled) this.el.nativeElement.setAttribute('disabled', '');
120
+ else this.el.nativeElement.removeAttribute('disabled');
121
+ }
122
+ }
123
+ }