@eduboxpro/studio 0.1.12 → 0.1.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/fesm2022/eduboxpro-studio.mjs +755 -10
- package/fesm2022/eduboxpro-studio.mjs.map +1 -1
- package/index.d.ts +303 -4
- package/package.json +1 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, ElementRef, forwardRef, DOCUMENT as DOCUMENT$1, DestroyRef, contentChild,
|
|
2
|
+
import { InjectionToken, inject, signal, effect, Injectable, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, input, computed, ChangeDetectionStrategy, Component, output, ElementRef, forwardRef, viewChild, DOCUMENT as DOCUMENT$1, DestroyRef, contentChild, model, HostListener, PLATFORM_ID, Renderer2, Directive } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { DOCUMENT, CommonModule, NgTemplateOutlet, isPlatformBrowser } from '@angular/common';
|
|
5
5
|
import * as LucideIcons from 'lucide-angular';
|
|
6
6
|
import { icons, LucideAngularModule, LucideIconProvider, LUCIDE_ICONS } from 'lucide-angular';
|
|
7
|
-
import
|
|
7
|
+
import * as i1$1 from '@angular/forms';
|
|
8
|
+
import { NG_VALUE_ACCESSOR, FormsModule, NG_VALIDATORS } from '@angular/forms';
|
|
8
9
|
import { Router, RouterLink, RouterLinkActive, NavigationEnd } from '@angular/router';
|
|
9
10
|
import { trigger, state, transition, style, animate } from '@angular/animations';
|
|
10
11
|
import { filter } from 'rxjs/operators';
|
|
@@ -1278,6 +1279,400 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
1278
1279
|
}, template: "<label\n [for]=\"checkboxId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <!-- Checkbox input -->\n <input\n type=\"checkbox\"\n [id]=\"checkboxId()\"\n [name]=\"name()\"\n [checked]=\"internalChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? checkboxId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-checkbox__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <!-- Custom checkbox -->\n <span [ngClass]=\"checkboxClasses()\">\n <!-- Checkmark icon -->\n @if (internalChecked() && !indeterminate()) {\n <svg\n class=\"studio-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M13.3333 4L6 11.3333L2.66666 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n\n <!-- Indeterminate icon -->\n @if (indeterminate()) {\n <svg\n class=\"studio-checkbox__icon studio-checkbox__icon--indeterminate\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 8H12\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n }\n </span>\n\n <!-- Label content -->\n @if (label() || description()) {\n <span class=\"studio-checkbox__label-wrapper\">\n @if (label()) {\n <span class=\"studio-checkbox__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-checkbox__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-checkbox__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n<!-- Helper text / Error message -->\n@if (showHint() || showError()) {\n <div\n [id]=\"checkboxId() + '-description'\"\n class=\"studio-checkbox__info\"\n >\n @if (showError()) {\n <span class=\"studio-checkbox__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-checkbox__hint\">\n {{ hint() }}\n </span>\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-direction:column;font-family:var(--studio-font-family)!important}.studio-checkbox-wrapper{display:inline-flex;align-items:flex-start;gap:var(--studio-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.studio-checkbox-wrapper--label-left{flex-direction:row-reverse}.studio-checkbox-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-checkbox-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-checkbox-wrapper--md{font-size:var(--studio-font-size-base)}.studio-checkbox-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-checkbox__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-checkbox{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border:2px solid var(--studio-border-primary);background-color:var(--studio-bg-primary);transition:all var(--studio-transition-base)}.studio-checkbox--sm{width:1rem;height:1rem}.studio-checkbox--md{width:1.25rem;height:1.25rem}.studio-checkbox--lg{width:1.5rem;height:1.5rem}.studio-checkbox--radius-none{border-radius:0}.studio-checkbox--radius-sm{border-radius:var(--studio-radius-sm)}.studio-checkbox--radius-md{border-radius:var(--studio-radius-md)}.studio-checkbox--radius-lg{border-radius:var(--studio-radius-lg)}.studio-checkbox--radius-full{border-radius:var(--studio-radius-full)}.studio-checkbox--default.studio-checkbox--checked,.studio-checkbox--default.studio-checkbox--indeterminate{border-color:transparent}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--default.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--default.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--outlined.studio-checkbox--checked,.studio-checkbox--outlined.studio-checkbox--indeterminate{background-color:transparent}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--primary{border-color:var(--studio-primary);color:var(--studio-primary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--secondary{border-color:var(--studio-secondary);color:var(--studio-secondary)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--success{border-color:var(--studio-success);color:var(--studio-success)}.studio-checkbox--outlined.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--outlined.studio-checkbox--indeterminate.studio-checkbox--error{border-color:var(--studio-error);color:var(--studio-error)}.studio-checkbox--filled.studio-checkbox--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-checkbox--filled.studio-checkbox--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-checkbox--filled.studio-checkbox--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-checkbox--filled.studio-checkbox--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--primary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--primary{background-color:var(--studio-primary);border-color:var(--studio-primary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--secondary,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--success,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--success{background-color:var(--studio-success);border-color:var(--studio-success);color:var(--studio-text-inverse)}.studio-checkbox--filled.studio-checkbox--checked.studio-checkbox--error,.studio-checkbox--filled.studio-checkbox--indeterminate.studio-checkbox--error{background-color:var(--studio-error);border-color:var(--studio-error);color:var(--studio-text-inverse)}.studio-checkbox--error:not(.studio-checkbox--checked):not(.studio-checkbox--indeterminate){border-color:var(--studio-error)}.studio-checkbox:hover:not(.studio-checkbox--disabled){border-color:var(--studio-border-secondary)}.studio-checkbox__input:focus-visible+.studio-checkbox{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-checkbox__icon{width:100%;height:100%;opacity:0;transform:scale(.8);transition:all var(--studio-transition-fast)}.studio-checkbox--checked .studio-checkbox__icon,.studio-checkbox--indeterminate .studio-checkbox__icon{opacity:1;transform:scale(1)}.studio-checkbox__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-checkbox__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-checkbox__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-checkbox__info{display:flex;flex-direction:column;gap:var(--studio-spacing-xs);margin-top:var(--studio-spacing-xs);padding-left:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--label-left+.studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-checkbox-wrapper--sm .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--sm.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-checkbox-wrapper--lg .studio-checkbox__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox-wrapper--lg.studio-checkbox-wrapper--label-left .studio-checkbox__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-checkbox__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-checkbox__error{font-size:var(--studio-font-size-xs);color:var(--studio-error);line-height:var(--studio-line-height-normal)}\n"] }]
|
|
1279
1280
|
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
|
|
1280
1281
|
|
|
1282
|
+
class ColorConverter {
|
|
1283
|
+
static hexToRgb(hex) {
|
|
1284
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
1285
|
+
return result ? {
|
|
1286
|
+
r: parseInt(result[1], 16),
|
|
1287
|
+
g: parseInt(result[2], 16),
|
|
1288
|
+
b: parseInt(result[3], 16)
|
|
1289
|
+
} : null;
|
|
1290
|
+
}
|
|
1291
|
+
static rgbToHex(r, g, b) {
|
|
1292
|
+
return "#" + [r, g, b]
|
|
1293
|
+
.map(x => {
|
|
1294
|
+
const hex = Math.round(x).toString(16);
|
|
1295
|
+
return hex.length === 1 ? "0" + hex : hex;
|
|
1296
|
+
})
|
|
1297
|
+
.join("");
|
|
1298
|
+
}
|
|
1299
|
+
static rgbToHsl(r, g, b) {
|
|
1300
|
+
r /= 255;
|
|
1301
|
+
g /= 255;
|
|
1302
|
+
b /= 255;
|
|
1303
|
+
const max = Math.max(r, g, b);
|
|
1304
|
+
const min = Math.min(r, g, b);
|
|
1305
|
+
let h = 0, s = 0;
|
|
1306
|
+
const l = (max + min) / 2;
|
|
1307
|
+
if (max !== min) {
|
|
1308
|
+
const d = max - min;
|
|
1309
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
1310
|
+
switch (max) {
|
|
1311
|
+
case r:
|
|
1312
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
1313
|
+
break;
|
|
1314
|
+
case g:
|
|
1315
|
+
h = ((b - r) / d + 2) / 6;
|
|
1316
|
+
break;
|
|
1317
|
+
case b:
|
|
1318
|
+
h = ((r - g) / d + 4) / 6;
|
|
1319
|
+
break;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
return {
|
|
1323
|
+
h: Math.round(h * 360),
|
|
1324
|
+
s: Math.round(s * 100),
|
|
1325
|
+
l: Math.round(l * 100)
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
static hslToRgb(h, s, l) {
|
|
1329
|
+
h = h / 360;
|
|
1330
|
+
s = s / 100;
|
|
1331
|
+
l = l / 100;
|
|
1332
|
+
let r, g, b;
|
|
1333
|
+
if (s === 0) {
|
|
1334
|
+
r = g = b = l;
|
|
1335
|
+
}
|
|
1336
|
+
else {
|
|
1337
|
+
const hue2rgb = (p, q, t) => {
|
|
1338
|
+
if (t < 0)
|
|
1339
|
+
t += 1;
|
|
1340
|
+
if (t > 1)
|
|
1341
|
+
t -= 1;
|
|
1342
|
+
if (t < 1 / 6)
|
|
1343
|
+
return p + (q - p) * 6 * t;
|
|
1344
|
+
if (t < 1 / 2)
|
|
1345
|
+
return q;
|
|
1346
|
+
if (t < 2 / 3)
|
|
1347
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
1348
|
+
return p;
|
|
1349
|
+
};
|
|
1350
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
1351
|
+
const p = 2 * l - q;
|
|
1352
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
1353
|
+
g = hue2rgb(p, q, h);
|
|
1354
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
1355
|
+
}
|
|
1356
|
+
return {
|
|
1357
|
+
r: Math.round(r * 255),
|
|
1358
|
+
g: Math.round(g * 255),
|
|
1359
|
+
b: Math.round(b * 255)
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
static format(color, format) {
|
|
1363
|
+
switch (format) {
|
|
1364
|
+
case 'hex':
|
|
1365
|
+
return color.hex;
|
|
1366
|
+
case 'rgb':
|
|
1367
|
+
if (color.alpha < 1) {
|
|
1368
|
+
return `rgba(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b}, ${color.alpha})`;
|
|
1369
|
+
}
|
|
1370
|
+
return `rgb(${color.rgb.r}, ${color.rgb.g}, ${color.rgb.b})`;
|
|
1371
|
+
case 'hsl':
|
|
1372
|
+
if (color.alpha < 1) {
|
|
1373
|
+
return `hsla(${color.hsl.h}, ${color.hsl.s}%, ${color.hsl.l}%, ${color.alpha})`;
|
|
1374
|
+
}
|
|
1375
|
+
return `hsl(${color.hsl.h}, ${color.hsl.s}%, ${color.hsl.l}%)`;
|
|
1376
|
+
default:
|
|
1377
|
+
return color.hex;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
static parse(colorString) {
|
|
1381
|
+
const trimmed = colorString.trim();
|
|
1382
|
+
const hexMatch = /^#?([a-f\d]{6})$/i.exec(trimmed);
|
|
1383
|
+
if (hexMatch) {
|
|
1384
|
+
const hex = '#' + hexMatch[1];
|
|
1385
|
+
const rgb = this.hexToRgb(hex);
|
|
1386
|
+
if (!rgb)
|
|
1387
|
+
return null;
|
|
1388
|
+
return {
|
|
1389
|
+
hex,
|
|
1390
|
+
rgb,
|
|
1391
|
+
hsl: this.rgbToHsl(rgb.r, rgb.g, rgb.b),
|
|
1392
|
+
alpha: 1
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
const rgbMatch = /^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)$/i.exec(trimmed);
|
|
1396
|
+
if (rgbMatch) {
|
|
1397
|
+
const r = parseInt(rgbMatch[1]);
|
|
1398
|
+
const g = parseInt(rgbMatch[2]);
|
|
1399
|
+
const b = parseInt(rgbMatch[3]);
|
|
1400
|
+
const alpha = rgbMatch[4] ? parseFloat(rgbMatch[4]) : 1;
|
|
1401
|
+
return {
|
|
1402
|
+
hex: this.rgbToHex(r, g, b),
|
|
1403
|
+
rgb: { r, g, b },
|
|
1404
|
+
hsl: this.rgbToHsl(r, g, b),
|
|
1405
|
+
alpha
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
const hslMatch = /^hsla?\((\d+),\s*(\d+)%?,\s*(\d+)%?(?:,\s*([\d.]+))?\)$/i.exec(trimmed);
|
|
1409
|
+
if (hslMatch) {
|
|
1410
|
+
const h = parseInt(hslMatch[1]);
|
|
1411
|
+
const s = parseInt(hslMatch[2]);
|
|
1412
|
+
const l = parseInt(hslMatch[3]);
|
|
1413
|
+
const alpha = hslMatch[4] ? parseFloat(hslMatch[4]) : 1;
|
|
1414
|
+
const rgb = this.hslToRgb(h, s, l);
|
|
1415
|
+
return {
|
|
1416
|
+
hex: this.rgbToHex(rgb.r, rgb.g, rgb.b),
|
|
1417
|
+
rgb,
|
|
1418
|
+
hsl: { h, s, l },
|
|
1419
|
+
alpha
|
|
1420
|
+
};
|
|
1421
|
+
}
|
|
1422
|
+
return null;
|
|
1423
|
+
}
|
|
1424
|
+
static isValid(colorString) {
|
|
1425
|
+
return this.parse(colorString) !== null;
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
const DEFAULT_COLOR_PRESETS = [
|
|
1430
|
+
{
|
|
1431
|
+
label: 'Brand Colors',
|
|
1432
|
+
colors: [
|
|
1433
|
+
{ label: 'Primary', value: '#7c3aed' },
|
|
1434
|
+
{ label: 'Secondary', value: '#6366f1' },
|
|
1435
|
+
{ label: 'Success', value: '#10b981' },
|
|
1436
|
+
{ label: 'Error', value: '#ef4444' },
|
|
1437
|
+
{ label: 'Warning', value: '#f59e0b' },
|
|
1438
|
+
{ label: 'Info', value: '#3b82f6' }
|
|
1439
|
+
]
|
|
1440
|
+
},
|
|
1441
|
+
{
|
|
1442
|
+
label: 'Grays',
|
|
1443
|
+
colors: [
|
|
1444
|
+
{ value: '#ffffff' },
|
|
1445
|
+
{ value: '#f3f4f6' },
|
|
1446
|
+
{ value: '#d1d5db' },
|
|
1447
|
+
{ value: '#9ca3af' },
|
|
1448
|
+
{ value: '#6b7280' },
|
|
1449
|
+
{ value: '#374151' },
|
|
1450
|
+
{ value: '#1f2937' },
|
|
1451
|
+
{ value: '#000000' }
|
|
1452
|
+
]
|
|
1453
|
+
},
|
|
1454
|
+
{
|
|
1455
|
+
label: 'Common',
|
|
1456
|
+
colors: [
|
|
1457
|
+
{ value: '#ff0000' },
|
|
1458
|
+
{ value: '#ff7f00' },
|
|
1459
|
+
{ value: '#ffff00' },
|
|
1460
|
+
{ value: '#00ff00' },
|
|
1461
|
+
{ value: '#0000ff' },
|
|
1462
|
+
{ value: '#4b0082' },
|
|
1463
|
+
{ value: '#9400d3' },
|
|
1464
|
+
{ value: '#ff1493' }
|
|
1465
|
+
]
|
|
1466
|
+
}
|
|
1467
|
+
];
|
|
1468
|
+
|
|
1469
|
+
class ColorPickerComponent {
|
|
1470
|
+
configService = inject(StudioConfigService);
|
|
1471
|
+
pickerDefaults = computed(() => this.configService.config().components?.colorPicker, ...(ngDevMode ? [{ debugName: "pickerDefaults" }] : []));
|
|
1472
|
+
colorAreaCanvas = viewChild('colorArea', ...(ngDevMode ? [{ debugName: "colorAreaCanvas" }] : []));
|
|
1473
|
+
variantInput = input(undefined, ...(ngDevMode ? [{ debugName: "variantInput", alias: 'variant' }] : [{ alias: 'variant' }]));
|
|
1474
|
+
sizeInput = input(undefined, ...(ngDevMode ? [{ debugName: "sizeInput", alias: 'size' }] : [{ alias: 'size' }]));
|
|
1475
|
+
variant = withConfigDefault(this.variantInput, computed(() => this.pickerDefaults()?.variant), 'inline');
|
|
1476
|
+
size = withConfigDefault(this.sizeInput, computed(() => this.pickerDefaults()?.size), 'md');
|
|
1477
|
+
format = input('hex', ...(ngDevMode ? [{ debugName: "format" }] : []));
|
|
1478
|
+
showAlpha = input(false, ...(ngDevMode ? [{ debugName: "showAlpha" }] : []));
|
|
1479
|
+
showPresets = input(true, ...(ngDevMode ? [{ debugName: "showPresets" }] : []));
|
|
1480
|
+
showFormatToggle = input(true, ...(ngDevMode ? [{ debugName: "showFormatToggle" }] : []));
|
|
1481
|
+
showCopyButton = input(true, ...(ngDevMode ? [{ debugName: "showCopyButton" }] : []));
|
|
1482
|
+
presets = input(...(ngDevMode ? [undefined, { debugName: "presets" }] : []));
|
|
1483
|
+
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
1484
|
+
hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : []));
|
|
1485
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
|
|
1486
|
+
error = input(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
1487
|
+
errorMessage = input(undefined, ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
|
|
1488
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
1489
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
1490
|
+
colorChange = output();
|
|
1491
|
+
colorValueChange = output();
|
|
1492
|
+
copied = output();
|
|
1493
|
+
currentColor = signal(this.createColorValue('#000000'), ...(ngDevMode ? [{ debugName: "currentColor" }] : []));
|
|
1494
|
+
hue = signal(0, ...(ngDevMode ? [{ debugName: "hue" }] : []));
|
|
1495
|
+
saturation = signal(100, ...(ngDevMode ? [{ debugName: "saturation" }] : []));
|
|
1496
|
+
lightness = signal(50, ...(ngDevMode ? [{ debugName: "lightness" }] : []));
|
|
1497
|
+
alpha = signal(1, ...(ngDevMode ? [{ debugName: "alpha" }] : []));
|
|
1498
|
+
currentFormat = signal('hex', ...(ngDevMode ? [{ debugName: "currentFormat" }] : []));
|
|
1499
|
+
generatedId = `studio-color-picker-${Math.random().toString(36).substr(2, 9)}`;
|
|
1500
|
+
onChange = () => { };
|
|
1501
|
+
onTouched = () => { };
|
|
1502
|
+
isDragging = false;
|
|
1503
|
+
constructor() {
|
|
1504
|
+
effect(() => {
|
|
1505
|
+
this.currentFormat.set(this.format());
|
|
1506
|
+
});
|
|
1507
|
+
effect(() => {
|
|
1508
|
+
this.renderColorArea();
|
|
1509
|
+
});
|
|
1510
|
+
}
|
|
1511
|
+
ngAfterViewInit() {
|
|
1512
|
+
this.renderColorArea();
|
|
1513
|
+
}
|
|
1514
|
+
displayColor = computed(() => {
|
|
1515
|
+
const color = this.currentColor();
|
|
1516
|
+
return ColorConverter.format(color, this.currentFormat());
|
|
1517
|
+
}, ...(ngDevMode ? [{ debugName: "displayColor" }] : []));
|
|
1518
|
+
effectivePresets = computed(() => {
|
|
1519
|
+
const custom = this.presets();
|
|
1520
|
+
return custom && custom.length > 0 ? custom : DEFAULT_COLOR_PRESETS;
|
|
1521
|
+
}, ...(ngDevMode ? [{ debugName: "effectivePresets" }] : []));
|
|
1522
|
+
hostClasses = computed(() => classNames('studio-color-picker', `studio-color-picker--${this.variant()}`, `studio-color-picker--${this.size()}`, this.error() && 'studio-color-picker--error', this.disabled() && 'studio-color-picker--disabled'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
1523
|
+
writeValue(value) {
|
|
1524
|
+
if (!value)
|
|
1525
|
+
return;
|
|
1526
|
+
const colorValue = ColorConverter.parse(value);
|
|
1527
|
+
if (colorValue) {
|
|
1528
|
+
this.currentColor.set(colorValue);
|
|
1529
|
+
this.hue.set(colorValue.hsl.h);
|
|
1530
|
+
this.saturation.set(colorValue.hsl.s);
|
|
1531
|
+
this.lightness.set(colorValue.hsl.l);
|
|
1532
|
+
this.alpha.set(colorValue.alpha);
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
registerOnChange(fn) {
|
|
1536
|
+
this.onChange = fn;
|
|
1537
|
+
}
|
|
1538
|
+
registerOnTouched(fn) {
|
|
1539
|
+
this.onTouched = fn;
|
|
1540
|
+
}
|
|
1541
|
+
setDisabledState(isDisabled) { }
|
|
1542
|
+
onHueChange(event) {
|
|
1543
|
+
const value = +event.target.value;
|
|
1544
|
+
this.hue.set(value);
|
|
1545
|
+
this.updateColor();
|
|
1546
|
+
}
|
|
1547
|
+
onAlphaChange(event) {
|
|
1548
|
+
const value = +event.target.value;
|
|
1549
|
+
this.alpha.set(value / 100);
|
|
1550
|
+
this.updateColor();
|
|
1551
|
+
}
|
|
1552
|
+
onColorAreaMouseDown(event) {
|
|
1553
|
+
if (this.disabled() || this.readonly())
|
|
1554
|
+
return;
|
|
1555
|
+
this.isDragging = true;
|
|
1556
|
+
this.updateColorArea(event);
|
|
1557
|
+
const onMouseMove = (e) => {
|
|
1558
|
+
if (this.isDragging) {
|
|
1559
|
+
this.updateColorArea(e);
|
|
1560
|
+
}
|
|
1561
|
+
};
|
|
1562
|
+
const onMouseUp = () => {
|
|
1563
|
+
this.isDragging = false;
|
|
1564
|
+
document.removeEventListener('mousemove', onMouseMove);
|
|
1565
|
+
document.removeEventListener('mouseup', onMouseUp);
|
|
1566
|
+
};
|
|
1567
|
+
document.addEventListener('mousemove', onMouseMove);
|
|
1568
|
+
document.addEventListener('mouseup', onMouseUp);
|
|
1569
|
+
}
|
|
1570
|
+
updateColorArea(event) {
|
|
1571
|
+
const canvas = this.colorAreaCanvas()?.nativeElement;
|
|
1572
|
+
if (!canvas)
|
|
1573
|
+
return;
|
|
1574
|
+
const rect = canvas.getBoundingClientRect();
|
|
1575
|
+
const x = Math.max(0, Math.min(event.clientX - rect.left, rect.width));
|
|
1576
|
+
const y = Math.max(0, Math.min(event.clientY - rect.top, rect.height));
|
|
1577
|
+
this.saturation.set((x / rect.width) * 100);
|
|
1578
|
+
this.lightness.set(100 - (y / rect.height) * 100);
|
|
1579
|
+
this.updateColor();
|
|
1580
|
+
}
|
|
1581
|
+
updateColor() {
|
|
1582
|
+
const h = this.hue();
|
|
1583
|
+
const s = this.saturation();
|
|
1584
|
+
const l = this.lightness();
|
|
1585
|
+
const rgb = ColorConverter.hslToRgb(h, s, l);
|
|
1586
|
+
const hex = ColorConverter.rgbToHex(rgb.r, rgb.g, rgb.b);
|
|
1587
|
+
const colorValue = {
|
|
1588
|
+
hex,
|
|
1589
|
+
rgb,
|
|
1590
|
+
hsl: { h, s, l },
|
|
1591
|
+
alpha: this.alpha()
|
|
1592
|
+
};
|
|
1593
|
+
this.currentColor.set(colorValue);
|
|
1594
|
+
const formatted = ColorConverter.format(colorValue, this.currentFormat());
|
|
1595
|
+
this.onChange(formatted);
|
|
1596
|
+
this.colorChange.emit(formatted);
|
|
1597
|
+
this.colorValueChange.emit(colorValue);
|
|
1598
|
+
}
|
|
1599
|
+
renderColorArea() {
|
|
1600
|
+
const canvas = this.colorAreaCanvas()?.nativeElement;
|
|
1601
|
+
if (!canvas)
|
|
1602
|
+
return;
|
|
1603
|
+
const ctx = canvas.getContext('2d');
|
|
1604
|
+
if (!ctx)
|
|
1605
|
+
return;
|
|
1606
|
+
const width = canvas.width;
|
|
1607
|
+
const height = canvas.height;
|
|
1608
|
+
const hue = this.hue();
|
|
1609
|
+
const horizGradient = ctx.createLinearGradient(0, 0, width, 0);
|
|
1610
|
+
horizGradient.addColorStop(0, 'white');
|
|
1611
|
+
horizGradient.addColorStop(1, `hsl(${hue}, 100%, 50%)`);
|
|
1612
|
+
ctx.fillStyle = horizGradient;
|
|
1613
|
+
ctx.fillRect(0, 0, width, height);
|
|
1614
|
+
const vertGradient = ctx.createLinearGradient(0, 0, 0, height);
|
|
1615
|
+
vertGradient.addColorStop(0, 'transparent');
|
|
1616
|
+
vertGradient.addColorStop(1, 'black');
|
|
1617
|
+
ctx.fillStyle = vertGradient;
|
|
1618
|
+
ctx.fillRect(0, 0, width, height);
|
|
1619
|
+
}
|
|
1620
|
+
toggleFormat() {
|
|
1621
|
+
const formats = ['hex', 'rgb', 'hsl'];
|
|
1622
|
+
const current = this.currentFormat();
|
|
1623
|
+
const index = formats.indexOf(current);
|
|
1624
|
+
const next = formats[(index + 1) % formats.length];
|
|
1625
|
+
this.currentFormat.set(next);
|
|
1626
|
+
}
|
|
1627
|
+
async copyColor() {
|
|
1628
|
+
const color = this.displayColor();
|
|
1629
|
+
try {
|
|
1630
|
+
await navigator.clipboard.writeText(color);
|
|
1631
|
+
this.copied.emit(color);
|
|
1632
|
+
}
|
|
1633
|
+
catch (error) {
|
|
1634
|
+
console.error('Copy failed:', error);
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
selectPreset(preset) {
|
|
1638
|
+
this.writeValue(preset.value);
|
|
1639
|
+
this.updateColor();
|
|
1640
|
+
}
|
|
1641
|
+
isPresetGroup(item) {
|
|
1642
|
+
return item && 'colors' in item && Array.isArray(item.colors);
|
|
1643
|
+
}
|
|
1644
|
+
createColorValue(hex) {
|
|
1645
|
+
const rgb = ColorConverter.hexToRgb(hex) || { r: 0, g: 0, b: 0 };
|
|
1646
|
+
const hsl = ColorConverter.rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
1647
|
+
return {
|
|
1648
|
+
hex,
|
|
1649
|
+
rgb,
|
|
1650
|
+
hsl,
|
|
1651
|
+
alpha: 1
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1655
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: ColorPickerComponent, isStandalone: true, selector: "studio-color-picker", inputs: { variantInput: { classPropertyName: "variantInput", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, showAlpha: { classPropertyName: "showAlpha", publicName: "showAlpha", isSignal: true, isRequired: false, transformFunction: null }, showPresets: { classPropertyName: "showPresets", publicName: "showPresets", isSignal: true, isRequired: false, transformFunction: null }, showFormatToggle: { classPropertyName: "showFormatToggle", publicName: "showFormatToggle", isSignal: true, isRequired: false, transformFunction: null }, showCopyButton: { classPropertyName: "showCopyButton", publicName: "showCopyButton", isSignal: true, isRequired: false, transformFunction: null }, presets: { classPropertyName: "presets", publicName: "presets", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { colorChange: "colorChange", colorValueChange: "colorValueChange", copied: "copied" }, host: { properties: { "class": "hostClasses()" } }, providers: [
|
|
1656
|
+
{
|
|
1657
|
+
provide: NG_VALUE_ACCESSOR,
|
|
1658
|
+
useExisting: forwardRef(() => ColorPickerComponent),
|
|
1659
|
+
multi: true
|
|
1660
|
+
}
|
|
1661
|
+
], viewQueries: [{ propertyName: "colorAreaCanvas", first: true, predicate: ["colorArea"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (label()) {\n <label [for]=\"generatedId\" class=\"studio-color-picker__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-color-picker__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-color-picker__picker\">\n <div class=\"studio-color-picker__preview\">\n <div\n class=\"studio-color-picker__preview-color\"\n [style.background-color]=\"displayColor()\"\n ></div>\n <div class=\"studio-color-picker__preview-info\">\n <span class=\"studio-color-picker__preview-value\">{{ displayColor() }}</span>\n @if (showFormatToggle()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__format-btn\"\n (click)=\"toggleFormat()\"\n [disabled]=\"disabled() || readonly()\"\n >\n {{ currentFormat().toUpperCase() }}\n </button>\n }\n </div>\n @if (showCopyButton()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__copy-btn\"\n (click)=\"copyColor()\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Copy color\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\n </svg>\n </button>\n }\n </div>\n\n <div class=\"studio-color-picker__area\">\n <canvas\n #colorArea\n class=\"studio-color-picker__canvas\"\n width=\"280\"\n height=\"180\"\n (mousedown)=\"onColorAreaMouseDown($event)\"\n ></canvas>\n <div\n class=\"studio-color-picker__cursor\"\n [style.left.%]=\"saturation()\"\n [style.top.%]=\"100 - lightness()\"\n ></div>\n </div>\n\n <div class=\"studio-color-picker__sliders\">\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Hue</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__hue-slider\"\n min=\"0\"\n max=\"360\"\n [value]=\"hue()\"\n (input)=\"onHueChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Hue\"\n />\n </div>\n\n @if (showAlpha()) {\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Opacity</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__alpha-slider\"\n min=\"0\"\n max=\"100\"\n [value]=\"alpha() * 100\"\n (input)=\"onAlphaChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Opacity\"\n />\n <span class=\"studio-color-picker__alpha-value\">{{ (alpha() * 100).toFixed(0) }}%</span>\n </div>\n }\n </div>\n\n @if (showPresets() && effectivePresets().length > 0) {\n <div class=\"studio-color-picker__presets\">\n @for (preset of effectivePresets(); track $index) {\n @if (isPresetGroup(preset)) {\n <div class=\"studio-color-picker__preset-group\">\n <div class=\"studio-color-picker__preset-group-label\">{{ preset.label }}</div>\n <div class=\"studio-color-picker__preset-swatches\">\n @for (color of preset.colors; track color.value) {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"color.value\"\n [title]=\"color.label || color.value\"\n (click)=\"selectPreset(color)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n </div>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"preset.value\"\n [title]=\"preset.label || preset.value\"\n (click)=\"selectPreset(preset)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n }\n </div>\n }\n</div>\n\n@if (hint() && !error()) {\n <span class=\"studio-color-picker__hint\">\n {{ hint() }}\n </span>\n}\n\n@if (error() && errorMessage()) {\n <span class=\"studio-color-picker__error\" role=\"alert\">\n {{ errorMessage() }}\n </span>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.5rem;font-family:var(--studio-font-family)}.studio-color-picker__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-color-picker__label .studio-color-picker__required{color:var(--studio-error);margin-left:.125rem}.studio-color-picker__picker{display:flex;flex-direction:column;gap:1rem;padding:1rem;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md)}.studio-color-picker__preview{display:flex;align-items:center;gap:.75rem}.studio-color-picker__preview-color{width:3rem;height:3rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);flex-shrink:0}.studio-color-picker__preview-info{flex:1;display:flex;align-items:center;gap:.5rem}.studio-color-picker__preview-value{font-family:var(--studio-font-mono, monospace);font-size:.875rem;color:var(--studio-text-primary)}.studio-color-picker__format-btn{padding:.25rem .5rem;background:var(--studio-bg-secondary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary);cursor:pointer;transition:all var(--studio-transition-fast)}.studio-color-picker__format-btn:hover:not(:disabled){background:var(--studio-bg-tertiary);color:var(--studio-text-primary)}.studio-color-picker__format-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__copy-btn{padding:.5rem;background:none;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);color:var(--studio-text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--studio-transition-fast)}.studio-color-picker__copy-btn:hover:not(:disabled){background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-color-picker__copy-btn:active:not(:disabled){transform:scale(.95)}.studio-color-picker__copy-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__area{position:relative;width:100%;aspect-ratio:28/18;border-radius:var(--studio-radius-sm);overflow:hidden;border:1px solid var(--studio-border-primary)}.studio-color-picker__canvas{display:block;width:100%;height:100%;cursor:crosshair}.studio-color-picker__cursor{position:absolute;width:16px;height:16px;border:2px solid white;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003}.studio-color-picker__sliders{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__slider{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__slider-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__hue-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red);outline:none;cursor:pointer}.studio-color-picker__hue-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,transparent 0%,var(--studio-text-primary) 100%);outline:none;cursor:pointer;position:relative}.studio-color-picker__alpha-slider:before{content:\"\";position:absolute;inset:0;border-radius:6px;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:10px 10px;background-position:0 0,0 5px,5px -5px,-5px 0px;z-index:-1}.studio-color-picker__alpha-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-value{font-size:.75rem;color:var(--studio-text-secondary);margin-left:auto}.studio-color-picker__presets{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__preset-group{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__preset-group-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__preset-swatches{display:flex;flex-wrap:wrap;gap:.375rem}.studio-color-picker__preset-swatch{width:2rem;height:2rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);cursor:pointer;transition:all var(--studio-transition-fast);padding:0}.studio-color-picker__preset-swatch:hover:not(:disabled){transform:scale(1.1);box-shadow:0 2px 8px #00000026}.studio-color-picker__preset-swatch:active:not(:disabled){transform:scale(1.05)}.studio-color-picker__preset-swatch:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-color-picker__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}:host(.studio-color-picker--disabled) .studio-color-picker__picker{opacity:.6;pointer-events:none}:host(.studio-color-picker--error) .studio-color-picker__picker{border-color:var(--studio-error)}:host(.studio-color-picker--sm) .studio-color-picker__preview-color{width:2.5rem;height:2.5rem}:host(.studio-color-picker--sm) .studio-color-picker__picker{padding:.75rem}:host(.studio-color-picker--lg) .studio-color-picker__preview-color{width:3.5rem;height:3.5rem}:host(.studio-color-picker--lg) .studio-color-picker__picker{padding:1.25rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1662
|
+
}
|
|
1663
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: ColorPickerComponent, decorators: [{
|
|
1664
|
+
type: Component,
|
|
1665
|
+
args: [{ selector: 'studio-color-picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1666
|
+
{
|
|
1667
|
+
provide: NG_VALUE_ACCESSOR,
|
|
1668
|
+
useExisting: forwardRef(() => ColorPickerComponent),
|
|
1669
|
+
multi: true
|
|
1670
|
+
}
|
|
1671
|
+
], host: {
|
|
1672
|
+
'[class]': 'hostClasses()',
|
|
1673
|
+
}, template: "@if (label()) {\n <label [for]=\"generatedId\" class=\"studio-color-picker__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-color-picker__required\">*</span>\n }\n </label>\n}\n\n<div class=\"studio-color-picker__picker\">\n <div class=\"studio-color-picker__preview\">\n <div\n class=\"studio-color-picker__preview-color\"\n [style.background-color]=\"displayColor()\"\n ></div>\n <div class=\"studio-color-picker__preview-info\">\n <span class=\"studio-color-picker__preview-value\">{{ displayColor() }}</span>\n @if (showFormatToggle()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__format-btn\"\n (click)=\"toggleFormat()\"\n [disabled]=\"disabled() || readonly()\"\n >\n {{ currentFormat().toUpperCase() }}\n </button>\n }\n </div>\n @if (showCopyButton()) {\n <button\n type=\"button\"\n class=\"studio-color-picker__copy-btn\"\n (click)=\"copyColor()\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Copy color\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect>\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>\n </svg>\n </button>\n }\n </div>\n\n <div class=\"studio-color-picker__area\">\n <canvas\n #colorArea\n class=\"studio-color-picker__canvas\"\n width=\"280\"\n height=\"180\"\n (mousedown)=\"onColorAreaMouseDown($event)\"\n ></canvas>\n <div\n class=\"studio-color-picker__cursor\"\n [style.left.%]=\"saturation()\"\n [style.top.%]=\"100 - lightness()\"\n ></div>\n </div>\n\n <div class=\"studio-color-picker__sliders\">\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Hue</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__hue-slider\"\n min=\"0\"\n max=\"360\"\n [value]=\"hue()\"\n (input)=\"onHueChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Hue\"\n />\n </div>\n\n @if (showAlpha()) {\n <div class=\"studio-color-picker__slider\">\n <div class=\"studio-color-picker__slider-label\">Opacity</div>\n <input\n type=\"range\"\n class=\"studio-color-picker__alpha-slider\"\n min=\"0\"\n max=\"100\"\n [value]=\"alpha() * 100\"\n (input)=\"onAlphaChange($event)\"\n [disabled]=\"disabled() || readonly()\"\n aria-label=\"Opacity\"\n />\n <span class=\"studio-color-picker__alpha-value\">{{ (alpha() * 100).toFixed(0) }}%</span>\n </div>\n }\n </div>\n\n @if (showPresets() && effectivePresets().length > 0) {\n <div class=\"studio-color-picker__presets\">\n @for (preset of effectivePresets(); track $index) {\n @if (isPresetGroup(preset)) {\n <div class=\"studio-color-picker__preset-group\">\n <div class=\"studio-color-picker__preset-group-label\">{{ preset.label }}</div>\n <div class=\"studio-color-picker__preset-swatches\">\n @for (color of preset.colors; track color.value) {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"color.value\"\n [title]=\"color.label || color.value\"\n (click)=\"selectPreset(color)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n </div>\n </div>\n } @else {\n <button\n type=\"button\"\n class=\"studio-color-picker__preset-swatch\"\n [style.background-color]=\"preset.value\"\n [title]=\"preset.label || preset.value\"\n (click)=\"selectPreset(preset)\"\n [disabled]=\"disabled() || readonly()\"\n ></button>\n }\n }\n </div>\n }\n</div>\n\n@if (hint() && !error()) {\n <span class=\"studio-color-picker__hint\">\n {{ hint() }}\n </span>\n}\n\n@if (error() && errorMessage()) {\n <span class=\"studio-color-picker__error\" role=\"alert\">\n {{ errorMessage() }}\n </span>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:.5rem;font-family:var(--studio-font-family)}.studio-color-picker__label{display:block;font-size:.875rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-color-picker__label .studio-color-picker__required{color:var(--studio-error);margin-left:.125rem}.studio-color-picker__picker{display:flex;flex-direction:column;gap:1rem;padding:1rem;background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md)}.studio-color-picker__preview{display:flex;align-items:center;gap:.75rem}.studio-color-picker__preview-color{width:3rem;height:3rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);flex-shrink:0}.studio-color-picker__preview-info{flex:1;display:flex;align-items:center;gap:.5rem}.studio-color-picker__preview-value{font-family:var(--studio-font-mono, monospace);font-size:.875rem;color:var(--studio-text-primary)}.studio-color-picker__format-btn{padding:.25rem .5rem;background:var(--studio-bg-secondary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary);cursor:pointer;transition:all var(--studio-transition-fast)}.studio-color-picker__format-btn:hover:not(:disabled){background:var(--studio-bg-tertiary);color:var(--studio-text-primary)}.studio-color-picker__format-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__copy-btn{padding:.5rem;background:none;border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-sm);color:var(--studio-text-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--studio-transition-fast)}.studio-color-picker__copy-btn:hover:not(:disabled){background:var(--studio-bg-secondary);color:var(--studio-text-primary)}.studio-color-picker__copy-btn:active:not(:disabled){transform:scale(.95)}.studio-color-picker__copy-btn:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__area{position:relative;width:100%;aspect-ratio:28/18;border-radius:var(--studio-radius-sm);overflow:hidden;border:1px solid var(--studio-border-primary)}.studio-color-picker__canvas{display:block;width:100%;height:100%;cursor:crosshair}.studio-color-picker__cursor{position:absolute;width:16px;height:16px;border:2px solid white;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003}.studio-color-picker__sliders{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__slider{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__slider-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__hue-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red);outline:none;cursor:pointer}.studio-color-picker__hue-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__hue-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-slider{-webkit-appearance:none;appearance:none;width:100%;height:12px;border-radius:6px;background:linear-gradient(to right,transparent 0%,var(--studio-text-primary) 100%);outline:none;cursor:pointer;position:relative}.studio-color-picker__alpha-slider:before{content:\"\";position:absolute;inset:0;border-radius:6px;background-image:linear-gradient(45deg,#ccc 25%,transparent 25%),linear-gradient(-45deg,#ccc 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#ccc 75%),linear-gradient(-45deg,transparent 75%,#ccc 75%);background-size:10px 10px;background-position:0 0,0 5px,5px -5px,-5px 0px;z-index:-1}.studio-color-picker__alpha-slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider::-moz-range-thumb{width:18px;height:18px;border-radius:50%;background:#fff;border:2px solid var(--studio-border-primary);cursor:pointer;box-shadow:0 2px 4px #0003}.studio-color-picker__alpha-slider:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__alpha-value{font-size:.75rem;color:var(--studio-text-secondary);margin-left:auto}.studio-color-picker__presets{display:flex;flex-direction:column;gap:.75rem}.studio-color-picker__preset-group{display:flex;flex-direction:column;gap:.5rem}.studio-color-picker__preset-group-label{font-size:.75rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-secondary)}.studio-color-picker__preset-swatches{display:flex;flex-wrap:wrap;gap:.375rem}.studio-color-picker__preset-swatch{width:2rem;height:2rem;border-radius:var(--studio-radius-sm);border:1px solid var(--studio-border-primary);cursor:pointer;transition:all var(--studio-transition-fast);padding:0}.studio-color-picker__preset-swatch:hover:not(:disabled){transform:scale(1.1);box-shadow:0 2px 8px #00000026}.studio-color-picker__preset-swatch:active:not(:disabled){transform:scale(1.05)}.studio-color-picker__preset-swatch:disabled{opacity:.5;cursor:not-allowed}.studio-color-picker__hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-color-picker__error{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--studio-error);line-height:1.4}:host(.studio-color-picker--disabled) .studio-color-picker__picker{opacity:.6;pointer-events:none}:host(.studio-color-picker--error) .studio-color-picker__picker{border-color:var(--studio-error)}:host(.studio-color-picker--sm) .studio-color-picker__preview-color{width:2.5rem;height:2.5rem}:host(.studio-color-picker--sm) .studio-color-picker__picker{padding:.75rem}:host(.studio-color-picker--lg) .studio-color-picker__preview-color{width:3.5rem;height:3.5rem}:host(.studio-color-picker--lg) .studio-color-picker__picker{padding:1.25rem}\n"] }]
|
|
1674
|
+
}], ctorParameters: () => [], propDecorators: { colorAreaCanvas: [{ type: i0.ViewChild, args: ['colorArea', { isSignal: true }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], showAlpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAlpha", required: false }] }], showPresets: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPresets", required: false }] }], showFormatToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFormatToggle", required: false }] }], showCopyButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCopyButton", required: false }] }], presets: [{ type: i0.Input, args: [{ isSignal: true, alias: "presets", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], colorChange: [{ type: i0.Output, args: ["colorChange"] }], colorValueChange: [{ type: i0.Output, args: ["colorValueChange"] }], copied: [{ type: i0.Output, args: ["copied"] }] } });
|
|
1675
|
+
|
|
1281
1676
|
/**
|
|
1282
1677
|
* Service for programmatic control of Drawer components
|
|
1283
1678
|
*
|
|
@@ -2322,6 +2717,117 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
2322
2717
|
}, template: "<div class=\"studio-navbar__left\">\n <ng-content select=\"[navbarLeft]\" />\n</div>\n\n<div class=\"studio-navbar__center\">\n <ng-content select=\"[navbarCenter]\" />\n</div>\n\n<div class=\"studio-navbar__right\">\n <ng-content select=\"[navbarRight]\" />\n</div>\n\n<ng-content />\n", styles: [":host{display:flex;align-items:center;width:100%;min-height:var(--navbar-height, 4rem);padding:0 var(--navbar-padding-x, 1.5rem);gap:var(--navbar-gap, 1.5rem);background:var(--studio-bg-primary);transition:all .2s cubic-bezier(.4,0,.2,1);--navbar-height: 4rem;--navbar-padding-x: 1.5rem;--navbar-gap: 1.5rem;--navbar-z-index: 1000}:host(.studio-navbar--sm){--navbar-height: 3.5rem;--navbar-padding-x: 1rem;--navbar-gap: 1rem}:host(.studio-navbar--md){--navbar-height: 4rem;--navbar-padding-x: 1.5rem;--navbar-gap: 1.5rem}:host(.studio-navbar--lg){--navbar-height: 5rem;--navbar-padding-x: 2rem;--navbar-gap: 2rem}:host(.studio-navbar--sticky){position:sticky;top:0;z-index:var(--navbar-z-index)}:host(.studio-navbar--blur){-webkit-backdrop-filter:blur(12px) saturate(180%);backdrop-filter:blur(12px) saturate(180%);background:hsl(var(--studio-bg-primary-hsl)/.8)}:host(.studio-navbar--default){background:var(--studio-bg-primary);border-bottom:1px solid hsl(var(--studio-border-primary-hsl)/.1)}:host(.studio-navbar--filled){background:var(--studio-bg-secondary);border-bottom:1px solid var(--studio-border-secondary)}:host(.studio-navbar--outlined){background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-left:none;border-right:none}:host(.studio-navbar--ghost){background:transparent}:host(.studio-navbar--transparent){background:transparent}:host(.studio-navbar--primary){background:var(--studio-primary);color:var(--studio-primary-contrast);border-bottom:1px solid hsl(var(--studio-primary-hsl)/.2)}:host(.studio-navbar--secondary){background:var(--studio-secondary);color:var(--studio-secondary-contrast);border-bottom:1px solid hsl(var(--studio-secondary-hsl)/.2)}:host(.studio-navbar--bordered){border-bottom:1px solid var(--studio-border-secondary)}:host(.studio-navbar--shadow-none){box-shadow:none}:host(.studio-navbar--shadow-sm){box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a}:host(.studio-navbar--shadow-md){box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}:host(.studio-navbar--shadow-lg){box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.studio-navbar__left{display:flex;align-items:center;gap:var(--navbar-gap);flex-shrink:0}.studio-navbar__center{display:flex;align-items:center;justify-content:center;gap:calc(var(--navbar-gap) * .75);flex:1}.studio-navbar__right{display:flex;align-items:center;gap:calc(var(--navbar-gap) * .5);flex-shrink:0;margin-left:auto}@media (max-width: 768px){:host{--navbar-padding-x: 1rem;--navbar-gap: 1rem}.studio-navbar__center{display:none}}\n"] }]
|
|
2323
2718
|
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], shadow: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], customHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "customHeight", required: false }] }], sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }], blurBg: [{ type: i0.Input, args: [{ isSignal: true, alias: "blurBg", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], navbarClick: [{ type: i0.Output, args: ["navbarClick"] }] } });
|
|
2324
2719
|
|
|
2720
|
+
/**
|
|
2721
|
+
* RadioButton component for selecting a single option from a group
|
|
2722
|
+
*
|
|
2723
|
+
* @example
|
|
2724
|
+
* <studio-radio-button
|
|
2725
|
+
* [(ngModel)]="selectedValue"
|
|
2726
|
+
* [value]="'option1'"
|
|
2727
|
+
* label="Option 1"
|
|
2728
|
+
* name="options"
|
|
2729
|
+
* />
|
|
2730
|
+
*/
|
|
2731
|
+
class RadioButtonComponent {
|
|
2732
|
+
configService = inject(StudioConfigService);
|
|
2733
|
+
radioDefaults = computed(() => this.configService.config().components?.radioButton, ...(ngDevMode ? [{ debugName: "radioDefaults" }] : []));
|
|
2734
|
+
size = input(this.radioDefaults()?.size ?? 'md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
2735
|
+
color = input(this.radioDefaults()?.color ?? 'primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
|
|
2736
|
+
variant = input(this.radioDefaults()?.variant ?? 'default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
2737
|
+
radius = input(this.radioDefaults()?.radius ?? 'full', ...(ngDevMode ? [{ debugName: "radius" }] : []));
|
|
2738
|
+
label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : []));
|
|
2739
|
+
labelPosition = input(this.radioDefaults()?.labelPosition ?? 'right', ...(ngDevMode ? [{ debugName: "labelPosition" }] : []));
|
|
2740
|
+
description = input(...(ngDevMode ? [undefined, { debugName: "description" }] : []));
|
|
2741
|
+
hint = input(...(ngDevMode ? [undefined, { debugName: "hint" }] : []));
|
|
2742
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
|
|
2743
|
+
error = input(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
2744
|
+
errorMessage = input(...(ngDevMode ? [undefined, { debugName: "errorMessage" }] : []));
|
|
2745
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
2746
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
2747
|
+
name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
|
|
2748
|
+
tabIndex = input(0, ...(ngDevMode ? [{ debugName: "tabIndex" }] : []));
|
|
2749
|
+
value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
|
|
2750
|
+
changed = output();
|
|
2751
|
+
internalValue = signal(null, ...(ngDevMode ? [{ debugName: "internalValue" }] : []));
|
|
2752
|
+
isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
|
|
2753
|
+
radioId = signal(`studio-radio-${Math.random().toString(36).substr(2, 9)}`, ...(ngDevMode ? [{ debugName: "radioId" }] : []));
|
|
2754
|
+
hostClasses = computed(() => ({
|
|
2755
|
+
'studio-radio-wrapper': true,
|
|
2756
|
+
[`studio-radio-wrapper--${this.size()}`]: true,
|
|
2757
|
+
'studio-radio-wrapper--disabled': this.disabled(),
|
|
2758
|
+
'studio-radio-wrapper--error': this.error(),
|
|
2759
|
+
'studio-radio-wrapper--focused': this.isFocused(),
|
|
2760
|
+
'studio-radio-wrapper--label-left': this.labelPosition() === 'left'
|
|
2761
|
+
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
2762
|
+
radioClasses = computed(() => ({
|
|
2763
|
+
'studio-radio': true,
|
|
2764
|
+
[`studio-radio--${this.size()}`]: true,
|
|
2765
|
+
[`studio-radio--${this.color()}`]: true,
|
|
2766
|
+
[`studio-radio--${this.variant()}`]: true,
|
|
2767
|
+
[`studio-radio--radius-${this.radius()}`]: true,
|
|
2768
|
+
'studio-radio--checked': this.isChecked(),
|
|
2769
|
+
'studio-radio--disabled': this.disabled(),
|
|
2770
|
+
'studio-radio--error': this.error()
|
|
2771
|
+
}), ...(ngDevMode ? [{ debugName: "radioClasses" }] : []));
|
|
2772
|
+
showError = computed(() => this.error() && this.errorMessage(), ...(ngDevMode ? [{ debugName: "showError" }] : []));
|
|
2773
|
+
showHint = computed(() => !this.error() && this.hint(), ...(ngDevMode ? [{ debugName: "showHint" }] : []));
|
|
2774
|
+
isChecked = computed(() => this.internalValue() === this.value(), ...(ngDevMode ? [{ debugName: "isChecked" }] : []));
|
|
2775
|
+
onChange = () => { };
|
|
2776
|
+
onTouched = () => { };
|
|
2777
|
+
writeValue(value) {
|
|
2778
|
+
this.internalValue.set(value);
|
|
2779
|
+
}
|
|
2780
|
+
registerOnChange(fn) {
|
|
2781
|
+
this.onChange = fn;
|
|
2782
|
+
}
|
|
2783
|
+
registerOnTouched(fn) {
|
|
2784
|
+
this.onTouched = fn;
|
|
2785
|
+
}
|
|
2786
|
+
setDisabledState(isDisabled) { }
|
|
2787
|
+
handleChange(event) {
|
|
2788
|
+
if (this.disabled() || this.readonly()) {
|
|
2789
|
+
event.preventDefault();
|
|
2790
|
+
return;
|
|
2791
|
+
}
|
|
2792
|
+
const inputValue = this.value();
|
|
2793
|
+
this.internalValue.set(inputValue);
|
|
2794
|
+
this.onChange(inputValue);
|
|
2795
|
+
this.changed.emit(inputValue);
|
|
2796
|
+
}
|
|
2797
|
+
handleFocus() {
|
|
2798
|
+
this.isFocused.set(true);
|
|
2799
|
+
}
|
|
2800
|
+
handleBlur() {
|
|
2801
|
+
this.isFocused.set(false);
|
|
2802
|
+
this.onTouched();
|
|
2803
|
+
}
|
|
2804
|
+
handleLabelClick(event) {
|
|
2805
|
+
if (this.disabled() || this.readonly()) {
|
|
2806
|
+
event.preventDefault();
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: RadioButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2810
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: RadioButtonComponent, isStandalone: true, selector: "studio-radio-button", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, radius: { classPropertyName: "radius", publicName: "radius", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changed: "changed" }, host: { properties: { "class": "hostClasses()", "attr.data-size": "size()", "attr.data-color": "color()", "attr.data-disabled": "disabled()", "attr.data-error": "error()" } }, providers: [{
|
|
2811
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2812
|
+
useExisting: forwardRef(() => RadioButtonComponent),
|
|
2813
|
+
multi: true
|
|
2814
|
+
}], ngImport: i0, template: "<label\n [for]=\"radioId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <input\n type=\"radio\"\n [id]=\"radioId()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"isChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"isChecked() ? 'true' : 'false'\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? radioId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-radio__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <span [ngClass]=\"radioClasses()\">\n @if (isChecked()) {\n <span class=\"studio-radio__dot\"></span>\n }\n </span>\n\n @if (label() || description()) {\n <span class=\"studio-radio__label-wrapper\">\n @if (label()) {\n <span class=\"studio-radio__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-radio__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-radio__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n@if (showHint() || showError()) {\n <div\n [id]=\"radioId() + '-description'\"\n class=\"studio-radio__info\"\n >\n @if (showError()) {\n <span class=\"studio-radio__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-radio__hint\">\n {{ hint() }}\n </span>\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-direction:column;font-family:var(--studio-font-family)!important}.studio-radio-wrapper{display:inline-flex;align-items:flex-start;gap:var(--studio-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.studio-radio-wrapper--label-left{flex-direction:row-reverse}.studio-radio-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-radio-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-radio-wrapper--md{font-size:var(--studio-font-size-base)}.studio-radio-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-radio__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-radio{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border:2px solid var(--studio-border-primary);background-color:var(--studio-bg-primary);transition:all var(--studio-transition-base);border-radius:var(--studio-radius-full)}.studio-radio--sm{width:1rem;height:1rem}.studio-radio--md{width:1.25rem;height:1.25rem}.studio-radio--lg{width:1.5rem;height:1.5rem}.studio-radio--radius-none{border-radius:0}.studio-radio--radius-sm{border-radius:var(--studio-radius-sm)}.studio-radio--radius-md{border-radius:var(--studio-radius-md)}.studio-radio--radius-lg{border-radius:var(--studio-radius-lg)}.studio-radio--radius-full{border-radius:var(--studio-radius-full)}.studio-radio--default.studio-radio--checked{border-color:transparent}.studio-radio--default.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary)}.studio-radio--default.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary)}.studio-radio--default.studio-radio--checked.studio-radio--success{background-color:var(--studio-success)}.studio-radio--default.studio-radio--checked.studio-radio--error{background-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked{background-color:transparent}.studio-radio--outlined.studio-radio--checked.studio-radio--primary{border-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--primary .studio-radio__dot{background-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary{border-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary .studio-radio__dot{background-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--success{border-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--success .studio-radio__dot{background-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--error{border-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked.studio-radio--error .studio-radio__dot{background-color:var(--studio-error)}.studio-radio--filled.studio-radio--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-radio--filled.studio-radio--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-radio--filled.studio-radio--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-radio--filled.studio-radio--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-radio--filled.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary);border-color:var(--studio-primary)}.studio-radio--filled.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary)}.studio-radio--filled.studio-radio--checked.studio-radio--success{background-color:var(--studio-success);border-color:var(--studio-success)}.studio-radio--filled.studio-radio--checked.studio-radio--error{background-color:var(--studio-error);border-color:var(--studio-error)}.studio-radio--error:not(.studio-radio--checked){border-color:var(--studio-error)}.studio-radio:hover:not(.studio-radio--disabled){border-color:var(--studio-border-secondary)}.studio-radio__input:focus-visible+.studio-radio{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-radio__dot{border-radius:var(--studio-radius-full);background-color:var(--studio-text-inverse);opacity:0;transform:scale(.5);transition:all var(--studio-transition-fast)}.studio-radio--sm .studio-radio__dot{width:.375rem;height:.375rem}.studio-radio--md .studio-radio__dot{width:.5rem;height:.5rem}.studio-radio--lg .studio-radio__dot{width:.625rem;height:.625rem}.studio-radio--checked .studio-radio__dot{opacity:1;transform:scale(1)}.studio-radio__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-radio__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-radio__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-radio__info{display:flex;flex-direction:column;gap:var(--studio-spacing-xs);margin-top:var(--studio-spacing-xs);padding-left:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-radio-wrapper--label-left+.studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-radio-wrapper--sm .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--sm.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--lg .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio-wrapper--lg.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__error{font-size:var(--studio-font-size-xs);color:var(--studio-error);line-height:var(--studio-line-height-normal)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
2815
|
+
}
|
|
2816
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: RadioButtonComponent, decorators: [{
|
|
2817
|
+
type: Component,
|
|
2818
|
+
args: [{ selector: 'studio-radio-button', standalone: true, imports: [CommonModule], providers: [{
|
|
2819
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2820
|
+
useExisting: forwardRef(() => RadioButtonComponent),
|
|
2821
|
+
multi: true
|
|
2822
|
+
}], host: {
|
|
2823
|
+
'[class]': 'hostClasses()',
|
|
2824
|
+
'[attr.data-size]': 'size()',
|
|
2825
|
+
'[attr.data-color]': 'color()',
|
|
2826
|
+
'[attr.data-disabled]': 'disabled()',
|
|
2827
|
+
'[attr.data-error]': 'error()'
|
|
2828
|
+
}, template: "<label\n [for]=\"radioId()\"\n [ngClass]=\"hostClasses()\"\n (click)=\"handleLabelClick($event)\"\n>\n <input\n type=\"radio\"\n [id]=\"radioId()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"isChecked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [tabIndex]=\"tabIndex()\"\n [attr.aria-checked]=\"isChecked() ? 'true' : 'false'\"\n [attr.aria-label]=\"label() || undefined\"\n [attr.aria-describedby]=\"showHint() || showError() ? radioId() + '-description' : undefined\"\n [attr.aria-invalid]=\"error()\"\n [attr.aria-required]=\"required()\"\n class=\"studio-radio__input\"\n (change)=\"handleChange($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n />\n\n <span [ngClass]=\"radioClasses()\">\n @if (isChecked()) {\n <span class=\"studio-radio__dot\"></span>\n }\n </span>\n\n @if (label() || description()) {\n <span class=\"studio-radio__label-wrapper\">\n @if (label()) {\n <span class=\"studio-radio__label\">\n {{ label() }}\n @if (required()) {\n <span class=\"studio-radio__required\" aria-hidden=\"true\">*</span>\n }\n </span>\n }\n\n @if (description()) {\n <span class=\"studio-radio__description\">\n {{ description() }}\n </span>\n }\n </span>\n }\n</label>\n\n@if (showHint() || showError()) {\n <div\n [id]=\"radioId() + '-description'\"\n class=\"studio-radio__info\"\n >\n @if (showError()) {\n <span class=\"studio-radio__error\">\n {{ errorMessage() }}\n </span>\n }\n\n @if (showHint()) {\n <span class=\"studio-radio__hint\">\n {{ hint() }}\n </span>\n }\n </div>\n}\n", styles: [":host{display:inline-flex;flex-direction:column;font-family:var(--studio-font-family)!important}.studio-radio-wrapper{display:inline-flex;align-items:flex-start;gap:var(--studio-spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.studio-radio-wrapper--label-left{flex-direction:row-reverse}.studio-radio-wrapper--disabled{cursor:not-allowed;opacity:.5}.studio-radio-wrapper--sm{font-size:var(--studio-font-size-sm)}.studio-radio-wrapper--md{font-size:var(--studio-font-size-base)}.studio-radio-wrapper--lg{font-size:var(--studio-font-size-lg)}.studio-radio__input{position:absolute;opacity:0;pointer-events:none;width:0;height:0}.studio-radio{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border:2px solid var(--studio-border-primary);background-color:var(--studio-bg-primary);transition:all var(--studio-transition-base);border-radius:var(--studio-radius-full)}.studio-radio--sm{width:1rem;height:1rem}.studio-radio--md{width:1.25rem;height:1.25rem}.studio-radio--lg{width:1.5rem;height:1.5rem}.studio-radio--radius-none{border-radius:0}.studio-radio--radius-sm{border-radius:var(--studio-radius-sm)}.studio-radio--radius-md{border-radius:var(--studio-radius-md)}.studio-radio--radius-lg{border-radius:var(--studio-radius-lg)}.studio-radio--radius-full{border-radius:var(--studio-radius-full)}.studio-radio--default.studio-radio--checked{border-color:transparent}.studio-radio--default.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary)}.studio-radio--default.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary)}.studio-radio--default.studio-radio--checked.studio-radio--success{background-color:var(--studio-success)}.studio-radio--default.studio-radio--checked.studio-radio--error{background-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked{background-color:transparent}.studio-radio--outlined.studio-radio--checked.studio-radio--primary{border-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--primary .studio-radio__dot{background-color:var(--studio-primary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary{border-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--secondary .studio-radio__dot{background-color:var(--studio-secondary)}.studio-radio--outlined.studio-radio--checked.studio-radio--success{border-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--success .studio-radio__dot{background-color:var(--studio-success)}.studio-radio--outlined.studio-radio--checked.studio-radio--error{border-color:var(--studio-error)}.studio-radio--outlined.studio-radio--checked.studio-radio--error .studio-radio__dot{background-color:var(--studio-error)}.studio-radio--filled.studio-radio--primary{background-color:var(--studio-primary-bg);border-color:var(--studio-primary-bg)}.studio-radio--filled.studio-radio--secondary{background-color:var(--studio-secondary-bg);border-color:var(--studio-secondary-bg)}.studio-radio--filled.studio-radio--success{background-color:var(--studio-success-bg);border-color:var(--studio-success-bg)}.studio-radio--filled.studio-radio--error{background-color:var(--studio-error-bg);border-color:var(--studio-error-bg)}.studio-radio--filled.studio-radio--checked.studio-radio--primary{background-color:var(--studio-primary);border-color:var(--studio-primary)}.studio-radio--filled.studio-radio--checked.studio-radio--secondary{background-color:var(--studio-secondary);border-color:var(--studio-secondary)}.studio-radio--filled.studio-radio--checked.studio-radio--success{background-color:var(--studio-success);border-color:var(--studio-success)}.studio-radio--filled.studio-radio--checked.studio-radio--error{background-color:var(--studio-error);border-color:var(--studio-error)}.studio-radio--error:not(.studio-radio--checked){border-color:var(--studio-error)}.studio-radio:hover:not(.studio-radio--disabled){border-color:var(--studio-border-secondary)}.studio-radio__input:focus-visible+.studio-radio{outline:2px solid var(--studio-primary);outline-offset:2px}.studio-radio__dot{border-radius:var(--studio-radius-full);background-color:var(--studio-text-inverse);opacity:0;transform:scale(.5);transition:all var(--studio-transition-fast)}.studio-radio--sm .studio-radio__dot{width:.375rem;height:.375rem}.studio-radio--md .studio-radio__dot{width:.5rem;height:.5rem}.studio-radio--lg .studio-radio__dot{width:.625rem;height:.625rem}.studio-radio--checked .studio-radio__dot{opacity:1;transform:scale(1)}.studio-radio__label-wrapper{display:flex;flex-direction:column;gap:var(--studio-spacing-xs)}.studio-radio__label{font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary);line-height:var(--studio-line-height-normal)}.studio-radio__description{font-size:var(--studio-font-size-sm);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__required{color:var(--studio-error);margin-left:var(--studio-spacing-xs)}.studio-radio__info{display:flex;flex-direction:column;gap:var(--studio-spacing-xs);margin-top:var(--studio-spacing-xs);padding-left:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-radio-wrapper--label-left+.studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.25rem)}.studio-radio-wrapper--sm .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--sm.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1rem)}.studio-radio-wrapper--lg .studio-radio__info{padding-left:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio-wrapper--lg.studio-radio-wrapper--label-left .studio-radio__info{padding-left:0;padding-right:calc(var(--studio-spacing-sm) + 1.5rem)}.studio-radio__hint{font-size:var(--studio-font-size-xs);color:var(--studio-text-secondary);line-height:var(--studio-line-height-normal)}.studio-radio__error{font-size:var(--studio-font-size-xs);color:var(--studio-error);line-height:var(--studio-line-height-normal)}\n"] }]
|
|
2829
|
+
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], radius: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], tabIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
|
|
2830
|
+
|
|
2325
2831
|
class SelectComponent {
|
|
2326
2832
|
configService = inject(StudioConfigService);
|
|
2327
2833
|
selectDefaults = computed(() => this.configService.config().components?.select, ...(ngDevMode ? [{ debugName: "selectDefaults" }] : []));
|
|
@@ -2722,6 +3228,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
2722
3228
|
*
|
|
2723
3229
|
* @example
|
|
2724
3230
|
* <studio-switch [(checked)]="isEnabled" label="Enable feature" />
|
|
3231
|
+
* <studio-switch [(ngModel)]="isEnabled" label="Enable feature" />
|
|
2725
3232
|
*/
|
|
2726
3233
|
class SwitchComponent {
|
|
2727
3234
|
configService = inject(StudioConfigService);
|
|
@@ -2737,11 +3244,25 @@ class SwitchComponent {
|
|
|
2737
3244
|
size = withConfigDefault(this.sizeInput, computed(() => this.switchDefaults()?.size), 'md');
|
|
2738
3245
|
color = withConfigDefault(this.colorInput, computed(() => this.switchDefaults()?.color), 'primary');
|
|
2739
3246
|
checkedChange = output();
|
|
3247
|
+
internalChecked = signal(false, ...(ngDevMode ? [{ debugName: "internalChecked" }] : []));
|
|
3248
|
+
onChange = () => { };
|
|
3249
|
+
onTouched = () => { };
|
|
2740
3250
|
iconSize = computed(() => {
|
|
2741
3251
|
const sizeMap = { sm: 10, md: 12, lg: 14 };
|
|
2742
3252
|
return sizeMap[this.size()];
|
|
2743
3253
|
}, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
|
|
2744
|
-
hostClasses = computed(() => classNames('studio-switch', `studio-switch--${this.size()}`, `studio-switch--${this.color()}`, this.
|
|
3254
|
+
hostClasses = computed(() => classNames('studio-switch', `studio-switch--${this.size()}`, `studio-switch--${this.color()}`, this.internalChecked() && 'studio-switch--checked', this.disabled() && 'studio-switch--disabled'), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
3255
|
+
writeValue(value) {
|
|
3256
|
+
this.internalChecked.set(value ?? false);
|
|
3257
|
+
this.checked.set(value ?? false);
|
|
3258
|
+
}
|
|
3259
|
+
registerOnChange(fn) {
|
|
3260
|
+
this.onChange = fn;
|
|
3261
|
+
}
|
|
3262
|
+
registerOnTouched(fn) {
|
|
3263
|
+
this.onTouched = fn;
|
|
3264
|
+
}
|
|
3265
|
+
setDisabledState(isDisabled) { }
|
|
2745
3266
|
handleClick() {
|
|
2746
3267
|
if (this.disabled())
|
|
2747
3268
|
return;
|
|
@@ -2754,12 +3275,21 @@ class SwitchComponent {
|
|
|
2754
3275
|
this.toggle();
|
|
2755
3276
|
}
|
|
2756
3277
|
toggle() {
|
|
2757
|
-
const newValue = !this.
|
|
3278
|
+
const newValue = !this.internalChecked();
|
|
3279
|
+
this.internalChecked.set(newValue);
|
|
2758
3280
|
this.checked.set(newValue);
|
|
3281
|
+
this.onChange(newValue);
|
|
3282
|
+
this.onTouched();
|
|
2759
3283
|
this.checkedChange.emit(newValue);
|
|
2760
3284
|
}
|
|
2761
3285
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2762
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: SwitchComponent, isStandalone: true, selector: "studio-switch", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, colorInput: { classPropertyName: "colorInput", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", checkedChange: "checkedChange" }, host: { listeners: { "click": "handleClick()", "keydown.space": "handleKeydown($event)", "keydown.enter": "handleKeydown($event)" }, properties: { "class": "hostClasses()", "attr.role": "\"switch\"", "attr.aria-checked": "
|
|
3286
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: SwitchComponent, isStandalone: true, selector: "studio-switch", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, sizeInput: { classPropertyName: "sizeInput", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, colorInput: { classPropertyName: "colorInput", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", checkedChange: "checkedChange" }, host: { listeners: { "click": "handleClick()", "keydown.space": "handleKeydown($event)", "keydown.enter": "handleKeydown($event)" }, properties: { "class": "hostClasses()", "attr.role": "\"switch\"", "attr.aria-checked": "internalChecked()", "attr.aria-disabled": "disabled() ? \"true\" : null", "attr.aria-label": "ariaLabel() || label()", "tabindex": "disabled() ? -1 : 0" } }, providers: [
|
|
3287
|
+
{
|
|
3288
|
+
provide: NG_VALUE_ACCESSOR,
|
|
3289
|
+
useExisting: forwardRef(() => SwitchComponent),
|
|
3290
|
+
multi: true
|
|
3291
|
+
}
|
|
3292
|
+
], ngImport: i0, template: `
|
|
2763
3293
|
<span class="studio-switch__container">
|
|
2764
3294
|
@if (label() && labelPosition() === 'left') {
|
|
2765
3295
|
<span class="studio-switch__label studio-switch__label--left">
|
|
@@ -2770,7 +3300,7 @@ class SwitchComponent {
|
|
|
2770
3300
|
<span class="studio-switch__track">
|
|
2771
3301
|
<span class="studio-switch__thumb">
|
|
2772
3302
|
@if (showIcons()) {
|
|
2773
|
-
@if (
|
|
3303
|
+
@if (internalChecked()) {
|
|
2774
3304
|
<studio-icon name="check" [size]="iconSize()" color="inherit" />
|
|
2775
3305
|
} @else {
|
|
2776
3306
|
<studio-icon name="x" [size]="iconSize()" color="inherit" />
|
|
@@ -2789,10 +3319,16 @@ class SwitchComponent {
|
|
|
2789
3319
|
}
|
|
2790
3320
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SwitchComponent, decorators: [{
|
|
2791
3321
|
type: Component,
|
|
2792
|
-
args: [{ selector: 'studio-switch', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3322
|
+
args: [{ selector: 'studio-switch', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
3323
|
+
{
|
|
3324
|
+
provide: NG_VALUE_ACCESSOR,
|
|
3325
|
+
useExisting: forwardRef(() => SwitchComponent),
|
|
3326
|
+
multi: true
|
|
3327
|
+
}
|
|
3328
|
+
], host: {
|
|
2793
3329
|
'[class]': 'hostClasses()',
|
|
2794
3330
|
'[attr.role]': '"switch"',
|
|
2795
|
-
'[attr.aria-checked]': '
|
|
3331
|
+
'[attr.aria-checked]': 'internalChecked()',
|
|
2796
3332
|
'[attr.aria-disabled]': 'disabled() ? "true" : null',
|
|
2797
3333
|
'[attr.aria-label]': 'ariaLabel() || label()',
|
|
2798
3334
|
'(click)': 'handleClick()',
|
|
@@ -2810,7 +3346,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
2810
3346
|
<span class="studio-switch__track">
|
|
2811
3347
|
<span class="studio-switch__thumb">
|
|
2812
3348
|
@if (showIcons()) {
|
|
2813
|
-
@if (
|
|
3349
|
+
@if (internalChecked()) {
|
|
2814
3350
|
<studio-icon name="check" [size]="iconSize()" color="inherit" />
|
|
2815
3351
|
} @else {
|
|
2816
3352
|
<studio-icon name="x" [size]="iconSize()" color="inherit" />
|
|
@@ -3344,6 +3880,215 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
3344
3880
|
`, styles: [":host{display:inline-block}:host(.studio-button-toggle-group--disabled){opacity:.6;pointer-events:none}\n"] }]
|
|
3345
3881
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], allowEmpty: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowEmpty", required: false }] }], orientationInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], sizeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variantInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], colorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], radiusInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "radius", required: false }] }], shadowInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "shadow", required: false }] }], attached: [{ type: i0.Input, args: [{ isSignal: true, alias: "attached", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
3346
3882
|
|
|
3883
|
+
class InspectorComponent {
|
|
3884
|
+
configService = inject(StudioConfigService);
|
|
3885
|
+
componentSize = input('sm', ...(ngDevMode ? [{ debugName: "componentSize" }] : []));
|
|
3886
|
+
componentVariant = input('outline', ...(ngDevMode ? [{ debugName: "componentVariant" }] : []));
|
|
3887
|
+
compact = input(false, ...(ngDevMode ? [{ debugName: "compact" }] : []));
|
|
3888
|
+
showIcons = input(true, ...(ngDevMode ? [{ debugName: "showIcons" }] : []));
|
|
3889
|
+
showDefaultIndicator = input(true, ...(ngDevMode ? [{ debugName: "showDefaultIndicator" }] : []));
|
|
3890
|
+
collapsible = input(true, ...(ngDevMode ? [{ debugName: "collapsible" }] : []));
|
|
3891
|
+
expandedByDefault = input(true, ...(ngDevMode ? [{ debugName: "expandedByDefault" }] : []));
|
|
3892
|
+
expandedSectionsInput = input([], ...(ngDevMode ? [{ debugName: "expandedSectionsInput", alias: 'expandedSections' }] : [{ alias: 'expandedSections' }]));
|
|
3893
|
+
showGroupLabels = input(true, ...(ngDevMode ? [{ debugName: "showGroupLabels" }] : []));
|
|
3894
|
+
groupDivider = input('line', ...(ngDevMode ? [{ debugName: "groupDivider" }] : []));
|
|
3895
|
+
groupDividerSpacing = input('md', ...(ngDevMode ? [{ debugName: "groupDividerSpacing" }] : []));
|
|
3896
|
+
labelWidth = input('auto', ...(ngDevMode ? [{ debugName: "labelWidth" }] : []));
|
|
3897
|
+
fullWidth = input(true, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
|
|
3898
|
+
spacing = input('md', ...(ngDevMode ? [{ debugName: "spacing" }] : []));
|
|
3899
|
+
sectionTemplate = input(undefined, ...(ngDevMode ? [{ debugName: "sectionTemplate" }] : []));
|
|
3900
|
+
parameterTemplates = input(undefined, ...(ngDevMode ? [{ debugName: "parameterTemplates" }] : []));
|
|
3901
|
+
ariaLabel = input('Inspector panel', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
3902
|
+
ariaDescribedBy = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
|
|
3903
|
+
sectionToggled = output();
|
|
3904
|
+
parameterFocused = output();
|
|
3905
|
+
parameterBlurred = output();
|
|
3906
|
+
values = signal(null, ...(ngDevMode ? [{ debugName: "values" }] : []));
|
|
3907
|
+
expandedSections = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedSections" }] : []));
|
|
3908
|
+
onChange = () => { };
|
|
3909
|
+
onTouched = () => { };
|
|
3910
|
+
constructor() {
|
|
3911
|
+
effect(() => {
|
|
3912
|
+
const inputSections = this.expandedSectionsInput();
|
|
3913
|
+
if (inputSections.length > 0) {
|
|
3914
|
+
this.expandedSections.set(new Set(inputSections));
|
|
3915
|
+
}
|
|
3916
|
+
});
|
|
3917
|
+
}
|
|
3918
|
+
hostClasses = computed(() => classNames('studio-inspector', this.compact() && 'studio-inspector--compact', `studio-inspector--spacing-${this.spacing()}`), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
3919
|
+
isSectionExpanded(componentId) {
|
|
3920
|
+
return this.expandedSections().has(componentId);
|
|
3921
|
+
}
|
|
3922
|
+
toggleSection(componentId) {
|
|
3923
|
+
if (!this.collapsible())
|
|
3924
|
+
return;
|
|
3925
|
+
const expanded = new Set(this.expandedSections());
|
|
3926
|
+
if (expanded.has(componentId)) {
|
|
3927
|
+
expanded.delete(componentId);
|
|
3928
|
+
}
|
|
3929
|
+
else {
|
|
3930
|
+
expanded.add(componentId);
|
|
3931
|
+
}
|
|
3932
|
+
this.expandedSections.set(expanded);
|
|
3933
|
+
this.sectionToggled.emit({
|
|
3934
|
+
id: componentId,
|
|
3935
|
+
expanded: expanded.has(componentId)
|
|
3936
|
+
});
|
|
3937
|
+
}
|
|
3938
|
+
onParameterChange(componentId, groupId, parameterId, newValue) {
|
|
3939
|
+
const updated = structuredClone(this.values());
|
|
3940
|
+
if (!updated)
|
|
3941
|
+
return;
|
|
3942
|
+
const section = updated.sections.find(c => c.id === componentId);
|
|
3943
|
+
if (!section)
|
|
3944
|
+
return;
|
|
3945
|
+
let parameter;
|
|
3946
|
+
if (groupId) {
|
|
3947
|
+
const group = section.groups?.find(g => g.id === groupId);
|
|
3948
|
+
parameter = group?.parameters.find(p => p.id === parameterId);
|
|
3949
|
+
}
|
|
3950
|
+
else {
|
|
3951
|
+
parameter = section.parameters?.find(p => p.id === parameterId);
|
|
3952
|
+
}
|
|
3953
|
+
if (parameter) {
|
|
3954
|
+
parameter.value = newValue;
|
|
3955
|
+
}
|
|
3956
|
+
this.values.set(updated);
|
|
3957
|
+
this.onChange(updated);
|
|
3958
|
+
this.onTouched();
|
|
3959
|
+
}
|
|
3960
|
+
onCheckboxChange(componentId, groupId, parameterId, optionValue, checked) {
|
|
3961
|
+
const updated = structuredClone(this.values());
|
|
3962
|
+
if (!updated)
|
|
3963
|
+
return;
|
|
3964
|
+
const section = updated.sections.find(c => c.id === componentId);
|
|
3965
|
+
if (!section)
|
|
3966
|
+
return;
|
|
3967
|
+
let parameter;
|
|
3968
|
+
if (groupId) {
|
|
3969
|
+
const group = section.groups?.find(g => g.id === groupId);
|
|
3970
|
+
parameter = group?.parameters.find(p => p.id === parameterId);
|
|
3971
|
+
}
|
|
3972
|
+
else {
|
|
3973
|
+
parameter = section.parameters?.find(p => p.id === parameterId);
|
|
3974
|
+
}
|
|
3975
|
+
if (parameter && parameter.type === 'checkbox') {
|
|
3976
|
+
const currentValues = Array.isArray(parameter.value) ? parameter.value : [];
|
|
3977
|
+
if (checked) {
|
|
3978
|
+
if (!currentValues.includes(optionValue)) {
|
|
3979
|
+
parameter.value = [...currentValues, optionValue];
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
else {
|
|
3983
|
+
parameter.value = currentValues.filter(v => v !== optionValue);
|
|
3984
|
+
}
|
|
3985
|
+
}
|
|
3986
|
+
this.values.set(updated);
|
|
3987
|
+
this.onChange(updated);
|
|
3988
|
+
this.onTouched();
|
|
3989
|
+
}
|
|
3990
|
+
onRadioChange(componentId, groupId, parameterId, newValue) {
|
|
3991
|
+
this.onParameterChange(componentId, groupId, parameterId, newValue);
|
|
3992
|
+
}
|
|
3993
|
+
getRadioName(componentId, groupId, parameterId) {
|
|
3994
|
+
return `${componentId}-${groupId || 'root'}-${parameterId}`;
|
|
3995
|
+
}
|
|
3996
|
+
isChecked(parameter, optionValue) {
|
|
3997
|
+
if (parameter.type === 'checkbox') {
|
|
3998
|
+
return Array.isArray(parameter.value) && parameter.value.includes(optionValue);
|
|
3999
|
+
}
|
|
4000
|
+
else if (parameter.type === 'radio') {
|
|
4001
|
+
return parameter.value === optionValue;
|
|
4002
|
+
}
|
|
4003
|
+
return false;
|
|
4004
|
+
}
|
|
4005
|
+
isRadioChecked(parameter, optionValue) {
|
|
4006
|
+
return parameter.value === optionValue;
|
|
4007
|
+
}
|
|
4008
|
+
isDefault(parameter, optionValue) {
|
|
4009
|
+
return parameter.default !== undefined && parameter.default === optionValue;
|
|
4010
|
+
}
|
|
4011
|
+
trackBySectionId(_, section) {
|
|
4012
|
+
return section.id;
|
|
4013
|
+
}
|
|
4014
|
+
trackByGroupId(_, group) {
|
|
4015
|
+
return group.id;
|
|
4016
|
+
}
|
|
4017
|
+
trackByParameterId(_, param) {
|
|
4018
|
+
return param.id;
|
|
4019
|
+
}
|
|
4020
|
+
trackByOptionValue(_, option) {
|
|
4021
|
+
return option.value;
|
|
4022
|
+
}
|
|
4023
|
+
writeValue(value) {
|
|
4024
|
+
this.values.set(value);
|
|
4025
|
+
this.initializeExpandedSections();
|
|
4026
|
+
}
|
|
4027
|
+
registerOnChange(fn) {
|
|
4028
|
+
this.onChange = fn;
|
|
4029
|
+
}
|
|
4030
|
+
registerOnTouched(fn) {
|
|
4031
|
+
this.onTouched = fn;
|
|
4032
|
+
}
|
|
4033
|
+
setDisabledState(_) { }
|
|
4034
|
+
initializeExpandedSections() {
|
|
4035
|
+
const expanded = new Set();
|
|
4036
|
+
const inputSections = this.expandedSectionsInput();
|
|
4037
|
+
if (inputSections.length > 0) {
|
|
4038
|
+
inputSections.forEach(id => expanded.add(id));
|
|
4039
|
+
}
|
|
4040
|
+
else if (this.expandedByDefault()) {
|
|
4041
|
+
this.values()?.sections.forEach(c => {
|
|
4042
|
+
if (c.expanded !== false) {
|
|
4043
|
+
expanded.add(c.id);
|
|
4044
|
+
}
|
|
4045
|
+
});
|
|
4046
|
+
}
|
|
4047
|
+
else {
|
|
4048
|
+
this.values()?.sections.forEach(c => {
|
|
4049
|
+
if (c.expanded === true) {
|
|
4050
|
+
expanded.add(c.id);
|
|
4051
|
+
}
|
|
4052
|
+
});
|
|
4053
|
+
}
|
|
4054
|
+
this.expandedSections.set(expanded);
|
|
4055
|
+
}
|
|
4056
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: InspectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4057
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: InspectorComponent, isStandalone: true, selector: "studio-inspector", inputs: { componentSize: { classPropertyName: "componentSize", publicName: "componentSize", isSignal: true, isRequired: false, transformFunction: null }, componentVariant: { classPropertyName: "componentVariant", publicName: "componentVariant", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, showDefaultIndicator: { classPropertyName: "showDefaultIndicator", publicName: "showDefaultIndicator", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, expandedByDefault: { classPropertyName: "expandedByDefault", publicName: "expandedByDefault", isSignal: true, isRequired: false, transformFunction: null }, expandedSectionsInput: { classPropertyName: "expandedSectionsInput", publicName: "expandedSections", isSignal: true, isRequired: false, transformFunction: null }, showGroupLabels: { classPropertyName: "showGroupLabels", publicName: "showGroupLabels", isSignal: true, isRequired: false, transformFunction: null }, groupDivider: { classPropertyName: "groupDivider", publicName: "groupDivider", isSignal: true, isRequired: false, transformFunction: null }, groupDividerSpacing: { classPropertyName: "groupDividerSpacing", publicName: "groupDividerSpacing", isSignal: true, isRequired: false, transformFunction: null }, labelWidth: { classPropertyName: "labelWidth", publicName: "labelWidth", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, spacing: { classPropertyName: "spacing", publicName: "spacing", isSignal: true, isRequired: false, transformFunction: null }, sectionTemplate: { classPropertyName: "sectionTemplate", publicName: "sectionTemplate", isSignal: true, isRequired: false, transformFunction: null }, parameterTemplates: { classPropertyName: "parameterTemplates", publicName: "parameterTemplates", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedBy: { classPropertyName: "ariaDescribedBy", publicName: "ariaDescribedBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sectionToggled: "sectionToggled", parameterFocused: "parameterFocused", parameterBlurred: "parameterBlurred" }, host: { properties: { "class": "hostClasses()", "attr.role": "\"region\"", "attr.aria-label": "ariaLabel()" } }, providers: [
|
|
4058
|
+
{
|
|
4059
|
+
provide: NG_VALUE_ACCESSOR,
|
|
4060
|
+
useExisting: forwardRef(() => InspectorComponent),
|
|
4061
|
+
multi: true
|
|
4062
|
+
}
|
|
4063
|
+
], ngImport: i0, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ButtonComponent, selector: "studio-button", inputs: ["variant", "size", "color", "radius", "shadow", "compact", "disabled", "loading", "loadingText", "fullWidth", "type", "icon", "iconPosition", "href", "target", "badge", "badgeColor", "ariaLabel"], outputs: ["clicked"] }, { kind: "component", type: IconComponent, selector: "studio-icon", inputs: ["name", "size", "color", "strokeWidth", "absoluteStrokeWidth", "showFallback", "fallbackIcon"] }, { kind: "component", type: InputComponent, selector: "studio-input", inputs: ["variant", "size", "radius", "disabled", "readonly", "loading", "type", "inputmode", "autocomplete", "placeholder", "maxLength", "minLength", "min", "max", "step", "pattern", "label", "floatingLabel", "hint", "required", "error", "errorMessage", "prefixIcon", "suffixIcon", "clearable", "showPasswordToggle", "fullWidth", "autoFocus", "name", "id", "ariaLabel"], outputs: ["valueChange", "focused", "blurred", "cleared", "entered"] }, { kind: "component", type: CheckboxComponent, selector: "studio-checkbox", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "indeterminate", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: RadioButtonComponent, selector: "studio-radio-button", inputs: ["size", "color", "variant", "radius", "label", "labelPosition", "description", "hint", "required", "error", "errorMessage", "disabled", "readonly", "name", "tabIndex", "value"], outputs: ["changed"] }, { kind: "component", type: ColorPickerComponent, selector: "studio-color-picker", inputs: ["variant", "size", "format", "showAlpha", "showPresets", "showFormatToggle", "showCopyButton", "presets", "label", "hint", "required", "error", "errorMessage", "disabled", "readonly"], outputs: ["colorChange", "colorValueChange", "copied"] }, { kind: "component", type: SelectComponent, selector: "studio-select", inputs: ["variant", "size", "radius", "options", "placeholder", "multiple", "searchable", "clearable", "disabled", "loading", "label", "floatingLabel", "hint", "error", "errorMessage", "required", "prefixIcon", "suffixIcon", "fullWidth", "maxHeight", "position", "searchPlaceholder"], outputs: ["valueChange", "searchChange", "opened", "closed", "optionSelected"] }, { kind: "component", type: TextareaComponent, selector: "studio-textarea", inputs: ["variant", "size", "color", "radius", "label", "floatingLabel", "placeholder", "hint", "rows", "minRows", "maxRows", "autoResize", "resize", "maxLength", "showCharCount", "charCountPosition", "required", "minLength", "error", "errorMessage", "disabled", "readonly", "fullWidth", "name", "autocomplete", "spellcheck", "clearable", "loading"], outputs: ["changed", "focused", "blurred", "keyPressed"] }, { kind: "component", type: SwitchComponent, selector: "studio-switch", inputs: ["checked", "disabled", "label", "labelPosition", "showIcons", "ariaLabel", "size", "color"], outputs: ["checkedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4064
|
+
}
|
|
4065
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: InspectorComponent, decorators: [{
|
|
4066
|
+
type: Component,
|
|
4067
|
+
args: [{ selector: 'studio-inspector', standalone: true, imports: [
|
|
4068
|
+
CommonModule,
|
|
4069
|
+
FormsModule,
|
|
4070
|
+
ButtonComponent,
|
|
4071
|
+
IconComponent,
|
|
4072
|
+
InputComponent,
|
|
4073
|
+
CheckboxComponent,
|
|
4074
|
+
RadioButtonComponent,
|
|
4075
|
+
ColorPickerComponent,
|
|
4076
|
+
SelectComponent,
|
|
4077
|
+
TextareaComponent,
|
|
4078
|
+
SwitchComponent
|
|
4079
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
4080
|
+
{
|
|
4081
|
+
provide: NG_VALUE_ACCESSOR,
|
|
4082
|
+
useExisting: forwardRef(() => InspectorComponent),
|
|
4083
|
+
multi: true
|
|
4084
|
+
}
|
|
4085
|
+
], host: {
|
|
4086
|
+
'[class]': 'hostClasses()',
|
|
4087
|
+
'[attr.role]': '"region"',
|
|
4088
|
+
'[attr.aria-label]': 'ariaLabel()'
|
|
4089
|
+
}, template: "@if (values()) {\n <div class=\"studio-inspector__container\">\n @for (section of values()!.sections; track trackBySectionId($index, section)) {\n <div class=\"studio-inspector__section\"\n [class.studio-inspector__section--expanded]=\"isSectionExpanded(section.id)\"\n [class.studio-inspector__section--collapsed]=\"!isSectionExpanded(section.id)\">\n\n <studio-button\n variant=\"ghost\"\n [fullWidth]=\"true\"\n class=\"studio-inspector__section-header\"\n [class.studio-inspector__section-header--collapsible]=\"collapsible()\"\n [disabled]=\"!collapsible()\"\n [attr.aria-expanded]=\"isSectionExpanded(section.id)\"\n [attr.aria-controls]=\"'section-content-' + section.id\"\n (click)=\"toggleSection(section.id)\">\n\n @if (showIcons() && section.icon) {\n <studio-icon\n [name]=\"section.icon\"\n [size]=\"16\"\n class=\"studio-inspector__section-icon\"\n />\n }\n\n <span class=\"studio-inspector__section-title\">{{ section.title }}</span>\n\n @if (collapsible()) {\n <studio-icon\n [name]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"studio-inspector__section-toggle\"\n />\n }\n </studio-button>\n\n @if (isSectionExpanded(section.id)) {\n <div\n class=\"studio-inspector__section-content\"\n [id]=\"'section-content-' + section.id\">\n\n @if (section.groups) {\n @for (group of section.groups; track trackByGroupId($index, group); let isLast = $last) {\n <div class=\"studio-inspector__group\">\n\n @if (showGroupLabels() && group.label) {\n <div class=\"studio-inspector__group-label\">{{ group.label }}</div>\n }\n\n @for (param of group.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + group.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, group.id, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + group.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, group.id, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, group.id, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, group.id, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n\n @if (!isLast && groupDivider() !== 'none') {\n <div class=\"studio-inspector__group-divider\"\n [class.studio-inspector__group-divider--line]=\"groupDivider() === 'line'\"\n [class.studio-inspector__group-divider--space]=\"groupDivider() === 'space'\">\n </div>\n }\n </div>\n }\n }\n\n @if (section.parameters) {\n @for (param of section.parameters; track trackByParameterId($index, param)) {\n <div class=\"studio-inspector__parameter\">\n @if (param.type !== 'boolean' && param.type !== 'checkbox' && param.type !== 'radio') {\n <div class=\"studio-inspector__parameter-label\">{{ param.label }}</div>\n }\n\n @if (param.type === 'text') {\n <studio-input\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'number') {\n <div class=\"studio-inspector__number-input\">\n <studio-input\n type=\"number\"\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [min]=\"param.min\"\n [max]=\"param.max\"\n [step]=\"param.step\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [fullWidth]=\"fullWidth()\"\n />\n @if (param.suffix) {\n <span class=\"studio-inspector__suffix\">{{ param.suffix }}</span>\n }\n </div>\n }\n\n @if (param.type === 'textarea') {\n <studio-textarea\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [readonly]=\"param.readonly || false\"\n [maxLength]=\"param.maxLength\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'color') {\n <studio-color-picker\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'select') {\n <studio-select\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [variant]=\"componentVariant()\"\n [size]=\"componentSize()\"\n [options]=\"param.options || []\"\n [placeholder]=\"param.placeholder || ''\"\n [disabled]=\"param.disabled || false\"\n [fullWidth]=\"fullWidth()\"\n />\n }\n\n @if (param.type === 'boolean') {\n <studio-switch\n [ngModel]=\"param.value\"\n [name]=\"section.id + '-' + param.id\"\n (ngModelChange)=\"onParameterChange(section.id, null, param.id, $event)\"\n [label]=\"param.label\"\n [size]=\"componentSize()\"\n [disabled]=\"param.disabled || false\"\n />\n }\n\n @if (param.type === 'checkbox') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <studio-checkbox\n [ngModel]=\"isChecked(param, option.value)\"\n [name]=\"section.id + '-' + param.id + '-' + option.value\"\n (ngModelChange)=\"onCheckboxChange(section.id, null, param.id, option.value, $event)\"\n [label]=\"option.label\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n }\n </div>\n }\n\n @if (param.type === 'radio') {\n <div class=\"studio-inspector__options\">\n @for (option of param.options; track trackByOptionValue($index, option)) {\n <div class=\"studio-inspector__option\">\n <studio-radio-button\n [ngModel]=\"param.value\"\n (ngModelChange)=\"onRadioChange(section.id, null, param.id, $event)\"\n [value]=\"option.value\"\n [label]=\"option.label\"\n [name]=\"getRadioName(section.id, null, param.id)\"\n [disabled]=\"param.disabled || option.disabled || false\"\n [size]=\"componentSize()\"\n />\n @if (showDefaultIndicator() && isDefault(param, option.value)) {\n <span class=\"studio-inspector__default-indicator\">(default)</span>\n }\n </div>\n }\n </div>\n }\n\n @if (param.hint) {\n <div class=\"studio-inspector__parameter-hint\">{{ param.hint }}</div>\n }\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:block;font-family:var(--studio-font-family)}.studio-inspector__container{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__section{background:var(--studio-bg-primary);border:1px solid var(--studio-border-primary);border-radius:var(--studio-radius-md);overflow:hidden}.studio-inspector__section-header{width:100%;display:flex;align-items:center;gap:.75rem;padding:.875rem 1rem;background:var(--studio-bg-secondary);border:none;border-bottom:1px solid var(--studio-border-primary);cursor:pointer;transition:background var(--studio-transition-fast);text-align:left}.studio-inspector__section-header--collapsible:hover{background:var(--studio-bg-tertiary)}.studio-inspector__section-header:disabled{cursor:default}.studio-inspector__section-icon{color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__section-title{flex:1;font-size:.875rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-primary)}.studio-inspector__section-toggle{color:var(--studio-text-secondary);flex-shrink:0;transition:transform var(--studio-transition-fast)}.studio-inspector__section--collapsed .studio-inspector__section-toggle{transform:rotate(-90deg)}.studio-inspector__section--collapsed .studio-inspector__section-content{display:none}.studio-inspector__section--expanded .studio-inspector__section-toggle{transform:rotate(0)}.studio-inspector__section-content{padding:1rem;display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group{display:flex;flex-direction:column;gap:.75rem}.studio-inspector__group-label{font-size:.75rem;font-weight:var(--studio-font-weight-semibold);color:var(--studio-text-secondary);text-transform:uppercase;letter-spacing:.05em}.studio-inspector__group-divider--line{height:1px;background:var(--studio-border-primary);margin:.5rem 0}.studio-inspector__group-divider--space{height:.5rem}.studio-inspector__parameter{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__parameter-label{font-size:.8125rem;font-weight:var(--studio-font-weight-medium);color:var(--studio-text-primary)}.studio-inspector__parameter-hint{font-size:.75rem;color:var(--studio-text-secondary);line-height:1.4}.studio-inspector__number-input{display:flex;align-items:center;gap:.5rem}.studio-inspector__suffix{font-size:.875rem;color:var(--studio-text-secondary);flex-shrink:0}.studio-inspector__options{display:flex;flex-direction:column;gap:.5rem}.studio-inspector__option{display:flex;align-items:center;gap:.5rem}.studio-inspector__default-indicator{font-size:.75rem;color:var(--studio-text-tertiary);font-style:italic}:host(.studio-inspector--compact) .studio-inspector__container{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__section-header{padding:.625rem .75rem}:host(.studio-inspector--compact) .studio-inspector__section-content{padding:.75rem;gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--compact) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-sm) .studio-inspector__section-content{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__group{gap:.5rem}:host(.studio-inspector--spacing-sm) .studio-inspector__parameter{gap:.375rem}:host(.studio-inspector--spacing-lg) .studio-inspector__section-content{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group{gap:1rem}:host(.studio-inspector--spacing-lg) .studio-inspector__parameter{gap:.625rem}:host(.studio-inspector--spacing-lg) .studio-inspector__group-divider--space{height:1rem}\n"] }]
|
|
4090
|
+
}], ctorParameters: () => [], propDecorators: { componentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentSize", required: false }] }], componentVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentVariant", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], showDefaultIndicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDefaultIndicator", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], expandedByDefault: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedByDefault", required: false }] }], expandedSectionsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedSections", required: false }] }], showGroupLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGroupLabels", required: false }] }], groupDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupDivider", required: false }] }], groupDividerSpacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupDividerSpacing", required: false }] }], labelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelWidth", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }], sectionTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionTemplate", required: false }] }], parameterTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "parameterTemplates", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedBy", required: false }] }], sectionToggled: [{ type: i0.Output, args: ["sectionToggled"] }], parameterFocused: [{ type: i0.Output, args: ["parameterFocused"] }], parameterBlurred: [{ type: i0.Output, args: ["parameterBlurred"] }] } });
|
|
4091
|
+
|
|
3347
4092
|
/**
|
|
3348
4093
|
* Theme toggle switch with sun/moon icons
|
|
3349
4094
|
*
|
|
@@ -3872,5 +4617,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
3872
4617
|
* Generated bundle index. Do not edit.
|
|
3873
4618
|
*/
|
|
3874
4619
|
|
|
3875
|
-
export { BadgeComponent, BadgeWrapperComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CheckboxComponent, DrawerComponent, DrawerService, IconComponent, InputComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, NavbarComponent, STUDIO_CONFIG, SelectComponent, SidebarComponent, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
|
|
4620
|
+
export { BadgeComponent, BadgeWrapperComponent, ButtonComponent, ButtonGroupComponent, ButtonToggleGroupComponent, CheckboxComponent, ColorPickerComponent, DEFAULT_COLOR_PRESETS, DrawerComponent, DrawerService, IconComponent, InputComponent, InspectorComponent, MASK_PRESETS, MaskDirective, MaskEngine, MenuComponent, NavbarComponent, RadioButtonComponent, STUDIO_CONFIG, SelectComponent, SidebarComponent, StudioConfigService, SwitchComponent, TextareaComponent, ThemeSwitchComponent, classNames, isSafeUrl, loadGoogleFont, loadGoogleFonts, provideStudioConfig, provideStudioIcons, sanitizeUrl, withConfigDefault };
|
|
3876
4621
|
//# sourceMappingURL=eduboxpro-studio.mjs.map
|