@eduboxpro/studio 0.1.2 → 0.1.4
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 +47 -0
- package/fesm2022/eduboxpro-studio.mjs +425 -91
- package/fesm2022/eduboxpro-studio.mjs.map +1 -1
- package/index.d.ts +191 -35
- package/package.json +3 -2
- package/src/styles/_tokens.scss +4 -0
package/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { InjectionToken, EnvironmentProviders, Signal } from '@angular/core';
|
|
2
|
+
import { InjectionToken, EnvironmentProviders, ElementRef, Signal } from '@angular/core';
|
|
3
3
|
import { icons } from 'lucide-angular';
|
|
4
|
+
import { ControlValueAccessor } from '@angular/forms';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Theme mode: light or dark
|
|
@@ -147,18 +148,31 @@ interface BadgeDefaultsConfig {
|
|
|
147
148
|
color?: 'primary' | 'secondary' | 'success' | 'error' | 'warning' | 'info' | 'neutral';
|
|
148
149
|
radius?: 'sm' | 'md' | 'lg' | 'full';
|
|
149
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Switch component defaults configuration
|
|
153
|
+
*/
|
|
154
|
+
interface SwitchDefaultsConfig {
|
|
155
|
+
size?: 'sm' | 'md' | 'lg';
|
|
156
|
+
color?: 'primary' | 'secondary' | 'success';
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Input component defaults configuration
|
|
160
|
+
*/
|
|
161
|
+
interface InputDefaultsConfig {
|
|
162
|
+
variant?: 'outline' | 'filled' | 'underline';
|
|
163
|
+
size?: 'sm' | 'md' | 'lg';
|
|
164
|
+
radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';
|
|
165
|
+
floatingLabel?: boolean;
|
|
166
|
+
clearable?: boolean;
|
|
167
|
+
}
|
|
150
168
|
/**
|
|
151
169
|
* Components defaults configuration
|
|
152
170
|
*/
|
|
153
171
|
interface ComponentsConfig {
|
|
154
|
-
/**
|
|
155
|
-
* Button component defaults
|
|
156
|
-
*/
|
|
157
172
|
button?: ButtonDefaultsConfig;
|
|
158
|
-
/**
|
|
159
|
-
* Badge component defaults
|
|
160
|
-
*/
|
|
161
173
|
badge?: BadgeDefaultsConfig;
|
|
174
|
+
switch?: SwitchDefaultsConfig;
|
|
175
|
+
input?: InputDefaultsConfig;
|
|
162
176
|
}
|
|
163
177
|
/**
|
|
164
178
|
* Main Studio configuration interface
|
|
@@ -186,7 +200,8 @@ declare class StudioConfigService {
|
|
|
186
200
|
configure(config: StudioConfig): void;
|
|
187
201
|
setThemeMode(mode: ThemeMode): void;
|
|
188
202
|
toggleTheme(): void;
|
|
189
|
-
|
|
203
|
+
updateTheme(theme: Partial<StudioThemeConfig>): void;
|
|
204
|
+
reset(): void;
|
|
190
205
|
private applyTheme;
|
|
191
206
|
private applyColorTokens;
|
|
192
207
|
private applyZIndexTokens;
|
|
@@ -257,6 +272,14 @@ declare class BadgeComponent {
|
|
|
257
272
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<BadgeComponent, "studio-badge", never, { "variantInput": { "alias": "variant"; "required": false; "isSignal": true; }; "sizeInput": { "alias": "size"; "required": false; "isSignal": true; }; "colorInput": { "alias": "color"; "required": false; "isSignal": true; }; "radiusInput": { "alias": "radius"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconPosition": { "alias": "iconPosition"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; "dotColor": { "alias": "dotColor"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "target": { "alias": "target"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "showZero": { "alias": "showZero"; "required": false; "isSignal": true; }; "uppercase": { "alias": "uppercase"; "required": false; "isSignal": true; }; "bold": { "alias": "bold"; "required": false; "isSignal": true; }; "pulse": { "alias": "pulse"; "required": false; "isSignal": true; }; "autoColor": { "alias": "autoColor"; "required": false; "isSignal": true; }; }, { "removed": "removed"; "clicked": "clicked"; }, never, ["*"], true, never>;
|
|
258
273
|
}
|
|
259
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Button component with multiple variants, sizes, colors and states
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* <studio-button variant="solid" color="primary" (clicked)="onClick()">
|
|
280
|
+
* Click me
|
|
281
|
+
* </studio-button>
|
|
282
|
+
*/
|
|
260
283
|
declare class ButtonComponent {
|
|
261
284
|
private readonly configService;
|
|
262
285
|
private readonly buttonDefaults;
|
|
@@ -292,23 +315,32 @@ declare class ButtonComponent {
|
|
|
292
315
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ButtonComponent, "studio-button", never, { "variantInput": { "alias": "variant"; "required": false; "isSignal": true; }; "sizeInput": { "alias": "size"; "required": false; "isSignal": true; }; "colorInput": { "alias": "color"; "required": false; "isSignal": true; }; "radiusInput": { "alias": "radius"; "required": false; "isSignal": true; }; "shadowInput": { "alias": "shadow"; "required": false; "isSignal": true; }; "compactInput": { "alias": "compact"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "loadingText": { "alias": "loadingText"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconPosition": { "alias": "iconPosition"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "target": { "alias": "target"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeColor": { "alias": "badgeColor"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "clicked": "clicked"; }, never, ["*"], true, never>;
|
|
293
316
|
}
|
|
294
317
|
|
|
318
|
+
/**
|
|
319
|
+
* Icon component with Lucide icons support
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* <studio-icon name="check" size="24" color="primary" />
|
|
323
|
+
*/
|
|
295
324
|
declare class IconComponent {
|
|
296
325
|
name: _angular_core.InputSignal<string>;
|
|
297
326
|
size: _angular_core.InputSignal<number>;
|
|
298
327
|
color: _angular_core.InputSignal<string>;
|
|
299
328
|
strokeWidth: _angular_core.InputSignal<number>;
|
|
300
329
|
absoluteStrokeWidth: _angular_core.InputSignal<boolean>;
|
|
330
|
+
showFallback: _angular_core.InputSignal<boolean>;
|
|
331
|
+
fallbackIcon: _angular_core.InputSignal<string>;
|
|
301
332
|
protected readonly icons: typeof icons;
|
|
302
|
-
protected lucideIcon: _angular_core.Signal<string>;
|
|
333
|
+
protected lucideIcon: _angular_core.Signal<string | null>;
|
|
334
|
+
private kebabToPascalCase;
|
|
303
335
|
protected computedColor: _angular_core.Signal<string>;
|
|
304
336
|
protected hostClasses: _angular_core.Signal<string[]>;
|
|
305
337
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<IconComponent, never>;
|
|
306
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<IconComponent, "studio-icon", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "strokeWidth": { "alias": "strokeWidth"; "required": false; "isSignal": true; }; "absoluteStrokeWidth": { "alias": "absoluteStrokeWidth"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
338
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<IconComponent, "studio-icon", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "strokeWidth": { "alias": "strokeWidth"; "required": false; "isSignal": true; }; "absoluteStrokeWidth": { "alias": "absoluteStrokeWidth"; "required": false; "isSignal": true; }; "showFallback": { "alias": "showFallback"; "required": false; "isSignal": true; }; "fallbackIcon": { "alias": "fallbackIcon"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
307
339
|
}
|
|
308
340
|
|
|
309
341
|
/**
|
|
310
|
-
*
|
|
311
|
-
*
|
|
342
|
+
* Studio icon provider
|
|
343
|
+
* Registers commonly used Lucide icons
|
|
312
344
|
*
|
|
313
345
|
* @example
|
|
314
346
|
* ```typescript
|
|
@@ -322,7 +354,7 @@ declare class IconComponent {
|
|
|
322
354
|
* };
|
|
323
355
|
* ```
|
|
324
356
|
*
|
|
325
|
-
*
|
|
357
|
+
* To add additional icons:
|
|
326
358
|
* @example
|
|
327
359
|
* ```typescript
|
|
328
360
|
* import { LUCIDE_ICONS, LucideIconProvider } from 'lucide-angular';
|
|
@@ -340,11 +372,139 @@ declare class IconComponent {
|
|
|
340
372
|
*/
|
|
341
373
|
declare function provideStudioIcons(): EnvironmentProviders;
|
|
342
374
|
|
|
375
|
+
type InputType = 'text' | 'email' | 'tel' | 'url' | 'password' | 'number' | 'search' | 'date' | 'time';
|
|
376
|
+
type InputMode = 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
|
|
343
377
|
/**
|
|
344
|
-
*
|
|
378
|
+
* Input component with form control support, variants, and accessibility
|
|
345
379
|
*
|
|
346
|
-
* @
|
|
347
|
-
*
|
|
380
|
+
* @example
|
|
381
|
+
* <studio-input [(ngModel)]="email" label="Email" type="email" />
|
|
382
|
+
* <studio-input [formControl]="passwordControl" type="password" [showPasswordToggle]="true" />
|
|
383
|
+
*/
|
|
384
|
+
declare class InputComponent implements ControlValueAccessor {
|
|
385
|
+
private readonly configService;
|
|
386
|
+
private readonly inputDefaults;
|
|
387
|
+
protected readonly inputEl: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
|
|
388
|
+
variantInput: _angular_core.InputSignal<"outline" | "filled" | "underline" | undefined>;
|
|
389
|
+
sizeInput: _angular_core.InputSignal<"sm" | "md" | "lg" | undefined>;
|
|
390
|
+
radiusInput: _angular_core.InputSignal<"sm" | "md" | "lg" | "none" | "full" | undefined>;
|
|
391
|
+
variant: _angular_core.Signal<"outline" | "filled" | "underline">;
|
|
392
|
+
size: _angular_core.Signal<"sm" | "md" | "lg">;
|
|
393
|
+
radius: _angular_core.Signal<"sm" | "md" | "lg" | "none" | "full">;
|
|
394
|
+
disabled: _angular_core.InputSignal<boolean>;
|
|
395
|
+
readonly: _angular_core.InputSignal<boolean>;
|
|
396
|
+
loading: _angular_core.InputSignal<boolean>;
|
|
397
|
+
type: _angular_core.InputSignal<InputType>;
|
|
398
|
+
inputmode: _angular_core.InputSignal<InputMode | undefined>;
|
|
399
|
+
autocomplete: _angular_core.InputSignal<string | undefined>;
|
|
400
|
+
placeholder: _angular_core.InputSignal<string | undefined>;
|
|
401
|
+
maxLength: _angular_core.InputSignal<number | undefined>;
|
|
402
|
+
minLength: _angular_core.InputSignal<number | undefined>;
|
|
403
|
+
min: _angular_core.InputSignal<string | number | undefined>;
|
|
404
|
+
max: _angular_core.InputSignal<string | number | undefined>;
|
|
405
|
+
step: _angular_core.InputSignal<number | undefined>;
|
|
406
|
+
pattern: _angular_core.InputSignal<string | undefined>;
|
|
407
|
+
label: _angular_core.InputSignal<string | undefined>;
|
|
408
|
+
floatingLabel: _angular_core.InputSignal<boolean>;
|
|
409
|
+
hint: _angular_core.InputSignal<string | undefined>;
|
|
410
|
+
required: _angular_core.InputSignal<boolean>;
|
|
411
|
+
error: _angular_core.InputSignal<boolean>;
|
|
412
|
+
errorMessage: _angular_core.InputSignal<string | undefined>;
|
|
413
|
+
prefixIcon: _angular_core.InputSignal<string | undefined>;
|
|
414
|
+
suffixIcon: _angular_core.InputSignal<string | undefined>;
|
|
415
|
+
clearable: _angular_core.InputSignal<boolean>;
|
|
416
|
+
showPasswordToggle: _angular_core.InputSignal<boolean>;
|
|
417
|
+
fullWidth: _angular_core.InputSignal<boolean>;
|
|
418
|
+
autoFocus: _angular_core.InputSignal<boolean>;
|
|
419
|
+
name: _angular_core.InputSignal<string | undefined>;
|
|
420
|
+
id: _angular_core.InputSignal<string | undefined>;
|
|
421
|
+
ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
422
|
+
valueChange: _angular_core.OutputEmitterRef<string | number>;
|
|
423
|
+
focused: _angular_core.OutputEmitterRef<FocusEvent>;
|
|
424
|
+
blurred: _angular_core.OutputEmitterRef<FocusEvent>;
|
|
425
|
+
cleared: _angular_core.OutputEmitterRef<void>;
|
|
426
|
+
entered: _angular_core.OutputEmitterRef<KeyboardEvent>;
|
|
427
|
+
protected value: _angular_core.WritableSignal<string | number>;
|
|
428
|
+
protected isPasswordVisible: _angular_core.WritableSignal<boolean>;
|
|
429
|
+
protected isFocused: _angular_core.WritableSignal<boolean>;
|
|
430
|
+
protected isTouched: _angular_core.WritableSignal<boolean>;
|
|
431
|
+
protected generatedId: string;
|
|
432
|
+
private onChange;
|
|
433
|
+
private onTouched;
|
|
434
|
+
constructor();
|
|
435
|
+
writeValue(value: string | number): void;
|
|
436
|
+
registerOnChange(fn: (value: string | number) => void): void;
|
|
437
|
+
registerOnTouched(fn: () => void): void;
|
|
438
|
+
setDisabledState(isDisabled: boolean): void;
|
|
439
|
+
protected computedType: _angular_core.Signal<InputType>;
|
|
440
|
+
protected hasValue: _angular_core.Signal<boolean>;
|
|
441
|
+
protected hostClasses: _angular_core.Signal<string>;
|
|
442
|
+
protected ariaDescribedByValue: _angular_core.Signal<string | null>;
|
|
443
|
+
protected hintId: string;
|
|
444
|
+
protected errorId: string;
|
|
445
|
+
protected handleInput(event: Event): void;
|
|
446
|
+
protected handleFocus(event: FocusEvent): void;
|
|
447
|
+
protected handleBlur(event: FocusEvent): void;
|
|
448
|
+
protected handleClear(): void;
|
|
449
|
+
protected handleEnter(event: Event): void;
|
|
450
|
+
protected togglePasswordVisibility(): void;
|
|
451
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<InputComponent, never>;
|
|
452
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<InputComponent, "studio-input", never, { "variantInput": { "alias": "variant"; "required": false; "isSignal": true; }; "sizeInput": { "alias": "size"; "required": false; "isSignal": true; }; "radiusInput": { "alias": "radius"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "inputmode": { "alias": "inputmode"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "minLength": { "alias": "minLength"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "pattern": { "alias": "pattern"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "floatingLabel": { "alias": "floatingLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "prefixIcon": { "alias": "prefixIcon"; "required": false; "isSignal": true; }; "suffixIcon": { "alias": "suffixIcon"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "showPasswordToggle": { "alias": "showPasswordToggle"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; "autoFocus": { "alias": "autoFocus"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; "focused": "focused"; "blurred": "blurred"; "cleared": "cleared"; "entered": "entered"; }, never, never, true, never>;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Toggle switch component with customizable size and color
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* <studio-switch [(checked)]="isEnabled" label="Enable feature" />
|
|
460
|
+
*/
|
|
461
|
+
declare class SwitchComponent {
|
|
462
|
+
private readonly configService;
|
|
463
|
+
private readonly switchDefaults;
|
|
464
|
+
checked: _angular_core.ModelSignal<boolean>;
|
|
465
|
+
disabled: _angular_core.InputSignal<boolean>;
|
|
466
|
+
label: _angular_core.InputSignal<string | undefined>;
|
|
467
|
+
labelPosition: _angular_core.InputSignal<"left" | "right">;
|
|
468
|
+
showIcons: _angular_core.InputSignal<boolean>;
|
|
469
|
+
ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
470
|
+
sizeInput: _angular_core.InputSignal<"sm" | "md" | "lg" | undefined>;
|
|
471
|
+
colorInput: _angular_core.InputSignal<"primary" | "secondary" | "success" | undefined>;
|
|
472
|
+
size: _angular_core.Signal<"sm" | "md" | "lg">;
|
|
473
|
+
color: _angular_core.Signal<"primary" | "secondary" | "success">;
|
|
474
|
+
checkedChange: _angular_core.OutputEmitterRef<boolean>;
|
|
475
|
+
protected iconSize: _angular_core.Signal<number>;
|
|
476
|
+
protected hostClasses: _angular_core.Signal<string>;
|
|
477
|
+
protected handleClick(): void;
|
|
478
|
+
protected handleKeydown(event: KeyboardEvent): void;
|
|
479
|
+
private toggle;
|
|
480
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SwitchComponent, never>;
|
|
481
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SwitchComponent, "studio-switch", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "labelPosition": { "alias": "labelPosition"; "required": false; "isSignal": true; }; "showIcons": { "alias": "showIcons"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "sizeInput": { "alias": "size"; "required": false; "isSignal": true; }; "colorInput": { "alias": "color"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "checkedChange": "checkedChange"; }, never, never, true, never>;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Theme toggle switch with sun/moon icons
|
|
486
|
+
*
|
|
487
|
+
* @example
|
|
488
|
+
* <studio-theme-switch />
|
|
489
|
+
* <studio-theme-switch [showLabel]="true" />
|
|
490
|
+
*/
|
|
491
|
+
declare class ThemeSwitchComponent {
|
|
492
|
+
private readonly configService;
|
|
493
|
+
size: _angular_core.InputSignal<"sm" | "md" | "lg">;
|
|
494
|
+
showLabel: _angular_core.InputSignal<boolean>;
|
|
495
|
+
iconOnly: _angular_core.InputSignal<boolean>;
|
|
496
|
+
protected isDark: _angular_core.Signal<boolean>;
|
|
497
|
+
protected iconSize: _angular_core.Signal<number>;
|
|
498
|
+
protected toggleTheme(): void;
|
|
499
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ThemeSwitchComponent, never>;
|
|
500
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ThemeSwitchComponent, "studio-theme-switch", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; "showLabel": { "alias": "showLabel"; "required": false; "isSignal": true; }; "iconOnly": { "alias": "iconOnly"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Checks if URL is safe for navigation
|
|
505
|
+
*
|
|
506
|
+
* @param url - URL to check
|
|
507
|
+
* @returns true if URL is safe (http/https or relative)
|
|
348
508
|
*
|
|
349
509
|
* @example
|
|
350
510
|
* ```typescript
|
|
@@ -355,53 +515,49 @@ declare function provideStudioIcons(): EnvironmentProviders;
|
|
|
355
515
|
*/
|
|
356
516
|
declare function isSafeUrl(url: string): boolean;
|
|
357
517
|
/**
|
|
358
|
-
* Sanitize URL
|
|
518
|
+
* Sanitize URL before using in navigation
|
|
359
519
|
*
|
|
360
|
-
* @param url - URL
|
|
361
|
-
* @returns
|
|
520
|
+
* @param url - URL to sanitize
|
|
521
|
+
* @returns Safe URL or '#' if URL is unsafe
|
|
362
522
|
*
|
|
363
523
|
* @example
|
|
364
524
|
* ```typescript
|
|
365
525
|
* sanitizeUrl('https://example.com') // 'https://example.com'
|
|
366
|
-
* sanitizeUrl('javascript:alert(1)') // '#' (
|
|
526
|
+
* sanitizeUrl('javascript:alert(1)') // '#' (with console warning)
|
|
367
527
|
* ```
|
|
368
528
|
*/
|
|
369
529
|
declare function sanitizeUrl(url: string): string;
|
|
370
530
|
|
|
371
531
|
/**
|
|
372
|
-
*
|
|
532
|
+
* Combines CSS classes, ignoring falsy values
|
|
373
533
|
*
|
|
374
|
-
* @param classes -
|
|
375
|
-
* @returns
|
|
534
|
+
* @param classes - Array of classes (strings, undefined, null, false)
|
|
535
|
+
* @returns String with combined classes
|
|
376
536
|
*
|
|
377
537
|
* @example
|
|
378
538
|
* ```typescript
|
|
379
539
|
* classNames('btn', 'btn-primary') // 'btn btn-primary'
|
|
380
|
-
* classNames('btn', isActive && 'active') // 'btn active'
|
|
540
|
+
* classNames('btn', isActive && 'active') // 'btn active' if isActive=true, else 'btn'
|
|
381
541
|
* classNames('btn', undefined, null, false, 'large') // 'btn large'
|
|
382
542
|
* ```
|
|
383
543
|
*/
|
|
384
544
|
declare function classNames(...classes: (string | false | undefined | null)[]): string;
|
|
385
545
|
|
|
386
546
|
/**
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
* Упрощает паттерн configurable inputs, убирая boilerplate код.
|
|
547
|
+
* Creates computed signal with fallback chain: input → config → default
|
|
390
548
|
*
|
|
391
|
-
* @param inputSignal -
|
|
392
|
-
* @param configSignal - Config
|
|
393
|
-
* @param defaultValue - Fallback
|
|
394
|
-
* @returns Computed signal
|
|
549
|
+
* @param inputSignal - User input signal
|
|
550
|
+
* @param configSignal - Config value (can be undefined)
|
|
551
|
+
* @param defaultValue - Fallback value
|
|
552
|
+
* @returns Computed signal with resolved value
|
|
395
553
|
*
|
|
396
554
|
* @example
|
|
397
555
|
* ```typescript
|
|
398
556
|
* export class ButtonComponent {
|
|
399
557
|
* private defaults = computed(() => this.configService.config().components?.button);
|
|
400
558
|
*
|
|
401
|
-
* // Input
|
|
402
559
|
* variantInput = input<Variant | undefined>(undefined, { alias: 'variant' });
|
|
403
560
|
*
|
|
404
|
-
* // Resolved value с config fallback
|
|
405
561
|
* variant = withConfigDefault(
|
|
406
562
|
* this.variantInput,
|
|
407
563
|
* computed(() => this.defaults()?.variant),
|
|
@@ -412,5 +568,5 @@ declare function classNames(...classes: (string | false | undefined | null)[]):
|
|
|
412
568
|
*/
|
|
413
569
|
declare function withConfigDefault<T>(inputSignal: Signal<T | undefined>, configSignal: Signal<T | undefined>, defaultValue: T): Signal<T>;
|
|
414
570
|
|
|
415
|
-
export { BadgeComponent, ButtonComponent, IconComponent, STUDIO_CONFIG, StudioConfigService, classNames, isSafeUrl, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
|
|
416
|
-
export type { BadgeDefaultsConfig, ButtonDefaultsConfig, ColorConfig, ComponentsConfig, StudioConfig, StudioThemeConfig, ThemeMode };
|
|
571
|
+
export { BadgeComponent, ButtonComponent, IconComponent, InputComponent, STUDIO_CONFIG, StudioConfigService, SwitchComponent, ThemeSwitchComponent, classNames, isSafeUrl, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
|
|
572
|
+
export type { BadgeDefaultsConfig, ButtonDefaultsConfig, ColorConfig, ComponentsConfig, InputDefaultsConfig, InputMode, InputType, StudioConfig, StudioThemeConfig, SwitchDefaultsConfig, ThemeMode };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eduboxpro/studio",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Modern Angular UI library for educational platforms with customizable design system",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"@angular/common": "^20.0.0",
|
|
23
23
|
"@angular/core": "^20.0.0",
|
|
24
|
-
"
|
|
24
|
+
"@angular/forms": "^20.0.0",
|
|
25
|
+
"lucide-angular": "^0.553.0"
|
|
25
26
|
},
|
|
26
27
|
"sideEffects": [
|
|
27
28
|
"*.css",
|
package/src/styles/_tokens.scss
CHANGED
|
@@ -27,10 +27,12 @@
|
|
|
27
27
|
--studio-primary: #7c3aed;
|
|
28
28
|
--studio-primary-hover: #6d28d9;
|
|
29
29
|
--studio-primary-active: #5b21b6;
|
|
30
|
+
--studio-primary-bg: #f5f3ff;
|
|
30
31
|
|
|
31
32
|
--studio-secondary: #6366f1;
|
|
32
33
|
--studio-secondary-hover: #4f46e5;
|
|
33
34
|
--studio-secondary-active: #4338ca;
|
|
35
|
+
--studio-secondary-bg: #eef2ff;
|
|
34
36
|
|
|
35
37
|
/* Semantic colors */
|
|
36
38
|
--studio-success: #10b981;
|
|
@@ -151,10 +153,12 @@
|
|
|
151
153
|
--studio-primary: #a78bfa;
|
|
152
154
|
--studio-primary-hover: #c4b5fd;
|
|
153
155
|
--studio-primary-active: #ddd6fe;
|
|
156
|
+
--studio-primary-bg: #2e1065;
|
|
154
157
|
|
|
155
158
|
--studio-secondary: #818cf8;
|
|
156
159
|
--studio-secondary-hover: #a5b4fc;
|
|
157
160
|
--studio-secondary-active: #c7d2fe;
|
|
161
|
+
--studio-secondary-bg: #312e81;
|
|
158
162
|
|
|
159
163
|
/* Semantic colors */
|
|
160
164
|
--studio-success: #34d399;
|