@sonny-ui/core 0.1.0-alpha.12 → 0.1.0-alpha.13
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 +133 -133
- package/fesm2022/sonny-ui-core.mjs +52 -122
- package/fesm2022/sonny-ui-core.mjs.map +1 -1
- package/package.json +1 -1
- package/schematics/ng-generate/component/index.js +6 -6
- package/schematics/ng-generate/component/schema.json +32 -32
- package/src/lib/button/button.directive.ts +1 -1
- package/src/lib/calendar/calendar.component.ts +3 -14
- package/src/lib/combobox/combobox.component.ts +2 -15
- package/src/lib/file-input/file-input.component.ts +2 -14
- package/src/lib/rating/rating.component.ts +11 -18
- package/src/lib/select/select.component.ts +2 -15
- package/src/lib/slider/slider.component.ts +13 -19
- package/src/lib/switch/switch.component.ts +8 -15
- package/src/lib/toggle/toggle.directive.ts +4 -15
- package/src/styles/sonny-theme.css +33 -0
- package/types/sonny-ui-core.d.ts +1 -16
package/package.json
CHANGED
|
@@ -393,12 +393,12 @@ function generateComponent(options) {
|
|
|
393
393
|
// Ensure cn.ts utility exists
|
|
394
394
|
const cnTargetPath = `${targetDir}/utils/cn.ts`;
|
|
395
395
|
if (!tree.exists(cnTargetPath)) {
|
|
396
|
-
const cnContent = `import { clsx, type ClassValue } from 'clsx';
|
|
397
|
-
import { twMerge } from 'tailwind-merge';
|
|
398
|
-
|
|
399
|
-
export function cn(...inputs: ClassValue[]): string {
|
|
400
|
-
return twMerge(clsx(inputs));
|
|
401
|
-
}
|
|
396
|
+
const cnContent = `import { clsx, type ClassValue } from 'clsx';
|
|
397
|
+
import { twMerge } from 'tailwind-merge';
|
|
398
|
+
|
|
399
|
+
export function cn(...inputs: ClassValue[]): string {
|
|
400
|
+
return twMerge(clsx(inputs));
|
|
401
|
+
}
|
|
402
402
|
`;
|
|
403
403
|
tree.create(cnTargetPath, cnContent);
|
|
404
404
|
context.logger.info('Created utils/cn.ts');
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/schema",
|
|
3
|
-
"$id": "SonnyUIGenerateComponentSchema",
|
|
4
|
-
"title": "SonnyUI component generator (copy-paste style)",
|
|
5
|
-
"type": "object",
|
|
6
|
-
"properties": {
|
|
7
|
-
"name": {
|
|
8
|
-
"type": "string",
|
|
9
|
-
"description": "The component to copy (accordion, alert, avatar, badge, breadcrumb, button, button-group, calendar, card, carousel, chat-bubble, checkbox, combobox, diff, divider, dock, drawer, dropdown, fab, fieldset, file-input, indicator, input, kbd, link, list, loader, modal, navbar, pagination, progress, radial-progress, radio, rating, select, sheet, skeleton, slider, stat, status, steps, switch, table, tabs, textarea, timeline, toast, toggle, tooltip, validator).",
|
|
10
|
-
"$default": {
|
|
11
|
-
"$source": "argv",
|
|
12
|
-
"index": 0
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"path": {
|
|
16
|
-
"type": "string",
|
|
17
|
-
"default": "src/app/ui",
|
|
18
|
-
"description": "The path to copy the component into."
|
|
19
|
-
},
|
|
20
|
-
"prefix": {
|
|
21
|
-
"type": "string",
|
|
22
|
-
"default": "sny",
|
|
23
|
-
"description": "The prefix to use for selectors."
|
|
24
|
-
},
|
|
25
|
-
"skipTests": {
|
|
26
|
-
"type": "boolean",
|
|
27
|
-
"default": false,
|
|
28
|
-
"description": "Skip copying test files."
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"required": ["name"]
|
|
32
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "SonnyUIGenerateComponentSchema",
|
|
4
|
+
"title": "SonnyUI component generator (copy-paste style)",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"name": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "The component to copy (accordion, alert, avatar, badge, breadcrumb, button, button-group, calendar, card, carousel, chat-bubble, checkbox, combobox, diff, divider, dock, drawer, dropdown, fab, fieldset, file-input, indicator, input, kbd, link, list, loader, modal, navbar, pagination, progress, radial-progress, radio, rating, select, sheet, skeleton, slider, stat, status, steps, switch, table, tabs, textarea, timeline, toast, toggle, tooltip, validator).",
|
|
10
|
+
"$default": {
|
|
11
|
+
"$source": "argv",
|
|
12
|
+
"index": 0
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"path": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"default": "src/app/ui",
|
|
18
|
+
"description": "The path to copy the component into."
|
|
19
|
+
},
|
|
20
|
+
"prefix": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"default": "sny",
|
|
23
|
+
"description": "The prefix to use for selectors."
|
|
24
|
+
},
|
|
25
|
+
"skipTests": {
|
|
26
|
+
"type": "boolean",
|
|
27
|
+
"default": false,
|
|
28
|
+
"description": "Skip copying test files."
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"required": ["name"]
|
|
32
|
+
}
|
|
@@ -22,7 +22,7 @@ export class SnyButtonDirective {
|
|
|
22
22
|
protected readonly computedClass = computed(() =>
|
|
23
23
|
cn(
|
|
24
24
|
buttonVariants({ variant: this.variant(), size: this.size() }),
|
|
25
|
-
this.loading() && '
|
|
25
|
+
this.loading() && 'cursor-wait opacity-70',
|
|
26
26
|
this.class()
|
|
27
27
|
)
|
|
28
28
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, computed,
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, forwardRef, input, model, signal } from '@angular/core';
|
|
2
2
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
3
|
import { cn } from '../core/utils/cn';
|
|
4
4
|
|
|
@@ -74,21 +74,8 @@ export class SnyCalendarComponent implements ControlValueAccessor {
|
|
|
74
74
|
|
|
75
75
|
private _onChange: (value: Date | null) => void = () => {};
|
|
76
76
|
protected onTouched: () => void = () => {};
|
|
77
|
-
private _writing = false;
|
|
78
|
-
|
|
79
|
-
constructor() {
|
|
80
|
-
effect(() => {
|
|
81
|
-
const val = this.value();
|
|
82
|
-
if (this._writing) {
|
|
83
|
-
this._writing = false;
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
this._onChange(val);
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
77
|
|
|
90
78
|
writeValue(val: Date | null): void {
|
|
91
|
-
this._writing = true;
|
|
92
79
|
this.value.set(val ?? null);
|
|
93
80
|
if (val) {
|
|
94
81
|
this.viewDate.set(new Date(val.getFullYear(), val.getMonth(), 1));
|
|
@@ -160,6 +147,7 @@ export class SnyCalendarComponent implements ControlValueAccessor {
|
|
|
160
147
|
|
|
161
148
|
selectDate(date: Date): void {
|
|
162
149
|
this.value.set(date);
|
|
150
|
+
this._onChange(date);
|
|
163
151
|
this.onTouched();
|
|
164
152
|
}
|
|
165
153
|
|
|
@@ -201,6 +189,7 @@ export class SnyCalendarComponent implements ControlValueAccessor {
|
|
|
201
189
|
const next = new Date(current);
|
|
202
190
|
next.setDate(next.getDate() + offset);
|
|
203
191
|
this.value.set(next);
|
|
192
|
+
this._onChange(next);
|
|
204
193
|
this.viewDate.set(new Date(next.getFullYear(), next.getMonth(), 1));
|
|
205
194
|
}
|
|
206
195
|
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
ChangeDetectionStrategy,
|
|
3
3
|
Component,
|
|
4
4
|
computed,
|
|
5
|
-
effect,
|
|
6
5
|
ElementRef,
|
|
7
6
|
forwardRef,
|
|
8
7
|
HostListener,
|
|
@@ -72,7 +71,7 @@ export interface ComboboxOption {
|
|
|
72
71
|
|
|
73
72
|
<!-- Options list -->
|
|
74
73
|
@if (filtered().length > 0) {
|
|
75
|
-
<ul role="listbox" class="max-h-60 overflow-auto p-1">
|
|
74
|
+
<ul role="listbox" class="max-h-60 overflow-auto p-1 sny-scrollbar">
|
|
76
75
|
@for (opt of filtered(); track opt.value; let i = $index) {
|
|
77
76
|
<li
|
|
78
77
|
role="option"
|
|
@@ -122,21 +121,8 @@ export class SnyComboboxComponent implements ControlValueAccessor, OnDestroy {
|
|
|
122
121
|
|
|
123
122
|
private _onChange: (value: string) => void = () => {};
|
|
124
123
|
protected onTouched: () => void = () => {};
|
|
125
|
-
private _writing = false;
|
|
126
|
-
|
|
127
|
-
constructor() {
|
|
128
|
-
effect(() => {
|
|
129
|
-
const val = this.value();
|
|
130
|
-
if (this._writing) {
|
|
131
|
-
this._writing = false;
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
this._onChange(val);
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
124
|
|
|
138
125
|
writeValue(val: string): void {
|
|
139
|
-
this._writing = true;
|
|
140
126
|
this.value.set(val ?? '');
|
|
141
127
|
}
|
|
142
128
|
|
|
@@ -244,6 +230,7 @@ export class SnyComboboxComponent implements ControlValueAccessor, OnDestroy {
|
|
|
244
230
|
|
|
245
231
|
select(opt: ComboboxOption): void {
|
|
246
232
|
this.value.set(opt.value);
|
|
233
|
+
this._onChange(opt.value);
|
|
247
234
|
this.close();
|
|
248
235
|
}
|
|
249
236
|
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
ChangeDetectionStrategy,
|
|
3
3
|
Component,
|
|
4
4
|
computed,
|
|
5
|
-
effect,
|
|
6
5
|
forwardRef,
|
|
7
6
|
input,
|
|
8
7
|
model,
|
|
@@ -74,21 +73,8 @@ export class SnyFileInputComponent implements ControlValueAccessor {
|
|
|
74
73
|
|
|
75
74
|
private _onChange: (value: FileList | null) => void = () => {};
|
|
76
75
|
protected onTouched: () => void = () => {};
|
|
77
|
-
private _writing = false;
|
|
78
|
-
|
|
79
|
-
constructor() {
|
|
80
|
-
effect(() => {
|
|
81
|
-
const val = this.value();
|
|
82
|
-
if (this._writing) {
|
|
83
|
-
this._writing = false;
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
this._onChange(val);
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
76
|
|
|
90
77
|
writeValue(val: FileList | null): void {
|
|
91
|
-
this._writing = true;
|
|
92
78
|
this.value.set(val ?? null);
|
|
93
79
|
}
|
|
94
80
|
|
|
@@ -148,6 +134,7 @@ export class SnyFileInputComponent implements ControlValueAccessor {
|
|
|
148
134
|
|
|
149
135
|
clear(): void {
|
|
150
136
|
this.value.set(null);
|
|
137
|
+
this._onChange(null);
|
|
151
138
|
const inputEl = this.fileInputRef()?.nativeElement;
|
|
152
139
|
if (inputEl) inputEl.value = '';
|
|
153
140
|
}
|
|
@@ -163,6 +150,7 @@ export class SnyFileInputComponent implements ControlValueAccessor {
|
|
|
163
150
|
}
|
|
164
151
|
}
|
|
165
152
|
this.value.set(files);
|
|
153
|
+
this._onChange(files);
|
|
166
154
|
this.fileChange.emit(files);
|
|
167
155
|
}
|
|
168
156
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, computed,
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, forwardRef, input, model, signal } from '@angular/core';
|
|
2
2
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
3
|
import { cn } from '../core/utils/cn';
|
|
4
4
|
import { ratingVariants, type RatingSize, type RatingVariant } from './rating.variants';
|
|
@@ -62,21 +62,8 @@ export class SnyRatingComponent implements ControlValueAccessor {
|
|
|
62
62
|
|
|
63
63
|
private _onChange: (value: number) => void = () => {};
|
|
64
64
|
protected onTouched: () => void = () => {};
|
|
65
|
-
private _writing = false;
|
|
66
|
-
|
|
67
|
-
constructor() {
|
|
68
|
-
effect(() => {
|
|
69
|
-
const val = this.value();
|
|
70
|
-
if (this._writing) {
|
|
71
|
-
this._writing = false;
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
this._onChange(val);
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
65
|
|
|
78
66
|
writeValue(val: number): void {
|
|
79
|
-
this._writing = true;
|
|
80
67
|
this.value.set(val ?? 0);
|
|
81
68
|
}
|
|
82
69
|
|
|
@@ -133,6 +120,7 @@ export class SnyRatingComponent implements ControlValueAccessor {
|
|
|
133
120
|
onStarClick(index: number): void {
|
|
134
121
|
if (this.isDisabled()) return;
|
|
135
122
|
this.value.set(index);
|
|
123
|
+
this._onChange(index);
|
|
136
124
|
}
|
|
137
125
|
|
|
138
126
|
onStarHover(index: number): void {
|
|
@@ -147,25 +135,30 @@ export class SnyRatingComponent implements ControlValueAccessor {
|
|
|
147
135
|
onKeydown(event: KeyboardEvent): void {
|
|
148
136
|
if (this.isDisabled()) return;
|
|
149
137
|
const step = this.half() ? 0.5 : 1;
|
|
138
|
+
let newVal: number | undefined;
|
|
150
139
|
switch (event.key) {
|
|
151
140
|
case 'ArrowRight':
|
|
152
141
|
case 'ArrowUp':
|
|
153
142
|
event.preventDefault();
|
|
154
|
-
|
|
143
|
+
newVal = Math.min(this.max(), this.value() + step);
|
|
155
144
|
break;
|
|
156
145
|
case 'ArrowLeft':
|
|
157
146
|
case 'ArrowDown':
|
|
158
147
|
event.preventDefault();
|
|
159
|
-
|
|
148
|
+
newVal = Math.max(0, this.value() - step);
|
|
160
149
|
break;
|
|
161
150
|
case 'Home':
|
|
162
151
|
event.preventDefault();
|
|
163
|
-
|
|
152
|
+
newVal = 0;
|
|
164
153
|
break;
|
|
165
154
|
case 'End':
|
|
166
155
|
event.preventDefault();
|
|
167
|
-
this.
|
|
156
|
+
newVal = this.max();
|
|
168
157
|
break;
|
|
169
158
|
}
|
|
159
|
+
if (newVal !== undefined) {
|
|
160
|
+
this.value.set(newVal);
|
|
161
|
+
this._onChange(newVal);
|
|
162
|
+
}
|
|
170
163
|
}
|
|
171
164
|
}
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
ChangeDetectionStrategy,
|
|
3
3
|
Component,
|
|
4
4
|
computed,
|
|
5
|
-
effect,
|
|
6
5
|
ElementRef,
|
|
7
6
|
forwardRef,
|
|
8
7
|
HostListener,
|
|
@@ -56,7 +55,7 @@ export interface SelectOption {
|
|
|
56
55
|
#dropdownEl
|
|
57
56
|
class="fixed z-50 rounded-sm border border-border bg-popover text-popover-foreground shadow-md"
|
|
58
57
|
>
|
|
59
|
-
<ul role="listbox" class="max-h-60 overflow-auto p-1">
|
|
58
|
+
<ul role="listbox" class="max-h-60 overflow-auto p-1 sny-scrollbar">
|
|
60
59
|
@for (opt of options(); track opt.value; let i = $index) {
|
|
61
60
|
<li
|
|
62
61
|
role="option"
|
|
@@ -101,21 +100,8 @@ export class SnySelectComponent implements ControlValueAccessor, OnDestroy {
|
|
|
101
100
|
|
|
102
101
|
private _onChange: (value: string) => void = () => {};
|
|
103
102
|
protected onTouched: () => void = () => {};
|
|
104
|
-
private _writing = false;
|
|
105
|
-
|
|
106
|
-
constructor() {
|
|
107
|
-
effect(() => {
|
|
108
|
-
const val = this.value();
|
|
109
|
-
if (this._writing) {
|
|
110
|
-
this._writing = false;
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
this._onChange(val);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
103
|
|
|
117
104
|
writeValue(val: string): void {
|
|
118
|
-
this._writing = true;
|
|
119
105
|
this.value.set(val ?? '');
|
|
120
106
|
}
|
|
121
107
|
|
|
@@ -207,6 +193,7 @@ export class SnySelectComponent implements ControlValueAccessor, OnDestroy {
|
|
|
207
193
|
|
|
208
194
|
select(opt: SelectOption): void {
|
|
209
195
|
this.value.set(opt.value);
|
|
196
|
+
this._onChange(opt.value);
|
|
210
197
|
this.close();
|
|
211
198
|
}
|
|
212
199
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, computed,
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, ElementRef, forwardRef, input, model, OnDestroy, signal, viewChild } from '@angular/core';
|
|
2
2
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
3
|
import { cn } from '../core/utils/cn';
|
|
4
4
|
import { sliderTrackVariants, sliderThumbSize, type SliderSize } from './slider.variants';
|
|
@@ -55,21 +55,8 @@ export class SnySliderComponent implements ControlValueAccessor, OnDestroy {
|
|
|
55
55
|
|
|
56
56
|
private _onChange: (value: number) => void = () => {};
|
|
57
57
|
protected onTouched: () => void = () => {};
|
|
58
|
-
private _writing = false;
|
|
59
|
-
|
|
60
|
-
constructor() {
|
|
61
|
-
effect(() => {
|
|
62
|
-
const val = this.value();
|
|
63
|
-
if (this._writing) {
|
|
64
|
-
this._writing = false;
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
this._onChange(val);
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
58
|
|
|
71
59
|
writeValue(val: number): void {
|
|
72
|
-
this._writing = true;
|
|
73
60
|
this.value.set(val ?? 0);
|
|
74
61
|
}
|
|
75
62
|
|
|
@@ -110,7 +97,9 @@ export class SnySliderComponent implements ControlValueAccessor, OnDestroy {
|
|
|
110
97
|
const percent = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
|
|
111
98
|
const raw = this.min() + percent * (this.max() - this.min());
|
|
112
99
|
const stepped = Math.round(raw / this.step()) * this.step();
|
|
113
|
-
|
|
100
|
+
const clamped = Math.max(this.min(), Math.min(this.max(), stepped));
|
|
101
|
+
this.value.set(clamped);
|
|
102
|
+
this._onChange(clamped);
|
|
114
103
|
}
|
|
115
104
|
|
|
116
105
|
onTrackMousedown(event: MouseEvent): void {
|
|
@@ -147,26 +136,31 @@ export class SnySliderComponent implements ControlValueAccessor, OnDestroy {
|
|
|
147
136
|
onKeydown(event: KeyboardEvent): void {
|
|
148
137
|
if (this.isDisabled()) return;
|
|
149
138
|
const step = this.step();
|
|
139
|
+
let newVal: number | undefined;
|
|
150
140
|
switch (event.key) {
|
|
151
141
|
case 'ArrowRight':
|
|
152
142
|
case 'ArrowUp':
|
|
153
143
|
event.preventDefault();
|
|
154
|
-
|
|
144
|
+
newVal = Math.min(this.max(), this.value() + step);
|
|
155
145
|
break;
|
|
156
146
|
case 'ArrowLeft':
|
|
157
147
|
case 'ArrowDown':
|
|
158
148
|
event.preventDefault();
|
|
159
|
-
|
|
149
|
+
newVal = Math.max(this.min(), this.value() - step);
|
|
160
150
|
break;
|
|
161
151
|
case 'Home':
|
|
162
152
|
event.preventDefault();
|
|
163
|
-
this.
|
|
153
|
+
newVal = this.min();
|
|
164
154
|
break;
|
|
165
155
|
case 'End':
|
|
166
156
|
event.preventDefault();
|
|
167
|
-
this.
|
|
157
|
+
newVal = this.max();
|
|
168
158
|
break;
|
|
169
159
|
}
|
|
160
|
+
if (newVal !== undefined) {
|
|
161
|
+
this.value.set(newVal);
|
|
162
|
+
this._onChange(newVal);
|
|
163
|
+
}
|
|
170
164
|
}
|
|
171
165
|
|
|
172
166
|
private removeListeners(): void {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, computed,
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, forwardRef, input, model, signal } from '@angular/core';
|
|
2
2
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
3
|
import { cn } from '../core/utils/cn';
|
|
4
4
|
import { switchTrackVariants, switchThumbSize, switchThumbTranslate, type SwitchSize } from './switch.variants';
|
|
@@ -18,7 +18,7 @@ import { switchTrackVariants, switchThumbSize, switchThumbTranslate, type Switch
|
|
|
18
18
|
[attr.aria-checked]="checked()"
|
|
19
19
|
[disabled]="isDisabled()"
|
|
20
20
|
[class]="trackClass()"
|
|
21
|
-
(click)="
|
|
21
|
+
(click)="toggle()"
|
|
22
22
|
(blur)="onTouched()"
|
|
23
23
|
>
|
|
24
24
|
<span [class]="thumbClass()"></span>
|
|
@@ -36,21 +36,8 @@ export class SnySwitchComponent implements ControlValueAccessor {
|
|
|
36
36
|
|
|
37
37
|
private _onChange: (value: boolean) => void = () => {};
|
|
38
38
|
protected onTouched: () => void = () => {};
|
|
39
|
-
private _writing = false;
|
|
40
|
-
|
|
41
|
-
constructor() {
|
|
42
|
-
effect(() => {
|
|
43
|
-
const val = this.checked();
|
|
44
|
-
if (this._writing) {
|
|
45
|
-
this._writing = false;
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
this._onChange(val);
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
39
|
|
|
52
40
|
writeValue(val: boolean): void {
|
|
53
|
-
this._writing = true;
|
|
54
41
|
this.checked.set(val ?? false);
|
|
55
42
|
}
|
|
56
43
|
|
|
@@ -66,6 +53,12 @@ export class SnySwitchComponent implements ControlValueAccessor {
|
|
|
66
53
|
this._disabledByCva.set(isDisabled);
|
|
67
54
|
}
|
|
68
55
|
|
|
56
|
+
toggle(): void {
|
|
57
|
+
const newVal = !this.checked();
|
|
58
|
+
this.checked.set(newVal);
|
|
59
|
+
this._onChange(newVal);
|
|
60
|
+
}
|
|
61
|
+
|
|
69
62
|
protected readonly trackClass = computed(() =>
|
|
70
63
|
cn(
|
|
71
64
|
switchTrackVariants({ size: this.size() }),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Directive, computed,
|
|
1
|
+
import { Directive, computed, forwardRef, input, model, signal } from '@angular/core';
|
|
2
2
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
3
|
import { cn } from '../core/utils/cn';
|
|
4
4
|
import { toggleVariants, type ToggleVariant, type ToggleSize } from './toggle.variants';
|
|
@@ -28,21 +28,8 @@ export class SnyToggleDirective implements ControlValueAccessor {
|
|
|
28
28
|
|
|
29
29
|
private _onChange: (value: boolean) => void = () => {};
|
|
30
30
|
protected onTouched: () => void = () => {};
|
|
31
|
-
private _writing = false;
|
|
32
|
-
|
|
33
|
-
constructor() {
|
|
34
|
-
effect(() => {
|
|
35
|
-
const val = this.pressed();
|
|
36
|
-
if (this._writing) {
|
|
37
|
-
this._writing = false;
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
this._onChange(val);
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
31
|
|
|
44
32
|
writeValue(val: boolean): void {
|
|
45
|
-
this._writing = true;
|
|
46
33
|
this.pressed.set(val ?? false);
|
|
47
34
|
}
|
|
48
35
|
|
|
@@ -60,7 +47,9 @@ export class SnyToggleDirective implements ControlValueAccessor {
|
|
|
60
47
|
|
|
61
48
|
protected toggle(): void {
|
|
62
49
|
if (this.isDisabled()) return;
|
|
63
|
-
|
|
50
|
+
const newVal = !this.pressed();
|
|
51
|
+
this.pressed.set(newVal);
|
|
52
|
+
this._onChange(newVal);
|
|
64
53
|
}
|
|
65
54
|
|
|
66
55
|
protected readonly computedClass = computed(() =>
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
--color-destructive-foreground: var(--sny-destructive-foreground);
|
|
18
18
|
--color-card: var(--sny-card);
|
|
19
19
|
--color-card-foreground: var(--sny-card-foreground);
|
|
20
|
+
--color-popover: var(--sny-popover);
|
|
21
|
+
--color-popover-foreground: var(--sny-popover-foreground);
|
|
20
22
|
--color-border: var(--sny-border);
|
|
21
23
|
--color-input: var(--sny-input);
|
|
22
24
|
--color-ring: var(--sny-ring);
|
|
@@ -38,6 +40,8 @@
|
|
|
38
40
|
--sny-destructive-foreground: #fafafa;
|
|
39
41
|
--sny-card: #ffffff;
|
|
40
42
|
--sny-card-foreground: #0a0a0a;
|
|
43
|
+
--sny-popover: #ffffff;
|
|
44
|
+
--sny-popover-foreground: #0a0a0a;
|
|
41
45
|
--sny-border: #e5e5e5;
|
|
42
46
|
--sny-input: #e5e5e5;
|
|
43
47
|
--sny-ring: #0a0a0a;
|
|
@@ -60,6 +64,8 @@
|
|
|
60
64
|
--sny-destructive-foreground: #fafafa;
|
|
61
65
|
--sny-card: #0a0a0a;
|
|
62
66
|
--sny-card-foreground: #fafafa;
|
|
67
|
+
--sny-popover: #171717;
|
|
68
|
+
--sny-popover-foreground: #fafafa;
|
|
63
69
|
--sny-border: #262626;
|
|
64
70
|
--sny-input: #262626;
|
|
65
71
|
--sny-ring: #d4d4d4;
|
|
@@ -80,12 +86,39 @@
|
|
|
80
86
|
--sny-destructive-foreground: #ffffff;
|
|
81
87
|
--sny-card: #ffffff;
|
|
82
88
|
--sny-card-foreground: #0f172a;
|
|
89
|
+
--sny-popover: #ffffff;
|
|
90
|
+
--sny-popover-foreground: #0f172a;
|
|
83
91
|
--sny-border: #cbd5e1;
|
|
84
92
|
--sny-input: #cbd5e1;
|
|
85
93
|
--sny-ring: #3b82f6;
|
|
86
94
|
--sny-radius: 0.375rem;
|
|
87
95
|
}
|
|
88
96
|
|
|
97
|
+
/* ─── Custom scrollbar ─── */
|
|
98
|
+
|
|
99
|
+
.sny-scrollbar {
|
|
100
|
+
scrollbar-width: thin;
|
|
101
|
+
scrollbar-color: var(--sny-muted-foreground) transparent;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.sny-scrollbar::-webkit-scrollbar {
|
|
105
|
+
width: 6px;
|
|
106
|
+
height: 6px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.sny-scrollbar::-webkit-scrollbar-track {
|
|
110
|
+
background: transparent;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.sny-scrollbar::-webkit-scrollbar-thumb {
|
|
114
|
+
background-color: var(--sny-muted-foreground);
|
|
115
|
+
border-radius: 9999px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.sny-scrollbar::-webkit-scrollbar-thumb:hover {
|
|
119
|
+
background-color: var(--sny-foreground);
|
|
120
|
+
}
|
|
121
|
+
|
|
89
122
|
/* ─── Dialog / Sheet overlay ─── */
|
|
90
123
|
|
|
91
124
|
.sny-dialog-backdrop {
|
package/types/sonny-ui-core.d.ts
CHANGED
|
@@ -412,8 +412,6 @@ declare class SnyComboboxComponent implements ControlValueAccessor, OnDestroy {
|
|
|
412
412
|
private resizeHandler;
|
|
413
413
|
private _onChange;
|
|
414
414
|
protected onTouched: () => void;
|
|
415
|
-
private _writing;
|
|
416
|
-
constructor();
|
|
417
415
|
writeValue(val: string): void;
|
|
418
416
|
registerOnChange(fn: (value: string) => void): void;
|
|
419
417
|
registerOnTouched(fn: () => void): void;
|
|
@@ -479,12 +477,11 @@ declare class SnySwitchComponent implements ControlValueAccessor {
|
|
|
479
477
|
protected readonly isDisabled: _angular_core.Signal<boolean>;
|
|
480
478
|
private _onChange;
|
|
481
479
|
protected onTouched: () => void;
|
|
482
|
-
private _writing;
|
|
483
|
-
constructor();
|
|
484
480
|
writeValue(val: boolean): void;
|
|
485
481
|
registerOnChange(fn: (value: boolean) => void): void;
|
|
486
482
|
registerOnTouched(fn: () => void): void;
|
|
487
483
|
setDisabledState(isDisabled: boolean): void;
|
|
484
|
+
toggle(): void;
|
|
488
485
|
protected readonly trackClass: _angular_core.Signal<string>;
|
|
489
486
|
protected readonly thumbClass: _angular_core.Signal<string>;
|
|
490
487
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SnySwitchComponent, never>;
|
|
@@ -507,8 +504,6 @@ declare class SnyToggleDirective implements ControlValueAccessor {
|
|
|
507
504
|
protected readonly isDisabled: _angular_core.Signal<boolean>;
|
|
508
505
|
private _onChange;
|
|
509
506
|
protected onTouched: () => void;
|
|
510
|
-
private _writing;
|
|
511
|
-
constructor();
|
|
512
507
|
writeValue(val: boolean): void;
|
|
513
508
|
registerOnChange(fn: (value: boolean) => void): void;
|
|
514
509
|
registerOnTouched(fn: () => void): void;
|
|
@@ -539,8 +534,6 @@ declare class SnySliderComponent implements ControlValueAccessor, OnDestroy {
|
|
|
539
534
|
private upHandler;
|
|
540
535
|
private _onChange;
|
|
541
536
|
protected onTouched: () => void;
|
|
542
|
-
private _writing;
|
|
543
|
-
constructor();
|
|
544
537
|
writeValue(val: number): void;
|
|
545
538
|
registerOnChange(fn: (value: number) => void): void;
|
|
546
539
|
registerOnTouched(fn: () => void): void;
|
|
@@ -639,8 +632,6 @@ declare class SnySelectComponent implements ControlValueAccessor, OnDestroy {
|
|
|
639
632
|
private resizeHandler;
|
|
640
633
|
private _onChange;
|
|
641
634
|
protected onTouched: () => void;
|
|
642
|
-
private _writing;
|
|
643
|
-
constructor();
|
|
644
635
|
writeValue(val: string): void;
|
|
645
636
|
registerOnChange(fn: (value: string) => void): void;
|
|
646
637
|
registerOnTouched(fn: () => void): void;
|
|
@@ -983,8 +974,6 @@ declare class SnyFileInputComponent implements ControlValueAccessor {
|
|
|
983
974
|
readonly isDragOver: _angular_core.WritableSignal<boolean>;
|
|
984
975
|
private _onChange;
|
|
985
976
|
protected onTouched: () => void;
|
|
986
|
-
private _writing;
|
|
987
|
-
constructor();
|
|
988
977
|
writeValue(val: FileList | null): void;
|
|
989
978
|
registerOnChange(fn: (value: FileList | null) => void): void;
|
|
990
979
|
registerOnTouched(fn: () => void): void;
|
|
@@ -1050,8 +1039,6 @@ declare class SnyRatingComponent implements ControlValueAccessor {
|
|
|
1050
1039
|
readonly hoverValue: _angular_core.WritableSignal<number | null>;
|
|
1051
1040
|
private _onChange;
|
|
1052
1041
|
protected onTouched: () => void;
|
|
1053
|
-
private _writing;
|
|
1054
|
-
constructor();
|
|
1055
1042
|
writeValue(val: number): void;
|
|
1056
1043
|
registerOnChange(fn: (value: number) => void): void;
|
|
1057
1044
|
registerOnTouched(fn: () => void): void;
|
|
@@ -1562,8 +1549,6 @@ declare class SnyCalendarComponent implements ControlValueAccessor {
|
|
|
1562
1549
|
readonly weekDays: string[];
|
|
1563
1550
|
private _onChange;
|
|
1564
1551
|
protected onTouched: () => void;
|
|
1565
|
-
private _writing;
|
|
1566
|
-
constructor();
|
|
1567
1552
|
writeValue(val: Date | null): void;
|
|
1568
1553
|
registerOnChange(fn: (value: Date | null) => void): void;
|
|
1569
1554
|
registerOnTouched(fn: () => void): void;
|