@kksdev/ds-angular 1.5.0 → 1.6.0
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/kksdev-ds-angular.mjs +1466 -2
- package/fesm2022/kksdev-ds-angular.mjs.map +1 -1
- package/index.d.ts +265 -2
- package/package.json +2 -2
- package/src/styles/themes/_dark.scss +41 -0
- package/src/styles/themes/_light.scss +41 -0
- package/src/styles/tokens/_semantic.scss +73 -0
- package/src/styles/tokens/_tokens.scss +61 -0
|
@@ -6,7 +6,7 @@ import * as i1$1 from '@fortawesome/angular-fontawesome';
|
|
|
6
6
|
import { FaIconComponent, FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
|
7
7
|
import * as i1$4 from '@angular/forms';
|
|
8
8
|
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
9
|
-
import { faInfoCircle, faTimesCircle, faExclamationTriangle, faCheckCircle, faTimes, faEye, faEyeSlash, faClose, faCircleInfo, faCircleXmark, faCircleExclamation, faCircleCheck, faChevronDown, faChevronLeft, faChevronRight, faAnglesLeft, faAnglesRight, faCheck, faSearch, faXmark, faSpinner, faCalendar, faCloudArrowUp, faFile, faFileImage, faFilePdf, faFileWord, faFileExcel, faInbox, faStar, faStarHalfStroke, faClock, faChevronUp, faFolder, faFolderOpen, faCircle, faCircleHalfStroke, faTriangleExclamation } from '@fortawesome/free-solid-svg-icons';
|
|
9
|
+
import { faInfoCircle, faTimesCircle, faExclamationTriangle, faCheckCircle, faTimes, faEye, faEyeSlash, faClose, faCircleInfo, faCircleXmark, faCircleExclamation, faCircleCheck, faChevronDown, faChevronLeft, faChevronRight, faAnglesLeft, faAnglesRight, faCheck, faSearch, faXmark, faSpinner, faCalendar, faCloudArrowUp, faFile, faFileImage, faFilePdf, faFileWord, faFileExcel, faInbox, faStar, faStarHalfStroke, faClock, faChevronUp, faFolder, faFolderOpen, faCircle, faCircleHalfStroke, faTriangleExclamation, faMinus, faPlus, faEyeDropper } from '@fortawesome/free-solid-svg-icons';
|
|
10
10
|
import * as i1$2 from '@angular/router';
|
|
11
11
|
import { RouterModule } from '@angular/router';
|
|
12
12
|
import * as i1$3 from '@angular/cdk/overlay';
|
|
@@ -11431,6 +11431,1470 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
11431
11431
|
}, template: "<div class=\"ds-calendar__container\">\n <!-- Header avec navigation et s\u00E9lecteur mode -->\n <div class=\"ds-calendar__header\">\n <div class=\"ds-calendar__nav\">\n @if (currentMode() === 'month') {\n <button\n type=\"button\"\n class=\"ds-calendar__nav-btn\"\n (click)=\"previousMonth()\"\n aria-label=\"Mois pr\u00E9c\u00E9dent\"\n >\n <fa-icon [icon]=\"icons.chevronLeft\"></fa-icon>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"ds-calendar__nav-btn\"\n (click)=\"previousYear()\"\n aria-label=\"Ann\u00E9e pr\u00E9c\u00E9dente\"\n >\n <fa-icon [icon]=\"icons.chevronLeft\"></fa-icon>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"ds-calendar__title\"\n (click)=\"toggleMode()\"\n [attr.aria-label]=\"currentMode() === 'month' ? 'Voir l\\'ann\u00E9e' : 'Voir le mois'\"\n >\n {{ calendarTitle() }}\n </button>\n\n @if (currentMode() === 'month') {\n <button\n type=\"button\"\n class=\"ds-calendar__nav-btn\"\n (click)=\"nextMonth()\"\n aria-label=\"Mois suivant\"\n >\n <fa-icon [icon]=\"icons.chevronRight\"></fa-icon>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"ds-calendar__nav-btn\"\n (click)=\"nextYear()\"\n aria-label=\"Ann\u00E9e suivante\"\n >\n <fa-icon [icon]=\"icons.chevronRight\"></fa-icon>\n </button>\n }\n </div>\n\n <div class=\"ds-calendar__mode-selector\">\n <button\n type=\"button\"\n class=\"ds-calendar__mode-btn\"\n [class.ds-calendar__mode-btn--active]=\"currentMode() === 'month'\"\n (click)=\"currentMode() === 'year' && toggleMode()\"\n >\n Mois\n </button>\n <button\n type=\"button\"\n class=\"ds-calendar__mode-btn\"\n [class.ds-calendar__mode-btn--active]=\"currentMode() === 'year'\"\n (click)=\"currentMode() === 'month' && toggleMode()\"\n >\n Ann\u00E9e\n </button>\n </div>\n </div>\n\n <!-- Vue mois -->\n @if (currentMode() === 'month') {\n <div class=\"ds-calendar__month-view\">\n <!-- Noms des jours de la semaine -->\n <div class=\"ds-calendar__weekdays\">\n @for (day of weekDays(); track day) {\n <div class=\"ds-calendar__weekday\">{{ day }}</div>\n }\n </div>\n\n <!-- Grille des jours -->\n <div class=\"ds-calendar__grid\">\n @for (day of calendarGrid(); track day.date.getTime()) {\n <button\n type=\"button\"\n [class]=\"getDayClasses(day)\"\n [disabled]=\"day.isDisabled\"\n (click)=\"selectDate(day)\"\n [attr.aria-label]=\"day.date.toLocaleDateString(locale())\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n >\n <span class=\"ds-calendar__day-number\">{{ day.date.getDate() }}</span>\n\n @if (day.events.length > 0) {\n <div class=\"ds-calendar__events\">\n @for (event of day.events; track event.id) {\n <div\n [class]=\"getEventClasses(event)\"\n [title]=\"event.title\"\n (click)=\"onEventClick(event, $event)\"\n role=\"button\"\n [attr.aria-label]=\"event.title\"\n >\n <span class=\"ds-calendar__event-dot\"></span>\n @if (size() === 'lg') {\n <span class=\"ds-calendar__event-title\">{{ event.title }}</span>\n }\n </div>\n }\n </div>\n }\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Vue ann\u00E9e -->\n @if (currentMode() === 'year') {\n <div class=\"ds-calendar__year-view\">\n <div class=\"ds-calendar__months-grid\">\n @for (month of monthGrid(); track month.monthIndex) {\n <button\n type=\"button\"\n [class]=\"getMonthClasses(month)\"\n (click)=\"selectMonth(month)\"\n [attr.aria-label]=\"month.label\"\n [attr.aria-current]=\"month.isCurrentMonth ? 'true' : null\"\n >\n {{ month.label }}\n </button>\n }\n </div>\n </div>\n }\n</div>\n", styles: [".ds-calendar{display:block;width:100%}.ds-calendar__container{background:var(--calendar-bg, var(--white));border:1px solid var(--calendar-border, var(--gray-200));border-radius:var(--calendar-radius, var(--radius-2));overflow:hidden}.ds-calendar__header{display:flex;align-items:center;justify-content:space-between;padding:var(--calendar-header-padding, var(--space-4));border-bottom:1px solid var(--calendar-border, var(--gray-200));background:var(--calendar-header-bg, var(--gray-50))}.ds-calendar__nav{display:flex;align-items:center;gap:var(--calendar-nav-gap, var(--space-2))}.ds-calendar__nav-btn{display:inline-flex;align-items:center;justify-content:center;width:var(--calendar-nav-btn-size, 32px);height:var(--calendar-nav-btn-size, 32px);padding:0;background:transparent;border:1px solid var(--calendar-nav-btn-border, var(--gray-300));border-radius:var(--calendar-nav-btn-radius, var(--radius-1));color:var(--calendar-nav-btn-color, var(--gray-700));font-size:var(--calendar-nav-btn-font-size, var(--font-size-3));cursor:pointer;transition:all .2s ease}.ds-calendar__nav-btn:hover:not(:disabled){background:var(--calendar-nav-btn-hover-bg, var(--gray-100));border-color:var(--calendar-nav-btn-hover-border, var(--gray-400));color:var(--calendar-nav-btn-hover-color, var(--gray-900))}.ds-calendar__nav-btn:active:not(:disabled){transform:scale(.95)}.ds-calendar__nav-btn:disabled{opacity:.5;cursor:not-allowed}.ds-calendar__title{padding:var(--calendar-title-padding, var(--space-2) var(--space-3));background:transparent;border:1px solid transparent;border-radius:var(--calendar-title-radius, var(--radius-1));color:var(--calendar-title-color, var(--gray-900));font-size:var(--calendar-title-font-size, var(--font-size-4));font-weight:var(--calendar-title-font-weight, 600);cursor:pointer;transition:all .2s ease}.ds-calendar__title:hover{background:var(--calendar-title-hover-bg, var(--gray-100));border-color:var(--calendar-title-hover-border, var(--gray-300))}.ds-calendar__mode-selector{display:flex;gap:var(--calendar-mode-gap, var(--space-1));background:var(--calendar-mode-bg, var(--white));border:1px solid var(--calendar-mode-border, var(--gray-300));border-radius:var(--calendar-mode-radius, var(--radius-1));padding:var(--calendar-mode-padding, 2px)}.ds-calendar__mode-btn{padding:var(--calendar-mode-btn-padding, var(--space-1) var(--space-3));background:transparent;border:none;border-radius:var(--calendar-mode-btn-radius, var(--radius-1));color:var(--calendar-mode-btn-color, var(--gray-700));font-size:var(--calendar-mode-btn-font-size, var(--font-size-2));cursor:pointer;transition:all .2s ease}.ds-calendar__mode-btn:hover{color:var(--calendar-mode-btn-hover-color, var(--gray-900))}.ds-calendar__mode-btn--active{background:var(--calendar-mode-btn-active-bg, var(--color-primary));color:var(--calendar-mode-btn-active-color, var(--white))}.ds-calendar__month-view{padding:var(--calendar-month-view-padding, var(--space-4))}.ds-calendar__weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--calendar-weekday-gap, var(--space-1));margin-bottom:var(--calendar-weekday-margin, var(--space-2))}.ds-calendar__weekday{text-align:center;color:var(--calendar-weekday-color, var(--gray-600));font-size:var(--calendar-weekday-font-size, var(--font-size-2));font-weight:var(--calendar-weekday-font-weight, 600);text-transform:uppercase;padding:var(--calendar-weekday-padding, var(--space-2) 0)}.ds-calendar__grid{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--calendar-grid-gap, var(--space-1))}.ds-calendar__day{position:relative;aspect-ratio:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding:var(--calendar-day-padding, var(--space-2));background:var(--calendar-day-bg, transparent);border:1px solid var(--calendar-day-border, transparent);border-radius:var(--calendar-day-radius, var(--radius-1));color:var(--calendar-day-color, var(--gray-900));font-size:var(--calendar-day-font-size, var(--font-size-3));cursor:pointer;transition:all .2s ease}.ds-calendar__day:hover:not(:disabled){background:var(--calendar-day-hover-bg, var(--gray-100));border-color:var(--calendar-day-hover-border, var(--gray-300))}.ds-calendar__day--other-month{color:var(--calendar-day-other-month-color, var(--gray-400))}.ds-calendar__day--today{background:var(--calendar-day-today-bg, var(--blue-50));border-color:var(--calendar-day-today-border, var(--color-primary));color:var(--calendar-day-today-color, var(--color-primary));font-weight:600}.ds-calendar__day--disabled{opacity:.4;cursor:not-allowed;background:var(--calendar-day-disabled-bg, var(--gray-50))}.ds-calendar__day--has-events .ds-calendar__day-number{font-weight:600}.ds-calendar__day-number{line-height:1;margin-bottom:var(--calendar-day-number-margin, var(--space-1))}.ds-calendar__events{display:flex;flex-direction:column;gap:var(--calendar-events-gap, 2px);width:100%;margin-top:auto}.ds-calendar__event{display:flex;align-items:center;gap:var(--calendar-event-gap, var(--space-1));padding:var(--calendar-event-padding, 2px);border-radius:var(--calendar-event-radius, var(--radius-1));cursor:pointer;transition:all .2s ease}.ds-calendar__event:hover{transform:scale(1.05)}.ds-calendar__event-dot{width:var(--calendar-event-dot-size, 6px);height:var(--calendar-event-dot-size, 6px);border-radius:50%;background:var(--calendar-event-dot-color, var(--gray-500));flex-shrink:0}.ds-calendar__event-title{font-size:var(--calendar-event-title-font-size, var(--font-size-1));color:var(--calendar-event-title-color, var(--gray-700));white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ds-calendar__event--success .ds-calendar__event-dot{background:var(--calendar-event-success-color, var(--success))}.ds-calendar__event--warning .ds-calendar__event-dot{background:var(--calendar-event-warning-color, var(--warning))}.ds-calendar__event--error .ds-calendar__event-dot{background:var(--calendar-event-error-color, var(--error))}.ds-calendar__year-view{padding:var(--calendar-year-view-padding, var(--space-4))}.ds-calendar__months-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--calendar-months-gap, var(--space-3))}.ds-calendar__month{padding:var(--calendar-month-padding, var(--space-4));background:var(--calendar-month-bg, transparent);border:1px solid var(--calendar-month-border, var(--gray-200));border-radius:var(--calendar-month-radius, var(--radius-2));color:var(--calendar-month-color, var(--gray-900));font-size:var(--calendar-month-font-size, var(--font-size-3));font-weight:500;cursor:pointer;transition:all .2s ease;text-align:center}.ds-calendar__month:hover{background:var(--calendar-month-hover-bg, var(--gray-50));border-color:var(--calendar-month-hover-border, var(--gray-300))}.ds-calendar__month--current{background:var(--calendar-month-current-bg, var(--blue-50));border-color:var(--calendar-month-current-border, var(--color-primary));color:var(--calendar-month-current-color, var(--color-primary));font-weight:600}.ds-calendar--sm .ds-calendar__header{padding:var(--calendar-header-padding-sm, var(--space-2))}.ds-calendar--sm .ds-calendar__title{font-size:var(--calendar-title-font-size-sm, var(--font-size-3))}.ds-calendar--sm .ds-calendar__weekday{font-size:var(--calendar-weekday-font-size-sm, var(--font-size-1))}.ds-calendar--sm .ds-calendar__day{padding:var(--calendar-day-padding-sm, var(--space-1));font-size:var(--calendar-day-font-size-sm, var(--font-size-2))}.ds-calendar--sm .ds-calendar__month{padding:var(--calendar-month-padding-sm, var(--space-2));font-size:var(--calendar-month-font-size-sm, var(--font-size-2))}.ds-calendar--lg .ds-calendar__header{padding:var(--calendar-header-padding-lg, var(--space-6))}.ds-calendar--lg .ds-calendar__title{font-size:var(--calendar-title-font-size-lg, var(--font-size-5))}.ds-calendar--lg .ds-calendar__weekday{font-size:var(--calendar-weekday-font-size-lg, var(--font-size-3))}.ds-calendar--lg .ds-calendar__day{padding:var(--calendar-day-padding-lg, var(--space-3));font-size:var(--calendar-day-font-size-lg, var(--font-size-4))}.ds-calendar--lg .ds-calendar__month{padding:var(--calendar-month-padding-lg, var(--space-6));font-size:var(--calendar-month-font-size-lg, var(--font-size-4))}\n"] }]
|
|
11432
11432
|
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], events: [{ type: i0.Input, args: [{ isSignal: true, alias: "events", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], disabledDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabledDate", required: false }] }], dateSelect: [{ type: i0.Output, args: ["dateSelect"] }], monthChange: [{ type: i0.Output, args: ["monthChange"] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }], eventClick: [{ type: i0.Output, args: ["eventClick"] }] } });
|
|
11433
11433
|
|
|
11434
|
+
class DsInputNumber {
|
|
11435
|
+
// Config
|
|
11436
|
+
min = input(-Infinity, ...(ngDevMode ? [{ debugName: "min" }] : []));
|
|
11437
|
+
max = input(Infinity, ...(ngDevMode ? [{ debugName: "max" }] : []));
|
|
11438
|
+
step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : []));
|
|
11439
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
11440
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : []));
|
|
11441
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
|
|
11442
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
11443
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
11444
|
+
prefix = input(undefined, ...(ngDevMode ? [{ debugName: "prefix" }] : []));
|
|
11445
|
+
suffix = input(undefined, ...(ngDevMode ? [{ debugName: "suffix" }] : []));
|
|
11446
|
+
precision = input(0, ...(ngDevMode ? [{ debugName: "precision" }] : []));
|
|
11447
|
+
controls = input(true, ...(ngDevMode ? [{ debugName: "controls" }] : []));
|
|
11448
|
+
controlsPosition = input('both', ...(ngDevMode ? [{ debugName: "controlsPosition" }] : []));
|
|
11449
|
+
// Accessibility
|
|
11450
|
+
ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
11451
|
+
id = input(crypto.randomUUID(), ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
11452
|
+
name = input(undefined, ...(ngDevMode ? [{ debugName: "name" }] : []));
|
|
11453
|
+
// Events
|
|
11454
|
+
valueChange = output();
|
|
11455
|
+
// ViewChild
|
|
11456
|
+
inputElement;
|
|
11457
|
+
// Icons
|
|
11458
|
+
faMinus = faMinus;
|
|
11459
|
+
faPlus = faPlus;
|
|
11460
|
+
// Internal state
|
|
11461
|
+
disabledState = signal(false, ...(ngDevMode ? [{ debugName: "disabledState" }] : []));
|
|
11462
|
+
internalValue = signal(null, ...(ngDevMode ? [{ debugName: "internalValue" }] : []));
|
|
11463
|
+
focused = signal(false, ...(ngDevMode ? [{ debugName: "focused" }] : []));
|
|
11464
|
+
displayValue = signal('', ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
|
|
11465
|
+
constructor() {
|
|
11466
|
+
// Effect pour formater l'affichage
|
|
11467
|
+
effect(() => {
|
|
11468
|
+
const val = this.internalValue();
|
|
11469
|
+
if (val === null) {
|
|
11470
|
+
this.displayValue.set('');
|
|
11471
|
+
return;
|
|
11472
|
+
}
|
|
11473
|
+
const formatted = this.formatValue(val);
|
|
11474
|
+
this.displayValue.set(formatted);
|
|
11475
|
+
});
|
|
11476
|
+
}
|
|
11477
|
+
isDisabled = computed(() => this.disabled() || this.disabledState(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
11478
|
+
isReadonly = computed(() => this.readonly(), ...(ngDevMode ? [{ debugName: "isReadonly" }] : []));
|
|
11479
|
+
showControls = computed(() => this.controls() && !this.isDisabled() && !this.isReadonly(), ...(ngDevMode ? [{ debugName: "showControls" }] : []));
|
|
11480
|
+
controlsOnRight = computed(() => this.controlsPosition() === 'right', ...(ngDevMode ? [{ debugName: "controlsOnRight" }] : []));
|
|
11481
|
+
controlsOnBoth = computed(() => this.controlsPosition() === 'both', ...(ngDevMode ? [{ debugName: "controlsOnBoth" }] : []));
|
|
11482
|
+
containerClasses = computed(() => {
|
|
11483
|
+
const classes = ['ds-input-number'];
|
|
11484
|
+
classes.push(`ds-input-number--${this.size()}`);
|
|
11485
|
+
if (this.isDisabled())
|
|
11486
|
+
classes.push('ds-input-number--disabled');
|
|
11487
|
+
if (this.isReadonly())
|
|
11488
|
+
classes.push('ds-input-number--readonly');
|
|
11489
|
+
if (this.focused())
|
|
11490
|
+
classes.push('ds-input-number--focused');
|
|
11491
|
+
if (this.controlsOnRight())
|
|
11492
|
+
classes.push('ds-input-number--controls-right');
|
|
11493
|
+
if (this.controlsOnBoth())
|
|
11494
|
+
classes.push('ds-input-number--controls-both');
|
|
11495
|
+
if (this.prefix())
|
|
11496
|
+
classes.push('ds-input-number--has-prefix');
|
|
11497
|
+
if (this.suffix())
|
|
11498
|
+
classes.push('ds-input-number--has-suffix');
|
|
11499
|
+
return classes.join(' ');
|
|
11500
|
+
}, ...(ngDevMode ? [{ debugName: "containerClasses" }] : []));
|
|
11501
|
+
canDecrement = computed(() => {
|
|
11502
|
+
if (!this.showControls())
|
|
11503
|
+
return false;
|
|
11504
|
+
const val = this.internalValue();
|
|
11505
|
+
if (val === null)
|
|
11506
|
+
return true;
|
|
11507
|
+
return val > this.min();
|
|
11508
|
+
}, ...(ngDevMode ? [{ debugName: "canDecrement" }] : []));
|
|
11509
|
+
canIncrement = computed(() => {
|
|
11510
|
+
if (!this.showControls())
|
|
11511
|
+
return false;
|
|
11512
|
+
const val = this.internalValue();
|
|
11513
|
+
if (val === null)
|
|
11514
|
+
return true;
|
|
11515
|
+
return val < this.max();
|
|
11516
|
+
}, ...(ngDevMode ? [{ debugName: "canIncrement" }] : []));
|
|
11517
|
+
// ControlValueAccessor
|
|
11518
|
+
onChange = () => { };
|
|
11519
|
+
onTouched = () => { };
|
|
11520
|
+
writeValue(value) {
|
|
11521
|
+
this.internalValue.set(value);
|
|
11522
|
+
}
|
|
11523
|
+
registerOnChange(fn) {
|
|
11524
|
+
this.onChange = fn;
|
|
11525
|
+
}
|
|
11526
|
+
registerOnTouched(fn) {
|
|
11527
|
+
this.onTouched = fn;
|
|
11528
|
+
}
|
|
11529
|
+
setDisabledState(isDisabled) {
|
|
11530
|
+
this.disabledState.set(isDisabled);
|
|
11531
|
+
}
|
|
11532
|
+
// Helpers
|
|
11533
|
+
formatValue(value) {
|
|
11534
|
+
const prec = this.precision();
|
|
11535
|
+
return prec > 0 ? value.toFixed(prec) : Math.floor(value).toString();
|
|
11536
|
+
}
|
|
11537
|
+
parseValue(input) {
|
|
11538
|
+
if (input === '' || input === '-')
|
|
11539
|
+
return null;
|
|
11540
|
+
const parsed = parseFloat(input);
|
|
11541
|
+
if (isNaN(parsed))
|
|
11542
|
+
return null;
|
|
11543
|
+
return parsed;
|
|
11544
|
+
}
|
|
11545
|
+
clampValue(value) {
|
|
11546
|
+
return Math.max(this.min(), Math.min(this.max(), value));
|
|
11547
|
+
}
|
|
11548
|
+
roundToPrecision(value) {
|
|
11549
|
+
const prec = this.precision();
|
|
11550
|
+
if (prec === 0)
|
|
11551
|
+
return Math.round(value);
|
|
11552
|
+
const multiplier = Math.pow(10, prec);
|
|
11553
|
+
return Math.round(value * multiplier) / multiplier;
|
|
11554
|
+
}
|
|
11555
|
+
emitValue(value) {
|
|
11556
|
+
this.onChange(value);
|
|
11557
|
+
if (value !== null) {
|
|
11558
|
+
this.valueChange.emit(value);
|
|
11559
|
+
}
|
|
11560
|
+
}
|
|
11561
|
+
// Event handlers
|
|
11562
|
+
onInputChange(event) {
|
|
11563
|
+
if (this.isDisabled() || this.isReadonly())
|
|
11564
|
+
return;
|
|
11565
|
+
const target = event.target;
|
|
11566
|
+
const parsed = this.parseValue(target.value);
|
|
11567
|
+
if (parsed === null) {
|
|
11568
|
+
this.internalValue.set(null);
|
|
11569
|
+
this.emitValue(null);
|
|
11570
|
+
return;
|
|
11571
|
+
}
|
|
11572
|
+
const clamped = this.clampValue(parsed);
|
|
11573
|
+
const rounded = this.roundToPrecision(clamped);
|
|
11574
|
+
this.internalValue.set(rounded);
|
|
11575
|
+
this.emitValue(rounded);
|
|
11576
|
+
}
|
|
11577
|
+
onInputBlur() {
|
|
11578
|
+
this.focused.set(false);
|
|
11579
|
+
this.onTouched();
|
|
11580
|
+
// Formater la valeur au blur
|
|
11581
|
+
const val = this.internalValue();
|
|
11582
|
+
if (val !== null) {
|
|
11583
|
+
const clamped = this.clampValue(val);
|
|
11584
|
+
const rounded = this.roundToPrecision(clamped);
|
|
11585
|
+
if (rounded !== val) {
|
|
11586
|
+
this.internalValue.set(rounded);
|
|
11587
|
+
this.emitValue(rounded);
|
|
11588
|
+
}
|
|
11589
|
+
}
|
|
11590
|
+
}
|
|
11591
|
+
onInputFocus() {
|
|
11592
|
+
this.focused.set(true);
|
|
11593
|
+
}
|
|
11594
|
+
onKeyDown(event) {
|
|
11595
|
+
if (this.isDisabled() || this.isReadonly())
|
|
11596
|
+
return;
|
|
11597
|
+
const stepVal = this.step();
|
|
11598
|
+
let handled = false;
|
|
11599
|
+
switch (event.key) {
|
|
11600
|
+
case 'ArrowUp':
|
|
11601
|
+
this.increment();
|
|
11602
|
+
handled = true;
|
|
11603
|
+
break;
|
|
11604
|
+
case 'ArrowDown':
|
|
11605
|
+
this.decrement();
|
|
11606
|
+
handled = true;
|
|
11607
|
+
break;
|
|
11608
|
+
case 'Home':
|
|
11609
|
+
this.setToMin();
|
|
11610
|
+
handled = true;
|
|
11611
|
+
break;
|
|
11612
|
+
case 'End':
|
|
11613
|
+
this.setToMax();
|
|
11614
|
+
handled = true;
|
|
11615
|
+
break;
|
|
11616
|
+
case 'PageUp':
|
|
11617
|
+
this.incrementBy(stepVal * 10);
|
|
11618
|
+
handled = true;
|
|
11619
|
+
break;
|
|
11620
|
+
case 'PageDown':
|
|
11621
|
+
this.decrementBy(stepVal * 10);
|
|
11622
|
+
handled = true;
|
|
11623
|
+
break;
|
|
11624
|
+
}
|
|
11625
|
+
if (handled) {
|
|
11626
|
+
event.preventDefault();
|
|
11627
|
+
}
|
|
11628
|
+
}
|
|
11629
|
+
increment() {
|
|
11630
|
+
if (!this.canIncrement())
|
|
11631
|
+
return;
|
|
11632
|
+
this.incrementBy(this.step());
|
|
11633
|
+
}
|
|
11634
|
+
decrement() {
|
|
11635
|
+
if (!this.canDecrement())
|
|
11636
|
+
return;
|
|
11637
|
+
this.decrementBy(this.step());
|
|
11638
|
+
}
|
|
11639
|
+
incrementBy(delta) {
|
|
11640
|
+
const current = this.internalValue() ?? this.min();
|
|
11641
|
+
const newValue = this.clampValue(this.roundToPrecision(current + delta));
|
|
11642
|
+
this.internalValue.set(newValue);
|
|
11643
|
+
this.emitValue(newValue);
|
|
11644
|
+
this.inputElement?.nativeElement.focus();
|
|
11645
|
+
}
|
|
11646
|
+
decrementBy(delta) {
|
|
11647
|
+
const current = this.internalValue() ?? this.max();
|
|
11648
|
+
const newValue = this.clampValue(this.roundToPrecision(current - delta));
|
|
11649
|
+
this.internalValue.set(newValue);
|
|
11650
|
+
this.emitValue(newValue);
|
|
11651
|
+
this.inputElement?.nativeElement.focus();
|
|
11652
|
+
}
|
|
11653
|
+
setToMin() {
|
|
11654
|
+
const newValue = this.min();
|
|
11655
|
+
this.internalValue.set(newValue);
|
|
11656
|
+
this.emitValue(newValue);
|
|
11657
|
+
}
|
|
11658
|
+
setToMax() {
|
|
11659
|
+
const newValue = this.max();
|
|
11660
|
+
this.internalValue.set(newValue);
|
|
11661
|
+
this.emitValue(newValue);
|
|
11662
|
+
}
|
|
11663
|
+
// ARIA helpers
|
|
11664
|
+
ariaValueMin = computed(() => this.min(), ...(ngDevMode ? [{ debugName: "ariaValueMin" }] : []));
|
|
11665
|
+
ariaValueMax = computed(() => this.max(), ...(ngDevMode ? [{ debugName: "ariaValueMax" }] : []));
|
|
11666
|
+
ariaValueNow = computed(() => this.internalValue() ?? undefined, ...(ngDevMode ? [{ debugName: "ariaValueNow" }] : []));
|
|
11667
|
+
ariaValueText = computed(() => {
|
|
11668
|
+
const val = this.internalValue();
|
|
11669
|
+
if (val === null)
|
|
11670
|
+
return undefined;
|
|
11671
|
+
const prefixStr = this.prefix() ?? '';
|
|
11672
|
+
const suffixStr = this.suffix() ?? '';
|
|
11673
|
+
return `${prefixStr}${this.formatValue(val)}${suffixStr}`;
|
|
11674
|
+
}, ...(ngDevMode ? [{ debugName: "ariaValueText" }] : []));
|
|
11675
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsInputNumber, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11676
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsInputNumber, isStandalone: true, selector: "ds-input-number", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", 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 }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null }, precision: { classPropertyName: "precision", publicName: "precision", isSignal: true, isRequired: false, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: false, transformFunction: null }, controlsPosition: { classPropertyName: "controlsPosition", publicName: "controlsPosition", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, providers: [
|
|
11677
|
+
{
|
|
11678
|
+
provide: NG_VALUE_ACCESSOR,
|
|
11679
|
+
useExisting: forwardRef(() => DsInputNumber),
|
|
11680
|
+
multi: true,
|
|
11681
|
+
},
|
|
11682
|
+
], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], ngImport: i0, template: "<div [class]=\"containerClasses()\">\n <!-- Bouton d\u00E9cr\u00E9mentation (position both) -->\n @if (showControls() && controlsOnBoth()) {\n <button\n type=\"button\"\n class=\"ds-input-number__btn ds-input-number__btn--decrement\"\n [disabled]=\"!canDecrement()\"\n (click)=\"decrement()\"\n [attr.aria-label]=\"'Decrement value'\"\n tabindex=\"-1\"\n >\n <fa-icon [icon]=\"faMinus\" />\n </button>\n }\n\n <!-- Wrapper pour input + prefix/suffix -->\n <div class=\"ds-input-number__input-wrapper\">\n @if (prefix()) {\n <span class=\"ds-input-number__prefix\">{{ prefix() }}</span>\n }\n\n <input\n #inputElement\n type=\"text\"\n class=\"ds-input-number__input\"\n [id]=\"id()\"\n [name]=\"name()\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"isReadonly()\"\n [required]=\"required()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-valuemin]=\"ariaValueMin()\"\n [attr.aria-valuemax]=\"ariaValueMax()\"\n [attr.aria-valuenow]=\"ariaValueNow()\"\n [attr.aria-valuetext]=\"ariaValueText()\"\n role=\"spinbutton\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n (focus)=\"onInputFocus()\"\n (keydown)=\"onKeyDown($event)\"\n />\n\n @if (suffix()) {\n <span class=\"ds-input-number__suffix\">{{ suffix() }}</span>\n }\n </div>\n\n <!-- Boutons position right -->\n @if (showControls() && controlsOnRight()) {\n <div class=\"ds-input-number__controls-right\">\n <button\n type=\"button\"\n class=\"ds-input-number__btn ds-input-number__btn--increment-right\"\n [disabled]=\"!canIncrement()\"\n (click)=\"increment()\"\n [attr.aria-label]=\"'Increment value'\"\n tabindex=\"-1\"\n >\n <fa-icon [icon]=\"faPlus\" />\n </button>\n <button\n type=\"button\"\n class=\"ds-input-number__btn ds-input-number__btn--decrement-right\"\n [disabled]=\"!canDecrement()\"\n (click)=\"decrement()\"\n [attr.aria-label]=\"'Decrement value'\"\n tabindex=\"-1\"\n >\n <fa-icon [icon]=\"faMinus\" />\n </button>\n </div>\n }\n\n <!-- Bouton incr\u00E9mentation (position both) -->\n @if (showControls() && controlsOnBoth()) {\n <button\n type=\"button\"\n class=\"ds-input-number__btn ds-input-number__btn--increment\"\n [disabled]=\"!canIncrement()\"\n (click)=\"increment()\"\n [attr.aria-label]=\"'Increment value'\"\n tabindex=\"-1\"\n >\n <fa-icon [icon]=\"faPlus\" />\n </button>\n }\n</div>\n", styles: [".ds-input-number{display:inline-flex;align-items:stretch;position:relative;vertical-align:middle;width:100%;max-width:200px}.ds-input-number__input-wrapper{display:flex;align-items:center;flex:1;position:relative;background-color:var(--input-bg, var(--gray-50));border:1px solid var(--input-border-color, var(--gray-300));border-radius:var(--input-border-radius, var(--radius-2));transition:all .2s ease;overflow:hidden}.ds-input-number--focused .ds-input-number__input-wrapper{border-color:var(--input-focus-border, var(--color-primary));box-shadow:0 0 0 3px var(--input-focus-ring, rgba(37, 99, 235, .1))}.ds-input-number--disabled .ds-input-number__input-wrapper{background-color:var(--input-bg-disabled, var(--gray-100));border-color:var(--input-border-disabled, var(--gray-200));cursor:not-allowed}.ds-input-number--readonly .ds-input-number__input-wrapper{background-color:var(--input-bg-readonly, var(--gray-50));border-color:var(--input-border-color, var(--gray-300))}.ds-input-number__input{flex:1;border:none;outline:none;background:transparent;color:var(--input-text-color, var(--gray-900));font-family:inherit;text-align:center;padding:0 var(--space-2, .5rem)}.ds-input-number__input::placeholder{color:var(--input-placeholder, var(--gray-500))}.ds-input-number__input:disabled{cursor:not-allowed;color:var(--input-text-disabled, var(--gray-500))}.ds-input-number--readonly .ds-input-number__input{cursor:default}.ds-input-number__input::-webkit-outer-spin-button,.ds-input-number__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.ds-input-number__input[type=number]{-moz-appearance:textfield}.ds-input-number__prefix,.ds-input-number__suffix{display:inline-flex;align-items:center;color:var(--input-placeholder, var(--gray-500));font-size:inherit;padding:0 var(--space-2, .5rem);-webkit-user-select:none;user-select:none}.ds-input-number__prefix{padding-right:0}.ds-input-number__suffix{padding-left:0}.ds-input-number__btn{display:inline-flex;align-items:center;justify-content:center;border:none;outline:none;cursor:pointer;background-color:var(--input-number-btn-bg, var(--gray-100));color:var(--input-text-color, var(--gray-900));transition:all .15s ease;-webkit-user-select:none;user-select:none}.ds-input-number__btn:hover:not(:disabled){background-color:var(--input-number-btn-hover, var(--gray-200))}.ds-input-number__btn:active:not(:disabled){background-color:var(--input-number-btn-active, var(--gray-300))}.ds-input-number__btn:disabled{cursor:not-allowed;background-color:var(--input-number-btn-disabled, var(--gray-50));color:var(--input-text-disabled, var(--gray-400))}.ds-input-number__btn fa-icon{font-size:.875em}.ds-input-number--controls-both .ds-input-number__btn--decrement{border-right:1px solid var(--input-border-color, var(--gray-300));border-top-left-radius:var(--input-border-radius, var(--radius-2));border-bottom-left-radius:var(--input-border-radius, var(--radius-2))}.ds-input-number--controls-both .ds-input-number__btn--increment{border-left:1px solid var(--input-border-color, var(--gray-300));border-top-right-radius:var(--input-border-radius, var(--radius-2));border-bottom-right-radius:var(--input-border-radius, var(--radius-2))}.ds-input-number--controls-both .ds-input-number__input-wrapper{border-radius:0}.ds-input-number--controls-right .ds-input-number__controls-right{display:flex;flex-direction:column;border-left:1px solid var(--input-border-color, var(--gray-300))}.ds-input-number--controls-right .ds-input-number__btn--increment-right,.ds-input-number--controls-right .ds-input-number__btn--decrement-right{flex:1;width:var(--input-number-btn-size-md, 24px)}.ds-input-number--controls-right .ds-input-number__btn--increment-right{border-bottom:1px solid var(--input-border-color, var(--gray-300));border-top-right-radius:var(--input-border-radius, var(--radius-2))}.ds-input-number--controls-right .ds-input-number__btn--decrement-right{border-bottom-right-radius:var(--input-border-radius, var(--radius-2))}.ds-input-number--controls-right .ds-input-number__input-wrapper{border-top-right-radius:0;border-bottom-right-radius:0}.ds-input-number--sm{font-size:var(--font-size-sm, .875rem)}.ds-input-number--sm .ds-input-number__input-wrapper{height:var(--input-number-height-sm, 32px)}.ds-input-number--sm .ds-input-number__btn{width:var(--input-number-btn-size-sm, 28px);height:var(--input-number-btn-size-sm, 28px)}.ds-input-number--sm.ds-input-number--controls-right .ds-input-number__btn{width:var(--input-number-btn-size-sm, 20px);height:calc(var(--input-number-height-sm, 32px) / 2)}.ds-input-number--md{font-size:var(--font-size-base, 1rem)}.ds-input-number--md .ds-input-number__input-wrapper{height:var(--input-number-height-md, 40px)}.ds-input-number--md .ds-input-number__btn{width:var(--input-number-btn-size-md, 36px);height:var(--input-number-btn-size-md, 36px)}.ds-input-number--md.ds-input-number--controls-right .ds-input-number__btn{width:var(--input-number-btn-size-md, 24px);height:calc(var(--input-number-height-md, 40px) / 2)}.ds-input-number--lg{font-size:var(--font-size-lg, 1.125rem)}.ds-input-number--lg .ds-input-number__input-wrapper{height:var(--input-number-height-lg, 48px)}.ds-input-number--lg .ds-input-number__btn{width:var(--input-number-btn-size-lg, 44px);height:var(--input-number-btn-size-lg, 44px)}.ds-input-number--lg.ds-input-number--controls-right .ds-input-number__btn{width:var(--input-number-btn-size-lg, 28px);height:calc(var(--input-number-height-lg, 48px) / 2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"], outputs: ["iconChange", "titleChange", "animationChange", "maskChange", "flipChange", "sizeChange", "pullChange", "borderChange", "inverseChange", "symbolChange", "rotateChange", "fixedWidthChange", "transformChange", "a11yRoleChange"] }] });
|
|
11683
|
+
}
|
|
11684
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsInputNumber, decorators: [{
|
|
11685
|
+
type: Component,
|
|
11686
|
+
args: [{ selector: 'ds-input-number', imports: [CommonModule, FaIconComponent], providers: [
|
|
11687
|
+
{
|
|
11688
|
+
provide: NG_VALUE_ACCESSOR,
|
|
11689
|
+
useExisting: forwardRef(() => DsInputNumber),
|
|
11690
|
+
multi: true,
|
|
11691
|
+
},
|
|
11692
|
+
], template: "<div [class]=\"containerClasses()\">\n <!-- Bouton d\u00E9cr\u00E9mentation (position both) -->\n @if (showControls() && controlsOnBoth()) {\n <button\n type=\"button\"\n class=\"ds-input-number__btn ds-input-number__btn--decrement\"\n [disabled]=\"!canDecrement()\"\n (click)=\"decrement()\"\n [attr.aria-label]=\"'Decrement value'\"\n tabindex=\"-1\"\n >\n <fa-icon [icon]=\"faMinus\" />\n </button>\n }\n\n <!-- Wrapper pour input + prefix/suffix -->\n <div class=\"ds-input-number__input-wrapper\">\n @if (prefix()) {\n <span class=\"ds-input-number__prefix\">{{ prefix() }}</span>\n }\n\n <input\n #inputElement\n type=\"text\"\n class=\"ds-input-number__input\"\n [id]=\"id()\"\n [name]=\"name()\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readonly]=\"isReadonly()\"\n [required]=\"required()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-valuemin]=\"ariaValueMin()\"\n [attr.aria-valuemax]=\"ariaValueMax()\"\n [attr.aria-valuenow]=\"ariaValueNow()\"\n [attr.aria-valuetext]=\"ariaValueText()\"\n role=\"spinbutton\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onInputBlur()\"\n (focus)=\"onInputFocus()\"\n (keydown)=\"onKeyDown($event)\"\n />\n\n @if (suffix()) {\n <span class=\"ds-input-number__suffix\">{{ suffix() }}</span>\n }\n </div>\n\n <!-- Boutons position right -->\n @if (showControls() && controlsOnRight()) {\n <div class=\"ds-input-number__controls-right\">\n <button\n type=\"button\"\n class=\"ds-input-number__btn ds-input-number__btn--increment-right\"\n [disabled]=\"!canIncrement()\"\n (click)=\"increment()\"\n [attr.aria-label]=\"'Increment value'\"\n tabindex=\"-1\"\n >\n <fa-icon [icon]=\"faPlus\" />\n </button>\n <button\n type=\"button\"\n class=\"ds-input-number__btn ds-input-number__btn--decrement-right\"\n [disabled]=\"!canDecrement()\"\n (click)=\"decrement()\"\n [attr.aria-label]=\"'Decrement value'\"\n tabindex=\"-1\"\n >\n <fa-icon [icon]=\"faMinus\" />\n </button>\n </div>\n }\n\n <!-- Bouton incr\u00E9mentation (position both) -->\n @if (showControls() && controlsOnBoth()) {\n <button\n type=\"button\"\n class=\"ds-input-number__btn ds-input-number__btn--increment\"\n [disabled]=\"!canIncrement()\"\n (click)=\"increment()\"\n [attr.aria-label]=\"'Increment value'\"\n tabindex=\"-1\"\n >\n <fa-icon [icon]=\"faPlus\" />\n </button>\n }\n</div>\n", styles: [".ds-input-number{display:inline-flex;align-items:stretch;position:relative;vertical-align:middle;width:100%;max-width:200px}.ds-input-number__input-wrapper{display:flex;align-items:center;flex:1;position:relative;background-color:var(--input-bg, var(--gray-50));border:1px solid var(--input-border-color, var(--gray-300));border-radius:var(--input-border-radius, var(--radius-2));transition:all .2s ease;overflow:hidden}.ds-input-number--focused .ds-input-number__input-wrapper{border-color:var(--input-focus-border, var(--color-primary));box-shadow:0 0 0 3px var(--input-focus-ring, rgba(37, 99, 235, .1))}.ds-input-number--disabled .ds-input-number__input-wrapper{background-color:var(--input-bg-disabled, var(--gray-100));border-color:var(--input-border-disabled, var(--gray-200));cursor:not-allowed}.ds-input-number--readonly .ds-input-number__input-wrapper{background-color:var(--input-bg-readonly, var(--gray-50));border-color:var(--input-border-color, var(--gray-300))}.ds-input-number__input{flex:1;border:none;outline:none;background:transparent;color:var(--input-text-color, var(--gray-900));font-family:inherit;text-align:center;padding:0 var(--space-2, .5rem)}.ds-input-number__input::placeholder{color:var(--input-placeholder, var(--gray-500))}.ds-input-number__input:disabled{cursor:not-allowed;color:var(--input-text-disabled, var(--gray-500))}.ds-input-number--readonly .ds-input-number__input{cursor:default}.ds-input-number__input::-webkit-outer-spin-button,.ds-input-number__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.ds-input-number__input[type=number]{-moz-appearance:textfield}.ds-input-number__prefix,.ds-input-number__suffix{display:inline-flex;align-items:center;color:var(--input-placeholder, var(--gray-500));font-size:inherit;padding:0 var(--space-2, .5rem);-webkit-user-select:none;user-select:none}.ds-input-number__prefix{padding-right:0}.ds-input-number__suffix{padding-left:0}.ds-input-number__btn{display:inline-flex;align-items:center;justify-content:center;border:none;outline:none;cursor:pointer;background-color:var(--input-number-btn-bg, var(--gray-100));color:var(--input-text-color, var(--gray-900));transition:all .15s ease;-webkit-user-select:none;user-select:none}.ds-input-number__btn:hover:not(:disabled){background-color:var(--input-number-btn-hover, var(--gray-200))}.ds-input-number__btn:active:not(:disabled){background-color:var(--input-number-btn-active, var(--gray-300))}.ds-input-number__btn:disabled{cursor:not-allowed;background-color:var(--input-number-btn-disabled, var(--gray-50));color:var(--input-text-disabled, var(--gray-400))}.ds-input-number__btn fa-icon{font-size:.875em}.ds-input-number--controls-both .ds-input-number__btn--decrement{border-right:1px solid var(--input-border-color, var(--gray-300));border-top-left-radius:var(--input-border-radius, var(--radius-2));border-bottom-left-radius:var(--input-border-radius, var(--radius-2))}.ds-input-number--controls-both .ds-input-number__btn--increment{border-left:1px solid var(--input-border-color, var(--gray-300));border-top-right-radius:var(--input-border-radius, var(--radius-2));border-bottom-right-radius:var(--input-border-radius, var(--radius-2))}.ds-input-number--controls-both .ds-input-number__input-wrapper{border-radius:0}.ds-input-number--controls-right .ds-input-number__controls-right{display:flex;flex-direction:column;border-left:1px solid var(--input-border-color, var(--gray-300))}.ds-input-number--controls-right .ds-input-number__btn--increment-right,.ds-input-number--controls-right .ds-input-number__btn--decrement-right{flex:1;width:var(--input-number-btn-size-md, 24px)}.ds-input-number--controls-right .ds-input-number__btn--increment-right{border-bottom:1px solid var(--input-border-color, var(--gray-300));border-top-right-radius:var(--input-border-radius, var(--radius-2))}.ds-input-number--controls-right .ds-input-number__btn--decrement-right{border-bottom-right-radius:var(--input-border-radius, var(--radius-2))}.ds-input-number--controls-right .ds-input-number__input-wrapper{border-top-right-radius:0;border-bottom-right-radius:0}.ds-input-number--sm{font-size:var(--font-size-sm, .875rem)}.ds-input-number--sm .ds-input-number__input-wrapper{height:var(--input-number-height-sm, 32px)}.ds-input-number--sm .ds-input-number__btn{width:var(--input-number-btn-size-sm, 28px);height:var(--input-number-btn-size-sm, 28px)}.ds-input-number--sm.ds-input-number--controls-right .ds-input-number__btn{width:var(--input-number-btn-size-sm, 20px);height:calc(var(--input-number-height-sm, 32px) / 2)}.ds-input-number--md{font-size:var(--font-size-base, 1rem)}.ds-input-number--md .ds-input-number__input-wrapper{height:var(--input-number-height-md, 40px)}.ds-input-number--md .ds-input-number__btn{width:var(--input-number-btn-size-md, 36px);height:var(--input-number-btn-size-md, 36px)}.ds-input-number--md.ds-input-number--controls-right .ds-input-number__btn{width:var(--input-number-btn-size-md, 24px);height:calc(var(--input-number-height-md, 40px) / 2)}.ds-input-number--lg{font-size:var(--font-size-lg, 1.125rem)}.ds-input-number--lg .ds-input-number__input-wrapper{height:var(--input-number-height-lg, 48px)}.ds-input-number--lg .ds-input-number__btn{width:var(--input-number-btn-size-lg, 44px);height:var(--input-number-btn-size-lg, 44px)}.ds-input-number--lg.ds-input-number--controls-right .ds-input-number__btn{width:var(--input-number-btn-size-lg, 28px);height:calc(var(--input-number-height-lg, 48px) / 2)}\n"] }]
|
|
11693
|
+
}], ctorParameters: () => [], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], precision: [{ type: i0.Input, args: [{ isSignal: true, alias: "precision", required: false }] }], controls: [{ type: i0.Input, args: [{ isSignal: true, alias: "controls", required: false }] }], controlsPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlsPosition", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], inputElement: [{
|
|
11694
|
+
type: ViewChild,
|
|
11695
|
+
args: ['inputElement', { static: false }]
|
|
11696
|
+
}] } });
|
|
11697
|
+
|
|
11698
|
+
/**
|
|
11699
|
+
* DS Segmented Control
|
|
11700
|
+
*
|
|
11701
|
+
* Composant groupe de boutons mutuellement exclusifs visuellement connectés.
|
|
11702
|
+
* Alternative stylisée aux boutons radio pour basculer entre vues, modes ou options.
|
|
11703
|
+
*
|
|
11704
|
+
* @example
|
|
11705
|
+
* // Formulaire réactif
|
|
11706
|
+
* <ds-segmented-control
|
|
11707
|
+
* formControlName="view"
|
|
11708
|
+
* [options]="viewOptions"
|
|
11709
|
+
* size="md"
|
|
11710
|
+
* fullWidth
|
|
11711
|
+
* />
|
|
11712
|
+
*
|
|
11713
|
+
* @example
|
|
11714
|
+
* // Template-driven
|
|
11715
|
+
* <ds-segmented-control
|
|
11716
|
+
* [(ngModel)]="selectedView"
|
|
11717
|
+
* [options]="[
|
|
11718
|
+
* { value: 'list', label: 'Liste', icon: 'fas-list' },
|
|
11719
|
+
* { value: 'grid', label: 'Grille', icon: 'fas-grid' },
|
|
11720
|
+
* { value: 'map', label: 'Carte', icon: 'fas-map' }
|
|
11721
|
+
* ]"
|
|
11722
|
+
* color="neutral"
|
|
11723
|
+
* />
|
|
11724
|
+
*/
|
|
11725
|
+
class DsSegmentedControl {
|
|
11726
|
+
/**
|
|
11727
|
+
* Liste des options du segmented control
|
|
11728
|
+
*/
|
|
11729
|
+
options = input.required(...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
11730
|
+
/**
|
|
11731
|
+
* Taille du segmented control (sm, md, lg)
|
|
11732
|
+
*/
|
|
11733
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
11734
|
+
/**
|
|
11735
|
+
* État désactivé global
|
|
11736
|
+
*/
|
|
11737
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
11738
|
+
/**
|
|
11739
|
+
* Prend toute la largeur du conteneur
|
|
11740
|
+
*/
|
|
11741
|
+
fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : []));
|
|
11742
|
+
/**
|
|
11743
|
+
* Orientation (horizontal, vertical)
|
|
11744
|
+
*/
|
|
11745
|
+
orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
|
|
11746
|
+
/**
|
|
11747
|
+
* Couleur du segment actif (primary, neutral)
|
|
11748
|
+
*/
|
|
11749
|
+
color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : []));
|
|
11750
|
+
// Internal state
|
|
11751
|
+
disabledState = signal(false, ...(ngDevMode ? [{ debugName: "disabledState" }] : []));
|
|
11752
|
+
internalValue = signal(null, ...(ngDevMode ? [{ debugName: "internalValue" }] : []));
|
|
11753
|
+
// Computed properties
|
|
11754
|
+
isDisabled = computed(() => this.disabled() || this.disabledState(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
11755
|
+
containerClasses = computed(() => ({
|
|
11756
|
+
'ds-segmented-control': true,
|
|
11757
|
+
[`ds-segmented-control--${this.size()}`]: true,
|
|
11758
|
+
[`ds-segmented-control--${this.orientation()}`]: true,
|
|
11759
|
+
[`ds-segmented-control--${this.color()}`]: true,
|
|
11760
|
+
'ds-segmented-control--full-width': this.fullWidth(),
|
|
11761
|
+
'ds-segmented-control--disabled': this.isDisabled(),
|
|
11762
|
+
}), ...(ngDevMode ? [{ debugName: "containerClasses" }] : []));
|
|
11763
|
+
activeIndex = computed(() => {
|
|
11764
|
+
const value = this.internalValue();
|
|
11765
|
+
if (!value)
|
|
11766
|
+
return -1;
|
|
11767
|
+
return this.options().findIndex((opt) => opt.value === value);
|
|
11768
|
+
}, ...(ngDevMode ? [{ debugName: "activeIndex" }] : []));
|
|
11769
|
+
/**
|
|
11770
|
+
* Vérifie si une option est sélectionnée
|
|
11771
|
+
*/
|
|
11772
|
+
isOptionSelected(option) {
|
|
11773
|
+
return this.internalValue() === option.value;
|
|
11774
|
+
}
|
|
11775
|
+
/**
|
|
11776
|
+
* Vérifie si une option est désactivée
|
|
11777
|
+
*/
|
|
11778
|
+
isOptionDisabled(option) {
|
|
11779
|
+
return this.isDisabled() || !!option.disabled;
|
|
11780
|
+
}
|
|
11781
|
+
/**
|
|
11782
|
+
* Classes CSS pour un segment
|
|
11783
|
+
*/
|
|
11784
|
+
getSegmentClasses(option) {
|
|
11785
|
+
return {
|
|
11786
|
+
'ds-segmented-control__segment': true,
|
|
11787
|
+
'ds-segmented-control__segment--active': this.isOptionSelected(option),
|
|
11788
|
+
'ds-segmented-control__segment--disabled': this.isOptionDisabled(option),
|
|
11789
|
+
};
|
|
11790
|
+
}
|
|
11791
|
+
// ControlValueAccessor implementation
|
|
11792
|
+
onChange = () => { };
|
|
11793
|
+
onTouched = () => { };
|
|
11794
|
+
writeValue(value) {
|
|
11795
|
+
this.internalValue.set(value);
|
|
11796
|
+
}
|
|
11797
|
+
registerOnChange(fn) {
|
|
11798
|
+
this.onChange = fn;
|
|
11799
|
+
}
|
|
11800
|
+
registerOnTouched(fn) {
|
|
11801
|
+
this.onTouched = fn;
|
|
11802
|
+
}
|
|
11803
|
+
setDisabledState(isDisabled) {
|
|
11804
|
+
this.disabledState.set(isDisabled);
|
|
11805
|
+
}
|
|
11806
|
+
// Event handlers
|
|
11807
|
+
onSegmentClick(option) {
|
|
11808
|
+
if (this.isOptionDisabled(option)) {
|
|
11809
|
+
return;
|
|
11810
|
+
}
|
|
11811
|
+
this.internalValue.set(option.value);
|
|
11812
|
+
this.onChange(option.value);
|
|
11813
|
+
this.onTouched();
|
|
11814
|
+
}
|
|
11815
|
+
onKeydown(event) {
|
|
11816
|
+
const target = event.target;
|
|
11817
|
+
if (target.getAttribute('role') !== 'radio')
|
|
11818
|
+
return;
|
|
11819
|
+
const currentIndex = this.activeIndex();
|
|
11820
|
+
const optionsArray = this.options();
|
|
11821
|
+
const isHorizontal = this.orientation() === 'horizontal';
|
|
11822
|
+
let nextIndex = currentIndex;
|
|
11823
|
+
switch (event.key) {
|
|
11824
|
+
case 'ArrowLeft':
|
|
11825
|
+
if (!isHorizontal)
|
|
11826
|
+
return;
|
|
11827
|
+
event.preventDefault();
|
|
11828
|
+
nextIndex = this.findPreviousEnabledOption(currentIndex);
|
|
11829
|
+
break;
|
|
11830
|
+
case 'ArrowRight':
|
|
11831
|
+
if (!isHorizontal)
|
|
11832
|
+
return;
|
|
11833
|
+
event.preventDefault();
|
|
11834
|
+
nextIndex = this.findNextEnabledOption(currentIndex);
|
|
11835
|
+
break;
|
|
11836
|
+
case 'ArrowUp':
|
|
11837
|
+
if (isHorizontal)
|
|
11838
|
+
return;
|
|
11839
|
+
event.preventDefault();
|
|
11840
|
+
nextIndex = this.findPreviousEnabledOption(currentIndex);
|
|
11841
|
+
break;
|
|
11842
|
+
case 'ArrowDown':
|
|
11843
|
+
if (isHorizontal)
|
|
11844
|
+
return;
|
|
11845
|
+
event.preventDefault();
|
|
11846
|
+
nextIndex = this.findNextEnabledOption(currentIndex);
|
|
11847
|
+
break;
|
|
11848
|
+
case 'Home':
|
|
11849
|
+
event.preventDefault();
|
|
11850
|
+
nextIndex = this.findNextEnabledOption(-1);
|
|
11851
|
+
break;
|
|
11852
|
+
case 'End':
|
|
11853
|
+
event.preventDefault();
|
|
11854
|
+
nextIndex = this.findPreviousEnabledOption(optionsArray.length);
|
|
11855
|
+
break;
|
|
11856
|
+
default:
|
|
11857
|
+
return;
|
|
11858
|
+
}
|
|
11859
|
+
if (nextIndex !== currentIndex && nextIndex !== -1) {
|
|
11860
|
+
this.onSegmentClick(optionsArray[nextIndex]);
|
|
11861
|
+
this.focusSegment(nextIndex);
|
|
11862
|
+
}
|
|
11863
|
+
}
|
|
11864
|
+
findNextEnabledOption(startIndex) {
|
|
11865
|
+
const optionsArray = this.options();
|
|
11866
|
+
for (let i = startIndex + 1; i < optionsArray.length; i++) {
|
|
11867
|
+
if (!optionsArray[i].disabled)
|
|
11868
|
+
return i;
|
|
11869
|
+
}
|
|
11870
|
+
return startIndex === -1 ? 0 : startIndex;
|
|
11871
|
+
}
|
|
11872
|
+
findPreviousEnabledOption(startIndex) {
|
|
11873
|
+
const optionsArray = this.options();
|
|
11874
|
+
for (let i = startIndex - 1; i >= 0; i--) {
|
|
11875
|
+
if (!optionsArray[i].disabled)
|
|
11876
|
+
return i;
|
|
11877
|
+
}
|
|
11878
|
+
return startIndex === optionsArray.length ? optionsArray.length - 1 : startIndex;
|
|
11879
|
+
}
|
|
11880
|
+
focusSegment(index) {
|
|
11881
|
+
setTimeout(() => {
|
|
11882
|
+
const segment = document.querySelector(`.ds-segmented-control__segment[data-index="${index}"]`);
|
|
11883
|
+
segment?.focus();
|
|
11884
|
+
}, 0);
|
|
11885
|
+
}
|
|
11886
|
+
// Track function for @for
|
|
11887
|
+
trackByValue(_index, option) {
|
|
11888
|
+
return option.value;
|
|
11889
|
+
}
|
|
11890
|
+
/**
|
|
11891
|
+
* Parse l'icône depuis le format string vers le format FontAwesome
|
|
11892
|
+
* @param iconName - Nom de l'icône (ex: 'fas-list', 'list', 'fa-solid fa-list')
|
|
11893
|
+
* @returns Tuple [prefix, iconName] pour FontAwesome
|
|
11894
|
+
*/
|
|
11895
|
+
parseIcon(iconName) {
|
|
11896
|
+
// Format: 'fas-list' ou 'far-check'
|
|
11897
|
+
if (iconName.includes('-')) {
|
|
11898
|
+
const parts = iconName.split('-');
|
|
11899
|
+
if (parts[0] === 'fas' || parts[0] === 'far' || parts[0] === 'fab') {
|
|
11900
|
+
return [parts[0], parts.slice(1).join('-')];
|
|
11901
|
+
}
|
|
11902
|
+
}
|
|
11903
|
+
// Par défaut, utiliser 'fas' comme préfixe
|
|
11904
|
+
return ['fas', iconName];
|
|
11905
|
+
}
|
|
11906
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsSegmentedControl, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11907
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsSegmentedControl, isStandalone: true, selector: "ds-segmented-control", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown": "onKeydown($event)" } }, providers: [
|
|
11908
|
+
{
|
|
11909
|
+
provide: NG_VALUE_ACCESSOR,
|
|
11910
|
+
useExisting: forwardRef(() => DsSegmentedControl),
|
|
11911
|
+
multi: true,
|
|
11912
|
+
},
|
|
11913
|
+
], ngImport: i0, template: "<div\n [ngClass]=\"containerClasses()\"\n role=\"radiogroup\"\n [attr.aria-disabled]=\"isDisabled()\"\n>\n @for (option of options(); track trackByValue($index, option)) {\n <button\n type=\"button\"\n role=\"radio\"\n [ngClass]=\"getSegmentClasses(option)\"\n [attr.data-index]=\"$index\"\n [attr.aria-checked]=\"isOptionSelected(option)\"\n [attr.aria-disabled]=\"isOptionDisabled(option)\"\n [disabled]=\"isOptionDisabled(option)\"\n [tabindex]=\"isOptionSelected(option) ? 0 : -1\"\n (click)=\"onSegmentClick(option)\"\n >\n @if (option.icon) {\n <fa-icon\n class=\"ds-segmented-control__icon\"\n [icon]=\"parseIcon(option.icon)\"\n />\n }\n <span class=\"ds-segmented-control__label\">{{ option.label }}</span>\n </button>\n }\n</div>\n", styles: [".ds-segmented-control{display:inline-flex;background:var(--segmented-bg);border-radius:var(--segmented-border-radius);padding:var(--segmented-gap);gap:var(--segmented-gap);box-shadow:inset 0 0 0 1px var(--segmented-border-color)}.ds-segmented-control--horizontal{flex-direction:row}.ds-segmented-control--vertical{flex-direction:column}.ds-segmented-control--full-width{display:flex;width:100%}.ds-segmented-control--full-width .ds-segmented-control__segment{flex:1}.ds-segmented-control--disabled{opacity:.5;cursor:not-allowed}.ds-segmented-control--sm .ds-segmented-control__segment{height:var(--segmented-height-sm);padding:0 var(--segmented-padding-sm);font-size:var(--segmented-font-size-sm);border-radius:calc(var(--segmented-border-radius) - var(--segmented-gap))}.ds-segmented-control--sm .ds-segmented-control__icon{font-size:var(--segmented-icon-size-sm)}.ds-segmented-control--md .ds-segmented-control__segment{height:var(--segmented-height-md);padding:0 var(--segmented-padding-md);font-size:var(--segmented-font-size-md);border-radius:calc(var(--segmented-border-radius) - var(--segmented-gap))}.ds-segmented-control--md .ds-segmented-control__icon{font-size:var(--segmented-icon-size-md)}.ds-segmented-control--lg .ds-segmented-control__segment{height:var(--segmented-height-lg);padding:0 var(--segmented-padding-lg);font-size:var(--segmented-font-size-lg);border-radius:calc(var(--segmented-border-radius) - var(--segmented-gap))}.ds-segmented-control--lg .ds-segmented-control__icon{font-size:var(--segmented-icon-size-lg)}.ds-segmented-control__segment{display:inline-flex;align-items:center;justify-content:center;gap:var(--segmented-segment-gap);border:none;background:transparent;color:var(--segmented-text);font-weight:500;cursor:pointer;transition:all .2s ease;white-space:nowrap;-webkit-user-select:none;user-select:none}.ds-segmented-control__segment:hover:not(.ds-segmented-control__segment--disabled):not(.ds-segmented-control__segment--active){background:var(--segmented-hover-bg)}.ds-segmented-control__segment:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.ds-segmented-control__segment--active{background:var(--segmented-active-bg);color:var(--segmented-active-text);box-shadow:var(--segmented-active-shadow);font-weight:600}.ds-segmented-control__segment--disabled{cursor:not-allowed;opacity:.4}.ds-segmented-control__icon{display:inline-flex;flex-shrink:0}.ds-segmented-control__label{display:inline-flex}.ds-segmented-control--primary .ds-segmented-control__segment--active{background:var(--segmented-active-bg-primary);color:var(--segmented-active-text-primary)}.ds-segmented-control--neutral .ds-segmented-control__segment--active{background:var(--segmented-active-bg-neutral);color:var(--segmented-active-text-neutral)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i1$1.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"], outputs: ["iconChange", "titleChange", "animationChange", "maskChange", "flipChange", "sizeChange", "pullChange", "borderChange", "inverseChange", "symbolChange", "rotateChange", "fixedWidthChange", "transformChange", "a11yRoleChange"] }] });
|
|
11914
|
+
}
|
|
11915
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsSegmentedControl, decorators: [{
|
|
11916
|
+
type: Component,
|
|
11917
|
+
args: [{ selector: 'ds-segmented-control', standalone: true, imports: [CommonModule, FontAwesomeModule], providers: [
|
|
11918
|
+
{
|
|
11919
|
+
provide: NG_VALUE_ACCESSOR,
|
|
11920
|
+
useExisting: forwardRef(() => DsSegmentedControl),
|
|
11921
|
+
multi: true,
|
|
11922
|
+
},
|
|
11923
|
+
], template: "<div\n [ngClass]=\"containerClasses()\"\n role=\"radiogroup\"\n [attr.aria-disabled]=\"isDisabled()\"\n>\n @for (option of options(); track trackByValue($index, option)) {\n <button\n type=\"button\"\n role=\"radio\"\n [ngClass]=\"getSegmentClasses(option)\"\n [attr.data-index]=\"$index\"\n [attr.aria-checked]=\"isOptionSelected(option)\"\n [attr.aria-disabled]=\"isOptionDisabled(option)\"\n [disabled]=\"isOptionDisabled(option)\"\n [tabindex]=\"isOptionSelected(option) ? 0 : -1\"\n (click)=\"onSegmentClick(option)\"\n >\n @if (option.icon) {\n <fa-icon\n class=\"ds-segmented-control__icon\"\n [icon]=\"parseIcon(option.icon)\"\n />\n }\n <span class=\"ds-segmented-control__label\">{{ option.label }}</span>\n </button>\n }\n</div>\n", styles: [".ds-segmented-control{display:inline-flex;background:var(--segmented-bg);border-radius:var(--segmented-border-radius);padding:var(--segmented-gap);gap:var(--segmented-gap);box-shadow:inset 0 0 0 1px var(--segmented-border-color)}.ds-segmented-control--horizontal{flex-direction:row}.ds-segmented-control--vertical{flex-direction:column}.ds-segmented-control--full-width{display:flex;width:100%}.ds-segmented-control--full-width .ds-segmented-control__segment{flex:1}.ds-segmented-control--disabled{opacity:.5;cursor:not-allowed}.ds-segmented-control--sm .ds-segmented-control__segment{height:var(--segmented-height-sm);padding:0 var(--segmented-padding-sm);font-size:var(--segmented-font-size-sm);border-radius:calc(var(--segmented-border-radius) - var(--segmented-gap))}.ds-segmented-control--sm .ds-segmented-control__icon{font-size:var(--segmented-icon-size-sm)}.ds-segmented-control--md .ds-segmented-control__segment{height:var(--segmented-height-md);padding:0 var(--segmented-padding-md);font-size:var(--segmented-font-size-md);border-radius:calc(var(--segmented-border-radius) - var(--segmented-gap))}.ds-segmented-control--md .ds-segmented-control__icon{font-size:var(--segmented-icon-size-md)}.ds-segmented-control--lg .ds-segmented-control__segment{height:var(--segmented-height-lg);padding:0 var(--segmented-padding-lg);font-size:var(--segmented-font-size-lg);border-radius:calc(var(--segmented-border-radius) - var(--segmented-gap))}.ds-segmented-control--lg .ds-segmented-control__icon{font-size:var(--segmented-icon-size-lg)}.ds-segmented-control__segment{display:inline-flex;align-items:center;justify-content:center;gap:var(--segmented-segment-gap);border:none;background:transparent;color:var(--segmented-text);font-weight:500;cursor:pointer;transition:all .2s ease;white-space:nowrap;-webkit-user-select:none;user-select:none}.ds-segmented-control__segment:hover:not(.ds-segmented-control__segment--disabled):not(.ds-segmented-control__segment--active){background:var(--segmented-hover-bg)}.ds-segmented-control__segment:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.ds-segmented-control__segment--active{background:var(--segmented-active-bg);color:var(--segmented-active-text);box-shadow:var(--segmented-active-shadow);font-weight:600}.ds-segmented-control__segment--disabled{cursor:not-allowed;opacity:.4}.ds-segmented-control__icon{display:inline-flex;flex-shrink:0}.ds-segmented-control__label{display:inline-flex}.ds-segmented-control--primary .ds-segmented-control__segment--active{background:var(--segmented-active-bg-primary);color:var(--segmented-active-text-primary)}.ds-segmented-control--neutral .ds-segmented-control__segment--active{background:var(--segmented-active-bg-neutral);color:var(--segmented-active-text-neutral)}\n"] }]
|
|
11924
|
+
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], onKeydown: [{
|
|
11925
|
+
type: HostListener,
|
|
11926
|
+
args: ['keydown', ['$event']]
|
|
11927
|
+
}] } });
|
|
11928
|
+
|
|
11929
|
+
class DsColorPickerPanelComponent {
|
|
11930
|
+
spectrumCanvas;
|
|
11931
|
+
// Config (set by parent)
|
|
11932
|
+
value = '';
|
|
11933
|
+
showAlpha = false;
|
|
11934
|
+
presetColors = [];
|
|
11935
|
+
recentColors = [];
|
|
11936
|
+
showRecentColors = false;
|
|
11937
|
+
format = 'hex';
|
|
11938
|
+
// Outputs
|
|
11939
|
+
colorSelected = output();
|
|
11940
|
+
closed = output();
|
|
11941
|
+
// Icons
|
|
11942
|
+
checkIcon = faCheck;
|
|
11943
|
+
// State
|
|
11944
|
+
hue = signal(0, ...(ngDevMode ? [{ debugName: "hue" }] : []));
|
|
11945
|
+
saturation = signal(100, ...(ngDevMode ? [{ debugName: "saturation" }] : []));
|
|
11946
|
+
lightness = signal(50, ...(ngDevMode ? [{ debugName: "lightness" }] : []));
|
|
11947
|
+
alpha = signal(1, ...(ngDevMode ? [{ debugName: "alpha" }] : []));
|
|
11948
|
+
cursorX = signal(null, ...(ngDevMode ? [{ debugName: "cursorX" }] : []));
|
|
11949
|
+
cursorY = signal(null, ...(ngDevMode ? [{ debugName: "cursorY" }] : []));
|
|
11950
|
+
isDragging = signal(false, ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
|
|
11951
|
+
// Computed
|
|
11952
|
+
rgb = computed(() => this.hslToRGB(this.hue(), this.saturation(), this.lightness()), ...(ngDevMode ? [{ debugName: "rgb" }] : []));
|
|
11953
|
+
hexValue = computed(() => {
|
|
11954
|
+
const rgb = this.rgb();
|
|
11955
|
+
const r = rgb.r.toString(16).padStart(2, '0');
|
|
11956
|
+
const g = rgb.g.toString(16).padStart(2, '0');
|
|
11957
|
+
const b = rgb.b.toString(16).padStart(2, '0');
|
|
11958
|
+
return `#${r}${g}${b}`;
|
|
11959
|
+
}, ...(ngDevMode ? [{ debugName: "hexValue" }] : []));
|
|
11960
|
+
currentColor = computed(() => {
|
|
11961
|
+
if (this.showAlpha && this.alpha() < 1) {
|
|
11962
|
+
const rgb = this.rgb();
|
|
11963
|
+
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${this.alpha()})`;
|
|
11964
|
+
}
|
|
11965
|
+
return this.hexValue();
|
|
11966
|
+
}, ...(ngDevMode ? [{ debugName: "currentColor" }] : []));
|
|
11967
|
+
constructor() {
|
|
11968
|
+
// Observer les changements de couleur
|
|
11969
|
+
effect(() => {
|
|
11970
|
+
const color = this.currentColor();
|
|
11971
|
+
if (color !== this.value) {
|
|
11972
|
+
this.colorSelected.emit(color);
|
|
11973
|
+
}
|
|
11974
|
+
});
|
|
11975
|
+
}
|
|
11976
|
+
ngAfterViewInit() {
|
|
11977
|
+
this.initializeFromValue();
|
|
11978
|
+
this.renderSpectrum();
|
|
11979
|
+
}
|
|
11980
|
+
initializeFromValue() {
|
|
11981
|
+
if (!this.value) {
|
|
11982
|
+
this.updateCursor();
|
|
11983
|
+
return;
|
|
11984
|
+
}
|
|
11985
|
+
const rgb = this.parseColor(this.value);
|
|
11986
|
+
if (rgb) {
|
|
11987
|
+
const hsl = this.rgbToHSL(rgb.r, rgb.g, rgb.b);
|
|
11988
|
+
this.hue.set(hsl.h);
|
|
11989
|
+
this.saturation.set(hsl.s);
|
|
11990
|
+
this.lightness.set(hsl.l);
|
|
11991
|
+
if (rgb.a !== undefined) {
|
|
11992
|
+
this.alpha.set(rgb.a);
|
|
11993
|
+
}
|
|
11994
|
+
this.updateCursor();
|
|
11995
|
+
}
|
|
11996
|
+
}
|
|
11997
|
+
renderSpectrum() {
|
|
11998
|
+
if (!this.spectrumCanvas)
|
|
11999
|
+
return;
|
|
12000
|
+
const canvas = this.spectrumCanvas.nativeElement;
|
|
12001
|
+
const ctx = canvas.getContext('2d');
|
|
12002
|
+
if (!ctx)
|
|
12003
|
+
return;
|
|
12004
|
+
const width = canvas.width;
|
|
12005
|
+
const height = canvas.height;
|
|
12006
|
+
// Gradient de saturation (horizontal)
|
|
12007
|
+
const satGradient = ctx.createLinearGradient(0, 0, width, 0);
|
|
12008
|
+
satGradient.addColorStop(0, 'white');
|
|
12009
|
+
satGradient.addColorStop(1, `hsl(${this.hue()}, 100%, 50%)`);
|
|
12010
|
+
ctx.fillStyle = satGradient;
|
|
12011
|
+
ctx.fillRect(0, 0, width, height);
|
|
12012
|
+
// Gradient de luminosité (vertical)
|
|
12013
|
+
const lightGradient = ctx.createLinearGradient(0, 0, 0, height);
|
|
12014
|
+
lightGradient.addColorStop(0, 'transparent');
|
|
12015
|
+
lightGradient.addColorStop(1, 'black');
|
|
12016
|
+
ctx.fillStyle = lightGradient;
|
|
12017
|
+
ctx.fillRect(0, 0, width, height);
|
|
12018
|
+
}
|
|
12019
|
+
updateCursor() {
|
|
12020
|
+
if (!this.spectrumCanvas)
|
|
12021
|
+
return;
|
|
12022
|
+
const canvas = this.spectrumCanvas.nativeElement;
|
|
12023
|
+
const x = (this.saturation() / 100) * canvas.width;
|
|
12024
|
+
const y = ((100 - this.lightness()) / 100) * canvas.height;
|
|
12025
|
+
this.cursorX.set(x);
|
|
12026
|
+
this.cursorY.set(y);
|
|
12027
|
+
}
|
|
12028
|
+
onHueChange(event) {
|
|
12029
|
+
const target = event.target;
|
|
12030
|
+
this.hue.set(parseInt(target.value, 10));
|
|
12031
|
+
this.renderSpectrum();
|
|
12032
|
+
}
|
|
12033
|
+
onAlphaChange(event) {
|
|
12034
|
+
const target = event.target;
|
|
12035
|
+
this.alpha.set(parseInt(target.value, 10) / 100);
|
|
12036
|
+
}
|
|
12037
|
+
onSpectrumMouseDown(event) {
|
|
12038
|
+
this.isDragging.set(true);
|
|
12039
|
+
this.updateColorFromSpectrum(event);
|
|
12040
|
+
}
|
|
12041
|
+
onSpectrumMouseMove(event) {
|
|
12042
|
+
if (this.isDragging()) {
|
|
12043
|
+
this.updateColorFromSpectrum(event);
|
|
12044
|
+
}
|
|
12045
|
+
}
|
|
12046
|
+
onSpectrumMouseUp() {
|
|
12047
|
+
this.isDragging.set(false);
|
|
12048
|
+
}
|
|
12049
|
+
updateColorFromSpectrum(event) {
|
|
12050
|
+
if (!this.spectrumCanvas)
|
|
12051
|
+
return;
|
|
12052
|
+
const canvas = this.spectrumCanvas.nativeElement;
|
|
12053
|
+
const rect = canvas.getBoundingClientRect();
|
|
12054
|
+
const x = Math.max(0, Math.min(event.clientX - rect.left, canvas.width));
|
|
12055
|
+
const y = Math.max(0, Math.min(event.clientY - rect.top, canvas.height));
|
|
12056
|
+
const saturation = (x / canvas.width) * 100;
|
|
12057
|
+
const lightness = 100 - (y / canvas.height) * 100;
|
|
12058
|
+
this.saturation.set(Math.round(saturation));
|
|
12059
|
+
this.lightness.set(Math.round(lightness));
|
|
12060
|
+
this.cursorX.set(x);
|
|
12061
|
+
this.cursorY.set(y);
|
|
12062
|
+
}
|
|
12063
|
+
onHexInput(event) {
|
|
12064
|
+
const target = event.target;
|
|
12065
|
+
const hex = target.value;
|
|
12066
|
+
if (!hex.startsWith('#')) {
|
|
12067
|
+
target.value = '#' + hex;
|
|
12068
|
+
return;
|
|
12069
|
+
}
|
|
12070
|
+
const rgb = this.parseColor(hex);
|
|
12071
|
+
if (rgb) {
|
|
12072
|
+
const hsl = this.rgbToHSL(rgb.r, rgb.g, rgb.b);
|
|
12073
|
+
this.hue.set(hsl.h);
|
|
12074
|
+
this.saturation.set(hsl.s);
|
|
12075
|
+
this.lightness.set(hsl.l);
|
|
12076
|
+
this.renderSpectrum();
|
|
12077
|
+
this.updateCursor();
|
|
12078
|
+
}
|
|
12079
|
+
}
|
|
12080
|
+
onRGBInput(channel, event) {
|
|
12081
|
+
const target = event.target;
|
|
12082
|
+
const value = parseInt(target.value, 10);
|
|
12083
|
+
if (isNaN(value) || value < 0 || value > 255)
|
|
12084
|
+
return;
|
|
12085
|
+
const currentRGB = this.rgb();
|
|
12086
|
+
const newRGB = { ...currentRGB, [channel]: value };
|
|
12087
|
+
const hsl = this.rgbToHSL(newRGB.r, newRGB.g, newRGB.b);
|
|
12088
|
+
this.hue.set(hsl.h);
|
|
12089
|
+
this.saturation.set(hsl.s);
|
|
12090
|
+
this.lightness.set(hsl.l);
|
|
12091
|
+
this.renderSpectrum();
|
|
12092
|
+
this.updateCursor();
|
|
12093
|
+
}
|
|
12094
|
+
onAlphaInputManual(event) {
|
|
12095
|
+
const target = event.target;
|
|
12096
|
+
const value = parseFloat(target.value);
|
|
12097
|
+
if (isNaN(value) || value < 0 || value > 1)
|
|
12098
|
+
return;
|
|
12099
|
+
this.alpha.set(value);
|
|
12100
|
+
}
|
|
12101
|
+
selectPreset(color) {
|
|
12102
|
+
const rgb = this.parseColor(color);
|
|
12103
|
+
if (rgb) {
|
|
12104
|
+
const hsl = this.rgbToHSL(rgb.r, rgb.g, rgb.b);
|
|
12105
|
+
this.hue.set(hsl.h);
|
|
12106
|
+
this.saturation.set(hsl.s);
|
|
12107
|
+
this.lightness.set(hsl.l);
|
|
12108
|
+
if (rgb.a !== undefined) {
|
|
12109
|
+
this.alpha.set(rgb.a);
|
|
12110
|
+
}
|
|
12111
|
+
this.renderSpectrum();
|
|
12112
|
+
this.updateCursor();
|
|
12113
|
+
}
|
|
12114
|
+
}
|
|
12115
|
+
// === Conversions de couleurs ===
|
|
12116
|
+
hslToRGB(h, s, l) {
|
|
12117
|
+
h = h / 360;
|
|
12118
|
+
s = s / 100;
|
|
12119
|
+
l = l / 100;
|
|
12120
|
+
let r, g, b;
|
|
12121
|
+
if (s === 0) {
|
|
12122
|
+
r = g = b = l;
|
|
12123
|
+
}
|
|
12124
|
+
else {
|
|
12125
|
+
const hue2rgb = (p, q, t) => {
|
|
12126
|
+
if (t < 0)
|
|
12127
|
+
t += 1;
|
|
12128
|
+
if (t > 1)
|
|
12129
|
+
t -= 1;
|
|
12130
|
+
if (t < 1 / 6)
|
|
12131
|
+
return p + (q - p) * 6 * t;
|
|
12132
|
+
if (t < 1 / 2)
|
|
12133
|
+
return q;
|
|
12134
|
+
if (t < 2 / 3)
|
|
12135
|
+
return p + (q - p) * (2 / 3 - t) * 6;
|
|
12136
|
+
return p;
|
|
12137
|
+
};
|
|
12138
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
12139
|
+
const p = 2 * l - q;
|
|
12140
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
12141
|
+
g = hue2rgb(p, q, h);
|
|
12142
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
12143
|
+
}
|
|
12144
|
+
return {
|
|
12145
|
+
r: Math.round(r * 255),
|
|
12146
|
+
g: Math.round(g * 255),
|
|
12147
|
+
b: Math.round(b * 255),
|
|
12148
|
+
};
|
|
12149
|
+
}
|
|
12150
|
+
rgbToHSL(r, g, b) {
|
|
12151
|
+
r /= 255;
|
|
12152
|
+
g /= 255;
|
|
12153
|
+
b /= 255;
|
|
12154
|
+
const max = Math.max(r, g, b);
|
|
12155
|
+
const min = Math.min(r, g, b);
|
|
12156
|
+
let h = 0;
|
|
12157
|
+
let s = 0;
|
|
12158
|
+
const l = (max + min) / 2;
|
|
12159
|
+
if (max !== min) {
|
|
12160
|
+
const d = max - min;
|
|
12161
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
12162
|
+
switch (max) {
|
|
12163
|
+
case r:
|
|
12164
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
12165
|
+
break;
|
|
12166
|
+
case g:
|
|
12167
|
+
h = ((b - r) / d + 2) / 6;
|
|
12168
|
+
break;
|
|
12169
|
+
case b:
|
|
12170
|
+
h = ((r - g) / d + 4) / 6;
|
|
12171
|
+
break;
|
|
12172
|
+
}
|
|
12173
|
+
}
|
|
12174
|
+
return {
|
|
12175
|
+
h: Math.round(h * 360),
|
|
12176
|
+
s: Math.round(s * 100),
|
|
12177
|
+
l: Math.round(l * 100),
|
|
12178
|
+
};
|
|
12179
|
+
}
|
|
12180
|
+
parseColor(color) {
|
|
12181
|
+
// Parse HEX
|
|
12182
|
+
if (color.startsWith('#')) {
|
|
12183
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(color);
|
|
12184
|
+
if (!result)
|
|
12185
|
+
return null;
|
|
12186
|
+
return {
|
|
12187
|
+
r: parseInt(result[1], 16),
|
|
12188
|
+
g: parseInt(result[2], 16),
|
|
12189
|
+
b: parseInt(result[3], 16),
|
|
12190
|
+
a: result[4] ? parseInt(result[4], 16) / 255 : undefined,
|
|
12191
|
+
};
|
|
12192
|
+
}
|
|
12193
|
+
// Parse RGB/RGBA
|
|
12194
|
+
if (color.startsWith('rgb')) {
|
|
12195
|
+
const match = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
|
|
12196
|
+
if (!match)
|
|
12197
|
+
return null;
|
|
12198
|
+
return {
|
|
12199
|
+
r: parseInt(match[1], 10),
|
|
12200
|
+
g: parseInt(match[2], 10),
|
|
12201
|
+
b: parseInt(match[3], 10),
|
|
12202
|
+
a: match[4] ? parseFloat(match[4]) : undefined,
|
|
12203
|
+
};
|
|
12204
|
+
}
|
|
12205
|
+
return null;
|
|
12206
|
+
}
|
|
12207
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsColorPickerPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12208
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsColorPickerPanelComponent, isStandalone: true, selector: "ds-color-picker-panel", outputs: { colorSelected: "colorSelected", closed: "closed" }, viewQueries: [{ propertyName: "spectrumCanvas", first: true, predicate: ["spectrumCanvas"], descendants: true }], ngImport: i0, template: `
|
|
12209
|
+
<div class="ds-color-picker-panel" role="dialog" aria-label="Color picker">
|
|
12210
|
+
<!-- Spectre de couleurs -->
|
|
12211
|
+
<div class="ds-color-picker-panel__spectrum">
|
|
12212
|
+
<canvas
|
|
12213
|
+
#spectrumCanvas
|
|
12214
|
+
class="ds-color-picker-panel__spectrum-canvas"
|
|
12215
|
+
width="280"
|
|
12216
|
+
height="180"
|
|
12217
|
+
(mousedown)="onSpectrumMouseDown($event)"
|
|
12218
|
+
(mousemove)="onSpectrumMouseMove($event)"
|
|
12219
|
+
(mouseup)="onSpectrumMouseUp()"
|
|
12220
|
+
(mouseleave)="onSpectrumMouseUp()">
|
|
12221
|
+
</canvas>
|
|
12222
|
+
|
|
12223
|
+
<!-- Curseur de sélection -->
|
|
12224
|
+
@if (cursorX() !== null && cursorY() !== null) {
|
|
12225
|
+
<div
|
|
12226
|
+
class="ds-color-picker-panel__cursor"
|
|
12227
|
+
[style.left.px]="cursorX()"
|
|
12228
|
+
[style.top.px]="cursorY()">
|
|
12229
|
+
</div>
|
|
12230
|
+
}
|
|
12231
|
+
</div>
|
|
12232
|
+
|
|
12233
|
+
<!-- Slider de teinte -->
|
|
12234
|
+
<div class="ds-color-picker-panel__hue-slider">
|
|
12235
|
+
<input
|
|
12236
|
+
type="range"
|
|
12237
|
+
class="ds-color-picker-panel__slider"
|
|
12238
|
+
min="0"
|
|
12239
|
+
max="360"
|
|
12240
|
+
step="1"
|
|
12241
|
+
[value]="hue()"
|
|
12242
|
+
(input)="onHueChange($event)"
|
|
12243
|
+
aria-label="Hue" />
|
|
12244
|
+
</div>
|
|
12245
|
+
|
|
12246
|
+
<!-- Slider alpha (optionnel) -->
|
|
12247
|
+
@if (showAlpha) {
|
|
12248
|
+
<div class="ds-color-picker-panel__alpha-slider">
|
|
12249
|
+
<div class="ds-color-picker-panel__alpha-bg"></div>
|
|
12250
|
+
<input
|
|
12251
|
+
type="range"
|
|
12252
|
+
class="ds-color-picker-panel__slider ds-color-picker-panel__slider--alpha"
|
|
12253
|
+
min="0"
|
|
12254
|
+
max="100"
|
|
12255
|
+
step="1"
|
|
12256
|
+
[value]="alpha() * 100"
|
|
12257
|
+
(input)="onAlphaChange($event)"
|
|
12258
|
+
aria-label="Alpha" />
|
|
12259
|
+
</div>
|
|
12260
|
+
}
|
|
12261
|
+
|
|
12262
|
+
<!-- Inputs manuels -->
|
|
12263
|
+
<div class="ds-color-picker-panel__inputs">
|
|
12264
|
+
@if (format === 'hex') {
|
|
12265
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12266
|
+
<label class="ds-color-picker-panel__label">HEX</label>
|
|
12267
|
+
<input
|
|
12268
|
+
type="text"
|
|
12269
|
+
class="ds-color-picker-panel__input"
|
|
12270
|
+
[value]="hexValue()"
|
|
12271
|
+
(input)="onHexInput($event)"
|
|
12272
|
+
maxlength="7"
|
|
12273
|
+
placeholder="#000000" />
|
|
12274
|
+
</div>
|
|
12275
|
+
}
|
|
12276
|
+
|
|
12277
|
+
@if (format === 'rgb') {
|
|
12278
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12279
|
+
<label class="ds-color-picker-panel__label">R</label>
|
|
12280
|
+
<input
|
|
12281
|
+
type="number"
|
|
12282
|
+
class="ds-color-picker-panel__input"
|
|
12283
|
+
min="0"
|
|
12284
|
+
max="255"
|
|
12285
|
+
[value]="rgb().r"
|
|
12286
|
+
(input)="onRGBInput('r', $event)" />
|
|
12287
|
+
</div>
|
|
12288
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12289
|
+
<label class="ds-color-picker-panel__label">G</label>
|
|
12290
|
+
<input
|
|
12291
|
+
type="number"
|
|
12292
|
+
class="ds-color-picker-panel__input"
|
|
12293
|
+
min="0"
|
|
12294
|
+
max="255"
|
|
12295
|
+
[value]="rgb().g"
|
|
12296
|
+
(input)="onRGBInput('g', $event)" />
|
|
12297
|
+
</div>
|
|
12298
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12299
|
+
<label class="ds-color-picker-panel__label">B</label>
|
|
12300
|
+
<input
|
|
12301
|
+
type="number"
|
|
12302
|
+
class="ds-color-picker-panel__input"
|
|
12303
|
+
min="0"
|
|
12304
|
+
max="255"
|
|
12305
|
+
[value]="rgb().b"
|
|
12306
|
+
(input)="onRGBInput('b', $event)" />
|
|
12307
|
+
</div>
|
|
12308
|
+
@if (showAlpha) {
|
|
12309
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12310
|
+
<label class="ds-color-picker-panel__label">A</label>
|
|
12311
|
+
<input
|
|
12312
|
+
type="number"
|
|
12313
|
+
class="ds-color-picker-panel__input"
|
|
12314
|
+
min="0"
|
|
12315
|
+
max="1"
|
|
12316
|
+
step="0.01"
|
|
12317
|
+
[value]="alpha()"
|
|
12318
|
+
(input)="onAlphaInputManual($event)" />
|
|
12319
|
+
</div>
|
|
12320
|
+
}
|
|
12321
|
+
}
|
|
12322
|
+
</div>
|
|
12323
|
+
|
|
12324
|
+
<!-- Couleurs prédéfinies -->
|
|
12325
|
+
@if (presetColors.length > 0) {
|
|
12326
|
+
<div class="ds-color-picker-panel__presets">
|
|
12327
|
+
<div class="ds-color-picker-panel__presets-label">Presets</div>
|
|
12328
|
+
<div class="ds-color-picker-panel__presets-grid">
|
|
12329
|
+
@for (color of presetColors; track color) {
|
|
12330
|
+
<button
|
|
12331
|
+
type="button"
|
|
12332
|
+
class="ds-color-picker-panel__preset"
|
|
12333
|
+
[style.background-color]="color"
|
|
12334
|
+
[class.ds-color-picker-panel__preset--selected]="color === value"
|
|
12335
|
+
(click)="selectPreset(color)"
|
|
12336
|
+
[attr.aria-label]="'Select ' + color">
|
|
12337
|
+
@if (color === value) {
|
|
12338
|
+
<fa-icon [icon]="checkIcon" class="ds-color-picker-panel__preset-check"></fa-icon>
|
|
12339
|
+
}
|
|
12340
|
+
</button>
|
|
12341
|
+
}
|
|
12342
|
+
</div>
|
|
12343
|
+
</div>
|
|
12344
|
+
}
|
|
12345
|
+
|
|
12346
|
+
<!-- Couleurs récentes -->
|
|
12347
|
+
@if (showRecentColors && recentColors.length > 0) {
|
|
12348
|
+
<div class="ds-color-picker-panel__recent">
|
|
12349
|
+
<div class="ds-color-picker-panel__recent-label">Recent</div>
|
|
12350
|
+
<div class="ds-color-picker-panel__recent-grid">
|
|
12351
|
+
@for (color of recentColors; track color) {
|
|
12352
|
+
<button
|
|
12353
|
+
type="button"
|
|
12354
|
+
class="ds-color-picker-panel__preset"
|
|
12355
|
+
[style.background-color]="color"
|
|
12356
|
+
[class.ds-color-picker-panel__preset--selected]="color === value"
|
|
12357
|
+
(click)="selectPreset(color)"
|
|
12358
|
+
[attr.aria-label]="'Select ' + color">
|
|
12359
|
+
@if (color === value) {
|
|
12360
|
+
<fa-icon [icon]="checkIcon" class="ds-color-picker-panel__preset-check"></fa-icon>
|
|
12361
|
+
}
|
|
12362
|
+
</button>
|
|
12363
|
+
}
|
|
12364
|
+
</div>
|
|
12365
|
+
</div>
|
|
12366
|
+
}
|
|
12367
|
+
</div>
|
|
12368
|
+
`, isInline: true, styles: [".ds-color-picker-panel{position:relative;display:flex;flex-direction:column;gap:var(--space-3);width:300px;padding:var(--space-4);background:var(--colorpicker-panel-bg, var(--background-main));border:1px solid var(--colorpicker-panel-border, var(--border-default));border-radius:var(--colorpicker-panel-radius, var(--radius-2));box-shadow:var(--colorpicker-panel-shadow, var(--shadow-3))}.ds-color-picker-panel__spectrum{position:relative;width:100%;height:180px;border-radius:var(--radius-1);overflow:hidden;cursor:crosshair;border:1px solid var(--border-default)}.ds-color-picker-panel__spectrum-canvas{display:block;width:100%;height:100%}.ds-color-picker-panel__cursor{position:absolute;width:16px;height:16px;border:2px solid white;border-radius:50%;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003;transform:translate(-50%,-50%);pointer-events:none}.ds-color-picker-panel__hue-slider,.ds-color-picker-panel__alpha-slider{position:relative;width:100%;height:12px;border-radius:var(--radius-1);overflow:hidden}.ds-color-picker-panel__hue-slider{background:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.ds-color-picker-panel__alpha-slider .ds-color-picker-panel__alpha-bg{position:absolute;inset:0;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:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.ds-color-picker-panel__slider{position:relative;width:100%;height:100%;-webkit-appearance:none;appearance:none;background:transparent;cursor:pointer;z-index:1}.ds-color-picker-panel__slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;border:2px solid white;border-radius:50%;background:transparent;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003;cursor:pointer}.ds-color-picker-panel__slider::-moz-range-thumb{width:16px;height:16px;border:2px solid white;border-radius:50%;background:transparent;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003;cursor:pointer}.ds-color-picker-panel__slider:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.ds-color-picker-panel__slider--alpha{background:linear-gradient(to right,transparent 0%,currentColor 100%)}.ds-color-picker-panel__inputs{display:flex;gap:var(--space-2)}.ds-color-picker-panel__input-group{display:flex;flex-direction:column;gap:var(--space-1);flex:1}.ds-color-picker-panel__label{font-size:var(--font-size-1);font-weight:600;color:var(--text-muted);text-transform:uppercase}.ds-color-picker-panel__input{width:100%;padding:var(--space-1) var(--space-2);background:var(--colorpicker-input-bg, var(--background-main));border:1px solid var(--colorpicker-input-border, var(--border-default));border-radius:var(--radius-1);color:var(--colorpicker-input-text, var(--text-default));font-size:var(--font-size-2);font-family:monospace;text-align:center;outline:none;transition:border-color var(--duration-fast, .15s) ease}.ds-color-picker-panel__input:focus{border-color:var(--color-primary)}.ds-color-picker-panel__input:hover:not(:focus){border-color:var(--border-strong)}.ds-color-picker-panel__input[type=number]{-moz-appearance:textfield}.ds-color-picker-panel__input[type=number]::-webkit-outer-spin-button,.ds-color-picker-panel__input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.ds-color-picker-panel__presets,.ds-color-picker-panel__recent{display:flex;flex-direction:column;gap:var(--space-2)}.ds-color-picker-panel__presets-label,.ds-color-picker-panel__recent-label{font-size:var(--font-size-2);font-weight:600;color:var(--text-muted)}.ds-color-picker-panel__presets-grid,.ds-color-picker-panel__recent-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:var(--space-2)}.ds-color-picker-panel__preset{position:relative;width:28px;height:28px;padding:0;background:currentColor;border:2px solid var(--colorpicker-preset-border, var(--border-default));border-radius:var(--radius-1);cursor:pointer;transition:transform var(--duration-fast, .15s) ease,border-color var(--duration-fast, .15s) ease;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:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.ds-color-picker-panel__preset:after{content:\"\";position:absolute;inset:0;background-color:currentColor;border-radius:inherit}.ds-color-picker-panel__preset:hover:not(:disabled){transform:scale(1.1);border-color:var(--color-primary)}.ds-color-picker-panel__preset:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.ds-color-picker-panel__preset--selected{border-color:var(--color-primary);border-width:3px}.ds-color-picker-panel__preset-check{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.5));font-size:var(--font-size-2);z-index:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i1$1.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"], outputs: ["iconChange", "titleChange", "animationChange", "maskChange", "flipChange", "sizeChange", "pullChange", "borderChange", "inverseChange", "symbolChange", "rotateChange", "fixedWidthChange", "transformChange", "a11yRoleChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
12369
|
+
}
|
|
12370
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsColorPickerPanelComponent, decorators: [{
|
|
12371
|
+
type: Component,
|
|
12372
|
+
args: [{ selector: 'ds-color-picker-panel', standalone: true, imports: [CommonModule, FormsModule, FontAwesomeModule], template: `
|
|
12373
|
+
<div class="ds-color-picker-panel" role="dialog" aria-label="Color picker">
|
|
12374
|
+
<!-- Spectre de couleurs -->
|
|
12375
|
+
<div class="ds-color-picker-panel__spectrum">
|
|
12376
|
+
<canvas
|
|
12377
|
+
#spectrumCanvas
|
|
12378
|
+
class="ds-color-picker-panel__spectrum-canvas"
|
|
12379
|
+
width="280"
|
|
12380
|
+
height="180"
|
|
12381
|
+
(mousedown)="onSpectrumMouseDown($event)"
|
|
12382
|
+
(mousemove)="onSpectrumMouseMove($event)"
|
|
12383
|
+
(mouseup)="onSpectrumMouseUp()"
|
|
12384
|
+
(mouseleave)="onSpectrumMouseUp()">
|
|
12385
|
+
</canvas>
|
|
12386
|
+
|
|
12387
|
+
<!-- Curseur de sélection -->
|
|
12388
|
+
@if (cursorX() !== null && cursorY() !== null) {
|
|
12389
|
+
<div
|
|
12390
|
+
class="ds-color-picker-panel__cursor"
|
|
12391
|
+
[style.left.px]="cursorX()"
|
|
12392
|
+
[style.top.px]="cursorY()">
|
|
12393
|
+
</div>
|
|
12394
|
+
}
|
|
12395
|
+
</div>
|
|
12396
|
+
|
|
12397
|
+
<!-- Slider de teinte -->
|
|
12398
|
+
<div class="ds-color-picker-panel__hue-slider">
|
|
12399
|
+
<input
|
|
12400
|
+
type="range"
|
|
12401
|
+
class="ds-color-picker-panel__slider"
|
|
12402
|
+
min="0"
|
|
12403
|
+
max="360"
|
|
12404
|
+
step="1"
|
|
12405
|
+
[value]="hue()"
|
|
12406
|
+
(input)="onHueChange($event)"
|
|
12407
|
+
aria-label="Hue" />
|
|
12408
|
+
</div>
|
|
12409
|
+
|
|
12410
|
+
<!-- Slider alpha (optionnel) -->
|
|
12411
|
+
@if (showAlpha) {
|
|
12412
|
+
<div class="ds-color-picker-panel__alpha-slider">
|
|
12413
|
+
<div class="ds-color-picker-panel__alpha-bg"></div>
|
|
12414
|
+
<input
|
|
12415
|
+
type="range"
|
|
12416
|
+
class="ds-color-picker-panel__slider ds-color-picker-panel__slider--alpha"
|
|
12417
|
+
min="0"
|
|
12418
|
+
max="100"
|
|
12419
|
+
step="1"
|
|
12420
|
+
[value]="alpha() * 100"
|
|
12421
|
+
(input)="onAlphaChange($event)"
|
|
12422
|
+
aria-label="Alpha" />
|
|
12423
|
+
</div>
|
|
12424
|
+
}
|
|
12425
|
+
|
|
12426
|
+
<!-- Inputs manuels -->
|
|
12427
|
+
<div class="ds-color-picker-panel__inputs">
|
|
12428
|
+
@if (format === 'hex') {
|
|
12429
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12430
|
+
<label class="ds-color-picker-panel__label">HEX</label>
|
|
12431
|
+
<input
|
|
12432
|
+
type="text"
|
|
12433
|
+
class="ds-color-picker-panel__input"
|
|
12434
|
+
[value]="hexValue()"
|
|
12435
|
+
(input)="onHexInput($event)"
|
|
12436
|
+
maxlength="7"
|
|
12437
|
+
placeholder="#000000" />
|
|
12438
|
+
</div>
|
|
12439
|
+
}
|
|
12440
|
+
|
|
12441
|
+
@if (format === 'rgb') {
|
|
12442
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12443
|
+
<label class="ds-color-picker-panel__label">R</label>
|
|
12444
|
+
<input
|
|
12445
|
+
type="number"
|
|
12446
|
+
class="ds-color-picker-panel__input"
|
|
12447
|
+
min="0"
|
|
12448
|
+
max="255"
|
|
12449
|
+
[value]="rgb().r"
|
|
12450
|
+
(input)="onRGBInput('r', $event)" />
|
|
12451
|
+
</div>
|
|
12452
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12453
|
+
<label class="ds-color-picker-panel__label">G</label>
|
|
12454
|
+
<input
|
|
12455
|
+
type="number"
|
|
12456
|
+
class="ds-color-picker-panel__input"
|
|
12457
|
+
min="0"
|
|
12458
|
+
max="255"
|
|
12459
|
+
[value]="rgb().g"
|
|
12460
|
+
(input)="onRGBInput('g', $event)" />
|
|
12461
|
+
</div>
|
|
12462
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12463
|
+
<label class="ds-color-picker-panel__label">B</label>
|
|
12464
|
+
<input
|
|
12465
|
+
type="number"
|
|
12466
|
+
class="ds-color-picker-panel__input"
|
|
12467
|
+
min="0"
|
|
12468
|
+
max="255"
|
|
12469
|
+
[value]="rgb().b"
|
|
12470
|
+
(input)="onRGBInput('b', $event)" />
|
|
12471
|
+
</div>
|
|
12472
|
+
@if (showAlpha) {
|
|
12473
|
+
<div class="ds-color-picker-panel__input-group">
|
|
12474
|
+
<label class="ds-color-picker-panel__label">A</label>
|
|
12475
|
+
<input
|
|
12476
|
+
type="number"
|
|
12477
|
+
class="ds-color-picker-panel__input"
|
|
12478
|
+
min="0"
|
|
12479
|
+
max="1"
|
|
12480
|
+
step="0.01"
|
|
12481
|
+
[value]="alpha()"
|
|
12482
|
+
(input)="onAlphaInputManual($event)" />
|
|
12483
|
+
</div>
|
|
12484
|
+
}
|
|
12485
|
+
}
|
|
12486
|
+
</div>
|
|
12487
|
+
|
|
12488
|
+
<!-- Couleurs prédéfinies -->
|
|
12489
|
+
@if (presetColors.length > 0) {
|
|
12490
|
+
<div class="ds-color-picker-panel__presets">
|
|
12491
|
+
<div class="ds-color-picker-panel__presets-label">Presets</div>
|
|
12492
|
+
<div class="ds-color-picker-panel__presets-grid">
|
|
12493
|
+
@for (color of presetColors; track color) {
|
|
12494
|
+
<button
|
|
12495
|
+
type="button"
|
|
12496
|
+
class="ds-color-picker-panel__preset"
|
|
12497
|
+
[style.background-color]="color"
|
|
12498
|
+
[class.ds-color-picker-panel__preset--selected]="color === value"
|
|
12499
|
+
(click)="selectPreset(color)"
|
|
12500
|
+
[attr.aria-label]="'Select ' + color">
|
|
12501
|
+
@if (color === value) {
|
|
12502
|
+
<fa-icon [icon]="checkIcon" class="ds-color-picker-panel__preset-check"></fa-icon>
|
|
12503
|
+
}
|
|
12504
|
+
</button>
|
|
12505
|
+
}
|
|
12506
|
+
</div>
|
|
12507
|
+
</div>
|
|
12508
|
+
}
|
|
12509
|
+
|
|
12510
|
+
<!-- Couleurs récentes -->
|
|
12511
|
+
@if (showRecentColors && recentColors.length > 0) {
|
|
12512
|
+
<div class="ds-color-picker-panel__recent">
|
|
12513
|
+
<div class="ds-color-picker-panel__recent-label">Recent</div>
|
|
12514
|
+
<div class="ds-color-picker-panel__recent-grid">
|
|
12515
|
+
@for (color of recentColors; track color) {
|
|
12516
|
+
<button
|
|
12517
|
+
type="button"
|
|
12518
|
+
class="ds-color-picker-panel__preset"
|
|
12519
|
+
[style.background-color]="color"
|
|
12520
|
+
[class.ds-color-picker-panel__preset--selected]="color === value"
|
|
12521
|
+
(click)="selectPreset(color)"
|
|
12522
|
+
[attr.aria-label]="'Select ' + color">
|
|
12523
|
+
@if (color === value) {
|
|
12524
|
+
<fa-icon [icon]="checkIcon" class="ds-color-picker-panel__preset-check"></fa-icon>
|
|
12525
|
+
}
|
|
12526
|
+
</button>
|
|
12527
|
+
}
|
|
12528
|
+
</div>
|
|
12529
|
+
</div>
|
|
12530
|
+
}
|
|
12531
|
+
</div>
|
|
12532
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".ds-color-picker-panel{position:relative;display:flex;flex-direction:column;gap:var(--space-3);width:300px;padding:var(--space-4);background:var(--colorpicker-panel-bg, var(--background-main));border:1px solid var(--colorpicker-panel-border, var(--border-default));border-radius:var(--colorpicker-panel-radius, var(--radius-2));box-shadow:var(--colorpicker-panel-shadow, var(--shadow-3))}.ds-color-picker-panel__spectrum{position:relative;width:100%;height:180px;border-radius:var(--radius-1);overflow:hidden;cursor:crosshair;border:1px solid var(--border-default)}.ds-color-picker-panel__spectrum-canvas{display:block;width:100%;height:100%}.ds-color-picker-panel__cursor{position:absolute;width:16px;height:16px;border:2px solid white;border-radius:50%;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003;transform:translate(-50%,-50%);pointer-events:none}.ds-color-picker-panel__hue-slider,.ds-color-picker-panel__alpha-slider{position:relative;width:100%;height:12px;border-radius:var(--radius-1);overflow:hidden}.ds-color-picker-panel__hue-slider{background:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.ds-color-picker-panel__alpha-slider .ds-color-picker-panel__alpha-bg{position:absolute;inset:0;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:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.ds-color-picker-panel__slider{position:relative;width:100%;height:100%;-webkit-appearance:none;appearance:none;background:transparent;cursor:pointer;z-index:1}.ds-color-picker-panel__slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:16px;height:16px;border:2px solid white;border-radius:50%;background:transparent;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003;cursor:pointer}.ds-color-picker-panel__slider::-moz-range-thumb{width:16px;height:16px;border:2px solid white;border-radius:50%;background:transparent;box-shadow:0 0 0 1px #0000004d,0 2px 4px #0003;cursor:pointer}.ds-color-picker-panel__slider:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.ds-color-picker-panel__slider--alpha{background:linear-gradient(to right,transparent 0%,currentColor 100%)}.ds-color-picker-panel__inputs{display:flex;gap:var(--space-2)}.ds-color-picker-panel__input-group{display:flex;flex-direction:column;gap:var(--space-1);flex:1}.ds-color-picker-panel__label{font-size:var(--font-size-1);font-weight:600;color:var(--text-muted);text-transform:uppercase}.ds-color-picker-panel__input{width:100%;padding:var(--space-1) var(--space-2);background:var(--colorpicker-input-bg, var(--background-main));border:1px solid var(--colorpicker-input-border, var(--border-default));border-radius:var(--radius-1);color:var(--colorpicker-input-text, var(--text-default));font-size:var(--font-size-2);font-family:monospace;text-align:center;outline:none;transition:border-color var(--duration-fast, .15s) ease}.ds-color-picker-panel__input:focus{border-color:var(--color-primary)}.ds-color-picker-panel__input:hover:not(:focus){border-color:var(--border-strong)}.ds-color-picker-panel__input[type=number]{-moz-appearance:textfield}.ds-color-picker-panel__input[type=number]::-webkit-outer-spin-button,.ds-color-picker-panel__input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.ds-color-picker-panel__presets,.ds-color-picker-panel__recent{display:flex;flex-direction:column;gap:var(--space-2)}.ds-color-picker-panel__presets-label,.ds-color-picker-panel__recent-label{font-size:var(--font-size-2);font-weight:600;color:var(--text-muted)}.ds-color-picker-panel__presets-grid,.ds-color-picker-panel__recent-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:var(--space-2)}.ds-color-picker-panel__preset{position:relative;width:28px;height:28px;padding:0;background:currentColor;border:2px solid var(--colorpicker-preset-border, var(--border-default));border-radius:var(--radius-1);cursor:pointer;transition:transform var(--duration-fast, .15s) ease,border-color var(--duration-fast, .15s) ease;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:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.ds-color-picker-panel__preset:after{content:\"\";position:absolute;inset:0;background-color:currentColor;border-radius:inherit}.ds-color-picker-panel__preset:hover:not(:disabled){transform:scale(1.1);border-color:var(--color-primary)}.ds-color-picker-panel__preset:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.ds-color-picker-panel__preset--selected{border-color:var(--color-primary);border-width:3px}.ds-color-picker-panel__preset-check{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;filter:drop-shadow(0 1px 2px rgba(0,0,0,.5));font-size:var(--font-size-2);z-index:1}\n"] }]
|
|
12533
|
+
}], ctorParameters: () => [], propDecorators: { spectrumCanvas: [{
|
|
12534
|
+
type: ViewChild,
|
|
12535
|
+
args: ['spectrumCanvas']
|
|
12536
|
+
}], colorSelected: [{ type: i0.Output, args: ["colorSelected"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
|
|
12537
|
+
|
|
12538
|
+
/**
|
|
12539
|
+
* DsColorPicker - Composant de sélection de couleur
|
|
12540
|
+
*
|
|
12541
|
+
* @description
|
|
12542
|
+
* Sélecteur de couleur avec palette prédéfinie, spectre de couleurs,
|
|
12543
|
+
* support RGB/HSL, alpha channel optionnel, et intégration formulaires.
|
|
12544
|
+
*
|
|
12545
|
+
* @example
|
|
12546
|
+
* ```html
|
|
12547
|
+
* <ds-color-picker
|
|
12548
|
+
* [value]="'#3b82f6'"
|
|
12549
|
+
* [showAlpha]="true"
|
|
12550
|
+
* (colorChange)="onColorChange($event)">
|
|
12551
|
+
* </ds-color-picker>
|
|
12552
|
+
* ```
|
|
12553
|
+
*/
|
|
12554
|
+
class DsColorPicker {
|
|
12555
|
+
overlay;
|
|
12556
|
+
elementRef;
|
|
12557
|
+
// Inputs
|
|
12558
|
+
value = input('', ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
12559
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
12560
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
12561
|
+
showAlpha = input(false, ...(ngDevMode ? [{ debugName: "showAlpha" }] : []));
|
|
12562
|
+
presetColors = input([], ...(ngDevMode ? [{ debugName: "presetColors" }] : []));
|
|
12563
|
+
format = input('hex', ...(ngDevMode ? [{ debugName: "format" }] : []));
|
|
12564
|
+
placeholder = input('Select color', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
12565
|
+
allowClear = input(true, ...(ngDevMode ? [{ debugName: "allowClear" }] : []));
|
|
12566
|
+
showRecentColors = input(true, ...(ngDevMode ? [{ debugName: "showRecentColors" }] : []));
|
|
12567
|
+
maxRecentColors = input(8, ...(ngDevMode ? [{ debugName: "maxRecentColors" }] : []));
|
|
12568
|
+
// Outputs
|
|
12569
|
+
colorChange = output();
|
|
12570
|
+
// Icons
|
|
12571
|
+
pickerIcon = faEyeDropper;
|
|
12572
|
+
clearIcon = faTimes;
|
|
12573
|
+
checkIcon = faCheck;
|
|
12574
|
+
// State
|
|
12575
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
12576
|
+
internalValue = signal('', ...(ngDevMode ? [{ debugName: "internalValue" }] : []));
|
|
12577
|
+
isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
|
|
12578
|
+
recentColors = signal([], ...(ngDevMode ? [{ debugName: "recentColors" }] : []));
|
|
12579
|
+
// Overlay
|
|
12580
|
+
overlayRef = null;
|
|
12581
|
+
// Computed
|
|
12582
|
+
containerClasses = computed(() => {
|
|
12583
|
+
const classes = ['ds-color-picker'];
|
|
12584
|
+
classes.push(`ds-color-picker--${this.size()}`);
|
|
12585
|
+
if (this.disabled())
|
|
12586
|
+
classes.push('ds-color-picker--disabled');
|
|
12587
|
+
if (this.isFocused())
|
|
12588
|
+
classes.push('ds-color-picker--focused');
|
|
12589
|
+
if (this.isOpen())
|
|
12590
|
+
classes.push('ds-color-picker--open');
|
|
12591
|
+
return classes.join(' ');
|
|
12592
|
+
}, ...(ngDevMode ? [{ debugName: "containerClasses" }] : []));
|
|
12593
|
+
displayValue = computed(() => {
|
|
12594
|
+
const val = this.internalValue();
|
|
12595
|
+
if (!val)
|
|
12596
|
+
return '';
|
|
12597
|
+
// Convertir selon le format demandé
|
|
12598
|
+
const format = this.format();
|
|
12599
|
+
if (format === 'hex') {
|
|
12600
|
+
return this.toHex(val);
|
|
12601
|
+
}
|
|
12602
|
+
else if (format === 'rgb') {
|
|
12603
|
+
return this.toRGB(val);
|
|
12604
|
+
}
|
|
12605
|
+
else if (format === 'hsl') {
|
|
12606
|
+
return this.toHSL(val);
|
|
12607
|
+
}
|
|
12608
|
+
return val;
|
|
12609
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
|
|
12610
|
+
previewColor = computed(() => {
|
|
12611
|
+
return this.internalValue() || 'transparent';
|
|
12612
|
+
}, ...(ngDevMode ? [{ debugName: "previewColor" }] : []));
|
|
12613
|
+
effectivePresets = computed(() => {
|
|
12614
|
+
const custom = this.presetColors();
|
|
12615
|
+
if (custom.length > 0)
|
|
12616
|
+
return custom;
|
|
12617
|
+
// Palette par défaut
|
|
12618
|
+
return [
|
|
12619
|
+
'#000000', '#ffffff', '#f87171', '#fb923c', '#fbbf24', '#facc15',
|
|
12620
|
+
'#a3e635', '#4ade80', '#34d399', '#2dd4bf', '#22d3ee', '#38bdf8',
|
|
12621
|
+
'#60a5fa', '#818cf8', '#a78bfa', '#c084fc', '#e879f9', '#f472b6',
|
|
12622
|
+
'#fb7185', '#f43f5e', '#ef4444', '#dc2626', '#b91c1c', '#991b1b',
|
|
12623
|
+
];
|
|
12624
|
+
}, ...(ngDevMode ? [{ debugName: "effectivePresets" }] : []));
|
|
12625
|
+
// ControlValueAccessor
|
|
12626
|
+
onChange = () => { };
|
|
12627
|
+
onTouched = () => { };
|
|
12628
|
+
constructor(overlay, elementRef) {
|
|
12629
|
+
this.overlay = overlay;
|
|
12630
|
+
this.elementRef = elementRef;
|
|
12631
|
+
// Sync external value with internal
|
|
12632
|
+
effect(() => {
|
|
12633
|
+
const val = this.value();
|
|
12634
|
+
if (val !== this.internalValue()) {
|
|
12635
|
+
this.internalValue.set(val);
|
|
12636
|
+
}
|
|
12637
|
+
});
|
|
12638
|
+
// Charger les couleurs récentes depuis localStorage
|
|
12639
|
+
this.loadRecentColors();
|
|
12640
|
+
}
|
|
12641
|
+
writeValue(value) {
|
|
12642
|
+
this.internalValue.set(value || '');
|
|
12643
|
+
}
|
|
12644
|
+
registerOnChange(fn) {
|
|
12645
|
+
this.onChange = fn;
|
|
12646
|
+
}
|
|
12647
|
+
registerOnTouched(fn) {
|
|
12648
|
+
this.onTouched = fn;
|
|
12649
|
+
}
|
|
12650
|
+
setDisabledState(isDisabled) {
|
|
12651
|
+
// Géré par input disabled
|
|
12652
|
+
}
|
|
12653
|
+
toggle() {
|
|
12654
|
+
if (this.disabled())
|
|
12655
|
+
return;
|
|
12656
|
+
if (this.isOpen()) {
|
|
12657
|
+
this.close();
|
|
12658
|
+
}
|
|
12659
|
+
else {
|
|
12660
|
+
this.open();
|
|
12661
|
+
}
|
|
12662
|
+
}
|
|
12663
|
+
open() {
|
|
12664
|
+
if (this.disabled() || this.isOpen())
|
|
12665
|
+
return;
|
|
12666
|
+
this.isOpen.set(true);
|
|
12667
|
+
this.createOverlay();
|
|
12668
|
+
}
|
|
12669
|
+
close() {
|
|
12670
|
+
if (!this.isOpen())
|
|
12671
|
+
return;
|
|
12672
|
+
this.isOpen.set(false);
|
|
12673
|
+
this.destroyOverlay();
|
|
12674
|
+
this.onTouched();
|
|
12675
|
+
}
|
|
12676
|
+
onFocus() {
|
|
12677
|
+
if (!this.disabled()) {
|
|
12678
|
+
this.isFocused.set(true);
|
|
12679
|
+
}
|
|
12680
|
+
}
|
|
12681
|
+
onBlur() {
|
|
12682
|
+
this.isFocused.set(false);
|
|
12683
|
+
if (!this.isOpen()) {
|
|
12684
|
+
this.onTouched();
|
|
12685
|
+
}
|
|
12686
|
+
}
|
|
12687
|
+
clear() {
|
|
12688
|
+
if (this.disabled())
|
|
12689
|
+
return;
|
|
12690
|
+
this.updateValue('');
|
|
12691
|
+
}
|
|
12692
|
+
onColorSelected(color) {
|
|
12693
|
+
this.updateValue(color);
|
|
12694
|
+
this.addToRecentColors(color);
|
|
12695
|
+
}
|
|
12696
|
+
updateValue(value) {
|
|
12697
|
+
this.internalValue.set(value);
|
|
12698
|
+
this.onChange(value);
|
|
12699
|
+
this.colorChange.emit(value);
|
|
12700
|
+
}
|
|
12701
|
+
createOverlay() {
|
|
12702
|
+
if (this.overlayRef)
|
|
12703
|
+
return;
|
|
12704
|
+
const positionStrategy = this.overlay
|
|
12705
|
+
.position()
|
|
12706
|
+
.flexibleConnectedTo(this.elementRef.nativeElement.querySelector('.ds-color-picker__trigger'))
|
|
12707
|
+
.withPositions([
|
|
12708
|
+
{
|
|
12709
|
+
originX: 'start',
|
|
12710
|
+
originY: 'bottom',
|
|
12711
|
+
overlayX: 'start',
|
|
12712
|
+
overlayY: 'top',
|
|
12713
|
+
offsetY: 8,
|
|
12714
|
+
},
|
|
12715
|
+
{
|
|
12716
|
+
originX: 'start',
|
|
12717
|
+
originY: 'top',
|
|
12718
|
+
overlayX: 'start',
|
|
12719
|
+
overlayY: 'bottom',
|
|
12720
|
+
offsetY: -8,
|
|
12721
|
+
},
|
|
12722
|
+
]);
|
|
12723
|
+
this.overlayRef = this.overlay.create({
|
|
12724
|
+
positionStrategy,
|
|
12725
|
+
hasBackdrop: true,
|
|
12726
|
+
backdropClass: 'cdk-overlay-transparent-backdrop',
|
|
12727
|
+
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
12728
|
+
});
|
|
12729
|
+
const portal = new ComponentPortal(DsColorPickerPanelComponent);
|
|
12730
|
+
const componentRef = this.overlayRef.attach(portal);
|
|
12731
|
+
// Configuration du panel
|
|
12732
|
+
componentRef.instance.value = this.internalValue();
|
|
12733
|
+
componentRef.instance.showAlpha = this.showAlpha();
|
|
12734
|
+
componentRef.instance.presetColors = this.effectivePresets();
|
|
12735
|
+
componentRef.instance.recentColors = this.recentColors();
|
|
12736
|
+
componentRef.instance.showRecentColors = this.showRecentColors();
|
|
12737
|
+
componentRef.instance.format = this.format();
|
|
12738
|
+
// Écouter les événements
|
|
12739
|
+
componentRef.instance.colorSelected.subscribe((color) => {
|
|
12740
|
+
this.onColorSelected(color);
|
|
12741
|
+
});
|
|
12742
|
+
componentRef.instance.closed.subscribe(() => {
|
|
12743
|
+
this.close();
|
|
12744
|
+
});
|
|
12745
|
+
// Fermer au clic sur backdrop
|
|
12746
|
+
this.overlayRef.backdropClick().subscribe(() => {
|
|
12747
|
+
this.close();
|
|
12748
|
+
});
|
|
12749
|
+
}
|
|
12750
|
+
destroyOverlay() {
|
|
12751
|
+
if (this.overlayRef) {
|
|
12752
|
+
this.overlayRef.dispose();
|
|
12753
|
+
this.overlayRef = null;
|
|
12754
|
+
}
|
|
12755
|
+
}
|
|
12756
|
+
addToRecentColors(color) {
|
|
12757
|
+
if (!this.showRecentColors() || !color)
|
|
12758
|
+
return;
|
|
12759
|
+
const recent = this.recentColors();
|
|
12760
|
+
const filtered = recent.filter(c => c !== color);
|
|
12761
|
+
const updated = [color, ...filtered].slice(0, this.maxRecentColors());
|
|
12762
|
+
this.recentColors.set(updated);
|
|
12763
|
+
this.saveRecentColors(updated);
|
|
12764
|
+
}
|
|
12765
|
+
loadRecentColors() {
|
|
12766
|
+
try {
|
|
12767
|
+
const stored = localStorage.getItem('ds-color-picker-recent');
|
|
12768
|
+
if (stored) {
|
|
12769
|
+
const colors = JSON.parse(stored);
|
|
12770
|
+
if (Array.isArray(colors)) {
|
|
12771
|
+
this.recentColors.set(colors.slice(0, this.maxRecentColors()));
|
|
12772
|
+
}
|
|
12773
|
+
}
|
|
12774
|
+
}
|
|
12775
|
+
catch (e) {
|
|
12776
|
+
// Ignorer les erreurs de parsing
|
|
12777
|
+
}
|
|
12778
|
+
}
|
|
12779
|
+
saveRecentColors(colors) {
|
|
12780
|
+
try {
|
|
12781
|
+
localStorage.setItem('ds-color-picker-recent', JSON.stringify(colors));
|
|
12782
|
+
}
|
|
12783
|
+
catch (e) {
|
|
12784
|
+
// Ignorer les erreurs de stockage
|
|
12785
|
+
}
|
|
12786
|
+
}
|
|
12787
|
+
// === Conversions de couleurs ===
|
|
12788
|
+
toHex(color) {
|
|
12789
|
+
if (color.startsWith('#'))
|
|
12790
|
+
return color;
|
|
12791
|
+
const rgb = this.parseRGB(color);
|
|
12792
|
+
if (rgb) {
|
|
12793
|
+
const r = rgb.r.toString(16).padStart(2, '0');
|
|
12794
|
+
const g = rgb.g.toString(16).padStart(2, '0');
|
|
12795
|
+
const b = rgb.b.toString(16).padStart(2, '0');
|
|
12796
|
+
return `#${r}${g}${b}`;
|
|
12797
|
+
}
|
|
12798
|
+
return color;
|
|
12799
|
+
}
|
|
12800
|
+
toRGB(color) {
|
|
12801
|
+
if (color.startsWith('rgb'))
|
|
12802
|
+
return color;
|
|
12803
|
+
const rgb = this.hexToRGB(color);
|
|
12804
|
+
if (rgb) {
|
|
12805
|
+
if (rgb.a !== undefined) {
|
|
12806
|
+
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${rgb.a})`;
|
|
12807
|
+
}
|
|
12808
|
+
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
|
|
12809
|
+
}
|
|
12810
|
+
return color;
|
|
12811
|
+
}
|
|
12812
|
+
toHSL(color) {
|
|
12813
|
+
if (color.startsWith('hsl'))
|
|
12814
|
+
return color;
|
|
12815
|
+
const rgb = this.hexToRGB(color);
|
|
12816
|
+
if (rgb) {
|
|
12817
|
+
const hsl = this.rgbToHSL(rgb);
|
|
12818
|
+
if (hsl.a !== undefined) {
|
|
12819
|
+
return `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${hsl.a})`;
|
|
12820
|
+
}
|
|
12821
|
+
return `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`;
|
|
12822
|
+
}
|
|
12823
|
+
return color;
|
|
12824
|
+
}
|
|
12825
|
+
hexToRGB(hex) {
|
|
12826
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(hex);
|
|
12827
|
+
if (!result)
|
|
12828
|
+
return null;
|
|
12829
|
+
return {
|
|
12830
|
+
r: parseInt(result[1], 16),
|
|
12831
|
+
g: parseInt(result[2], 16),
|
|
12832
|
+
b: parseInt(result[3], 16),
|
|
12833
|
+
a: result[4] ? parseInt(result[4], 16) / 255 : undefined,
|
|
12834
|
+
};
|
|
12835
|
+
}
|
|
12836
|
+
parseRGB(rgb) {
|
|
12837
|
+
const match = rgb.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
|
|
12838
|
+
if (!match)
|
|
12839
|
+
return null;
|
|
12840
|
+
return {
|
|
12841
|
+
r: parseInt(match[1], 10),
|
|
12842
|
+
g: parseInt(match[2], 10),
|
|
12843
|
+
b: parseInt(match[3], 10),
|
|
12844
|
+
a: match[4] ? parseFloat(match[4]) : undefined,
|
|
12845
|
+
};
|
|
12846
|
+
}
|
|
12847
|
+
rgbToHSL(rgb) {
|
|
12848
|
+
const r = rgb.r / 255;
|
|
12849
|
+
const g = rgb.g / 255;
|
|
12850
|
+
const b = rgb.b / 255;
|
|
12851
|
+
const max = Math.max(r, g, b);
|
|
12852
|
+
const min = Math.min(r, g, b);
|
|
12853
|
+
let h = 0;
|
|
12854
|
+
let s = 0;
|
|
12855
|
+
const l = (max + min) / 2;
|
|
12856
|
+
if (max !== min) {
|
|
12857
|
+
const d = max - min;
|
|
12858
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
12859
|
+
switch (max) {
|
|
12860
|
+
case r:
|
|
12861
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
12862
|
+
break;
|
|
12863
|
+
case g:
|
|
12864
|
+
h = ((b - r) / d + 2) / 6;
|
|
12865
|
+
break;
|
|
12866
|
+
case b:
|
|
12867
|
+
h = ((r - g) / d + 4) / 6;
|
|
12868
|
+
break;
|
|
12869
|
+
}
|
|
12870
|
+
}
|
|
12871
|
+
return {
|
|
12872
|
+
h: Math.round(h * 360),
|
|
12873
|
+
s: Math.round(s * 100),
|
|
12874
|
+
l: Math.round(l * 100),
|
|
12875
|
+
a: rgb.a,
|
|
12876
|
+
};
|
|
12877
|
+
}
|
|
12878
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsColorPicker, deps: [{ token: i1$3.Overlay }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
12879
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DsColorPicker, isStandalone: true, selector: "ds-color-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showAlpha: { classPropertyName: "showAlpha", publicName: "showAlpha", isSignal: true, isRequired: false, transformFunction: null }, presetColors: { classPropertyName: "presetColors", publicName: "presetColors", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, allowClear: { classPropertyName: "allowClear", publicName: "allowClear", isSignal: true, isRequired: false, transformFunction: null }, showRecentColors: { classPropertyName: "showRecentColors", publicName: "showRecentColors", isSignal: true, isRequired: false, transformFunction: null }, maxRecentColors: { classPropertyName: "maxRecentColors", publicName: "maxRecentColors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { colorChange: "colorChange" }, providers: [
|
|
12880
|
+
{
|
|
12881
|
+
provide: NG_VALUE_ACCESSOR,
|
|
12882
|
+
useExisting: forwardRef(() => DsColorPicker),
|
|
12883
|
+
multi: true,
|
|
12884
|
+
},
|
|
12885
|
+
], ngImport: i0, template: "<div [class]=\"containerClasses()\">\n <div class=\"ds-color-picker__trigger\" (click)=\"toggle()\">\n <!-- Preview de la couleur -->\n <div\n class=\"ds-color-picker__preview\"\n [style.background-color]=\"previewColor()\"\n [attr.aria-label]=\"'Color: ' + displayValue()\">\n </div>\n\n <!-- Input texte -->\n <input\n type=\"text\"\n class=\"ds-color-picker__input\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n readonly\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n [attr.aria-label]=\"placeholder()\" />\n\n <!-- Actions -->\n <div class=\"ds-color-picker__actions\">\n @if (allowClear() && internalValue()) {\n <button\n type=\"button\"\n class=\"ds-color-picker__action ds-color-picker__action--clear\"\n [disabled]=\"disabled()\"\n (click)=\"clear(); $event.stopPropagation()\"\n [attr.aria-label]=\"'Clear color'\">\n <fa-icon [icon]=\"clearIcon\" aria-hidden=\"true\"></fa-icon>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"ds-color-picker__action ds-color-picker__action--picker\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"'Open color picker'\">\n <fa-icon [icon]=\"pickerIcon\" aria-hidden=\"true\"></fa-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: [".ds-color-picker{position:relative;display:inline-flex;width:100%}.ds-color-picker__trigger{position:relative;display:flex;align-items:center;gap:var(--colorpicker-gap, var(--space-2));width:100%;background:var(--colorpicker-bg, var(--background-main));border:1px solid var(--colorpicker-border, var(--border-default));border-radius:var(--colorpicker-radius, var(--radius-2));padding:var(--colorpicker-padding, var(--space-2));cursor:pointer;transition:border-color var(--duration-fast, .15s) ease,box-shadow var(--duration-fast, .15s) ease}.ds-color-picker__trigger:hover:not([disabled]){border-color:var(--colorpicker-border-hover, var(--border-strong))}.ds-color-picker__preview{flex-shrink:0;width:var(--colorpicker-preview-size, 28px);height:var(--colorpicker-preview-size, 28px);border:2px solid var(--colorpicker-preview-border, var(--border-default));border-radius:var(--radius-1);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:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0;position:relative}.ds-color-picker__preview:after{content:\"\";position:absolute;inset:0;background-color:currentColor;border-radius:inherit}.ds-color-picker__input{flex:1;min-width:0;background:transparent;border:none;color:var(--colorpicker-text, var(--text-default));font-size:var(--colorpicker-font-size, var(--font-size-3));outline:none;cursor:pointer}.ds-color-picker__input::placeholder{color:var(--colorpicker-placeholder, var(--text-muted))}.ds-color-picker__input:disabled{cursor:not-allowed}.ds-color-picker__actions{display:flex;align-items:center;gap:var(--space-1)}.ds-color-picker__action{display:flex;align-items:center;justify-content:center;width:var(--colorpicker-action-size, 24px);height:var(--colorpicker-action-size, 24px);padding:0;background:transparent;border:none;border-radius:var(--radius-1);color:var(--colorpicker-icon, var(--text-muted));cursor:pointer;transition:background-color var(--duration-fast, .15s) ease,color var(--duration-fast, .15s) ease}.ds-color-picker__action:hover:not(:disabled){background:var(--colorpicker-action-hover-bg, var(--surface-hover));color:var(--text-default)}.ds-color-picker__action:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}.ds-color-picker__action:disabled{opacity:.5;cursor:not-allowed}.ds-color-picker__action--clear{color:var(--colorpicker-clear-icon, var(--text-muted))}.ds-color-picker__action--clear:hover:not(:disabled){color:var(--error)}.ds-color-picker--sm .ds-color-picker__trigger{padding:var(--colorpicker-padding-sm, var(--space-1) var(--space-2));height:var(--colorpicker-height-sm, 32px)}.ds-color-picker--sm .ds-color-picker__preview{width:var(--colorpicker-preview-size-sm, 20px);height:var(--colorpicker-preview-size-sm, 20px)}.ds-color-picker--sm .ds-color-picker__input{font-size:var(--colorpicker-font-size-sm, var(--font-size-2))}.ds-color-picker--sm .ds-color-picker__action{width:var(--colorpicker-action-size-sm, 20px);height:var(--colorpicker-action-size-sm, 20px);font-size:var(--font-size-2)}.ds-color-picker--md .ds-color-picker__trigger{padding:var(--colorpicker-padding-md, var(--space-2));height:var(--colorpicker-height-md, 40px)}.ds-color-picker--md .ds-color-picker__preview{width:var(--colorpicker-preview-size-md, 28px);height:var(--colorpicker-preview-size-md, 28px)}.ds-color-picker--md .ds-color-picker__input{font-size:var(--colorpicker-font-size-md, var(--font-size-3))}.ds-color-picker--md .ds-color-picker__action{width:var(--colorpicker-action-size-md, 24px);height:var(--colorpicker-action-size-md, 24px);font-size:var(--font-size-3)}.ds-color-picker--lg .ds-color-picker__trigger{padding:var(--colorpicker-padding-lg, var(--space-3));height:var(--colorpicker-height-lg, 48px)}.ds-color-picker--lg .ds-color-picker__preview{width:var(--colorpicker-preview-size-lg, 36px);height:var(--colorpicker-preview-size-lg, 36px)}.ds-color-picker--lg .ds-color-picker__input{font-size:var(--colorpicker-font-size-lg, var(--font-size-4))}.ds-color-picker--lg .ds-color-picker__action{width:var(--colorpicker-action-size-lg, 28px);height:var(--colorpicker-action-size-lg, 28px);font-size:var(--font-size-4)}.ds-color-picker--focused .ds-color-picker__trigger{border-color:var(--color-primary);box-shadow:0 0 0 3px var(--colorpicker-focus-shadow, rgba(59, 130, 246, .25))}.ds-color-picker--open .ds-color-picker__trigger{border-color:var(--color-primary)}.ds-color-picker--disabled{opacity:.6;pointer-events:none;cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i1$1.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"], outputs: ["iconChange", "titleChange", "animationChange", "maskChange", "flipChange", "sizeChange", "pullChange", "borderChange", "inverseChange", "symbolChange", "rotateChange", "fixedWidthChange", "transformChange", "a11yRoleChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: OverlayModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
12886
|
+
}
|
|
12887
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DsColorPicker, decorators: [{
|
|
12888
|
+
type: Component,
|
|
12889
|
+
args: [{ selector: 'ds-color-picker', standalone: true, imports: [CommonModule, FontAwesomeModule, FormsModule, OverlayModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
12890
|
+
{
|
|
12891
|
+
provide: NG_VALUE_ACCESSOR,
|
|
12892
|
+
useExisting: forwardRef(() => DsColorPicker),
|
|
12893
|
+
multi: true,
|
|
12894
|
+
},
|
|
12895
|
+
], template: "<div [class]=\"containerClasses()\">\n <div class=\"ds-color-picker__trigger\" (click)=\"toggle()\">\n <!-- Preview de la couleur -->\n <div\n class=\"ds-color-picker__preview\"\n [style.background-color]=\"previewColor()\"\n [attr.aria-label]=\"'Color: ' + displayValue()\">\n </div>\n\n <!-- Input texte -->\n <input\n type=\"text\"\n class=\"ds-color-picker__input\"\n [value]=\"displayValue()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"disabled()\"\n readonly\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n [attr.aria-label]=\"placeholder()\" />\n\n <!-- Actions -->\n <div class=\"ds-color-picker__actions\">\n @if (allowClear() && internalValue()) {\n <button\n type=\"button\"\n class=\"ds-color-picker__action ds-color-picker__action--clear\"\n [disabled]=\"disabled()\"\n (click)=\"clear(); $event.stopPropagation()\"\n [attr.aria-label]=\"'Clear color'\">\n <fa-icon [icon]=\"clearIcon\" aria-hidden=\"true\"></fa-icon>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"ds-color-picker__action ds-color-picker__action--picker\"\n [disabled]=\"disabled()\"\n [attr.aria-label]=\"'Open color picker'\">\n <fa-icon [icon]=\"pickerIcon\" aria-hidden=\"true\"></fa-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: [".ds-color-picker{position:relative;display:inline-flex;width:100%}.ds-color-picker__trigger{position:relative;display:flex;align-items:center;gap:var(--colorpicker-gap, var(--space-2));width:100%;background:var(--colorpicker-bg, var(--background-main));border:1px solid var(--colorpicker-border, var(--border-default));border-radius:var(--colorpicker-radius, var(--radius-2));padding:var(--colorpicker-padding, var(--space-2));cursor:pointer;transition:border-color var(--duration-fast, .15s) ease,box-shadow var(--duration-fast, .15s) ease}.ds-color-picker__trigger:hover:not([disabled]){border-color:var(--colorpicker-border-hover, var(--border-strong))}.ds-color-picker__preview{flex-shrink:0;width:var(--colorpicker-preview-size, 28px);height:var(--colorpicker-preview-size, 28px);border:2px solid var(--colorpicker-preview-border, var(--border-default));border-radius:var(--radius-1);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:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0;position:relative}.ds-color-picker__preview:after{content:\"\";position:absolute;inset:0;background-color:currentColor;border-radius:inherit}.ds-color-picker__input{flex:1;min-width:0;background:transparent;border:none;color:var(--colorpicker-text, var(--text-default));font-size:var(--colorpicker-font-size, var(--font-size-3));outline:none;cursor:pointer}.ds-color-picker__input::placeholder{color:var(--colorpicker-placeholder, var(--text-muted))}.ds-color-picker__input:disabled{cursor:not-allowed}.ds-color-picker__actions{display:flex;align-items:center;gap:var(--space-1)}.ds-color-picker__action{display:flex;align-items:center;justify-content:center;width:var(--colorpicker-action-size, 24px);height:var(--colorpicker-action-size, 24px);padding:0;background:transparent;border:none;border-radius:var(--radius-1);color:var(--colorpicker-icon, var(--text-muted));cursor:pointer;transition:background-color var(--duration-fast, .15s) ease,color var(--duration-fast, .15s) ease}.ds-color-picker__action:hover:not(:disabled){background:var(--colorpicker-action-hover-bg, var(--surface-hover));color:var(--text-default)}.ds-color-picker__action:focus-visible{outline:2px solid var(--color-primary);outline-offset:1px}.ds-color-picker__action:disabled{opacity:.5;cursor:not-allowed}.ds-color-picker__action--clear{color:var(--colorpicker-clear-icon, var(--text-muted))}.ds-color-picker__action--clear:hover:not(:disabled){color:var(--error)}.ds-color-picker--sm .ds-color-picker__trigger{padding:var(--colorpicker-padding-sm, var(--space-1) var(--space-2));height:var(--colorpicker-height-sm, 32px)}.ds-color-picker--sm .ds-color-picker__preview{width:var(--colorpicker-preview-size-sm, 20px);height:var(--colorpicker-preview-size-sm, 20px)}.ds-color-picker--sm .ds-color-picker__input{font-size:var(--colorpicker-font-size-sm, var(--font-size-2))}.ds-color-picker--sm .ds-color-picker__action{width:var(--colorpicker-action-size-sm, 20px);height:var(--colorpicker-action-size-sm, 20px);font-size:var(--font-size-2)}.ds-color-picker--md .ds-color-picker__trigger{padding:var(--colorpicker-padding-md, var(--space-2));height:var(--colorpicker-height-md, 40px)}.ds-color-picker--md .ds-color-picker__preview{width:var(--colorpicker-preview-size-md, 28px);height:var(--colorpicker-preview-size-md, 28px)}.ds-color-picker--md .ds-color-picker__input{font-size:var(--colorpicker-font-size-md, var(--font-size-3))}.ds-color-picker--md .ds-color-picker__action{width:var(--colorpicker-action-size-md, 24px);height:var(--colorpicker-action-size-md, 24px);font-size:var(--font-size-3)}.ds-color-picker--lg .ds-color-picker__trigger{padding:var(--colorpicker-padding-lg, var(--space-3));height:var(--colorpicker-height-lg, 48px)}.ds-color-picker--lg .ds-color-picker__preview{width:var(--colorpicker-preview-size-lg, 36px);height:var(--colorpicker-preview-size-lg, 36px)}.ds-color-picker--lg .ds-color-picker__input{font-size:var(--colorpicker-font-size-lg, var(--font-size-4))}.ds-color-picker--lg .ds-color-picker__action{width:var(--colorpicker-action-size-lg, 28px);height:var(--colorpicker-action-size-lg, 28px);font-size:var(--font-size-4)}.ds-color-picker--focused .ds-color-picker__trigger{border-color:var(--color-primary);box-shadow:0 0 0 3px var(--colorpicker-focus-shadow, rgba(59, 130, 246, .25))}.ds-color-picker--open .ds-color-picker__trigger{border-color:var(--color-primary)}.ds-color-picker--disabled{opacity:.6;pointer-events:none;cursor:not-allowed}\n"] }]
|
|
12896
|
+
}], ctorParameters: () => [{ type: i1$3.Overlay }, { type: i0.ElementRef }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showAlpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAlpha", required: false }] }], presetColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "presetColors", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], allowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowClear", required: false }] }], showRecentColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRecentColors", required: false }] }], maxRecentColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRecentColors", required: false }] }], colorChange: [{ type: i0.Output, args: ["colorChange"] }] } });
|
|
12897
|
+
|
|
11434
12898
|
/*
|
|
11435
12899
|
* Components barrel export
|
|
11436
12900
|
*/
|
|
@@ -12002,5 +13466,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
|
|
|
12002
13466
|
* Generated bundle index. Do not edit.
|
|
12003
13467
|
*/
|
|
12004
13468
|
|
|
12005
|
-
export { AUTOCOMPLETE_POSITIONS, BUTTON_APPEARANCE_OPTIONS, BUTTON_SIZE_OPTIONS, BUTTON_VARIANT_OPTIONS, DROPDOWN_POSITIONS, DsAccordion, DsAlert, DsAvatar, DsBadge, DsBreadcrumb, DsButton, DsCalendar, DsCard, DsCarousel, DsCheckbox, DsChip, DsCombobox, DsContainer, DsDatePicker, DsDivider, DsDrawer, DsDropdown, DsEmpty, DsFileUpload, DsI18nService, DsInputField, DsInputTextarea, DsMenu, DsModalComponent, DsNotificationContainerComponent, DsNotificationItemComponent, DsNotificationService, DsPagination, DsPasswordStrength, DsPopover, DsPopoverComponent, DsProgressBar, DsRadioGroup, DsRating, DsSearchInput, DsSelect, DsSkeleton, DsSlider, DsStepper, DsTable, DsTabs, DsTimePicker, DsTimeline, DsToastComponent, DsToastContainerComponent, DsToastService, DsToggle, DsTooltip, DsTooltipComponent, DsTransfer, DsTree, IconRegistryService, POPOVER_POSITIONS, PrimitiveBadge, PrimitiveButton, PrimitiveCheckbox, PrimitiveInput, PrimitiveRadio, PrimitiveTextarea, PrimitiveToggle, TOOLTIP_POSITIONS, buildButtonArgTypes, buildButtonArgs, createSizeRender, createVariantRender };
|
|
13469
|
+
export { AUTOCOMPLETE_POSITIONS, BUTTON_APPEARANCE_OPTIONS, BUTTON_SIZE_OPTIONS, BUTTON_VARIANT_OPTIONS, DROPDOWN_POSITIONS, DsAccordion, DsAlert, DsAvatar, DsBadge, DsBreadcrumb, DsButton, DsCalendar, DsCard, DsCarousel, DsCheckbox, DsChip, DsColorPicker, DsCombobox, DsContainer, DsDatePicker, DsDivider, DsDrawer, DsDropdown, DsEmpty, DsFileUpload, DsI18nService, DsInputField, DsInputNumber, DsInputTextarea, DsMenu, DsModalComponent, DsNotificationContainerComponent, DsNotificationItemComponent, DsNotificationService, DsPagination, DsPasswordStrength, DsPopover, DsPopoverComponent, DsProgressBar, DsRadioGroup, DsRating, DsSearchInput, DsSegmentedControl, DsSelect, DsSkeleton, DsSlider, DsStepper, DsTable, DsTabs, DsTimePicker, DsTimeline, DsToastComponent, DsToastContainerComponent, DsToastService, DsToggle, DsTooltip, DsTooltipComponent, DsTransfer, DsTree, IconRegistryService, POPOVER_POSITIONS, PrimitiveBadge, PrimitiveButton, PrimitiveCheckbox, PrimitiveInput, PrimitiveRadio, PrimitiveTextarea, PrimitiveToggle, TOOLTIP_POSITIONS, buildButtonArgTypes, buildButtonArgs, createSizeRender, createVariantRender };
|
|
12006
13470
|
//# sourceMappingURL=kksdev-ds-angular.mjs.map
|