@ajuarezso/sui-design-system 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, input, computed, ChangeDetectionStrategy, Component, model, signal, viewChild, effect, untracked, output, inject, ElementRef, forwardRef,
|
|
2
|
+
import { InjectionToken, input, computed, ChangeDetectionStrategy, Component, model, signal, viewChild, effect, untracked, output, inject, ElementRef, forwardRef, TemplateRef, Directive, ViewContainerRef, DestroyRef, ContentChild, ViewChild, ViewEncapsulation, Renderer2, DOCUMENT, HostListener, viewChildren, afterNextRender, ContentChildren, ViewChildren, Injectable } from '@angular/core';
|
|
3
3
|
import { NgTemplateOutlet, DOCUMENT as DOCUMENT$1 } from '@angular/common';
|
|
4
4
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
5
5
|
import { Subscription } from 'rxjs';
|
|
@@ -2602,9 +2602,13 @@ class SuiCheckboxCard {
|
|
|
2602
2602
|
iconSrc = input(null, ...(ngDevMode ? [{ debugName: "iconSrc" }] : /* istanbul ignore next */ []));
|
|
2603
2603
|
/** URL de imagen para type='avatar'. Si falla, fallback a iniciales del label. */
|
|
2604
2604
|
imageUrl = input(null, ...(ngDevMode ? [{ debugName: "imageUrl" }] : /* istanbul ignore next */ []));
|
|
2605
|
-
/**
|
|
2606
|
-
|
|
2607
|
-
|
|
2605
|
+
/** Badge junto al label — string shorthand ('NEW') o SuiBadgeConfig
|
|
2606
|
+
(label + color/variant/size, tipado como sui-badge). null = sin badge. */
|
|
2607
|
+
badge = input(null, ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
|
|
2608
|
+
badgeCfg = computed(() => {
|
|
2609
|
+
const b = this.badge();
|
|
2610
|
+
return b ? (typeof b === 'string' ? { label: b } : b) : null;
|
|
2611
|
+
}, ...(ngDevMode ? [{ debugName: "badgeCfg" }] : /* istanbul ignore next */ []));
|
|
2608
2612
|
/** Indeterminate state (tri-state checkbox). */
|
|
2609
2613
|
indeterminate = input(false, ...(ngDevMode ? [{ debugName: "indeterminate" }] : /* istanbul ignore next */ []));
|
|
2610
2614
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
@@ -2659,13 +2663,13 @@ class SuiCheckboxCard {
|
|
|
2659
2663
|
this._disabledByForm.set(isDisabled);
|
|
2660
2664
|
}
|
|
2661
2665
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiCheckboxCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2662
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiCheckboxCard, isStandalone: true, selector: "sui-checkbox-card", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, emoji: { classPropertyName: "emoji", publicName: "emoji", isSignal: true, isRequired: false, transformFunction: null }, iconSrc: { classPropertyName: "iconSrc", publicName: "iconSrc", isSignal: true, isRequired: false, transformFunction: null }, imageUrl: { classPropertyName: "imageUrl", publicName: "imageUrl", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null },
|
|
2666
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiCheckboxCard, isStandalone: true, selector: "sui-checkbox-card", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, emoji: { classPropertyName: "emoji", publicName: "emoji", isSignal: true, isRequired: false, transformFunction: null }, iconSrc: { classPropertyName: "iconSrc", publicName: "iconSrc", isSignal: true, isRequired: false, transformFunction: null }, imageUrl: { classPropertyName: "imageUrl", publicName: "imageUrl", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", checkedChange2: "checkedChange2" }, host: { listeners: { "click": "onToggle($event)", "keydown.space": "onToggle($event)", "keydown.enter": "onToggle($event)", "touchstart": "$event.currentTarget", "touchend": "$any($event.currentTarget).blur()" }, properties: { "attr.data-sui-type": "type()", "attr.data-sui-checked": "checked() ? \"\" : null", "attr.data-sui-indeterminate": "indeterminate() ? \"\" : null", "attr.data-sui-disabled": "isDisabled() ? \"\" : null", "attr.data-sui-leading-fill": "iconSrc() ? \"\" : null", "attr.role": "\"checkbox\"", "attr.aria-checked": "indeterminate() ? \"mixed\" : (checked() ? \"true\" : \"false\")", "attr.aria-disabled": "isDisabled() ? \"true\" : null", "attr.aria-label": "label() || null", "attr.tabindex": "isDisabled() ? \"-1\" : \"0\"" } }, providers: [
|
|
2663
2667
|
{
|
|
2664
2668
|
provide: NG_VALUE_ACCESSOR,
|
|
2665
2669
|
useExisting: forwardRef(() => SuiCheckboxCard),
|
|
2666
2670
|
multi: true,
|
|
2667
2671
|
},
|
|
2668
|
-
], ngImport: i0, template: "<!-- Leading slot \u2014 solo basic / left-icon / avatar (Figma 261:3921/264:2858/264:3023) -->\n@if (type() === 'left-icon') {\n <div class=\"sui-checkbox-card__leading sui-checkbox-card__leading--icon\" aria-hidden=\"true\">\n @if (icon()) {\n <sui-icon [name]=\"icon()!\" [size]=\"20\" />\n } @else if (emoji()) {\n <sui-emoji [name]=\"emoji()\" size=\"md\" />\n } @else if (iconSrc()) {\n <sui-emoji [src]=\"iconSrc()\" size=\"full\" />\n }\n </div>\n} @else if (type() === 'avatar') {\n <sui-avatar\n class=\"sui-checkbox-card__leading sui-checkbox-card__leading--avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n} @else if (type() === 'card-provider' || type() === 'brand' || type() === 'company') {\n <!-- Leading proyectado por el consumer: logo de proveedor / brand / company.\n El componente solo da el contenedor + geometr\u00EDa por type (Figma\n 265:539/699/863). Ej: <sui-checkbox-card type=\"brand\"><img slot=\"leading\" \u2026></sui-checkbox-card> -->\n <div class=\"sui-checkbox-card__leading sui-checkbox-card__leading--slot\" aria-hidden=\"true\">\n <ng-content select=\"[slot=leading]\" />\n </div>\n}\n\n<!-- Texto: Title row + description -->\n<div class=\"sui-checkbox-card__text\">\n <div class=\"sui-checkbox-card__title\">\n @if (label()) {\n <span class=\"sui-checkbox-card__label\">{{ label() }}</span>\n }\n @if (sublabel()) {\n <span class=\"sui-checkbox-card__sublabel\">{{ sublabel() }}</span>\n }\n @if (
|
|
2672
|
+
], ngImport: i0, template: "<!-- Leading slot \u2014 solo basic / left-icon / avatar (Figma 261:3921/264:2858/264:3023) -->\n@if (type() === 'left-icon') {\n <div class=\"sui-checkbox-card__leading sui-checkbox-card__leading--icon\" aria-hidden=\"true\">\n @if (icon()) {\n <sui-icon [name]=\"icon()!\" [size]=\"20\" />\n } @else if (emoji()) {\n <sui-emoji [name]=\"emoji()\" size=\"md\" />\n } @else if (iconSrc()) {\n <sui-emoji [src]=\"iconSrc()\" size=\"full\" />\n }\n </div>\n} @else if (type() === 'avatar') {\n <sui-avatar\n class=\"sui-checkbox-card__leading sui-checkbox-card__leading--avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n} @else if (type() === 'card-provider' || type() === 'brand' || type() === 'company') {\n <!-- Leading proyectado por el consumer: logo de proveedor / brand / company.\n El componente solo da el contenedor + geometr\u00EDa por type (Figma\n 265:539/699/863). Ej: <sui-checkbox-card type=\"brand\"><img slot=\"leading\" \u2026></sui-checkbox-card> -->\n <div class=\"sui-checkbox-card__leading sui-checkbox-card__leading--slot\" aria-hidden=\"true\">\n <ng-content select=\"[slot=leading]\" />\n </div>\n}\n\n<!-- Texto: Title row + description -->\n<div class=\"sui-checkbox-card__text\">\n <div class=\"sui-checkbox-card__title\">\n @if (label()) {\n <span class=\"sui-checkbox-card__label\">{{ label() }}</span>\n }\n @if (sublabel()) {\n <span class=\"sui-checkbox-card__sublabel\">{{ sublabel() }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <span class=\"sui-checkbox-card__badge\">{{ bcfg.label }}</span>\n }\n </div>\n @if (description()) {\n <p class=\"sui-checkbox-card__description\">{{ description() }}</p>\n }\n</div>\n\n<!-- Checkbox trailing (20\u00D720 medium). El click del host ya togglea \u2014 el checkbox\n interno solo refleja el estado visual (sus listeners propios disparan\n onCheckboxChange para mantener sync con el form). -->\n<sui-checkbox\n class=\"sui-checkbox-card__checkbox\"\n [size]=\"size()\"\n [checked]=\"checked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onCheckboxChange($event)\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n/>\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;box-sizing:border-box;align-items:flex-start;gap:14px;padding:16px;width:100%;background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);border-radius:var(--sui-radius-12, 12px);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(10, 13, 20, .031372549));cursor:pointer;outline:none;-webkit-user-select:none;user-select:none;font-family:var(--sui-font-sans, var(--font-sans, sans-serif));touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:background-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),border-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),box-shadow var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),transform var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}@media(hover:hover)and (pointer:fine){:host(:hover:not([data-sui-disabled]):not([data-sui-checked]):not([data-sui-indeterminate])){background:var(--sui-bg-weak-50, #f7f7f7);border-color:transparent;box-shadow:none}}:host([data-sui-checked]),:host([data-sui-indeterminate]){border-color:var(--sui-primary-base, #fa7319);box-shadow:none;background:var(--sui-bg-white-0, #fff)}@media(hover:hover)and (pointer:fine){:host([data-sui-checked]:hover:not([data-sui-disabled])),:host([data-sui-indeterminate]:hover:not([data-sui-disabled])){background:var(--sui-bg-weak-50, #f7f7f7)}}:host(:focus-visible:not([data-sui-disabled])){border-color:var(--sui-primary-base, #fa7319);box-shadow:0 0 0 3px color-mix(in oklab,var(--sui-primary-base, #fa7319) 16%,transparent)}:host([data-sui-disabled]){cursor:not-allowed;background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);box-shadow:none}:host([data-sui-disabled]) .sui-checkbox-card__label{color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-disabled]) .sui-checkbox-card__sublabel,:host([data-sui-disabled]) .sui-checkbox-card__description{color:var(--sui-text-soft-400, #a3a3a3)}:host(:active:not([data-sui-disabled])){transform:scale(.99)}.sui-checkbox-card__leading{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}.sui-checkbox-card__leading--icon{box-sizing:border-box;width:40px;height:40px;padding:10px;border-radius:var(--sui-radius-full, 999px);background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(10, 13, 20, .031372549));color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-leading-fill]) .sui-checkbox-card__leading--icon{padding:0;border:none;background:none;box-shadow:none;border-radius:0;overflow:visible;display:flex;align-items:center;justify-content:center}:host([data-sui-leading-fill]) .sui-checkbox-card__leading--icon sui-emoji{display:block;width:100%;height:100%}:host([data-sui-type=avatar]) .sui-checkbox-card__leading--avatar{width:40px;height:40px}.sui-checkbox-card__leading--slot{box-sizing:border-box;overflow:hidden}.sui-checkbox-card__leading--slot>*{display:block;width:100%;height:100%;object-fit:contain}:host([data-sui-type=card-provider]) .sui-checkbox-card__leading--slot{width:32px;height:24px;border-radius:4px}:host([data-sui-type=brand]) .sui-checkbox-card__leading--slot{width:40px;height:40px}:host([data-sui-type=company]) .sui-checkbox-card__leading--slot{width:40px;height:40px;border-radius:var(--sui-radius-full, 999px)}.sui-checkbox-card__text{display:flex;flex-direction:column;gap:4px;align-items:flex-start;flex:1 1 auto;min-width:0;align-self:stretch}.sui-checkbox-card__text:not(:has(.sui-checkbox-card__description)){justify-content:center}.sui-checkbox-card__title{display:flex;gap:4px;align-items:center;flex-wrap:wrap}.sui-checkbox-card__label{font-size:14px;font-weight:500;line-height:20px;letter-spacing:-.084px;color:var(--sui-text-strong-950, #171717);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-checkbox-card__sublabel{font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600, #5c5c5c);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-checkbox-card__description{margin:0;font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600, #5c5c5c);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-checkbox-card__badge{display:inline-flex;align-items:center;justify-content:center;padding:2px 8px;border:1px solid transparent;border-radius:var(--sui-radius-full, 999px);background:var(--sui-state-information-light, #c0d5ff);color:var(--sui-state-information-dark, #122368);font-size:11px;font-weight:500;line-height:12px;letter-spacing:.22px;text-transform:uppercase;font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0;white-space:nowrap}:host([data-sui-disabled]) .sui-checkbox-card__badge{background:transparent;border-color:var(--sui-stroke-soft-200, #ebebeb);color:var(--sui-text-disabled-300, #d1d1d1)}.sui-checkbox-card__checkbox{flex-shrink:0;align-self:flex-start;pointer-events:none}\n"], dependencies: [{ kind: "component", type: SuiCheckbox, selector: "sui-checkbox", inputs: ["size", "checked", "indeterminate", "disabled"], outputs: ["checkedChange"] }, { kind: "component", type: SuiIcon, selector: "sui-icon", inputs: ["name", "size", "color"] }, { kind: "component", type: SuiEmoji, selector: "sui-emoji", inputs: ["name", "src", "size", "ariaLabel"] }, { kind: "component", type: SuiAvatar, selector: "sui-avatar", inputs: ["size", "src", "alt", "initials", "color", "status", "memojiSrc", "illustrationSrc", "icon", "companyLogoSrc", "topBadge", "bgColor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2669
2673
|
}
|
|
2670
2674
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiCheckboxCard, decorators: [{
|
|
2671
2675
|
type: Component,
|
|
@@ -2692,8 +2696,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
2692
2696
|
/* iOS WKWebView fix — sin esto :active stickea 300-500ms en standalone pages */
|
|
2693
2697
|
'(touchstart)': '$event.currentTarget',
|
|
2694
2698
|
'(touchend)': '$any($event.currentTarget).blur()',
|
|
2695
|
-
}, template: "<!-- Leading slot \u2014 solo basic / left-icon / avatar (Figma 261:3921/264:2858/264:3023) -->\n@if (type() === 'left-icon') {\n <div class=\"sui-checkbox-card__leading sui-checkbox-card__leading--icon\" aria-hidden=\"true\">\n @if (icon()) {\n <sui-icon [name]=\"icon()!\" [size]=\"20\" />\n } @else if (emoji()) {\n <sui-emoji [name]=\"emoji()\" size=\"md\" />\n } @else if (iconSrc()) {\n <sui-emoji [src]=\"iconSrc()\" size=\"full\" />\n }\n </div>\n} @else if (type() === 'avatar') {\n <sui-avatar\n class=\"sui-checkbox-card__leading sui-checkbox-card__leading--avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n} @else if (type() === 'card-provider' || type() === 'brand' || type() === 'company') {\n <!-- Leading proyectado por el consumer: logo de proveedor / brand / company.\n El componente solo da el contenedor + geometr\u00EDa por type (Figma\n 265:539/699/863). Ej: <sui-checkbox-card type=\"brand\"><img slot=\"leading\" \u2026></sui-checkbox-card> -->\n <div class=\"sui-checkbox-card__leading sui-checkbox-card__leading--slot\" aria-hidden=\"true\">\n <ng-content select=\"[slot=leading]\" />\n </div>\n}\n\n<!-- Texto: Title row + description -->\n<div class=\"sui-checkbox-card__text\">\n <div class=\"sui-checkbox-card__title\">\n @if (label()) {\n <span class=\"sui-checkbox-card__label\">{{ label() }}</span>\n }\n @if (sublabel()) {\n <span class=\"sui-checkbox-card__sublabel\">{{ sublabel() }}</span>\n }\n @if (
|
|
2696
|
-
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], emoji: [{ type: i0.Input, args: [{ isSignal: true, alias: "emoji", required: false }] }], iconSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSrc", required: false }] }], imageUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUrl", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }],
|
|
2699
|
+
}, template: "<!-- Leading slot \u2014 solo basic / left-icon / avatar (Figma 261:3921/264:2858/264:3023) -->\n@if (type() === 'left-icon') {\n <div class=\"sui-checkbox-card__leading sui-checkbox-card__leading--icon\" aria-hidden=\"true\">\n @if (icon()) {\n <sui-icon [name]=\"icon()!\" [size]=\"20\" />\n } @else if (emoji()) {\n <sui-emoji [name]=\"emoji()\" size=\"md\" />\n } @else if (iconSrc()) {\n <sui-emoji [src]=\"iconSrc()\" size=\"full\" />\n }\n </div>\n} @else if (type() === 'avatar') {\n <sui-avatar\n class=\"sui-checkbox-card__leading sui-checkbox-card__leading--avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n} @else if (type() === 'card-provider' || type() === 'brand' || type() === 'company') {\n <!-- Leading proyectado por el consumer: logo de proveedor / brand / company.\n El componente solo da el contenedor + geometr\u00EDa por type (Figma\n 265:539/699/863). Ej: <sui-checkbox-card type=\"brand\"><img slot=\"leading\" \u2026></sui-checkbox-card> -->\n <div class=\"sui-checkbox-card__leading sui-checkbox-card__leading--slot\" aria-hidden=\"true\">\n <ng-content select=\"[slot=leading]\" />\n </div>\n}\n\n<!-- Texto: Title row + description -->\n<div class=\"sui-checkbox-card__text\">\n <div class=\"sui-checkbox-card__title\">\n @if (label()) {\n <span class=\"sui-checkbox-card__label\">{{ label() }}</span>\n }\n @if (sublabel()) {\n <span class=\"sui-checkbox-card__sublabel\">{{ sublabel() }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <span class=\"sui-checkbox-card__badge\">{{ bcfg.label }}</span>\n }\n </div>\n @if (description()) {\n <p class=\"sui-checkbox-card__description\">{{ description() }}</p>\n }\n</div>\n\n<!-- Checkbox trailing (20\u00D720 medium). El click del host ya togglea \u2014 el checkbox\n interno solo refleja el estado visual (sus listeners propios disparan\n onCheckboxChange para mantener sync con el form). -->\n<sui-checkbox\n class=\"sui-checkbox-card__checkbox\"\n [size]=\"size()\"\n [checked]=\"checked()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onCheckboxChange($event)\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n/>\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;box-sizing:border-box;align-items:flex-start;gap:14px;padding:16px;width:100%;background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);border-radius:var(--sui-radius-12, 12px);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(10, 13, 20, .031372549));cursor:pointer;outline:none;-webkit-user-select:none;user-select:none;font-family:var(--sui-font-sans, var(--font-sans, sans-serif));touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:background-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),border-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),box-shadow var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),transform var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}@media(hover:hover)and (pointer:fine){:host(:hover:not([data-sui-disabled]):not([data-sui-checked]):not([data-sui-indeterminate])){background:var(--sui-bg-weak-50, #f7f7f7);border-color:transparent;box-shadow:none}}:host([data-sui-checked]),:host([data-sui-indeterminate]){border-color:var(--sui-primary-base, #fa7319);box-shadow:none;background:var(--sui-bg-white-0, #fff)}@media(hover:hover)and (pointer:fine){:host([data-sui-checked]:hover:not([data-sui-disabled])),:host([data-sui-indeterminate]:hover:not([data-sui-disabled])){background:var(--sui-bg-weak-50, #f7f7f7)}}:host(:focus-visible:not([data-sui-disabled])){border-color:var(--sui-primary-base, #fa7319);box-shadow:0 0 0 3px color-mix(in oklab,var(--sui-primary-base, #fa7319) 16%,transparent)}:host([data-sui-disabled]){cursor:not-allowed;background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);box-shadow:none}:host([data-sui-disabled]) .sui-checkbox-card__label{color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-disabled]) .sui-checkbox-card__sublabel,:host([data-sui-disabled]) .sui-checkbox-card__description{color:var(--sui-text-soft-400, #a3a3a3)}:host(:active:not([data-sui-disabled])){transform:scale(.99)}.sui-checkbox-card__leading{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}.sui-checkbox-card__leading--icon{box-sizing:border-box;width:40px;height:40px;padding:10px;border-radius:var(--sui-radius-full, 999px);background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(10, 13, 20, .031372549));color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-leading-fill]) .sui-checkbox-card__leading--icon{padding:0;border:none;background:none;box-shadow:none;border-radius:0;overflow:visible;display:flex;align-items:center;justify-content:center}:host([data-sui-leading-fill]) .sui-checkbox-card__leading--icon sui-emoji{display:block;width:100%;height:100%}:host([data-sui-type=avatar]) .sui-checkbox-card__leading--avatar{width:40px;height:40px}.sui-checkbox-card__leading--slot{box-sizing:border-box;overflow:hidden}.sui-checkbox-card__leading--slot>*{display:block;width:100%;height:100%;object-fit:contain}:host([data-sui-type=card-provider]) .sui-checkbox-card__leading--slot{width:32px;height:24px;border-radius:4px}:host([data-sui-type=brand]) .sui-checkbox-card__leading--slot{width:40px;height:40px}:host([data-sui-type=company]) .sui-checkbox-card__leading--slot{width:40px;height:40px;border-radius:var(--sui-radius-full, 999px)}.sui-checkbox-card__text{display:flex;flex-direction:column;gap:4px;align-items:flex-start;flex:1 1 auto;min-width:0;align-self:stretch}.sui-checkbox-card__text:not(:has(.sui-checkbox-card__description)){justify-content:center}.sui-checkbox-card__title{display:flex;gap:4px;align-items:center;flex-wrap:wrap}.sui-checkbox-card__label{font-size:14px;font-weight:500;line-height:20px;letter-spacing:-.084px;color:var(--sui-text-strong-950, #171717);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-checkbox-card__sublabel{font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600, #5c5c5c);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-checkbox-card__description{margin:0;font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600, #5c5c5c);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-checkbox-card__badge{display:inline-flex;align-items:center;justify-content:center;padding:2px 8px;border:1px solid transparent;border-radius:var(--sui-radius-full, 999px);background:var(--sui-state-information-light, #c0d5ff);color:var(--sui-state-information-dark, #122368);font-size:11px;font-weight:500;line-height:12px;letter-spacing:.22px;text-transform:uppercase;font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0;white-space:nowrap}:host([data-sui-disabled]) .sui-checkbox-card__badge{background:transparent;border-color:var(--sui-stroke-soft-200, #ebebeb);color:var(--sui-text-disabled-300, #d1d1d1)}.sui-checkbox-card__checkbox{flex-shrink:0;align-self:flex-start;pointer-events:none}\n"] }]
|
|
2700
|
+
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], emoji: [{ type: i0.Input, args: [{ isSignal: true, alias: "emoji", required: false }] }], iconSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSrc", required: false }] }], imageUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUrl", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], checkedChange2: [{ type: i0.Output, args: ["checkedChange2"] }] } });
|
|
2697
2701
|
|
|
2698
2702
|
/**
|
|
2699
2703
|
* SUI Checkbox Label — SUI Design System 2.0
|
|
@@ -2766,10 +2770,13 @@ class SuiCheckboxLabel {
|
|
|
2766
2770
|
/** Descripción opcional debajo del title. Cuando está set, el variant
|
|
2767
2771
|
cambia a "with description" (label en medium + multi-line content). */
|
|
2768
2772
|
description = input(null, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
2769
|
-
/**
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
+
/** Badge junto al label — string shorthand ('NEW') o SuiBadgeConfig
|
|
2774
|
+
(label + color/variant/size, tipado como sui-badge). null = sin badge. */
|
|
2775
|
+
badge = input(null, ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
|
|
2776
|
+
badgeCfg = computed(() => {
|
|
2777
|
+
const b = this.badge();
|
|
2778
|
+
return b ? (typeof b === 'string' ? { label: b } : b) : null;
|
|
2779
|
+
}, ...(ngDevMode ? [{ debugName: "badgeCfg" }] : /* istanbul ignore next */ []));
|
|
2773
2780
|
/** Texto del Link Button opcional debajo de la description. Solo se renderiza
|
|
2774
2781
|
cuando description tiene valor. */
|
|
2775
2782
|
linkLabel = input(null, ...(ngDevMode ? [{ debugName: "linkLabel" }] : /* istanbul ignore next */ []));
|
|
@@ -2835,13 +2842,13 @@ class SuiCheckboxLabel {
|
|
|
2835
2842
|
this._disabledByForm.set(isDisabled);
|
|
2836
2843
|
}
|
|
2837
2844
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiCheckboxLabel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2838
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiCheckboxLabel, isStandalone: true, selector: "sui-checkbox-label", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null },
|
|
2845
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiCheckboxLabel, isStandalone: true, selector: "sui-checkbox-label", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, linkLabel: { classPropertyName: "linkLabel", publicName: "linkLabel", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "flip", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { active: "activeChange", linkClick: "linkClick" }, host: { listeners: { "click": "onLabelClick($event)" }, properties: { "attr.data-sui-flip": "flip() ? \"\" : null", "attr.data-sui-with-description": "description() ? \"\" : null", "attr.data-sui-disabled": "isDisabled() ? \"\" : null" } }, providers: [
|
|
2839
2846
|
{
|
|
2840
2847
|
provide: NG_VALUE_ACCESSOR,
|
|
2841
2848
|
useExisting: forwardRef(() => SuiCheckboxLabel),
|
|
2842
2849
|
multi: true,
|
|
2843
2850
|
},
|
|
2844
|
-
], ngImport: i0, template: "<!-- Layout flex: el orden visual depende de [flip]. CSS rota via `order` para\n mantener un solo DOM order accesible (checkbox primero). -->\n<sui-checkbox\n class=\"sui-checkbox-label__checkbox\"\n [checked]=\"active()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onCheckboxChange($event)\"\n/>\n\n<div class=\"sui-checkbox-label__content\">\n <!-- Bloque de texto: Title + Description van pegados (gap-4 en Figma). -->\n <div class=\"sui-checkbox-label__text\">\n <div class=\"sui-checkbox-label__title\">\n <span class=\"sui-checkbox-label__label\">{{ label() }}</span>\n @if (sublabel(); as sl) {\n <span class=\"sui-checkbox-label__sublabel\">{{ sl }}</span>\n }\n @if (
|
|
2851
|
+
], ngImport: i0, template: "<!-- Layout flex: el orden visual depende de [flip]. CSS rota via `order` para\n mantener un solo DOM order accesible (checkbox primero). -->\n<sui-checkbox\n class=\"sui-checkbox-label__checkbox\"\n [checked]=\"active()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onCheckboxChange($event)\"\n/>\n\n<div class=\"sui-checkbox-label__content\">\n <!-- Bloque de texto: Title + Description van pegados (gap-4 en Figma). -->\n <div class=\"sui-checkbox-label__text\">\n <div class=\"sui-checkbox-label__title\">\n <span class=\"sui-checkbox-label__label\">{{ label() }}</span>\n @if (sublabel(); as sl) {\n <span class=\"sui-checkbox-label__sublabel\">{{ sl }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <sui-badge\n class=\"sui-checkbox-label__badge\"\n [color]=\"bcfg.color ?? 'orange'\"\n [variant]=\"bcfg.variant ?? 'light'\"\n [size]=\"bcfg.size ?? 'small'\"\n >{{ bcfg.label }}</sui-badge>\n }\n </div>\n\n @if (description(); as desc) {\n <p class=\"sui-checkbox-label__description\">{{ desc }}</p>\n }\n </div>\n\n @if (description() && linkLabel(); as link) {\n <sui-link-button\n variant=\"primary\"\n size=\"small\"\n [disabled]=\"isDisabled()\"\n (clicked)=\"onLinkClick($event)\"\n >{{ link }}</sui-link-button>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;align-items:flex-start;gap:8px;cursor:pointer;font-family:var(--sui-font-sans, \"Inter\", system-ui, sans-serif);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0;-webkit-tap-highlight-color:transparent}:host([data-sui-flip]) .sui-checkbox-label__checkbox{order:2}:host([data-sui-flip]) .sui-checkbox-label__content{order:1}:host([data-sui-disabled]){cursor:not-allowed}:host([data-sui-disabled]) .sui-checkbox-label__content{opacity:.5}.sui-checkbox-label__checkbox{flex-shrink:0}.sui-checkbox-label__content{display:flex;flex:1 0 0;min-width:0;flex-direction:column;align-items:flex-start;gap:4px}:host([data-sui-with-description]) .sui-checkbox-label__content{gap:10px}.sui-checkbox-label__text{display:flex;flex-direction:column;align-items:flex-start;gap:4px;width:100%}.sui-checkbox-label__title{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.sui-checkbox-label__label{font-size:14px;font-weight:400;line-height:20px;letter-spacing:-.084px;color:var(--sui-text-strong-950)}:host([data-sui-with-description]) .sui-checkbox-label__label{font-weight:500}.sui-checkbox-label__sublabel{font-size:12px;font-weight:400;line-height:16px;letter-spacing:0;color:var(--sui-text-sub-600)}.sui-checkbox-label__badge{flex-shrink:0}.sui-checkbox-label__description{margin:0;font-size:12px;font-weight:400;line-height:16px;letter-spacing:0;color:var(--sui-text-sub-600);word-break:break-word}\n"], dependencies: [{ kind: "component", type: SuiCheckbox, selector: "sui-checkbox", inputs: ["size", "checked", "indeterminate", "disabled"], outputs: ["checkedChange"] }, { kind: "component", type: SuiBadge, selector: "sui-badge", inputs: ["color", "variant", "size", "type", "disabled"] }, { kind: "component", type: SuiLinkButton, selector: "sui-link-button", inputs: ["variant", "size", "underline", "disabled", "leftIcon", "rightIcon", "href", "target", "rel", "type", "ariaLabel"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2845
2852
|
}
|
|
2846
2853
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiCheckboxLabel, decorators: [{
|
|
2847
2854
|
type: Component,
|
|
@@ -2856,8 +2863,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
2856
2863
|
'[attr.data-sui-with-description]': 'description() ? "" : null',
|
|
2857
2864
|
'[attr.data-sui-disabled]': 'isDisabled() ? "" : null',
|
|
2858
2865
|
'(click)': 'onLabelClick($event)',
|
|
2859
|
-
}, template: "<!-- Layout flex: el orden visual depende de [flip]. CSS rota via `order` para\n mantener un solo DOM order accesible (checkbox primero). -->\n<sui-checkbox\n class=\"sui-checkbox-label__checkbox\"\n [checked]=\"active()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onCheckboxChange($event)\"\n/>\n\n<div class=\"sui-checkbox-label__content\">\n <!-- Bloque de texto: Title + Description van pegados (gap-4 en Figma). -->\n <div class=\"sui-checkbox-label__text\">\n <div class=\"sui-checkbox-label__title\">\n <span class=\"sui-checkbox-label__label\">{{ label() }}</span>\n @if (sublabel(); as sl) {\n <span class=\"sui-checkbox-label__sublabel\">{{ sl }}</span>\n }\n @if (
|
|
2860
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }],
|
|
2866
|
+
}, template: "<!-- Layout flex: el orden visual depende de [flip]. CSS rota via `order` para\n mantener un solo DOM order accesible (checkbox primero). -->\n<sui-checkbox\n class=\"sui-checkbox-label__checkbox\"\n [checked]=\"active()\"\n [indeterminate]=\"indeterminate()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onCheckboxChange($event)\"\n/>\n\n<div class=\"sui-checkbox-label__content\">\n <!-- Bloque de texto: Title + Description van pegados (gap-4 en Figma). -->\n <div class=\"sui-checkbox-label__text\">\n <div class=\"sui-checkbox-label__title\">\n <span class=\"sui-checkbox-label__label\">{{ label() }}</span>\n @if (sublabel(); as sl) {\n <span class=\"sui-checkbox-label__sublabel\">{{ sl }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <sui-badge\n class=\"sui-checkbox-label__badge\"\n [color]=\"bcfg.color ?? 'orange'\"\n [variant]=\"bcfg.variant ?? 'light'\"\n [size]=\"bcfg.size ?? 'small'\"\n >{{ bcfg.label }}</sui-badge>\n }\n </div>\n\n @if (description(); as desc) {\n <p class=\"sui-checkbox-label__description\">{{ desc }}</p>\n }\n </div>\n\n @if (description() && linkLabel(); as link) {\n <sui-link-button\n variant=\"primary\"\n size=\"small\"\n [disabled]=\"isDisabled()\"\n (clicked)=\"onLinkClick($event)\"\n >{{ link }}</sui-link-button>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;align-items:flex-start;gap:8px;cursor:pointer;font-family:var(--sui-font-sans, \"Inter\", system-ui, sans-serif);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0;-webkit-tap-highlight-color:transparent}:host([data-sui-flip]) .sui-checkbox-label__checkbox{order:2}:host([data-sui-flip]) .sui-checkbox-label__content{order:1}:host([data-sui-disabled]){cursor:not-allowed}:host([data-sui-disabled]) .sui-checkbox-label__content{opacity:.5}.sui-checkbox-label__checkbox{flex-shrink:0}.sui-checkbox-label__content{display:flex;flex:1 0 0;min-width:0;flex-direction:column;align-items:flex-start;gap:4px}:host([data-sui-with-description]) .sui-checkbox-label__content{gap:10px}.sui-checkbox-label__text{display:flex;flex-direction:column;align-items:flex-start;gap:4px;width:100%}.sui-checkbox-label__title{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.sui-checkbox-label__label{font-size:14px;font-weight:400;line-height:20px;letter-spacing:-.084px;color:var(--sui-text-strong-950)}:host([data-sui-with-description]) .sui-checkbox-label__label{font-weight:500}.sui-checkbox-label__sublabel{font-size:12px;font-weight:400;line-height:16px;letter-spacing:0;color:var(--sui-text-sub-600)}.sui-checkbox-label__badge{flex-shrink:0}.sui-checkbox-label__description{margin:0;font-size:12px;font-weight:400;line-height:16px;letter-spacing:0;color:var(--sui-text-sub-600);word-break:break-word}\n"] }]
|
|
2867
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], linkLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "linkLabel", required: false }] }], flip: [{ type: i0.Input, args: [{ isSignal: true, alias: "flip", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }, { type: i0.Output, args: ["activeChange"] }], linkClick: [{ type: i0.Output, args: ["linkClick"] }] } });
|
|
2861
2868
|
|
|
2862
2869
|
/**
|
|
2863
2870
|
* sui-circular-progress-bar — SUI Design System 2.0 · Circular Progress Bar
|
|
@@ -3143,6 +3150,218 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
3143
3150
|
}, template: "<button\n type=\"button\"\n class=\"sui-color-dot__inner\"\n role=\"radio\"\n [disabled]=\"state() === 'disabled' || null\"\n [attr.aria-checked]=\"state() === 'selected' ? 'true' : 'false'\"\n [attr.aria-label]=\"ariaLabel() || defaultAriaLabel()\"\n (click)=\"onClick()\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n></button>\n", styles: ["@charset \"UTF-8\";:host{display:inline-block;width:24px;height:24px;vertical-align:middle;--c: var(--sui-neutral-500)}:host([data-sui-color=gray]){--c: var(--sui-neutral-500)}:host([data-sui-color=blue]){--c: var(--sui-blue-500)}:host([data-sui-color=orange]){--c: var(--sui-orange-500)}:host([data-sui-color=red]){--c: var(--sui-red-500)}:host([data-sui-color=green]){--c: var(--sui-green-500)}:host([data-sui-color=yellow]){--c: var(--sui-yellow-500)}:host([data-sui-color=purple]){--c: var(--sui-purple-500)}:host([data-sui-color=sky]){--c: var(--sui-sky-500)}:host([data-sui-color=pink]){--c: var(--sui-pink-500)}:host([data-sui-color=teal]){--c: var(--sui-teal-500)}:host([data-sui-state=disabled]){--c: var(--sui-bg-soft-200)}.sui-color-dot__inner{position:relative;display:block;width:24px;height:24px;padding:0;margin:0;border:none;background:transparent;cursor:pointer;appearance:none;outline:none;border-radius:50%;transition:transform var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}.sui-color-dot__inner:after{content:\"\";position:absolute;inset:4px;border-radius:50%;background:var(--c);transition:inset var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}:host([data-sui-state=selected]) .sui-color-dot__inner:after{inset:6px}.sui-color-dot__inner:before{content:\"\";position:absolute;inset:3px;border-radius:50%;border:2px solid transparent;transition:border-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}:host([data-sui-state=selected]) .sui-color-dot__inner:before{border-color:var(--c)}.sui-color-dot__inner:active{transform:none}:host([data-sui-state=default]) .sui-color-dot__inner:hover:after,:host([data-sui-state=hover]) .sui-color-dot__inner:after{inset:5px}.sui-color-dot__inner:focus-visible{outline:2px solid var(--c);outline-offset:2px}:host([data-sui-state=disabled]) .sui-color-dot__inner{cursor:not-allowed;pointer-events:none}\n"] }]
|
|
3144
3151
|
}], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], customHex: [{ type: i0.Input, args: [{ isSignal: true, alias: "customHex", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
|
|
3145
3152
|
|
|
3153
|
+
/**
|
|
3154
|
+
* Structural directive — marca un `<ng-template>` como panel del
|
|
3155
|
+
* sui-dropdown-menu. El componente padre captura este TemplateRef
|
|
3156
|
+
* via `@ContentChild(SuiDropdownPanel)` y lo monta en el CDK Overlay
|
|
3157
|
+
* cuando se abre el menu.
|
|
3158
|
+
*
|
|
3159
|
+
* Usa el patrón canon Angular (similar a `*matMenuContent` de Material):
|
|
3160
|
+
* un directive que se aplica al `<ng-template>` SE convierte en una
|
|
3161
|
+
* marca semántica, evitando que Angular renderee el contenido inline
|
|
3162
|
+
* cuando no hay `<ng-content>` matching para el template.
|
|
3163
|
+
*
|
|
3164
|
+
* Uso:
|
|
3165
|
+
* <sui-dropdown-menu>
|
|
3166
|
+
* <sui-compact-select trigger ... />
|
|
3167
|
+
* <ng-template suiDropdownPanel>
|
|
3168
|
+
* <sui-dropdown-item ...></sui-dropdown-item>
|
|
3169
|
+
* </ng-template>
|
|
3170
|
+
* </sui-dropdown-menu>
|
|
3171
|
+
*/
|
|
3172
|
+
class SuiDropdownPanel {
|
|
3173
|
+
template = inject(TemplateRef);
|
|
3174
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiDropdownPanel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3175
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: SuiDropdownPanel, isStandalone: true, selector: "ng-template[suiDropdownPanel]", ngImport: i0 });
|
|
3176
|
+
}
|
|
3177
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiDropdownPanel, decorators: [{
|
|
3178
|
+
type: Directive,
|
|
3179
|
+
args: [{
|
|
3180
|
+
selector: 'ng-template[suiDropdownPanel]',
|
|
3181
|
+
standalone: true,
|
|
3182
|
+
}]
|
|
3183
|
+
}] });
|
|
3184
|
+
|
|
3185
|
+
/* Posiciones con fallback HORIZONTAL: la primera (start-aligned, abre a la
|
|
3186
|
+
derecha) es la default; si el trigger está pegado al borde derecho y no entra,
|
|
3187
|
+
CDK cae a la end-aligned (abre hacia la izquierda) y recién después flipea
|
|
3188
|
+
vertical. Sin esto, un trigger en la esquina derecha (ej. kebab ⋮ de una card)
|
|
3189
|
+
recorta el panel fuera del viewport. */
|
|
3190
|
+
const POSITIONS_BELOW = [
|
|
3191
|
+
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
3192
|
+
{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
|
|
3193
|
+
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
3194
|
+
{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
|
|
3195
|
+
];
|
|
3196
|
+
const POSITIONS_ABOVE = [
|
|
3197
|
+
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
3198
|
+
{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
|
|
3199
|
+
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
3200
|
+
{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
|
|
3201
|
+
];
|
|
3202
|
+
class SuiDropdownMenu {
|
|
3203
|
+
/** Si true, el panel matchea el ancho del trigger. Default: auto width. */
|
|
3204
|
+
matchWidth = input(false, ...(ngDevMode ? [{ debugName: "matchWidth" }] : /* istanbul ignore next */ []));
|
|
3205
|
+
/** Min-width fijo del panel (px). Si matchWidth + minWidth: `max(triggerWidth, minWidth)`. */
|
|
3206
|
+
minWidth = input(null, ...(ngDevMode ? [{ debugName: "minWidth" }] : /* istanbul ignore next */ []));
|
|
3207
|
+
/** Position primary. Default: auto = below con fallback above. */
|
|
3208
|
+
position = input('auto', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
3209
|
+
/** Margen 8px del viewport edge (canon SUI). */
|
|
3210
|
+
viewportMargin = input(8, ...(ngDevMode ? [{ debugName: "viewportMargin" }] : /* istanbul ignore next */ []));
|
|
3211
|
+
/** Panel custom class para overrides de bg/padding/etc desde el consumer. */
|
|
3212
|
+
panelClass = input('', ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
|
|
3213
|
+
/** Disabled — no abre el menu al clickear el trigger. */
|
|
3214
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
3215
|
+
/**
|
|
3216
|
+
* Rol del popup para `aria-haspopup` del trigger. Default 'menu' (los items
|
|
3217
|
+
* proyectados llevan role="menuitem"). Los consumers de tipo listbox
|
|
3218
|
+
* (sui-select / compact-selects, items con role="option") DEBEN pasar
|
|
3219
|
+
* `popupRole="listbox"`. Ver SuiDropdownMenuPopupRole.
|
|
3220
|
+
*/
|
|
3221
|
+
popupRole = input('menu', ...(ngDevMode ? [{ debugName: "popupRole" }] : /* istanbul ignore next */ []));
|
|
3222
|
+
/**
|
|
3223
|
+
* Origin externo. Si presente, el menu se ancla a ese elemento y NO renderea
|
|
3224
|
+
* el trigger wrapper interno (el parent maneja el click). Caso de uso:
|
|
3225
|
+
* compact-selects donde el host element es el trigger visual.
|
|
3226
|
+
*/
|
|
3227
|
+
origin = input(null, ...(ngDevMode ? [{ debugName: "origin" }] : /* istanbul ignore next */ []));
|
|
3228
|
+
openedChange = output();
|
|
3229
|
+
/** Signal pública — wire al `[open]` del trigger para visual state. */
|
|
3230
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
3231
|
+
/** Wrapper del trigger projection — captura el click. NO existe si `[origin]` se pasa. */
|
|
3232
|
+
_triggerWrap;
|
|
3233
|
+
/** Panel directive proyectado — capturado via `[suiDropdownPanel]` en un ng-template. */
|
|
3234
|
+
_panel;
|
|
3235
|
+
_getTriggerEl() {
|
|
3236
|
+
const o = this.origin();
|
|
3237
|
+
if (o)
|
|
3238
|
+
return o instanceof ElementRef ? o.nativeElement : o;
|
|
3239
|
+
return this._triggerWrap?.nativeElement ?? null;
|
|
3240
|
+
}
|
|
3241
|
+
_vcr = inject(ViewContainerRef);
|
|
3242
|
+
_destroyRef = inject(DestroyRef);
|
|
3243
|
+
_overlay = inject(Overlay);
|
|
3244
|
+
_overlayRef = null;
|
|
3245
|
+
_overlaySubs = null;
|
|
3246
|
+
_resizeObserver = null;
|
|
3247
|
+
constructor() {
|
|
3248
|
+
this._destroyRef.onDestroy(() => this.close());
|
|
3249
|
+
}
|
|
3250
|
+
onTriggerClick(event) {
|
|
3251
|
+
if (this.disabled())
|
|
3252
|
+
return;
|
|
3253
|
+
event.stopPropagation();
|
|
3254
|
+
this.toggle();
|
|
3255
|
+
}
|
|
3256
|
+
onTriggerKeydown(event) {
|
|
3257
|
+
if (this.disabled())
|
|
3258
|
+
return;
|
|
3259
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
3260
|
+
event.preventDefault();
|
|
3261
|
+
this.toggle();
|
|
3262
|
+
}
|
|
3263
|
+
else if (event.key === 'ArrowDown') {
|
|
3264
|
+
event.preventDefault();
|
|
3265
|
+
this.open();
|
|
3266
|
+
}
|
|
3267
|
+
}
|
|
3268
|
+
toggle() {
|
|
3269
|
+
if (this.isOpen())
|
|
3270
|
+
this.close();
|
|
3271
|
+
else
|
|
3272
|
+
this.open();
|
|
3273
|
+
}
|
|
3274
|
+
open() {
|
|
3275
|
+
if (this.disabled() || this._overlayRef || !this._panel)
|
|
3276
|
+
return;
|
|
3277
|
+
const triggerEl = this._getTriggerEl();
|
|
3278
|
+
if (!triggerEl)
|
|
3279
|
+
return;
|
|
3280
|
+
const positions = this.position() === 'above' ? POSITIONS_ABOVE : POSITIONS_BELOW;
|
|
3281
|
+
const positionStrategy = this._overlay
|
|
3282
|
+
.position()
|
|
3283
|
+
.flexibleConnectedTo(triggerEl)
|
|
3284
|
+
.withPositions(positions)
|
|
3285
|
+
.withPush(false)
|
|
3286
|
+
.withFlexibleDimensions(true)
|
|
3287
|
+
.withViewportMargin(this.viewportMargin());
|
|
3288
|
+
const triggerWidth = triggerEl.getBoundingClientRect().width;
|
|
3289
|
+
const minW = this.minWidth();
|
|
3290
|
+
const effectiveMinWidth = this.matchWidth() && minW !== null
|
|
3291
|
+
? Math.max(triggerWidth, minW)
|
|
3292
|
+
: minW;
|
|
3293
|
+
const config = {
|
|
3294
|
+
positionStrategy,
|
|
3295
|
+
scrollStrategy: this._overlay.scrollStrategies.reposition(),
|
|
3296
|
+
hasBackdrop: true,
|
|
3297
|
+
backdropClass: 'cdk-overlay-transparent-backdrop',
|
|
3298
|
+
panelClass: ['sui-dropdown-menu__overlay-pane', this.panelClass()].filter(Boolean),
|
|
3299
|
+
disposeOnNavigation: true,
|
|
3300
|
+
};
|
|
3301
|
+
if (this.matchWidth() && minW === null) {
|
|
3302
|
+
config.width = `${triggerWidth}px`;
|
|
3303
|
+
}
|
|
3304
|
+
if (effectiveMinWidth !== null) {
|
|
3305
|
+
config.minWidth = effectiveMinWidth;
|
|
3306
|
+
}
|
|
3307
|
+
this._overlayRef = this._overlay.create(config);
|
|
3308
|
+
const portal = new TemplatePortal(this._panel.template, this._vcr);
|
|
3309
|
+
this._overlayRef.attach(portal);
|
|
3310
|
+
/* Width sync mientras el viewport cambia (canon sui-select). Solo aplica
|
|
3311
|
+
cuando matchWidth fija width o minWidth — para que el panel siga el trigger. */
|
|
3312
|
+
if (this.matchWidth() && typeof ResizeObserver !== 'undefined') {
|
|
3313
|
+
this._resizeObserver = new ResizeObserver(() => {
|
|
3314
|
+
if (!this._overlayRef)
|
|
3315
|
+
return;
|
|
3316
|
+
const w = triggerEl.getBoundingClientRect().width;
|
|
3317
|
+
if (minW === null) {
|
|
3318
|
+
this._overlayRef.updateSize({ width: `${w}px` });
|
|
3319
|
+
}
|
|
3320
|
+
else {
|
|
3321
|
+
this._overlayRef.updateSize({ minWidth: Math.max(w, minW) });
|
|
3322
|
+
}
|
|
3323
|
+
this._overlayRef.updatePosition();
|
|
3324
|
+
});
|
|
3325
|
+
this._resizeObserver.observe(triggerEl);
|
|
3326
|
+
}
|
|
3327
|
+
this._overlaySubs = new Subscription();
|
|
3328
|
+
this._overlaySubs.add(this._overlayRef.backdropClick().subscribe(() => this.close()));
|
|
3329
|
+
this._overlaySubs.add(this._overlayRef.keydownEvents().subscribe((e) => {
|
|
3330
|
+
if (e.key === 'Escape')
|
|
3331
|
+
this.close();
|
|
3332
|
+
}));
|
|
3333
|
+
this._overlaySubs.add(this._overlayRef.detachments().subscribe(() => {
|
|
3334
|
+
this.isOpen.set(false);
|
|
3335
|
+
}));
|
|
3336
|
+
this.isOpen.set(true);
|
|
3337
|
+
this.openedChange.emit(true);
|
|
3338
|
+
}
|
|
3339
|
+
close() {
|
|
3340
|
+
if (!this._overlayRef)
|
|
3341
|
+
return;
|
|
3342
|
+
this._overlaySubs?.unsubscribe();
|
|
3343
|
+
this._overlaySubs = null;
|
|
3344
|
+
this._resizeObserver?.disconnect();
|
|
3345
|
+
this._resizeObserver = null;
|
|
3346
|
+
this._overlayRef.dispose();
|
|
3347
|
+
this._overlayRef = null;
|
|
3348
|
+
this.isOpen.set(false);
|
|
3349
|
+
this.openedChange.emit(false);
|
|
3350
|
+
}
|
|
3351
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiDropdownMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3352
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiDropdownMenu, isStandalone: true, selector: "sui-dropdown-menu", inputs: { matchWidth: { classPropertyName: "matchWidth", publicName: "matchWidth", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, viewportMargin: { classPropertyName: "viewportMargin", publicName: "viewportMargin", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, popupRole: { classPropertyName: "popupRole", publicName: "popupRole", isSignal: true, isRequired: false, transformFunction: null }, origin: { classPropertyName: "origin", publicName: "origin", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openedChange: "openedChange" }, queries: [{ propertyName: "_panel", first: true, predicate: SuiDropdownPanel, descendants: true }], viewQueries: [{ propertyName: "_triggerWrap", first: true, predicate: ["triggerWrap"], descendants: true }], exportAs: ["suiDropdownMenu"], ngImport: i0, template: "<!-- Trigger wrapper \u2014 captura click y keydown del trigger child. Solo se\n renderea cuando NO se pasa [origin] (modo content-projection canon).\n Cuando se pasa [origin], el parent maneja el trigger y llama\n menu.toggle() desde su propio click handler. -->\n@if (!origin()) {\n <span\n #triggerWrap\n class=\"sui-dropdown-menu__trigger\"\n [attr.aria-haspopup]=\"popupRole()\"\n [attr.aria-expanded]=\"isOpen()\"\n (click)=\"onTriggerClick($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <ng-content select=\"[trigger]\" />\n </span>\n}\n", styles: ["@charset \"UTF-8\";:host{display:contents}.sui-dropdown-menu__trigger{display:inline-block;cursor:pointer;outline:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3353
|
+
}
|
|
3354
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiDropdownMenu, decorators: [{
|
|
3355
|
+
type: Component,
|
|
3356
|
+
args: [{ selector: 'sui-dropdown-menu', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, exportAs: 'suiDropdownMenu', template: "<!-- Trigger wrapper \u2014 captura click y keydown del trigger child. Solo se\n renderea cuando NO se pasa [origin] (modo content-projection canon).\n Cuando se pasa [origin], el parent maneja el trigger y llama\n menu.toggle() desde su propio click handler. -->\n@if (!origin()) {\n <span\n #triggerWrap\n class=\"sui-dropdown-menu__trigger\"\n [attr.aria-haspopup]=\"popupRole()\"\n [attr.aria-expanded]=\"isOpen()\"\n (click)=\"onTriggerClick($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <ng-content select=\"[trigger]\" />\n </span>\n}\n", styles: ["@charset \"UTF-8\";:host{display:contents}.sui-dropdown-menu__trigger{display:inline-block;cursor:pointer;outline:none}\n"] }]
|
|
3357
|
+
}], ctorParameters: () => [], propDecorators: { matchWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "matchWidth", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], viewportMargin: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewportMargin", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], popupRole: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupRole", required: false }] }], origin: [{ type: i0.Input, args: [{ isSignal: true, alias: "origin", required: false }] }], openedChange: [{ type: i0.Output, args: ["openedChange"] }], _triggerWrap: [{
|
|
3358
|
+
type: ViewChild,
|
|
3359
|
+
args: ['triggerWrap', { static: false }]
|
|
3360
|
+
}], _panel: [{
|
|
3361
|
+
type: ContentChild,
|
|
3362
|
+
args: [SuiDropdownPanel]
|
|
3363
|
+
}] } });
|
|
3364
|
+
|
|
3146
3365
|
/* ════════════════════════════════════════════════════════════════════════
|
|
3147
3366
|
* HSV ↔ RGB ↔ HEX conversion helpers
|
|
3148
3367
|
*
|
|
@@ -3391,6 +3610,7 @@ class SuiColorPicker {
|
|
|
3391
3610
|
/** Hex input visible (separate del value model para validación en blur). */
|
|
3392
3611
|
hexInput = signal('', ...(ngDevMode ? [{ debugName: "hexInput" }] : /* istanbul ignore next */ []));
|
|
3393
3612
|
/** Refs del spectrum y sliders para cálculos de bounds */
|
|
3613
|
+
_menu = viewChild(SuiDropdownMenu, ...(ngDevMode ? [{ debugName: "_menu" }] : /* istanbul ignore next */ []));
|
|
3394
3614
|
canvasRef = viewChild('canvas', ...(ngDevMode ? [{ debugName: "canvasRef" }] : /* istanbul ignore next */ []));
|
|
3395
3615
|
hueRef = viewChild('hueSlider', ...(ngDevMode ? [{ debugName: "hueRef" }] : /* istanbul ignore next */ []));
|
|
3396
3616
|
opacityRef = viewChild('opacitySlider', ...(ngDevMode ? [{ debugName: "opacityRef" }] : /* istanbul ignore next */ []));
|
|
@@ -3577,17 +3797,21 @@ class SuiColorPicker {
|
|
|
3577
3797
|
toggle() {
|
|
3578
3798
|
if (this.disabled())
|
|
3579
3799
|
return;
|
|
3580
|
-
this.
|
|
3581
|
-
|
|
3582
|
-
|
|
3800
|
+
this._menu()?.toggle();
|
|
3801
|
+
}
|
|
3802
|
+
close() {
|
|
3803
|
+
this._menu()?.close();
|
|
3804
|
+
}
|
|
3805
|
+
/** El sui-dropdown-menu (CDK overlay) es el dueño del open/close: acá solo se
|
|
3806
|
+
sincroniza el signal `open` (aria-expanded, chevron, data-sui-open) y el
|
|
3807
|
+
hex input al abrir. Backdrop + Esc + detachments los maneja el menu. */
|
|
3808
|
+
onMenuOpenedChange(opened) {
|
|
3809
|
+
this.open.set(opened);
|
|
3810
|
+
if (opened) {
|
|
3583
3811
|
const parsed = parseHexWithAlpha(this.value());
|
|
3584
3812
|
this.hexInput.set(parsed?.hex ?? '');
|
|
3585
3813
|
}
|
|
3586
3814
|
}
|
|
3587
|
-
close() {
|
|
3588
|
-
if (this.open())
|
|
3589
|
-
this.open.set(false);
|
|
3590
|
-
}
|
|
3591
3815
|
/* ─────────── Recommended dot click ─────────── */
|
|
3592
3816
|
onPresetClick(preset) {
|
|
3593
3817
|
// setColor atómico → garantiza que value, HSV y hexInput queden
|
|
@@ -3761,34 +3985,17 @@ class SuiColorPicker {
|
|
|
3761
3985
|
// user canceló (Esc) — no-op.
|
|
3762
3986
|
}
|
|
3763
3987
|
}
|
|
3764
|
-
/* ─────────── Outside click + Esc ─────────── */
|
|
3765
|
-
onDocumentClick(target) {
|
|
3766
|
-
if (!this.open())
|
|
3767
|
-
return;
|
|
3768
|
-
if (target instanceof Node && !this.hostRef.nativeElement.contains(target)) {
|
|
3769
|
-
this.close();
|
|
3770
|
-
}
|
|
3771
|
-
}
|
|
3772
|
-
onEscape() {
|
|
3773
|
-
this.close();
|
|
3774
|
-
}
|
|
3775
3988
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiColorPicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3776
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiColorPicker, isStandalone: true, selector: "sui-color-picker", inputs: { colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, recommendedLabel: { classPropertyName: "recommendedLabel", publicName: "recommendedLabel", isSignal: true, isRequired: false, transformFunction: null }, presetsOnly: { classPropertyName: "presetsOnly", publicName: "presetsOnly", isSignal: true, isRequired: false, transformFunction: null }, alpha: { classPropertyName: "alpha", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null }, eyedropper: { classPropertyName: "eyedropper", publicName: "eyedropper", isSignal: true, isRequired: false, transformFunction: null }, showFormatLabel: { classPropertyName: "showFormatLabel", publicName: "showFormatLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", change: "change" }, host: { listeners: { "document:click": "onDocumentClick($event.target)", "document:keydown.escape": "onEscape()" }, properties: { "attr.data-sui-open": "open() ? \"\" : null", "attr.data-sui-disabled": "disabled() ? \"\" : null", "attr.data-sui-presets-only": "presetsOnly() ? \"\" : null" } }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, isSignal: true }, { propertyName: "hueRef", first: true, predicate: ["hueSlider"], descendants: true, isSignal: true }, { propertyName: "opacityRef", first: true, predicate: ["opacitySlider"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n type=\"button\"\n class=\"sui-color-picker__trigger\"\n [disabled]=\"disabled() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-expanded]=\"open() ? 'true' : 'false'\"\n (click)=\"toggle()\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n>\n @if (value()) {\n @if (currentPreset()) {\n <sui-color-dot [color]=\"currentPreset()!\" state=\"selected\" class=\"sui-color-picker__preview\" />\n } @else {\n <sui-color-dot [customHex]=\"previewColor()\" state=\"selected\" class=\"sui-color-picker__preview\" />\n }\n } @else {\n <span class=\"sui-color-picker__placeholder-dot\" aria-hidden=\"true\"></span>\n }\n <span class=\"sui-color-picker__label\">{{ currentLabel() }}</span>\n <sui-icon name=\"arrow-down-s-line\" [size]=\"16\" class=\"sui-color-picker__chevron\" />\n</button>\n\n@if (open()) {\n <div\n class=\"sui-color-picker__panel\"\n role=\"dialog\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n @if (!presetsOnly()) {\n <!-- Secci\u00F3n \"Colors\" \u2014 Figma 4456:115716 -->\n <div class=\"sui-color-picker__section sui-color-picker__section--colors\">\n <!-- HSV Color Spectrum \u2014 Figma 4456:115425 -->\n <div\n #canvas\n class=\"sui-color-picker__canvas\"\n role=\"application\"\n aria-label=\"Saturaci\u00F3n y brillo\"\n [style.--hue-color]=\"hueColor()\"\n (pointerdown)=\"onCanvasPointerDown($event)\"\n (pointermove)=\"onCanvasPointerMove($event)\"\n (pointerup)=\"onCanvasPointerUp($event)\"\n (pointercancel)=\"onCanvasPointerUp($event)\"\n >\n <div\n class=\"sui-color-picker__canvas-thumb\"\n [style.left]=\"canvasThumbX()\"\n [style.top]=\"canvasThumbY()\"\n [style.background-color]=\"currentHex()\"\n ></div>\n </div>\n\n <!-- Hue slider \u2014 Figma 4415:53669 -->\n <div\n #hueSlider\n class=\"sui-color-picker__slider sui-color-picker__hue\"\n role=\"slider\"\n aria-label=\"Matiz\"\n aria-valuemin=\"0\"\n aria-valuemax=\"360\"\n [attr.aria-valuenow]=\"hueRounded()\"\n (pointerdown)=\"onHuePointerDown($event)\"\n (pointermove)=\"onHuePointerMove($event)\"\n (pointerup)=\"onHuePointerUp($event)\"\n (pointercancel)=\"onHuePointerUp($event)\"\n >\n <div class=\"sui-color-picker__slider-track\"></div>\n <div\n class=\"sui-color-picker__slider-thumb\"\n [style.left]=\"hueThumbX()\"\n [style.background-color]=\"hueColor()\"\n ></div>\n </div>\n\n <!-- Opacity slider \u2014 Figma 4415:53670. Visible por default (alpha on);\n ocultable con [alpha]=false. -->\n @if (alpha()) {\n <div\n #opacitySlider\n class=\"sui-color-picker__slider sui-color-picker__opacity\"\n role=\"slider\"\n aria-label=\"Opacidad\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [attr.aria-valuenow]=\"alphaPercent()\"\n [style.--opacity-color]=\"opacityColor()\"\n (pointerdown)=\"onOpacityPointerDown($event)\"\n (pointermove)=\"onOpacityPointerMove($event)\"\n (pointerup)=\"onOpacityPointerUp($event)\"\n (pointercancel)=\"onOpacityPointerUp($event)\"\n >\n <div class=\"sui-color-picker__slider-track\"></div>\n <div\n class=\"sui-color-picker__slider-thumb\"\n [style.left]=\"opacityThumbX()\"\n [style.--thumb-color]=\"opacityThumbColor()\"\n ></div>\n </div>\n }\n\n <!-- Color Input \u2014 Figma 4456:115720 -->\n <div class=\"sui-color-picker__color-input\">\n <!-- Format label \"Hex\" + chevron \u2014 Figma 4456:115721.\n Hex-only por ahora (ver PENDING VERIFY en el .ts). -->\n @if (showFormatLabel()) {\n <div class=\"sui-color-picker__format\" aria-hidden=\"true\">\n <span class=\"sui-color-picker__format-label\">Hex</span>\n <sui-icon name=\"arrow-down-s-line\" [size]=\"20\" class=\"sui-color-picker__format-chevron\" />\n </div>\n }\n\n <!-- Input row \u2014 Figma 4456:115724: sip | hex | opacity -->\n <div class=\"sui-color-picker__input-row\">\n <!-- Sip (eyedropper) \u2014 Figma 4456:115796. Solo con EyeDropper API. -->\n @if (showEyedropper()) {\n <button\n type=\"button\"\n class=\"sui-color-picker__sip\"\n aria-label=\"Cuentagotas\"\n (click)=\"onEyedropper()\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n >\n <sui-icon name=\"sip-line\" [size]=\"20\" />\n </button>\n }\n\n <!-- Hex field \u2014 Figma 4456:115725 / 4456:115726: el texto va SIN\n prefijo '#' (Figma muestra \"335CFF\" pelado dentro de la celda). -->\n <div class=\"sui-color-picker__hex-cell\">\n <input\n class=\"sui-color-picker__hex-field\"\n type=\"text\"\n inputmode=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n maxlength=\"8\"\n aria-label=\"Valor hexadecimal\"\n [value]=\"hexDisplayValue()\"\n (input)=\"onHexInputChange($event)\"\n (keydown)=\"onHexKeyDown($event)\"\n (blur)=\"onHexCommit()\"\n />\n </div>\n\n <!-- Opacity field \"%\" \u2014 Figma 4456:115727. Visible por default\n (alpha on); ocultable con [alpha]=false. -->\n @if (alpha()) {\n <div class=\"sui-color-picker__opacity-cell\">\n <input\n class=\"sui-color-picker__opacity-field\"\n type=\"text\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"3\"\n aria-label=\"Opacidad\"\n [value]=\"alphaPercent()\"\n (change)=\"onOpacityFieldCommit($event)\"\n (keydown)=\"onHexKeyDown($event)\"\n />\n <span class=\"sui-color-picker__opacity-suffix\" aria-hidden=\"true\">%</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Secci\u00F3n \"Recommended Colors\" \u2014 Figma 4456:115765 -->\n <div class=\"sui-color-picker__section sui-color-picker__section--recommended\">\n <p class=\"sui-color-picker__panel-label\">{{ recommendedLabel() }}</p>\n <div class=\"sui-color-picker__grid\" role=\"radiogroup\">\n @for (c of colors(); track c) {\n <sui-color-dot\n [color]=\"c\"\n [state]=\"currentPreset() === c ? 'selected' : 'default'\"\n (clicked)=\"onPresetClick(c)\"\n />\n }\n </div>\n </div>\n </div>\n}\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:inline-block;font-family:var(--sui-font-sans);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-color-picker__trigger{display:inline-flex;align-items:center;gap:8px;padding:6px 10px 6px 6px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-8);cursor:pointer;appearance:none;font:inherit;color:var(--sui-text-strong-950);font-size:var(--sui-type-label-sm-size);font-weight:var(--sui-type-label-sm-weight);line-height:var(--sui-type-label-sm-line);letter-spacing:var(--sui-type-label-sm-spacing);transition:background-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out),border-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}.sui-color-picker__trigger:hover{background:var(--sui-bg-weak-50)}:host([data-sui-open]) .sui-color-picker__trigger{border-color:var(--sui-stroke-strong-950, var(--sui-text-strong-950))}.sui-color-picker__trigger:focus-visible{outline:2px solid var(--sui-stroke-strong-950, var(--sui-text-strong-950));outline-offset:2px}.sui-color-picker__trigger:active{transform:none}:host([data-sui-disabled]) .sui-color-picker__trigger{background:var(--sui-bg-weak-50);color:var(--sui-text-disabled-300);cursor:not-allowed;pointer-events:none}.sui-color-picker__placeholder-dot{display:inline-block;width:24px;height:24px;border-radius:50%;background:var(--sui-bg-soft-200)}.sui-color-picker__label{flex:1 0 auto;white-space:nowrap}.sui-color-picker__chevron{flex-shrink:0;color:var(--sui-icon-sub-600);transition:transform var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}:host([data-sui-open]) .sui-color-picker__chevron{transform:rotate(180deg)}.sui-color-picker__panel{position:absolute;top:calc(100% + 6px);left:0;z-index:100;width:272px;box-sizing:border-box;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-16);box-shadow:var(--sui-shadow-medium);overflow:hidden;display:flex;flex-direction:column;animation:sui-color-picker__fade var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}@keyframes sui-color-picker__fade{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sui-color-picker__section{box-sizing:border-box;display:flex;flex-direction:column;gap:12px;padding:16px;width:100%}.sui-color-picker__section--colors{border-bottom:1px solid var(--sui-stroke-soft-200)}.sui-color-picker__section--recommended{gap:8px}:host([data-sui-presets-only]) .sui-color-picker__section--recommended{border-bottom:none}.sui-color-picker__canvas{position:relative;width:100%;height:232px;border-radius:var(--sui-radius-8);cursor:crosshair;-webkit-user-select:none;user-select:none;touch-action:none;overflow:hidden;background-color:var(--hue-color, #335cff);background-image:linear-gradient(to top,#000,#0000),linear-gradient(to right,#fff,#fff0)}.sui-color-picker__canvas-thumb{position:absolute;width:16px;height:16px;border-radius:50%;border:2px solid var(--sui-static-white, #fff);box-shadow:0 0 0 1px #00000026,0 1px 2px #0003;transform:translate(-50%,-50%);pointer-events:none}.sui-color-picker__slider{position:relative;width:100%;height:16px;cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:none}.sui-color-picker__slider-track{position:absolute;left:0;right:0;top:4px;height:8px;border-radius:var(--sui-radius-full);overflow:hidden}.sui-color-picker__hue .sui-color-picker__slider-track{background-image:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.sui-color-picker__opacity .sui-color-picker__slider-track{background-color:#fff;background-image:linear-gradient(to right,transparent,var(--opacity-color, #335cff)),conic-gradient(#ebebeb 0 25%,transparent 0 50%,#ebebeb 0 75%,transparent 0);background-size:auto,10.88px 10.88px}.sui-color-picker__slider-thumb{position:absolute;top:50%;width:16px;height:16px;border-radius:50%;border:2px solid var(--sui-static-white, #fff);box-shadow:0 0 0 1px #00000026,0 1px 2px #0003;transform:translate(-50%,-50%);pointer-events:none}.sui-color-picker__opacity .sui-color-picker__slider-thumb{background-image:linear-gradient(var(--thumb-color, #335cff),var(--thumb-color, #335cff)),conic-gradient(#ebebeb 0 25%,#fff 0 50%,#ebebeb 0 75%,#fff 0);background-size:auto,6px 6px}.sui-color-picker__color-input{display:flex;flex-direction:column;gap:4px;width:100%}.sui-color-picker__format{display:flex;align-items:center;gap:2px;appearance:none;border:none;background:transparent;padding:0;cursor:default;font:inherit;color:var(--sui-text-strong-950)}.sui-color-picker__format-label{font-size:var(--sui-type-label-sm-size);font-weight:var(--sui-type-label-sm-weight);line-height:var(--sui-type-label-sm-line);letter-spacing:var(--sui-type-label-sm-spacing);white-space:nowrap}.sui-color-picker__format-chevron{flex-shrink:0;color:var(--sui-icon-sub-600)}.sui-color-picker__input-row{box-sizing:border-box;display:flex;align-items:stretch;width:100%;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-8);overflow:hidden}.sui-color-picker__sip{display:flex;align-items:center;justify-content:center;padding:6px;border:none;border-right:1px solid var(--sui-stroke-soft-200);background:var(--sui-bg-white-0);color:var(--sui-icon-sub-600);cursor:pointer;appearance:none;flex-shrink:0;transition:background-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}.sui-color-picker__sip:hover{background:var(--sui-bg-weak-50)}.sui-color-picker__sip:focus-visible{outline:2px solid var(--sui-stroke-strong-950, var(--sui-text-strong-950));outline-offset:-2px}.sui-color-picker__sip:active{transform:none}.sui-color-picker__hex-cell{box-sizing:border-box;display:flex;align-items:center;flex:1 0 0;min-width:0;padding:6px 10px;border-right:1px solid var(--sui-stroke-soft-200)}.sui-color-picker__hex-cell:last-child{border-right:none}.sui-color-picker__hex-field{flex:1 0 0;min-width:0;width:100%;border:none;outline:none;background:transparent;padding:0;appearance:none;color:var(--sui-text-strong-950);font-family:inherit;font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing);text-transform:uppercase}.sui-color-picker__hex-field::placeholder{color:var(--sui-text-soft-400);text-transform:none}.sui-color-picker__opacity-cell{box-sizing:border-box;display:flex;align-items:center;flex-shrink:0;padding:6px 10px}.sui-color-picker__opacity-field{width:3.5ch;border:none;outline:none;background:transparent;padding:0;appearance:none;text-align:right;color:var(--sui-text-sub-600);font-family:inherit;font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing)}.sui-color-picker__opacity-suffix{color:var(--sui-text-sub-600);font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing)}.sui-color-picker__panel-label{margin:0;font-size:var(--sui-type-paragraph-xs-size);font-weight:var(--sui-type-paragraph-xs-weight);line-height:var(--sui-type-paragraph-xs-line);letter-spacing:var(--sui-type-paragraph-xs-spacing);color:var(--sui-text-sub-600)}.sui-color-picker__grid{display:flex;flex-wrap:wrap;gap:4px;width:100%}\n"], dependencies: [{ kind: "component", type: SuiIcon, selector: "sui-icon", inputs: ["name", "size", "color"] }, { kind: "component", type: SuiColorDot, selector: "sui-color-dot", inputs: ["color", "customHex", "state", "ariaLabel"], outputs: ["clicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3989
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiColorPicker, isStandalone: true, selector: "sui-color-picker", inputs: { colors: { classPropertyName: "colors", publicName: "colors", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, recommendedLabel: { classPropertyName: "recommendedLabel", publicName: "recommendedLabel", isSignal: true, isRequired: false, transformFunction: null }, presetsOnly: { classPropertyName: "presetsOnly", publicName: "presetsOnly", isSignal: true, isRequired: false, transformFunction: null }, alpha: { classPropertyName: "alpha", publicName: "alpha", isSignal: true, isRequired: false, transformFunction: null }, eyedropper: { classPropertyName: "eyedropper", publicName: "eyedropper", isSignal: true, isRequired: false, transformFunction: null }, showFormatLabel: { classPropertyName: "showFormatLabel", publicName: "showFormatLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", change: "change" }, host: { properties: { "attr.data-sui-open": "open() ? \"\" : null", "attr.data-sui-disabled": "disabled() ? \"\" : null", "attr.data-sui-presets-only": "presetsOnly() ? \"\" : null" } }, viewQueries: [{ propertyName: "_menu", first: true, predicate: SuiDropdownMenu, descendants: true, isSignal: true }, { propertyName: "canvasRef", first: true, predicate: ["canvas"], descendants: true, isSignal: true }, { propertyName: "hueRef", first: true, predicate: ["hueSlider"], descendants: true, isSignal: true }, { propertyName: "opacityRef", first: true, predicate: ["opacitySlider"], descendants: true, isSignal: true }], ngImport: i0, template: "<button\n #trigger\n type=\"button\"\n class=\"sui-color-picker__trigger\"\n [disabled]=\"disabled() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-expanded]=\"open() ? 'true' : 'false'\"\n (click)=\"toggle()\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n>\n @if (value()) {\n @if (currentPreset()) {\n <sui-color-dot [color]=\"currentPreset()!\" state=\"selected\" class=\"sui-color-picker__preview\" />\n } @else {\n <sui-color-dot [customHex]=\"previewColor()\" state=\"selected\" class=\"sui-color-picker__preview\" />\n }\n } @else {\n <span class=\"sui-color-picker__placeholder-dot\" aria-hidden=\"true\"></span>\n }\n <span class=\"sui-color-picker__label\">{{ currentLabel() }}</span>\n <sui-icon name=\"arrow-down-s-line\" [size]=\"16\" class=\"sui-color-picker__chevron\" />\n</button>\n\n<!-- Panel en CDK overlay (via sui-dropdown-menu): escapa cualquier overflow\n clipping del contenedor (Storybook docs, modales, tablas). El contenido del\n ng-template mantiene el scoping de estilos del componente. -->\n<sui-dropdown-menu\n [origin]=\"trigger\"\n [disabled]=\"disabled()\"\n panelClass=\"sui-color-picker__overlay-pane\"\n (openedChange)=\"onMenuOpenedChange($event)\"\n>\n <ng-template suiDropdownPanel>\n <div\n class=\"sui-color-picker__panel\"\n role=\"dialog\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n @if (!presetsOnly()) {\n <!-- Secci\u00F3n \"Colors\" \u2014 Figma 4456:115716 -->\n <div class=\"sui-color-picker__section sui-color-picker__section--colors\">\n <!-- HSV Color Spectrum \u2014 Figma 4456:115425 -->\n <div\n #canvas\n class=\"sui-color-picker__canvas\"\n role=\"application\"\n aria-label=\"Saturaci\u00F3n y brillo\"\n [style.--hue-color]=\"hueColor()\"\n (pointerdown)=\"onCanvasPointerDown($event)\"\n (pointermove)=\"onCanvasPointerMove($event)\"\n (pointerup)=\"onCanvasPointerUp($event)\"\n (pointercancel)=\"onCanvasPointerUp($event)\"\n >\n <div\n class=\"sui-color-picker__canvas-thumb\"\n [style.left]=\"canvasThumbX()\"\n [style.top]=\"canvasThumbY()\"\n [style.background-color]=\"currentHex()\"\n ></div>\n </div>\n\n <!-- Hue slider \u2014 Figma 4415:53669 -->\n <div\n #hueSlider\n class=\"sui-color-picker__slider sui-color-picker__hue\"\n role=\"slider\"\n aria-label=\"Matiz\"\n aria-valuemin=\"0\"\n aria-valuemax=\"360\"\n [attr.aria-valuenow]=\"hueRounded()\"\n (pointerdown)=\"onHuePointerDown($event)\"\n (pointermove)=\"onHuePointerMove($event)\"\n (pointerup)=\"onHuePointerUp($event)\"\n (pointercancel)=\"onHuePointerUp($event)\"\n >\n <div class=\"sui-color-picker__slider-track\"></div>\n <div\n class=\"sui-color-picker__slider-thumb\"\n [style.left]=\"hueThumbX()\"\n [style.background-color]=\"hueColor()\"\n ></div>\n </div>\n\n <!-- Opacity slider \u2014 Figma 4415:53670. Visible por default (alpha on);\n ocultable con [alpha]=false. -->\n @if (alpha()) {\n <div\n #opacitySlider\n class=\"sui-color-picker__slider sui-color-picker__opacity\"\n role=\"slider\"\n aria-label=\"Opacidad\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [attr.aria-valuenow]=\"alphaPercent()\"\n [style.--opacity-color]=\"opacityColor()\"\n (pointerdown)=\"onOpacityPointerDown($event)\"\n (pointermove)=\"onOpacityPointerMove($event)\"\n (pointerup)=\"onOpacityPointerUp($event)\"\n (pointercancel)=\"onOpacityPointerUp($event)\"\n >\n <div class=\"sui-color-picker__slider-track\"></div>\n <div\n class=\"sui-color-picker__slider-thumb\"\n [style.left]=\"opacityThumbX()\"\n [style.--thumb-color]=\"opacityThumbColor()\"\n ></div>\n </div>\n }\n\n <!-- Color Input \u2014 Figma 4456:115720 -->\n <div class=\"sui-color-picker__color-input\">\n <!-- Format label \"Hex\" + chevron \u2014 Figma 4456:115721.\n Hex-only por ahora (ver PENDING VERIFY en el .ts). -->\n @if (showFormatLabel()) {\n <div class=\"sui-color-picker__format\" aria-hidden=\"true\">\n <span class=\"sui-color-picker__format-label\">Hex</span>\n <sui-icon name=\"arrow-down-s-line\" [size]=\"20\" class=\"sui-color-picker__format-chevron\" />\n </div>\n }\n\n <!-- Input row \u2014 Figma 4456:115724: sip | hex | opacity -->\n <div class=\"sui-color-picker__input-row\">\n <!-- Sip (eyedropper) \u2014 Figma 4456:115796. Solo con EyeDropper API. -->\n @if (showEyedropper()) {\n <button\n type=\"button\"\n class=\"sui-color-picker__sip\"\n aria-label=\"Cuentagotas\"\n (click)=\"onEyedropper()\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n >\n <sui-icon name=\"sip-line\" [size]=\"20\" />\n </button>\n }\n\n <!-- Hex field \u2014 Figma 4456:115725 / 4456:115726: el texto va SIN\n prefijo '#' (Figma muestra \"335CFF\" pelado dentro de la celda). -->\n <div class=\"sui-color-picker__hex-cell\">\n <input\n class=\"sui-color-picker__hex-field\"\n type=\"text\"\n inputmode=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n maxlength=\"8\"\n aria-label=\"Valor hexadecimal\"\n [value]=\"hexDisplayValue()\"\n (input)=\"onHexInputChange($event)\"\n (keydown)=\"onHexKeyDown($event)\"\n (blur)=\"onHexCommit()\"\n />\n </div>\n\n <!-- Opacity field \"%\" \u2014 Figma 4456:115727. Visible por default\n (alpha on); ocultable con [alpha]=false. -->\n @if (alpha()) {\n <div class=\"sui-color-picker__opacity-cell\">\n <input\n class=\"sui-color-picker__opacity-field\"\n type=\"text\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"3\"\n aria-label=\"Opacidad\"\n [value]=\"alphaPercent()\"\n (change)=\"onOpacityFieldCommit($event)\"\n (keydown)=\"onHexKeyDown($event)\"\n />\n <span class=\"sui-color-picker__opacity-suffix\" aria-hidden=\"true\">%</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Secci\u00F3n \"Recommended Colors\" \u2014 Figma 4456:115765 -->\n <div class=\"sui-color-picker__section sui-color-picker__section--recommended\">\n <p class=\"sui-color-picker__panel-label\">{{ recommendedLabel() }}</p>\n <div class=\"sui-color-picker__grid\" role=\"radiogroup\">\n @for (c of colors(); track c) {\n <sui-color-dot\n [color]=\"c\"\n [state]=\"currentPreset() === c ? 'selected' : 'default'\"\n (clicked)=\"onPresetClick(c)\"\n />\n }\n </div>\n </div>\n </div>\n </ng-template>\n</sui-dropdown-menu>\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:inline-block;font-family:var(--sui-font-sans);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-color-picker__trigger{display:inline-flex;align-items:center;gap:8px;padding:6px 10px 6px 6px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-8);cursor:pointer;appearance:none;font:inherit;color:var(--sui-text-strong-950);font-size:var(--sui-type-label-sm-size);font-weight:var(--sui-type-label-sm-weight);line-height:var(--sui-type-label-sm-line);letter-spacing:var(--sui-type-label-sm-spacing);transition:background-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out),border-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}.sui-color-picker__trigger:hover{background:var(--sui-bg-weak-50)}:host([data-sui-open]) .sui-color-picker__trigger{border-color:var(--sui-stroke-strong-950, var(--sui-text-strong-950))}.sui-color-picker__trigger:focus-visible{outline:2px solid var(--sui-stroke-strong-950, var(--sui-text-strong-950));outline-offset:2px}.sui-color-picker__trigger:active{transform:none}:host([data-sui-disabled]) .sui-color-picker__trigger{background:var(--sui-bg-weak-50);color:var(--sui-text-disabled-300);cursor:not-allowed;pointer-events:none}.sui-color-picker__placeholder-dot{display:inline-block;width:24px;height:24px;border-radius:50%;background:var(--sui-bg-soft-200)}.sui-color-picker__label{flex:1 0 auto;white-space:nowrap}.sui-color-picker__chevron{flex-shrink:0;color:var(--sui-icon-sub-600);transition:transform var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}:host([data-sui-open]) .sui-color-picker__chevron{transform:rotate(180deg)}.sui-color-picker__panel{width:272px;margin-top:6px;box-sizing:border-box;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-16);box-shadow:var(--sui-shadow-medium);overflow:hidden;display:flex;flex-direction:column;animation:sui-color-picker__fade var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}@keyframes sui-color-picker__fade{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sui-color-picker__section{box-sizing:border-box;display:flex;flex-direction:column;gap:12px;padding:16px;width:100%}.sui-color-picker__section--colors{border-bottom:1px solid var(--sui-stroke-soft-200)}.sui-color-picker__section--recommended{gap:8px}:host([data-sui-presets-only]) .sui-color-picker__section--recommended{border-bottom:none}.sui-color-picker__canvas{position:relative;width:100%;height:232px;border-radius:var(--sui-radius-8);cursor:crosshair;-webkit-user-select:none;user-select:none;touch-action:none;overflow:hidden;background-color:var(--hue-color, #335cff);background-image:linear-gradient(to top,#000,#0000),linear-gradient(to right,#fff,#fff0)}.sui-color-picker__canvas-thumb{position:absolute;width:16px;height:16px;border-radius:50%;border:2px solid var(--sui-static-white, #fff);box-shadow:0 0 0 1px #00000026,0 1px 2px #0003;transform:translate(-50%,-50%);pointer-events:none}.sui-color-picker__slider{position:relative;width:100%;height:16px;cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:none}.sui-color-picker__slider-track{position:absolute;left:0;right:0;top:4px;height:8px;border-radius:var(--sui-radius-full);overflow:hidden}.sui-color-picker__hue .sui-color-picker__slider-track{background-image:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.sui-color-picker__opacity .sui-color-picker__slider-track{background-color:#fff;background-image:linear-gradient(to right,transparent,var(--opacity-color, #335cff)),conic-gradient(#ebebeb 0 25%,transparent 0 50%,#ebebeb 0 75%,transparent 0);background-size:auto,10.88px 10.88px}.sui-color-picker__slider-thumb{position:absolute;top:50%;width:16px;height:16px;border-radius:50%;border:2px solid var(--sui-static-white, #fff);box-shadow:0 0 0 1px #00000026,0 1px 2px #0003;transform:translate(-50%,-50%);pointer-events:none}.sui-color-picker__opacity .sui-color-picker__slider-thumb{background-image:linear-gradient(var(--thumb-color, #335cff),var(--thumb-color, #335cff)),conic-gradient(#ebebeb 0 25%,#fff 0 50%,#ebebeb 0 75%,#fff 0);background-size:auto,6px 6px}.sui-color-picker__color-input{display:flex;flex-direction:column;gap:4px;width:100%}.sui-color-picker__format{display:flex;align-items:center;gap:2px;appearance:none;border:none;background:transparent;padding:0;cursor:default;font:inherit;color:var(--sui-text-strong-950)}.sui-color-picker__format-label{font-size:var(--sui-type-label-sm-size);font-weight:var(--sui-type-label-sm-weight);line-height:var(--sui-type-label-sm-line);letter-spacing:var(--sui-type-label-sm-spacing);white-space:nowrap}.sui-color-picker__format-chevron{flex-shrink:0;color:var(--sui-icon-sub-600)}.sui-color-picker__input-row{box-sizing:border-box;display:flex;align-items:stretch;width:100%;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-8);overflow:hidden}.sui-color-picker__sip{display:flex;align-items:center;justify-content:center;padding:6px;border:none;border-right:1px solid var(--sui-stroke-soft-200);background:var(--sui-bg-white-0);color:var(--sui-icon-sub-600);cursor:pointer;appearance:none;flex-shrink:0;transition:background-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}.sui-color-picker__sip:hover{background:var(--sui-bg-weak-50)}.sui-color-picker__sip:focus-visible{outline:2px solid var(--sui-stroke-strong-950, var(--sui-text-strong-950));outline-offset:-2px}.sui-color-picker__sip:active{transform:none}.sui-color-picker__hex-cell{box-sizing:border-box;display:flex;align-items:center;flex:1 0 0;min-width:0;padding:6px 10px;border-right:1px solid var(--sui-stroke-soft-200)}.sui-color-picker__hex-cell:last-child{border-right:none}.sui-color-picker__hex-field{flex:1 0 0;min-width:0;width:100%;border:none;outline:none;background:transparent;padding:0;appearance:none;color:var(--sui-text-strong-950);font-family:inherit;font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing);text-transform:uppercase}.sui-color-picker__hex-field::placeholder{color:var(--sui-text-soft-400);text-transform:none}.sui-color-picker__opacity-cell{box-sizing:border-box;display:flex;align-items:center;flex-shrink:0;padding:6px 10px}.sui-color-picker__opacity-field{width:3.5ch;border:none;outline:none;background:transparent;padding:0;appearance:none;text-align:right;color:var(--sui-text-sub-600);font-family:inherit;font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing)}.sui-color-picker__opacity-suffix{color:var(--sui-text-sub-600);font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing)}.sui-color-picker__panel-label{margin:0;font-size:var(--sui-type-paragraph-xs-size);font-weight:var(--sui-type-paragraph-xs-weight);line-height:var(--sui-type-paragraph-xs-line);letter-spacing:var(--sui-type-paragraph-xs-spacing);color:var(--sui-text-sub-600)}.sui-color-picker__grid{display:flex;flex-wrap:wrap;gap:4px;width:100%}\n"], dependencies: [{ kind: "component", type: SuiIcon, selector: "sui-icon", inputs: ["name", "size", "color"] }, { kind: "component", type: SuiColorDot, selector: "sui-color-dot", inputs: ["color", "customHex", "state", "ariaLabel"], outputs: ["clicked"] }, { kind: "component", type: SuiDropdownMenu, selector: "sui-dropdown-menu", inputs: ["matchWidth", "minWidth", "position", "viewportMargin", "panelClass", "disabled", "popupRole", "origin"], outputs: ["openedChange"], exportAs: ["suiDropdownMenu"] }, { kind: "directive", type: SuiDropdownPanel, selector: "ng-template[suiDropdownPanel]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3777
3990
|
}
|
|
3778
3991
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiColorPicker, decorators: [{
|
|
3779
3992
|
type: Component,
|
|
3780
|
-
args: [{ selector: 'sui-color-picker', standalone: true, imports: [SuiIcon, SuiColorDot], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
3993
|
+
args: [{ selector: 'sui-color-picker', standalone: true, imports: [SuiIcon, SuiColorDot, SuiDropdownMenu, SuiDropdownPanel], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
3781
3994
|
'[attr.data-sui-open]': 'open() ? "" : null',
|
|
3782
3995
|
'[attr.data-sui-disabled]': 'disabled() ? "" : null',
|
|
3783
3996
|
'[attr.data-sui-presets-only]': 'presetsOnly() ? "" : null',
|
|
3784
|
-
}, template: "<button\n type=\"button\"\n class=\"sui-color-picker__trigger\"\n [disabled]=\"disabled() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-expanded]=\"open() ? 'true' : 'false'\"\n (click)=\"toggle()\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n>\n @if (value()) {\n @if (currentPreset()) {\n <sui-color-dot [color]=\"currentPreset()!\" state=\"selected\" class=\"sui-color-picker__preview\" />\n } @else {\n <sui-color-dot [customHex]=\"previewColor()\" state=\"selected\" class=\"sui-color-picker__preview\" />\n }\n } @else {\n <span class=\"sui-color-picker__placeholder-dot\" aria-hidden=\"true\"></span>\n }\n <span class=\"sui-color-picker__label\">{{ currentLabel() }}</span>\n <sui-icon name=\"arrow-down-s-line\" [size]=\"16\" class=\"sui-color-picker__chevron\" />\n</button>\n\n@if (open()) {\n <div\n class=\"sui-color-picker__panel\"\n role=\"dialog\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n @if (!presetsOnly()) {\n <!-- Secci\u00F3n \"Colors\" \u2014 Figma 4456:115716 -->\n <div class=\"sui-color-picker__section sui-color-picker__section--colors\">\n <!-- HSV Color Spectrum \u2014 Figma 4456:115425 -->\n <div\n #canvas\n class=\"sui-color-picker__canvas\"\n role=\"application\"\n aria-label=\"Saturaci\u00F3n y brillo\"\n [style.--hue-color]=\"hueColor()\"\n (pointerdown)=\"onCanvasPointerDown($event)\"\n (pointermove)=\"onCanvasPointerMove($event)\"\n (pointerup)=\"onCanvasPointerUp($event)\"\n (pointercancel)=\"onCanvasPointerUp($event)\"\n >\n <div\n class=\"sui-color-picker__canvas-thumb\"\n [style.left]=\"canvasThumbX()\"\n [style.top]=\"canvasThumbY()\"\n [style.background-color]=\"currentHex()\"\n ></div>\n </div>\n\n <!-- Hue slider \u2014 Figma 4415:53669 -->\n <div\n #hueSlider\n class=\"sui-color-picker__slider sui-color-picker__hue\"\n role=\"slider\"\n aria-label=\"Matiz\"\n aria-valuemin=\"0\"\n aria-valuemax=\"360\"\n [attr.aria-valuenow]=\"hueRounded()\"\n (pointerdown)=\"onHuePointerDown($event)\"\n (pointermove)=\"onHuePointerMove($event)\"\n (pointerup)=\"onHuePointerUp($event)\"\n (pointercancel)=\"onHuePointerUp($event)\"\n >\n <div class=\"sui-color-picker__slider-track\"></div>\n <div\n class=\"sui-color-picker__slider-thumb\"\n [style.left]=\"hueThumbX()\"\n [style.background-color]=\"hueColor()\"\n ></div>\n </div>\n\n <!-- Opacity slider \u2014 Figma 4415:53670. Visible por default (alpha on);\n ocultable con [alpha]=false. -->\n @if (alpha()) {\n <div\n #opacitySlider\n class=\"sui-color-picker__slider sui-color-picker__opacity\"\n role=\"slider\"\n aria-label=\"Opacidad\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [attr.aria-valuenow]=\"alphaPercent()\"\n [style.--opacity-color]=\"opacityColor()\"\n (pointerdown)=\"onOpacityPointerDown($event)\"\n (pointermove)=\"onOpacityPointerMove($event)\"\n (pointerup)=\"onOpacityPointerUp($event)\"\n (pointercancel)=\"onOpacityPointerUp($event)\"\n >\n <div class=\"sui-color-picker__slider-track\"></div>\n <div\n class=\"sui-color-picker__slider-thumb\"\n [style.left]=\"opacityThumbX()\"\n [style.--thumb-color]=\"opacityThumbColor()\"\n ></div>\n </div>\n }\n\n <!-- Color Input \u2014 Figma 4456:115720 -->\n <div class=\"sui-color-picker__color-input\">\n <!-- Format label \"Hex\" + chevron \u2014 Figma 4456:115721.\n Hex-only por ahora (ver PENDING VERIFY en el .ts). -->\n @if (showFormatLabel()) {\n <div class=\"sui-color-picker__format\" aria-hidden=\"true\">\n <span class=\"sui-color-picker__format-label\">Hex</span>\n <sui-icon name=\"arrow-down-s-line\" [size]=\"20\" class=\"sui-color-picker__format-chevron\" />\n </div>\n }\n\n <!-- Input row \u2014 Figma 4456:115724: sip | hex | opacity -->\n <div class=\"sui-color-picker__input-row\">\n <!-- Sip (eyedropper) \u2014 Figma 4456:115796. Solo con EyeDropper API. -->\n @if (showEyedropper()) {\n <button\n type=\"button\"\n class=\"sui-color-picker__sip\"\n aria-label=\"Cuentagotas\"\n (click)=\"onEyedropper()\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n >\n <sui-icon name=\"sip-line\" [size]=\"20\" />\n </button>\n }\n\n <!-- Hex field \u2014 Figma 4456:115725 / 4456:115726: el texto va SIN\n prefijo '#' (Figma muestra \"335CFF\" pelado dentro de la celda). -->\n <div class=\"sui-color-picker__hex-cell\">\n <input\n class=\"sui-color-picker__hex-field\"\n type=\"text\"\n inputmode=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n maxlength=\"8\"\n aria-label=\"Valor hexadecimal\"\n [value]=\"hexDisplayValue()\"\n (input)=\"onHexInputChange($event)\"\n (keydown)=\"onHexKeyDown($event)\"\n (blur)=\"onHexCommit()\"\n />\n </div>\n\n <!-- Opacity field \"%\" \u2014 Figma 4456:115727. Visible por default\n (alpha on); ocultable con [alpha]=false. -->\n @if (alpha()) {\n <div class=\"sui-color-picker__opacity-cell\">\n <input\n class=\"sui-color-picker__opacity-field\"\n type=\"text\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"3\"\n aria-label=\"Opacidad\"\n [value]=\"alphaPercent()\"\n (change)=\"onOpacityFieldCommit($event)\"\n (keydown)=\"onHexKeyDown($event)\"\n />\n <span class=\"sui-color-picker__opacity-suffix\" aria-hidden=\"true\">%</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Secci\u00F3n \"Recommended Colors\" \u2014 Figma 4456:115765 -->\n <div class=\"sui-color-picker__section sui-color-picker__section--recommended\">\n <p class=\"sui-color-picker__panel-label\">{{ recommendedLabel() }}</p>\n <div class=\"sui-color-picker__grid\" role=\"radiogroup\">\n @for (c of colors(); track c) {\n <sui-color-dot\n [color]=\"c\"\n [state]=\"currentPreset() === c ? 'selected' : 'default'\"\n (clicked)=\"onPresetClick(c)\"\n />\n }\n </div>\n </div>\n </div>\n}\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:inline-block;font-family:var(--sui-font-sans);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-color-picker__trigger{display:inline-flex;align-items:center;gap:8px;padding:6px 10px 6px 6px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-8);cursor:pointer;appearance:none;font:inherit;color:var(--sui-text-strong-950);font-size:var(--sui-type-label-sm-size);font-weight:var(--sui-type-label-sm-weight);line-height:var(--sui-type-label-sm-line);letter-spacing:var(--sui-type-label-sm-spacing);transition:background-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out),border-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}.sui-color-picker__trigger:hover{background:var(--sui-bg-weak-50)}:host([data-sui-open]) .sui-color-picker__trigger{border-color:var(--sui-stroke-strong-950, var(--sui-text-strong-950))}.sui-color-picker__trigger:focus-visible{outline:2px solid var(--sui-stroke-strong-950, var(--sui-text-strong-950));outline-offset:2px}.sui-color-picker__trigger:active{transform:none}:host([data-sui-disabled]) .sui-color-picker__trigger{background:var(--sui-bg-weak-50);color:var(--sui-text-disabled-300);cursor:not-allowed;pointer-events:none}.sui-color-picker__placeholder-dot{display:inline-block;width:24px;height:24px;border-radius:50%;background:var(--sui-bg-soft-200)}.sui-color-picker__label{flex:1 0 auto;white-space:nowrap}.sui-color-picker__chevron{flex-shrink:0;color:var(--sui-icon-sub-600);transition:transform var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}:host([data-sui-open]) .sui-color-picker__chevron{transform:rotate(180deg)}.sui-color-picker__panel{position:absolute;top:calc(100% + 6px);left:0;z-index:100;width:272px;box-sizing:border-box;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-16);box-shadow:var(--sui-shadow-medium);overflow:hidden;display:flex;flex-direction:column;animation:sui-color-picker__fade var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}@keyframes sui-color-picker__fade{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sui-color-picker__section{box-sizing:border-box;display:flex;flex-direction:column;gap:12px;padding:16px;width:100%}.sui-color-picker__section--colors{border-bottom:1px solid var(--sui-stroke-soft-200)}.sui-color-picker__section--recommended{gap:8px}:host([data-sui-presets-only]) .sui-color-picker__section--recommended{border-bottom:none}.sui-color-picker__canvas{position:relative;width:100%;height:232px;border-radius:var(--sui-radius-8);cursor:crosshair;-webkit-user-select:none;user-select:none;touch-action:none;overflow:hidden;background-color:var(--hue-color, #335cff);background-image:linear-gradient(to top,#000,#0000),linear-gradient(to right,#fff,#fff0)}.sui-color-picker__canvas-thumb{position:absolute;width:16px;height:16px;border-radius:50%;border:2px solid var(--sui-static-white, #fff);box-shadow:0 0 0 1px #00000026,0 1px 2px #0003;transform:translate(-50%,-50%);pointer-events:none}.sui-color-picker__slider{position:relative;width:100%;height:16px;cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:none}.sui-color-picker__slider-track{position:absolute;left:0;right:0;top:4px;height:8px;border-radius:var(--sui-radius-full);overflow:hidden}.sui-color-picker__hue .sui-color-picker__slider-track{background-image:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.sui-color-picker__opacity .sui-color-picker__slider-track{background-color:#fff;background-image:linear-gradient(to right,transparent,var(--opacity-color, #335cff)),conic-gradient(#ebebeb 0 25%,transparent 0 50%,#ebebeb 0 75%,transparent 0);background-size:auto,10.88px 10.88px}.sui-color-picker__slider-thumb{position:absolute;top:50%;width:16px;height:16px;border-radius:50%;border:2px solid var(--sui-static-white, #fff);box-shadow:0 0 0 1px #00000026,0 1px 2px #0003;transform:translate(-50%,-50%);pointer-events:none}.sui-color-picker__opacity .sui-color-picker__slider-thumb{background-image:linear-gradient(var(--thumb-color, #335cff),var(--thumb-color, #335cff)),conic-gradient(#ebebeb 0 25%,#fff 0 50%,#ebebeb 0 75%,#fff 0);background-size:auto,6px 6px}.sui-color-picker__color-input{display:flex;flex-direction:column;gap:4px;width:100%}.sui-color-picker__format{display:flex;align-items:center;gap:2px;appearance:none;border:none;background:transparent;padding:0;cursor:default;font:inherit;color:var(--sui-text-strong-950)}.sui-color-picker__format-label{font-size:var(--sui-type-label-sm-size);font-weight:var(--sui-type-label-sm-weight);line-height:var(--sui-type-label-sm-line);letter-spacing:var(--sui-type-label-sm-spacing);white-space:nowrap}.sui-color-picker__format-chevron{flex-shrink:0;color:var(--sui-icon-sub-600)}.sui-color-picker__input-row{box-sizing:border-box;display:flex;align-items:stretch;width:100%;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-8);overflow:hidden}.sui-color-picker__sip{display:flex;align-items:center;justify-content:center;padding:6px;border:none;border-right:1px solid var(--sui-stroke-soft-200);background:var(--sui-bg-white-0);color:var(--sui-icon-sub-600);cursor:pointer;appearance:none;flex-shrink:0;transition:background-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}.sui-color-picker__sip:hover{background:var(--sui-bg-weak-50)}.sui-color-picker__sip:focus-visible{outline:2px solid var(--sui-stroke-strong-950, var(--sui-text-strong-950));outline-offset:-2px}.sui-color-picker__sip:active{transform:none}.sui-color-picker__hex-cell{box-sizing:border-box;display:flex;align-items:center;flex:1 0 0;min-width:0;padding:6px 10px;border-right:1px solid var(--sui-stroke-soft-200)}.sui-color-picker__hex-cell:last-child{border-right:none}.sui-color-picker__hex-field{flex:1 0 0;min-width:0;width:100%;border:none;outline:none;background:transparent;padding:0;appearance:none;color:var(--sui-text-strong-950);font-family:inherit;font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing);text-transform:uppercase}.sui-color-picker__hex-field::placeholder{color:var(--sui-text-soft-400);text-transform:none}.sui-color-picker__opacity-cell{box-sizing:border-box;display:flex;align-items:center;flex-shrink:0;padding:6px 10px}.sui-color-picker__opacity-field{width:3.5ch;border:none;outline:none;background:transparent;padding:0;appearance:none;text-align:right;color:var(--sui-text-sub-600);font-family:inherit;font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing)}.sui-color-picker__opacity-suffix{color:var(--sui-text-sub-600);font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing)}.sui-color-picker__panel-label{margin:0;font-size:var(--sui-type-paragraph-xs-size);font-weight:var(--sui-type-paragraph-xs-weight);line-height:var(--sui-type-paragraph-xs-line);letter-spacing:var(--sui-type-paragraph-xs-spacing);color:var(--sui-text-sub-600)}.sui-color-picker__grid{display:flex;flex-wrap:wrap;gap:4px;width:100%}\n"] }]
|
|
3785
|
-
}], propDecorators: { colors: [{ type: i0.Input, args: [{ isSignal: true, alias: "colors", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], recommendedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "recommendedLabel", required: false }] }], presetsOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "presetsOnly", required: false }] }], alpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "alpha", required: false }] }], eyedropper: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyedropper", required: false }] }], showFormatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFormatLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], change: [{ type: i0.Output, args: ["change"] }], canvasRef: [{ type: i0.ViewChild, args: ['canvas', { isSignal: true }] }], hueRef: [{ type: i0.ViewChild, args: ['hueSlider', { isSignal: true }] }], opacityRef: [{ type: i0.ViewChild, args: ['opacitySlider', { isSignal: true }] }]
|
|
3786
|
-
type: HostListener,
|
|
3787
|
-
args: ['document:click', ['$event.target']]
|
|
3788
|
-
}], onEscape: [{
|
|
3789
|
-
type: HostListener,
|
|
3790
|
-
args: ['document:keydown.escape']
|
|
3791
|
-
}] } });
|
|
3997
|
+
}, template: "<button\n #trigger\n type=\"button\"\n class=\"sui-color-picker__trigger\"\n [disabled]=\"disabled() || null\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-expanded]=\"open() ? 'true' : 'false'\"\n (click)=\"toggle()\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n>\n @if (value()) {\n @if (currentPreset()) {\n <sui-color-dot [color]=\"currentPreset()!\" state=\"selected\" class=\"sui-color-picker__preview\" />\n } @else {\n <sui-color-dot [customHex]=\"previewColor()\" state=\"selected\" class=\"sui-color-picker__preview\" />\n }\n } @else {\n <span class=\"sui-color-picker__placeholder-dot\" aria-hidden=\"true\"></span>\n }\n <span class=\"sui-color-picker__label\">{{ currentLabel() }}</span>\n <sui-icon name=\"arrow-down-s-line\" [size]=\"16\" class=\"sui-color-picker__chevron\" />\n</button>\n\n<!-- Panel en CDK overlay (via sui-dropdown-menu): escapa cualquier overflow\n clipping del contenedor (Storybook docs, modales, tablas). El contenido del\n ng-template mantiene el scoping de estilos del componente. -->\n<sui-dropdown-menu\n [origin]=\"trigger\"\n [disabled]=\"disabled()\"\n panelClass=\"sui-color-picker__overlay-pane\"\n (openedChange)=\"onMenuOpenedChange($event)\"\n>\n <ng-template suiDropdownPanel>\n <div\n class=\"sui-color-picker__panel\"\n role=\"dialog\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n @if (!presetsOnly()) {\n <!-- Secci\u00F3n \"Colors\" \u2014 Figma 4456:115716 -->\n <div class=\"sui-color-picker__section sui-color-picker__section--colors\">\n <!-- HSV Color Spectrum \u2014 Figma 4456:115425 -->\n <div\n #canvas\n class=\"sui-color-picker__canvas\"\n role=\"application\"\n aria-label=\"Saturaci\u00F3n y brillo\"\n [style.--hue-color]=\"hueColor()\"\n (pointerdown)=\"onCanvasPointerDown($event)\"\n (pointermove)=\"onCanvasPointerMove($event)\"\n (pointerup)=\"onCanvasPointerUp($event)\"\n (pointercancel)=\"onCanvasPointerUp($event)\"\n >\n <div\n class=\"sui-color-picker__canvas-thumb\"\n [style.left]=\"canvasThumbX()\"\n [style.top]=\"canvasThumbY()\"\n [style.background-color]=\"currentHex()\"\n ></div>\n </div>\n\n <!-- Hue slider \u2014 Figma 4415:53669 -->\n <div\n #hueSlider\n class=\"sui-color-picker__slider sui-color-picker__hue\"\n role=\"slider\"\n aria-label=\"Matiz\"\n aria-valuemin=\"0\"\n aria-valuemax=\"360\"\n [attr.aria-valuenow]=\"hueRounded()\"\n (pointerdown)=\"onHuePointerDown($event)\"\n (pointermove)=\"onHuePointerMove($event)\"\n (pointerup)=\"onHuePointerUp($event)\"\n (pointercancel)=\"onHuePointerUp($event)\"\n >\n <div class=\"sui-color-picker__slider-track\"></div>\n <div\n class=\"sui-color-picker__slider-thumb\"\n [style.left]=\"hueThumbX()\"\n [style.background-color]=\"hueColor()\"\n ></div>\n </div>\n\n <!-- Opacity slider \u2014 Figma 4415:53670. Visible por default (alpha on);\n ocultable con [alpha]=false. -->\n @if (alpha()) {\n <div\n #opacitySlider\n class=\"sui-color-picker__slider sui-color-picker__opacity\"\n role=\"slider\"\n aria-label=\"Opacidad\"\n aria-valuemin=\"0\"\n aria-valuemax=\"100\"\n [attr.aria-valuenow]=\"alphaPercent()\"\n [style.--opacity-color]=\"opacityColor()\"\n (pointerdown)=\"onOpacityPointerDown($event)\"\n (pointermove)=\"onOpacityPointerMove($event)\"\n (pointerup)=\"onOpacityPointerUp($event)\"\n (pointercancel)=\"onOpacityPointerUp($event)\"\n >\n <div class=\"sui-color-picker__slider-track\"></div>\n <div\n class=\"sui-color-picker__slider-thumb\"\n [style.left]=\"opacityThumbX()\"\n [style.--thumb-color]=\"opacityThumbColor()\"\n ></div>\n </div>\n }\n\n <!-- Color Input \u2014 Figma 4456:115720 -->\n <div class=\"sui-color-picker__color-input\">\n <!-- Format label \"Hex\" + chevron \u2014 Figma 4456:115721.\n Hex-only por ahora (ver PENDING VERIFY en el .ts). -->\n @if (showFormatLabel()) {\n <div class=\"sui-color-picker__format\" aria-hidden=\"true\">\n <span class=\"sui-color-picker__format-label\">Hex</span>\n <sui-icon name=\"arrow-down-s-line\" [size]=\"20\" class=\"sui-color-picker__format-chevron\" />\n </div>\n }\n\n <!-- Input row \u2014 Figma 4456:115724: sip | hex | opacity -->\n <div class=\"sui-color-picker__input-row\">\n <!-- Sip (eyedropper) \u2014 Figma 4456:115796. Solo con EyeDropper API. -->\n @if (showEyedropper()) {\n <button\n type=\"button\"\n class=\"sui-color-picker__sip\"\n aria-label=\"Cuentagotas\"\n (click)=\"onEyedropper()\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n >\n <sui-icon name=\"sip-line\" [size]=\"20\" />\n </button>\n }\n\n <!-- Hex field \u2014 Figma 4456:115725 / 4456:115726: el texto va SIN\n prefijo '#' (Figma muestra \"335CFF\" pelado dentro de la celda). -->\n <div class=\"sui-color-picker__hex-cell\">\n <input\n class=\"sui-color-picker__hex-field\"\n type=\"text\"\n inputmode=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n maxlength=\"8\"\n aria-label=\"Valor hexadecimal\"\n [value]=\"hexDisplayValue()\"\n (input)=\"onHexInputChange($event)\"\n (keydown)=\"onHexKeyDown($event)\"\n (blur)=\"onHexCommit()\"\n />\n </div>\n\n <!-- Opacity field \"%\" \u2014 Figma 4456:115727. Visible por default\n (alpha on); ocultable con [alpha]=false. -->\n @if (alpha()) {\n <div class=\"sui-color-picker__opacity-cell\">\n <input\n class=\"sui-color-picker__opacity-field\"\n type=\"text\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"3\"\n aria-label=\"Opacidad\"\n [value]=\"alphaPercent()\"\n (change)=\"onOpacityFieldCommit($event)\"\n (keydown)=\"onHexKeyDown($event)\"\n />\n <span class=\"sui-color-picker__opacity-suffix\" aria-hidden=\"true\">%</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Secci\u00F3n \"Recommended Colors\" \u2014 Figma 4456:115765 -->\n <div class=\"sui-color-picker__section sui-color-picker__section--recommended\">\n <p class=\"sui-color-picker__panel-label\">{{ recommendedLabel() }}</p>\n <div class=\"sui-color-picker__grid\" role=\"radiogroup\">\n @for (c of colors(); track c) {\n <sui-color-dot\n [color]=\"c\"\n [state]=\"currentPreset() === c ? 'selected' : 'default'\"\n (clicked)=\"onPresetClick(c)\"\n />\n }\n </div>\n </div>\n </div>\n </ng-template>\n</sui-dropdown-menu>\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:inline-block;font-family:var(--sui-font-sans);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-color-picker__trigger{display:inline-flex;align-items:center;gap:8px;padding:6px 10px 6px 6px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-8);cursor:pointer;appearance:none;font:inherit;color:var(--sui-text-strong-950);font-size:var(--sui-type-label-sm-size);font-weight:var(--sui-type-label-sm-weight);line-height:var(--sui-type-label-sm-line);letter-spacing:var(--sui-type-label-sm-spacing);transition:background-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out),border-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}.sui-color-picker__trigger:hover{background:var(--sui-bg-weak-50)}:host([data-sui-open]) .sui-color-picker__trigger{border-color:var(--sui-stroke-strong-950, var(--sui-text-strong-950))}.sui-color-picker__trigger:focus-visible{outline:2px solid var(--sui-stroke-strong-950, var(--sui-text-strong-950));outline-offset:2px}.sui-color-picker__trigger:active{transform:none}:host([data-sui-disabled]) .sui-color-picker__trigger{background:var(--sui-bg-weak-50);color:var(--sui-text-disabled-300);cursor:not-allowed;pointer-events:none}.sui-color-picker__placeholder-dot{display:inline-block;width:24px;height:24px;border-radius:50%;background:var(--sui-bg-soft-200)}.sui-color-picker__label{flex:1 0 auto;white-space:nowrap}.sui-color-picker__chevron{flex-shrink:0;color:var(--sui-icon-sub-600);transition:transform var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}:host([data-sui-open]) .sui-color-picker__chevron{transform:rotate(180deg)}.sui-color-picker__panel{width:272px;margin-top:6px;box-sizing:border-box;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-16);box-shadow:var(--sui-shadow-medium);overflow:hidden;display:flex;flex-direction:column;animation:sui-color-picker__fade var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}@keyframes sui-color-picker__fade{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sui-color-picker__section{box-sizing:border-box;display:flex;flex-direction:column;gap:12px;padding:16px;width:100%}.sui-color-picker__section--colors{border-bottom:1px solid var(--sui-stroke-soft-200)}.sui-color-picker__section--recommended{gap:8px}:host([data-sui-presets-only]) .sui-color-picker__section--recommended{border-bottom:none}.sui-color-picker__canvas{position:relative;width:100%;height:232px;border-radius:var(--sui-radius-8);cursor:crosshair;-webkit-user-select:none;user-select:none;touch-action:none;overflow:hidden;background-color:var(--hue-color, #335cff);background-image:linear-gradient(to top,#000,#0000),linear-gradient(to right,#fff,#fff0)}.sui-color-picker__canvas-thumb{position:absolute;width:16px;height:16px;border-radius:50%;border:2px solid var(--sui-static-white, #fff);box-shadow:0 0 0 1px #00000026,0 1px 2px #0003;transform:translate(-50%,-50%);pointer-events:none}.sui-color-picker__slider{position:relative;width:100%;height:16px;cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:none}.sui-color-picker__slider-track{position:absolute;left:0;right:0;top:4px;height:8px;border-radius:var(--sui-radius-full);overflow:hidden}.sui-color-picker__hue .sui-color-picker__slider-track{background-image:linear-gradient(to right,red,#ff0,#0f0,#0ff,#00f,#f0f,red)}.sui-color-picker__opacity .sui-color-picker__slider-track{background-color:#fff;background-image:linear-gradient(to right,transparent,var(--opacity-color, #335cff)),conic-gradient(#ebebeb 0 25%,transparent 0 50%,#ebebeb 0 75%,transparent 0);background-size:auto,10.88px 10.88px}.sui-color-picker__slider-thumb{position:absolute;top:50%;width:16px;height:16px;border-radius:50%;border:2px solid var(--sui-static-white, #fff);box-shadow:0 0 0 1px #00000026,0 1px 2px #0003;transform:translate(-50%,-50%);pointer-events:none}.sui-color-picker__opacity .sui-color-picker__slider-thumb{background-image:linear-gradient(var(--thumb-color, #335cff),var(--thumb-color, #335cff)),conic-gradient(#ebebeb 0 25%,#fff 0 50%,#ebebeb 0 75%,#fff 0);background-size:auto,6px 6px}.sui-color-picker__color-input{display:flex;flex-direction:column;gap:4px;width:100%}.sui-color-picker__format{display:flex;align-items:center;gap:2px;appearance:none;border:none;background:transparent;padding:0;cursor:default;font:inherit;color:var(--sui-text-strong-950)}.sui-color-picker__format-label{font-size:var(--sui-type-label-sm-size);font-weight:var(--sui-type-label-sm-weight);line-height:var(--sui-type-label-sm-line);letter-spacing:var(--sui-type-label-sm-spacing);white-space:nowrap}.sui-color-picker__format-chevron{flex-shrink:0;color:var(--sui-icon-sub-600)}.sui-color-picker__input-row{box-sizing:border-box;display:flex;align-items:stretch;width:100%;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-8);overflow:hidden}.sui-color-picker__sip{display:flex;align-items:center;justify-content:center;padding:6px;border:none;border-right:1px solid var(--sui-stroke-soft-200);background:var(--sui-bg-white-0);color:var(--sui-icon-sub-600);cursor:pointer;appearance:none;flex-shrink:0;transition:background-color var(--sui-motion-duration-x-fast) var(--sui-motion-ease-out)}.sui-color-picker__sip:hover{background:var(--sui-bg-weak-50)}.sui-color-picker__sip:focus-visible{outline:2px solid var(--sui-stroke-strong-950, var(--sui-text-strong-950));outline-offset:-2px}.sui-color-picker__sip:active{transform:none}.sui-color-picker__hex-cell{box-sizing:border-box;display:flex;align-items:center;flex:1 0 0;min-width:0;padding:6px 10px;border-right:1px solid var(--sui-stroke-soft-200)}.sui-color-picker__hex-cell:last-child{border-right:none}.sui-color-picker__hex-field{flex:1 0 0;min-width:0;width:100%;border:none;outline:none;background:transparent;padding:0;appearance:none;color:var(--sui-text-strong-950);font-family:inherit;font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing);text-transform:uppercase}.sui-color-picker__hex-field::placeholder{color:var(--sui-text-soft-400);text-transform:none}.sui-color-picker__opacity-cell{box-sizing:border-box;display:flex;align-items:center;flex-shrink:0;padding:6px 10px}.sui-color-picker__opacity-field{width:3.5ch;border:none;outline:none;background:transparent;padding:0;appearance:none;text-align:right;color:var(--sui-text-sub-600);font-family:inherit;font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing)}.sui-color-picker__opacity-suffix{color:var(--sui-text-sub-600);font-size:var(--sui-type-paragraph-sm-size);font-weight:var(--sui-type-paragraph-sm-weight);line-height:var(--sui-type-paragraph-sm-line);letter-spacing:var(--sui-type-paragraph-sm-spacing)}.sui-color-picker__panel-label{margin:0;font-size:var(--sui-type-paragraph-xs-size);font-weight:var(--sui-type-paragraph-xs-weight);line-height:var(--sui-type-paragraph-xs-line);letter-spacing:var(--sui-type-paragraph-xs-spacing);color:var(--sui-text-sub-600)}.sui-color-picker__grid{display:flex;flex-wrap:wrap;gap:4px;width:100%}\n"] }]
|
|
3998
|
+
}], propDecorators: { colors: [{ type: i0.Input, args: [{ isSignal: true, alias: "colors", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], recommendedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "recommendedLabel", required: false }] }], presetsOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "presetsOnly", required: false }] }], alpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "alpha", required: false }] }], eyedropper: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyedropper", required: false }] }], showFormatLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFormatLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], change: [{ type: i0.Output, args: ["change"] }], _menu: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SuiDropdownMenu), { isSignal: true }] }], canvasRef: [{ type: i0.ViewChild, args: ['canvas', { isSignal: true }] }], hueRef: [{ type: i0.ViewChild, args: ['hueSlider', { isSignal: true }] }], opacityRef: [{ type: i0.ViewChild, args: ['opacitySlider', { isSignal: true }] }] } });
|
|
3792
3999
|
|
|
3793
4000
|
class SuiKbd {
|
|
3794
4001
|
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
@@ -4476,218 +4683,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
4476
4683
|
}, template: "<div class=\"sui-dropdown-item__leading\">\n <ng-content select=\"[slot=leading]\" />\n</div>\n\n<div class=\"sui-dropdown-item__text\">\n <span class=\"sui-dropdown-item__label\">{{ label() }}</span>\n @if (hasSublabel()) {\n <span class=\"sui-dropdown-item__sublabel\">{{ sublabel() }}</span>\n }\n @if (hasDescription()) {\n <span class=\"sui-dropdown-item__description\">{{ description() }}</span>\n }\n</div>\n\n<div class=\"sui-dropdown-item__trailing\">\n <!-- Canon trailing-slot (Figma 405:6432): el consumer proyecta en este orden DOM\n fijo \u2192 badge primero, luego shortcut (provisto por el input shortcut() abajo),\n luego toggle/button al final. El gap del flex (8px) los separa.\n Pill button (variante Large): bg primary-alpha-10, p-6, radius-8, label primary\n Inter Medium 14/20. Link button (variante Small): texto primary sin bg.\n El componente no fija sublots \u2014 el orden lo controla el consumer seg\u00FAn este\n patr\u00F3n para mantener consistencia visual vs Figma. -->\n <ng-content select=\"[slot=trailing]\" />\n @if (shortcut()) {\n <span class=\"sui-dropdown-item__shortcut\">{{ shortcut() }}</span>\n }\n @if (showCheck()) {\n <!-- Check icon autom\u00E1tico en mode='option' cuando selected=true.\n Remixicon check-line (ri-check-line) v\u00EDa sui-icon \u2014 mismo glyph que\n el resto del proyecto, color heredado de .sui-dropdown-item__check. -->\n <sui-icon class=\"sui-dropdown-item__check\" name=\"check-line\" [size]=\"20\" />\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:center;gap:8px;padding:8px;background:var(--sui-bg-white-0);border-radius:var(--sui-radius-8, 8px);cursor:pointer;outline:none;width:100%;box-sizing:border-box;font-family:var(--sui-font-sans);transition:background .1s ease-out,box-shadow .1s ease-out;-webkit-user-select:none;user-select:none}:host:hover{background:var(--sui-bg-weak-50)}:host:active:not([data-sui-disabled]),:host:focus-visible{box-shadow:0 0 0 2px var(--sui-bg-white-0),0 0 0 4px var(--sui-primary-alpha-10)}:host([data-sui-size=small]){min-height:36px;padding:8px;gap:8px}:host([data-sui-size=large]){min-height:56px;padding:8px;gap:12px;border-radius:var(--sui-radius-10, 10px)}:host([data-sui-size=large]) .sui-dropdown-item__text{flex-direction:column;align-items:flex-start;gap:4px}:host([data-sui-size=large]) .sui-dropdown-item__label{font-weight:var(--sui-type-label-sm-weight, 500)}:host([data-sui-size=xlarge]){min-height:76px;padding:8px;gap:16px;border-radius:var(--sui-radius-12, 12px)}:host([data-sui-size=xlarge]) .sui-dropdown-item__text{flex-direction:column;align-items:flex-start;gap:4px}:host([data-sui-size=xlarge]) .sui-dropdown-item__label{font-size:var(--sui-type-label-md-size, 16px);line-height:var(--sui-type-label-md-line, 24px);letter-spacing:var(--sui-type-label-md-spacing, -.011em);font-weight:var(--sui-type-label-md-weight, 500)}:host([data-sui-size=xlarge]) .sui-dropdown-item__description{font-size:var(--sui-type-paragraph-sm-size, 14px);line-height:var(--sui-type-paragraph-sm-line, 20px);letter-spacing:var(--sui-type-paragraph-sm-spacing, -.006em)}.sui-dropdown-item__leading{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}.sui-dropdown-item__leading:empty{display:none}:host([data-sui-size=large][data-sui-framed]) .sui-dropdown-item__leading,:host([data-sui-size=xlarge][data-sui-framed]) .sui-dropdown-item__leading{padding:10px;border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-full, 999px);box-shadow:var(--sui-regular-shadow-x-small, 0 1px 2px 0 rgba(10, 13, 20, .031372549));box-sizing:border-box}:host([data-sui-size=xlarge][data-sui-framed]) .sui-dropdown-item__leading{padding:12px}.sui-dropdown-item__text{flex:1 1 0;min-width:0;display:flex;align-items:center;gap:4px;font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-dropdown-item__label{font-size:var(--sui-type-paragraph-sm-size, 14px);line-height:var(--sui-type-paragraph-sm-line, 20px);letter-spacing:var(--sui-type-paragraph-sm-spacing, -.006em);font-weight:var(--sui-type-paragraph-sm-weight, 400);color:var(--sui-text-strong-950);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.sui-dropdown-item__sublabel{font-size:var(--sui-type-paragraph-xs-size, 12px);line-height:var(--sui-type-paragraph-xs-line, 16px);letter-spacing:var(--sui-type-paragraph-xs-spacing, 0);font-weight:var(--sui-type-paragraph-xs-weight, 400);color:var(--sui-text-soft-400);flex-shrink:0}.sui-dropdown-item__description{font-size:var(--sui-type-paragraph-xs-size, 12px);line-height:var(--sui-type-paragraph-xs-line, 16px);letter-spacing:var(--sui-type-paragraph-xs-spacing, 0);font-weight:var(--sui-type-paragraph-xs-weight, 400);color:var(--sui-text-sub-600);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.sui-dropdown-item__trailing{flex-shrink:0;display:inline-flex;align-items:center;gap:8px}.sui-dropdown-item__trailing:empty{display:none}.sui-dropdown-item__shortcut{display:inline-flex;align-items:center;padding:2px 6px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:var(--sui-radius-4, 4px);font-family:var(--sui-font-sans);font-size:12px;line-height:16px;font-weight:500;color:var(--sui-text-sub-600);letter-spacing:.04em;text-transform:uppercase;white-space:nowrap;flex-shrink:0}:host([data-sui-mode=option][data-sui-selected]){background:var(--sui-primary-alpha-10)}:host([data-sui-mode=option][data-sui-selected]) .sui-dropdown-item__label,:host([data-sui-mode=option][data-sui-selected]) .sui-dropdown-item__sublabel,:host([data-sui-mode=option][data-sui-selected]) .sui-dropdown-item__check{color:var(--sui-primary-base)}:host([data-sui-mode=option][data-sui-selected]):hover{background:var(--sui-primary-alpha-16)}.sui-dropdown-item__check{width:20px;height:20px;flex-shrink:0;color:var(--sui-primary-base)}:host([data-sui-highlighted]:not([data-sui-selected])){background:var(--sui-bg-weak-50)}:host([data-sui-disabled]){cursor:not-allowed;pointer-events:none}:host([data-sui-disabled]) .sui-dropdown-item__label,:host([data-sui-disabled]) .sui-dropdown-item__sublabel,:host([data-sui-disabled]) .sui-dropdown-item__description{color:var(--sui-text-disabled-300)}:host([data-sui-disabled]) .sui-dropdown-item__leading{color:var(--sui-icon-disabled-300, #d1d1d1)}:host([data-sui-disabled]) .sui-dropdown-item__leading>:not(sui-icon){opacity:.48}:host([data-sui-disabled]):hover{background:var(--sui-bg-white-0)}\n"] }]
|
|
4477
4684
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], leadingFramed: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingFramed", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], highlighted: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlighted", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], shortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "shortcut", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
|
|
4478
4685
|
|
|
4479
|
-
/**
|
|
4480
|
-
* Structural directive — marca un `<ng-template>` como panel del
|
|
4481
|
-
* sui-dropdown-menu. El componente padre captura este TemplateRef
|
|
4482
|
-
* via `@ContentChild(SuiDropdownPanel)` y lo monta en el CDK Overlay
|
|
4483
|
-
* cuando se abre el menu.
|
|
4484
|
-
*
|
|
4485
|
-
* Usa el patrón canon Angular (similar a `*matMenuContent` de Material):
|
|
4486
|
-
* un directive que se aplica al `<ng-template>` SE convierte en una
|
|
4487
|
-
* marca semántica, evitando que Angular renderee el contenido inline
|
|
4488
|
-
* cuando no hay `<ng-content>` matching para el template.
|
|
4489
|
-
*
|
|
4490
|
-
* Uso:
|
|
4491
|
-
* <sui-dropdown-menu>
|
|
4492
|
-
* <sui-compact-select trigger ... />
|
|
4493
|
-
* <ng-template suiDropdownPanel>
|
|
4494
|
-
* <sui-dropdown-item ...></sui-dropdown-item>
|
|
4495
|
-
* </ng-template>
|
|
4496
|
-
* </sui-dropdown-menu>
|
|
4497
|
-
*/
|
|
4498
|
-
class SuiDropdownPanel {
|
|
4499
|
-
template = inject(TemplateRef);
|
|
4500
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiDropdownPanel, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
4501
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: SuiDropdownPanel, isStandalone: true, selector: "ng-template[suiDropdownPanel]", ngImport: i0 });
|
|
4502
|
-
}
|
|
4503
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiDropdownPanel, decorators: [{
|
|
4504
|
-
type: Directive,
|
|
4505
|
-
args: [{
|
|
4506
|
-
selector: 'ng-template[suiDropdownPanel]',
|
|
4507
|
-
standalone: true,
|
|
4508
|
-
}]
|
|
4509
|
-
}] });
|
|
4510
|
-
|
|
4511
|
-
/* Posiciones con fallback HORIZONTAL: la primera (start-aligned, abre a la
|
|
4512
|
-
derecha) es la default; si el trigger está pegado al borde derecho y no entra,
|
|
4513
|
-
CDK cae a la end-aligned (abre hacia la izquierda) y recién después flipea
|
|
4514
|
-
vertical. Sin esto, un trigger en la esquina derecha (ej. kebab ⋮ de una card)
|
|
4515
|
-
recorta el panel fuera del viewport. */
|
|
4516
|
-
const POSITIONS_BELOW = [
|
|
4517
|
-
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
4518
|
-
{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
|
|
4519
|
-
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
4520
|
-
{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
|
|
4521
|
-
];
|
|
4522
|
-
const POSITIONS_ABOVE = [
|
|
4523
|
-
{ originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom', offsetY: -4 },
|
|
4524
|
-
{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -4 },
|
|
4525
|
-
{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top', offsetY: 4 },
|
|
4526
|
-
{ originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top', offsetY: 4 },
|
|
4527
|
-
];
|
|
4528
|
-
class SuiDropdownMenu {
|
|
4529
|
-
/** Si true, el panel matchea el ancho del trigger. Default: auto width. */
|
|
4530
|
-
matchWidth = input(false, ...(ngDevMode ? [{ debugName: "matchWidth" }] : /* istanbul ignore next */ []));
|
|
4531
|
-
/** Min-width fijo del panel (px). Si matchWidth + minWidth: `max(triggerWidth, minWidth)`. */
|
|
4532
|
-
minWidth = input(null, ...(ngDevMode ? [{ debugName: "minWidth" }] : /* istanbul ignore next */ []));
|
|
4533
|
-
/** Position primary. Default: auto = below con fallback above. */
|
|
4534
|
-
position = input('auto', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
4535
|
-
/** Margen 8px del viewport edge (canon SUI). */
|
|
4536
|
-
viewportMargin = input(8, ...(ngDevMode ? [{ debugName: "viewportMargin" }] : /* istanbul ignore next */ []));
|
|
4537
|
-
/** Panel custom class para overrides de bg/padding/etc desde el consumer. */
|
|
4538
|
-
panelClass = input('', ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
|
|
4539
|
-
/** Disabled — no abre el menu al clickear el trigger. */
|
|
4540
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
4541
|
-
/**
|
|
4542
|
-
* Rol del popup para `aria-haspopup` del trigger. Default 'menu' (los items
|
|
4543
|
-
* proyectados llevan role="menuitem"). Los consumers de tipo listbox
|
|
4544
|
-
* (sui-select / compact-selects, items con role="option") DEBEN pasar
|
|
4545
|
-
* `popupRole="listbox"`. Ver SuiDropdownMenuPopupRole.
|
|
4546
|
-
*/
|
|
4547
|
-
popupRole = input('menu', ...(ngDevMode ? [{ debugName: "popupRole" }] : /* istanbul ignore next */ []));
|
|
4548
|
-
/**
|
|
4549
|
-
* Origin externo. Si presente, el menu se ancla a ese elemento y NO renderea
|
|
4550
|
-
* el trigger wrapper interno (el parent maneja el click). Caso de uso:
|
|
4551
|
-
* compact-selects donde el host element es el trigger visual.
|
|
4552
|
-
*/
|
|
4553
|
-
origin = input(null, ...(ngDevMode ? [{ debugName: "origin" }] : /* istanbul ignore next */ []));
|
|
4554
|
-
openedChange = output();
|
|
4555
|
-
/** Signal pública — wire al `[open]` del trigger para visual state. */
|
|
4556
|
-
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
4557
|
-
/** Wrapper del trigger projection — captura el click. NO existe si `[origin]` se pasa. */
|
|
4558
|
-
_triggerWrap;
|
|
4559
|
-
/** Panel directive proyectado — capturado via `[suiDropdownPanel]` en un ng-template. */
|
|
4560
|
-
_panel;
|
|
4561
|
-
_getTriggerEl() {
|
|
4562
|
-
const o = this.origin();
|
|
4563
|
-
if (o)
|
|
4564
|
-
return o instanceof ElementRef ? o.nativeElement : o;
|
|
4565
|
-
return this._triggerWrap?.nativeElement ?? null;
|
|
4566
|
-
}
|
|
4567
|
-
_vcr = inject(ViewContainerRef);
|
|
4568
|
-
_destroyRef = inject(DestroyRef);
|
|
4569
|
-
_overlay = inject(Overlay);
|
|
4570
|
-
_overlayRef = null;
|
|
4571
|
-
_overlaySubs = null;
|
|
4572
|
-
_resizeObserver = null;
|
|
4573
|
-
constructor() {
|
|
4574
|
-
this._destroyRef.onDestroy(() => this.close());
|
|
4575
|
-
}
|
|
4576
|
-
onTriggerClick(event) {
|
|
4577
|
-
if (this.disabled())
|
|
4578
|
-
return;
|
|
4579
|
-
event.stopPropagation();
|
|
4580
|
-
this.toggle();
|
|
4581
|
-
}
|
|
4582
|
-
onTriggerKeydown(event) {
|
|
4583
|
-
if (this.disabled())
|
|
4584
|
-
return;
|
|
4585
|
-
if (event.key === 'Enter' || event.key === ' ') {
|
|
4586
|
-
event.preventDefault();
|
|
4587
|
-
this.toggle();
|
|
4588
|
-
}
|
|
4589
|
-
else if (event.key === 'ArrowDown') {
|
|
4590
|
-
event.preventDefault();
|
|
4591
|
-
this.open();
|
|
4592
|
-
}
|
|
4593
|
-
}
|
|
4594
|
-
toggle() {
|
|
4595
|
-
if (this.isOpen())
|
|
4596
|
-
this.close();
|
|
4597
|
-
else
|
|
4598
|
-
this.open();
|
|
4599
|
-
}
|
|
4600
|
-
open() {
|
|
4601
|
-
if (this.disabled() || this._overlayRef || !this._panel)
|
|
4602
|
-
return;
|
|
4603
|
-
const triggerEl = this._getTriggerEl();
|
|
4604
|
-
if (!triggerEl)
|
|
4605
|
-
return;
|
|
4606
|
-
const positions = this.position() === 'above' ? POSITIONS_ABOVE : POSITIONS_BELOW;
|
|
4607
|
-
const positionStrategy = this._overlay
|
|
4608
|
-
.position()
|
|
4609
|
-
.flexibleConnectedTo(triggerEl)
|
|
4610
|
-
.withPositions(positions)
|
|
4611
|
-
.withPush(false)
|
|
4612
|
-
.withFlexibleDimensions(true)
|
|
4613
|
-
.withViewportMargin(this.viewportMargin());
|
|
4614
|
-
const triggerWidth = triggerEl.getBoundingClientRect().width;
|
|
4615
|
-
const minW = this.minWidth();
|
|
4616
|
-
const effectiveMinWidth = this.matchWidth() && minW !== null
|
|
4617
|
-
? Math.max(triggerWidth, minW)
|
|
4618
|
-
: minW;
|
|
4619
|
-
const config = {
|
|
4620
|
-
positionStrategy,
|
|
4621
|
-
scrollStrategy: this._overlay.scrollStrategies.reposition(),
|
|
4622
|
-
hasBackdrop: true,
|
|
4623
|
-
backdropClass: 'cdk-overlay-transparent-backdrop',
|
|
4624
|
-
panelClass: ['sui-dropdown-menu__overlay-pane', this.panelClass()].filter(Boolean),
|
|
4625
|
-
disposeOnNavigation: true,
|
|
4626
|
-
};
|
|
4627
|
-
if (this.matchWidth() && minW === null) {
|
|
4628
|
-
config.width = `${triggerWidth}px`;
|
|
4629
|
-
}
|
|
4630
|
-
if (effectiveMinWidth !== null) {
|
|
4631
|
-
config.minWidth = effectiveMinWidth;
|
|
4632
|
-
}
|
|
4633
|
-
this._overlayRef = this._overlay.create(config);
|
|
4634
|
-
const portal = new TemplatePortal(this._panel.template, this._vcr);
|
|
4635
|
-
this._overlayRef.attach(portal);
|
|
4636
|
-
/* Width sync mientras el viewport cambia (canon sui-select). Solo aplica
|
|
4637
|
-
cuando matchWidth fija width o minWidth — para que el panel siga el trigger. */
|
|
4638
|
-
if (this.matchWidth() && typeof ResizeObserver !== 'undefined') {
|
|
4639
|
-
this._resizeObserver = new ResizeObserver(() => {
|
|
4640
|
-
if (!this._overlayRef)
|
|
4641
|
-
return;
|
|
4642
|
-
const w = triggerEl.getBoundingClientRect().width;
|
|
4643
|
-
if (minW === null) {
|
|
4644
|
-
this._overlayRef.updateSize({ width: `${w}px` });
|
|
4645
|
-
}
|
|
4646
|
-
else {
|
|
4647
|
-
this._overlayRef.updateSize({ minWidth: Math.max(w, minW) });
|
|
4648
|
-
}
|
|
4649
|
-
this._overlayRef.updatePosition();
|
|
4650
|
-
});
|
|
4651
|
-
this._resizeObserver.observe(triggerEl);
|
|
4652
|
-
}
|
|
4653
|
-
this._overlaySubs = new Subscription();
|
|
4654
|
-
this._overlaySubs.add(this._overlayRef.backdropClick().subscribe(() => this.close()));
|
|
4655
|
-
this._overlaySubs.add(this._overlayRef.keydownEvents().subscribe((e) => {
|
|
4656
|
-
if (e.key === 'Escape')
|
|
4657
|
-
this.close();
|
|
4658
|
-
}));
|
|
4659
|
-
this._overlaySubs.add(this._overlayRef.detachments().subscribe(() => {
|
|
4660
|
-
this.isOpen.set(false);
|
|
4661
|
-
}));
|
|
4662
|
-
this.isOpen.set(true);
|
|
4663
|
-
this.openedChange.emit(true);
|
|
4664
|
-
}
|
|
4665
|
-
close() {
|
|
4666
|
-
if (!this._overlayRef)
|
|
4667
|
-
return;
|
|
4668
|
-
this._overlaySubs?.unsubscribe();
|
|
4669
|
-
this._overlaySubs = null;
|
|
4670
|
-
this._resizeObserver?.disconnect();
|
|
4671
|
-
this._resizeObserver = null;
|
|
4672
|
-
this._overlayRef.dispose();
|
|
4673
|
-
this._overlayRef = null;
|
|
4674
|
-
this.isOpen.set(false);
|
|
4675
|
-
this.openedChange.emit(false);
|
|
4676
|
-
}
|
|
4677
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiDropdownMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4678
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiDropdownMenu, isStandalone: true, selector: "sui-dropdown-menu", inputs: { matchWidth: { classPropertyName: "matchWidth", publicName: "matchWidth", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, viewportMargin: { classPropertyName: "viewportMargin", publicName: "viewportMargin", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, popupRole: { classPropertyName: "popupRole", publicName: "popupRole", isSignal: true, isRequired: false, transformFunction: null }, origin: { classPropertyName: "origin", publicName: "origin", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openedChange: "openedChange" }, queries: [{ propertyName: "_panel", first: true, predicate: SuiDropdownPanel, descendants: true }], viewQueries: [{ propertyName: "_triggerWrap", first: true, predicate: ["triggerWrap"], descendants: true }], exportAs: ["suiDropdownMenu"], ngImport: i0, template: "<!-- Trigger wrapper \u2014 captura click y keydown del trigger child. Solo se\n renderea cuando NO se pasa [origin] (modo content-projection canon).\n Cuando se pasa [origin], el parent maneja el trigger y llama\n menu.toggle() desde su propio click handler. -->\n@if (!origin()) {\n <span\n #triggerWrap\n class=\"sui-dropdown-menu__trigger\"\n [attr.aria-haspopup]=\"popupRole()\"\n [attr.aria-expanded]=\"isOpen()\"\n (click)=\"onTriggerClick($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <ng-content select=\"[trigger]\" />\n </span>\n}\n", styles: ["@charset \"UTF-8\";:host{display:contents}.sui-dropdown-menu__trigger{display:inline-block;cursor:pointer;outline:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4679
|
-
}
|
|
4680
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiDropdownMenu, decorators: [{
|
|
4681
|
-
type: Component,
|
|
4682
|
-
args: [{ selector: 'sui-dropdown-menu', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, exportAs: 'suiDropdownMenu', template: "<!-- Trigger wrapper \u2014 captura click y keydown del trigger child. Solo se\n renderea cuando NO se pasa [origin] (modo content-projection canon).\n Cuando se pasa [origin], el parent maneja el trigger y llama\n menu.toggle() desde su propio click handler. -->\n@if (!origin()) {\n <span\n #triggerWrap\n class=\"sui-dropdown-menu__trigger\"\n [attr.aria-haspopup]=\"popupRole()\"\n [attr.aria-expanded]=\"isOpen()\"\n (click)=\"onTriggerClick($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <ng-content select=\"[trigger]\" />\n </span>\n}\n", styles: ["@charset \"UTF-8\";:host{display:contents}.sui-dropdown-menu__trigger{display:inline-block;cursor:pointer;outline:none}\n"] }]
|
|
4683
|
-
}], ctorParameters: () => [], propDecorators: { matchWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "matchWidth", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], viewportMargin: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewportMargin", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], popupRole: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupRole", required: false }] }], origin: [{ type: i0.Input, args: [{ isSignal: true, alias: "origin", required: false }] }], openedChange: [{ type: i0.Output, args: ["openedChange"] }], _triggerWrap: [{
|
|
4684
|
-
type: ViewChild,
|
|
4685
|
-
args: ['triggerWrap', { static: false }]
|
|
4686
|
-
}], _panel: [{
|
|
4687
|
-
type: ContentChild,
|
|
4688
|
-
args: [SuiDropdownPanel]
|
|
4689
|
-
}] } });
|
|
4690
|
-
|
|
4691
4686
|
class SuiCompactSelectForInput {
|
|
4692
4687
|
size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
4693
4688
|
value = input('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
@@ -9735,8 +9730,13 @@ class SuiIntegrationSwitch {
|
|
|
9735
9730
|
brandIconSrc = input(null, ...(ngDevMode ? [{ debugName: "brandIconSrc" }] : /* istanbul ignore next */ []));
|
|
9736
9731
|
/** RemixIcon fallback si no hay brandIconSrc (ej. 'plug-line' como genérico). */
|
|
9737
9732
|
brandIcon = input(null, ...(ngDevMode ? [{ debugName: "brandIcon" }] : /* istanbul ignore next */ []));
|
|
9738
|
-
|
|
9739
|
-
|
|
9733
|
+
/** Badge junto al label — string shorthand ('NEW') o SuiBadgeConfig
|
|
9734
|
+
(label + color/variant/size, tipado como sui-badge). null = sin badge. */
|
|
9735
|
+
badge = input(null, ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
|
|
9736
|
+
badgeCfg = computed(() => {
|
|
9737
|
+
const b = this.badge();
|
|
9738
|
+
return b ? (typeof b === 'string' ? { label: b } : b) : null;
|
|
9739
|
+
}, ...(ngDevMode ? [{ debugName: "badgeCfg" }] : /* istanbul ignore next */ []));
|
|
9740
9740
|
/** Mostrar el manage button. Default true. */
|
|
9741
9741
|
showManage = input(true, ...(ngDevMode ? [{ debugName: "showManage" }] : /* istanbul ignore next */ []));
|
|
9742
9742
|
manageLabel = input('Manage', ...(ngDevMode ? [{ debugName: "manageLabel" }] : /* istanbul ignore next */ []));
|
|
@@ -9802,13 +9802,13 @@ class SuiIntegrationSwitch {
|
|
|
9802
9802
|
this._disabledByForm.set(isDisabled);
|
|
9803
9803
|
}
|
|
9804
9804
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiIntegrationSwitch, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9805
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiIntegrationSwitch, isStandalone: true, selector: "sui-integration-switch", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, brandIconSrc: { classPropertyName: "brandIconSrc", publicName: "brandIconSrc", isSignal: true, isRequired: false, transformFunction: null }, brandIcon: { classPropertyName: "brandIcon", publicName: "brandIcon", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null },
|
|
9805
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiIntegrationSwitch, isStandalone: true, selector: "sui-integration-switch", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, brandIconSrc: { classPropertyName: "brandIconSrc", publicName: "brandIconSrc", isSignal: true, isRequired: false, transformFunction: null }, brandIcon: { classPropertyName: "brandIcon", publicName: "brandIcon", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, showManage: { classPropertyName: "showManage", publicName: "showManage", isSignal: true, isRequired: false, transformFunction: null }, manageLabel: { classPropertyName: "manageLabel", publicName: "manageLabel", isSignal: true, isRequired: false, transformFunction: null }, manageIcon: { classPropertyName: "manageIcon", publicName: "manageIcon", isSignal: true, isRequired: false, transformFunction: null }, showToggle: { classPropertyName: "showToggle", publicName: "showToggle", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeChange: "activeChange", manage: "manage" }, host: { properties: { "attr.title": "null", "attr.data-sui-type": "type()", "attr.data-sui-appearance": "appearance()", "attr.data-sui-disabled": "isDisabled() ? \"\" : null" } }, providers: [
|
|
9806
9806
|
{
|
|
9807
9807
|
provide: NG_VALUE_ACCESSOR,
|
|
9808
9808
|
useExisting: forwardRef(() => SuiIntegrationSwitch),
|
|
9809
9809
|
multi: true,
|
|
9810
9810
|
},
|
|
9811
|
-
], ngImport: i0, template: "<!-- Brand logo (circle 40 / 48 seg\u00FAn appearance) -->\n<div class=\"sui-integration-switch__brand\" aria-hidden=\"true\">\n <ng-content select=\"[sui-integration-brand]\">\n @if (brandIconSrc(); as src) {\n <img [src]=\"src\" alt=\"\" class=\"sui-integration-switch__brand-img\" />\n } @else if (brandIcon(); as icon) {\n <sui-icon [name]=\"icon\" [size]=\"appearance() === 'list' ? 32 : 24\" />\n }\n </ng-content>\n</div>\n\n<!-- Title + description block -->\n<div class=\"sui-integration-switch__text\">\n <div class=\"sui-integration-switch__title-row\">\n <span class=\"sui-integration-switch__title\">{{ title() }}</span>\n @if (
|
|
9811
|
+
], ngImport: i0, template: "<!-- Brand logo (circle 40 / 48 seg\u00FAn appearance) -->\n<div class=\"sui-integration-switch__brand\" aria-hidden=\"true\">\n <ng-content select=\"[sui-integration-brand]\">\n @if (brandIconSrc(); as src) {\n <img [src]=\"src\" alt=\"\" class=\"sui-integration-switch__brand-img\" />\n } @else if (brandIcon(); as icon) {\n <sui-icon [name]=\"icon\" [size]=\"appearance() === 'list' ? 32 : 24\" />\n }\n </ng-content>\n</div>\n\n<!-- Title + description block -->\n<div class=\"sui-integration-switch__text\">\n <div class=\"sui-integration-switch__title-row\">\n <span class=\"sui-integration-switch__title\">{{ title() }}</span>\n @if (badgeCfg(); as bcfg) {\n <sui-badge\n class=\"sui-integration-switch__badge\"\n [color]=\"bcfg.color ?? 'orange'\"\n [variant]=\"bcfg.variant ?? 'light'\"\n [size]=\"bcfg.size ?? 'small'\"\n >{{ bcfg.label }}</sui-badge>\n }\n </div>\n @if (description(); as desc) {\n <p class=\"sui-integration-switch__description\">{{ desc }}</p>\n }\n</div>\n\n<!-- Manage button (trailing en horizontal, full-width en vertical) -->\n@if (showManage()) {\n <button\n type=\"button\"\n class=\"sui-integration-switch__manage\"\n [attr.aria-label]=\"manageLabel()\"\n [disabled]=\"isDisabled()\"\n (click)=\"onManageClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n >\n <sui-icon [name]=\"manageIcon()\" [size]=\"20\" />\n <span class=\"sui-integration-switch__manage-label\">{{ manageLabel() }}</span>\n </button>\n}\n\n<!-- Switch (inline en horizontal \u00B7 absolute top-right en vertical) -->\n@if (showToggle()) {\n <sui-switch\n class=\"sui-integration-switch__toggle\"\n [checked]=\"effectiveActive()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onSwitchChange($event)\"\n />\n}\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:flex;box-sizing:border-box;width:100%;font-family:var(--sui-font-sans, \"Inter\", system-ui, sans-serif);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}:host([data-sui-type=horizontal]){flex-direction:row;align-items:center;gap:14px}:host([data-sui-type=vertical]){flex-direction:column;align-items:flex-start;gap:14px}:host([data-sui-appearance=card]){padding:16px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:12px;box-shadow:0 1px 2px #0a0d1408}:host([data-sui-appearance=list]){padding:0;background:transparent;border:0}.sui-integration-switch__brand{box-sizing:border-box;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;padding:8px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:999px;box-shadow:0 1px 2px #0a0d1408;overflow:hidden}:host([data-sui-appearance=card]) .sui-integration-switch__brand{width:40px;height:40px}:host([data-sui-appearance=list]) .sui-integration-switch__brand{width:48px;height:48px}.sui-integration-switch__brand-img{width:100%;height:100%;object-fit:contain;display:block}.sui-integration-switch__text{flex:1 0 0;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:4px}.sui-integration-switch__title-row{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.sui-integration-switch__title{color:var(--sui-text-strong-950);font-weight:500;word-break:break-word}:host([data-sui-appearance=card]) .sui-integration-switch__title{font-size:14px;line-height:20px;letter-spacing:-.006em}:host([data-sui-appearance=list]) .sui-integration-switch__title{font-size:16px;line-height:24px;letter-spacing:-.011em}.sui-integration-switch__description{margin:0;color:var(--sui-text-sub-600);font-weight:400;word-break:break-word}:host([data-sui-appearance=card]) .sui-integration-switch__description{font-size:12px;line-height:16px}:host([data-sui-appearance=list]) .sui-integration-switch__description{font-size:14px;line-height:20px;letter-spacing:-.006em}.sui-integration-switch__badge{flex-shrink:0}.sui-integration-switch__manage{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;gap:4px;padding:8px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:8px;box-shadow:0 1px 2px #0a0d1408;color:var(--sui-text-sub-600);font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color .15s ease,transform .12s ease}.sui-integration-switch__manage:hover:not(:disabled){background:var(--sui-bg-weak-50)}.sui-integration-switch__manage:active:not(:disabled){transform:scale(.97)}.sui-integration-switch__manage:focus-visible{outline:2px solid var(--sui-primary-base);outline-offset:2px}.sui-integration-switch__manage:disabled{opacity:.4;cursor:not-allowed}.sui-integration-switch__manage-label{padding:0 4px;font-size:14px;font-weight:500;line-height:20px;letter-spacing:-.006em}:host([data-sui-type=vertical]) .sui-integration-switch__manage{width:100%}.sui-integration-switch__toggle{flex-shrink:0}:host([data-sui-type=vertical]) .sui-integration-switch__toggle{position:absolute;top:19px;right:19px}:host([data-sui-type=vertical][data-sui-appearance=list]) .sui-integration-switch__toggle{top:12px;right:12px}:host([data-sui-disabled]){opacity:.5;pointer-events:none}\n"], dependencies: [{ kind: "component", type: SuiSwitch, selector: "sui-switch", inputs: ["size", "checked", "disabled"], outputs: ["checkedChange"] }, { kind: "component", type: SuiIcon, selector: "sui-icon", inputs: ["name", "size", "color"] }, { kind: "component", type: SuiBadge, selector: "sui-badge", inputs: ["color", "variant", "size", "type", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
9812
9812
|
}
|
|
9813
9813
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiIntegrationSwitch, decorators: [{
|
|
9814
9814
|
type: Component,
|
|
@@ -9826,8 +9826,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
9826
9826
|
'[attr.data-sui-type]': 'type()',
|
|
9827
9827
|
'[attr.data-sui-appearance]': 'appearance()',
|
|
9828
9828
|
'[attr.data-sui-disabled]': 'isDisabled() ? "" : null',
|
|
9829
|
-
}, template: "<!-- Brand logo (circle 40 / 48 seg\u00FAn appearance) -->\n<div class=\"sui-integration-switch__brand\" aria-hidden=\"true\">\n <ng-content select=\"[sui-integration-brand]\">\n @if (brandIconSrc(); as src) {\n <img [src]=\"src\" alt=\"\" class=\"sui-integration-switch__brand-img\" />\n } @else if (brandIcon(); as icon) {\n <sui-icon [name]=\"icon\" [size]=\"appearance() === 'list' ? 32 : 24\" />\n }\n </ng-content>\n</div>\n\n<!-- Title + description block -->\n<div class=\"sui-integration-switch__text\">\n <div class=\"sui-integration-switch__title-row\">\n <span class=\"sui-integration-switch__title\">{{ title() }}</span>\n @if (
|
|
9830
|
-
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], brandIconSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandIconSrc", required: false }] }], brandIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandIcon", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }],
|
|
9829
|
+
}, template: "<!-- Brand logo (circle 40 / 48 seg\u00FAn appearance) -->\n<div class=\"sui-integration-switch__brand\" aria-hidden=\"true\">\n <ng-content select=\"[sui-integration-brand]\">\n @if (brandIconSrc(); as src) {\n <img [src]=\"src\" alt=\"\" class=\"sui-integration-switch__brand-img\" />\n } @else if (brandIcon(); as icon) {\n <sui-icon [name]=\"icon\" [size]=\"appearance() === 'list' ? 32 : 24\" />\n }\n </ng-content>\n</div>\n\n<!-- Title + description block -->\n<div class=\"sui-integration-switch__text\">\n <div class=\"sui-integration-switch__title-row\">\n <span class=\"sui-integration-switch__title\">{{ title() }}</span>\n @if (badgeCfg(); as bcfg) {\n <sui-badge\n class=\"sui-integration-switch__badge\"\n [color]=\"bcfg.color ?? 'orange'\"\n [variant]=\"bcfg.variant ?? 'light'\"\n [size]=\"bcfg.size ?? 'small'\"\n >{{ bcfg.label }}</sui-badge>\n }\n </div>\n @if (description(); as desc) {\n <p class=\"sui-integration-switch__description\">{{ desc }}</p>\n }\n</div>\n\n<!-- Manage button (trailing en horizontal, full-width en vertical) -->\n@if (showManage()) {\n <button\n type=\"button\"\n class=\"sui-integration-switch__manage\"\n [attr.aria-label]=\"manageLabel()\"\n [disabled]=\"isDisabled()\"\n (click)=\"onManageClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n >\n <sui-icon [name]=\"manageIcon()\" [size]=\"20\" />\n <span class=\"sui-integration-switch__manage-label\">{{ manageLabel() }}</span>\n </button>\n}\n\n<!-- Switch (inline en horizontal \u00B7 absolute top-right en vertical) -->\n@if (showToggle()) {\n <sui-switch\n class=\"sui-integration-switch__toggle\"\n [checked]=\"effectiveActive()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onSwitchChange($event)\"\n />\n}\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:flex;box-sizing:border-box;width:100%;font-family:var(--sui-font-sans, \"Inter\", system-ui, sans-serif);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}:host([data-sui-type=horizontal]){flex-direction:row;align-items:center;gap:14px}:host([data-sui-type=vertical]){flex-direction:column;align-items:flex-start;gap:14px}:host([data-sui-appearance=card]){padding:16px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:12px;box-shadow:0 1px 2px #0a0d1408}:host([data-sui-appearance=list]){padding:0;background:transparent;border:0}.sui-integration-switch__brand{box-sizing:border-box;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;padding:8px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:999px;box-shadow:0 1px 2px #0a0d1408;overflow:hidden}:host([data-sui-appearance=card]) .sui-integration-switch__brand{width:40px;height:40px}:host([data-sui-appearance=list]) .sui-integration-switch__brand{width:48px;height:48px}.sui-integration-switch__brand-img{width:100%;height:100%;object-fit:contain;display:block}.sui-integration-switch__text{flex:1 0 0;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:4px}.sui-integration-switch__title-row{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.sui-integration-switch__title{color:var(--sui-text-strong-950);font-weight:500;word-break:break-word}:host([data-sui-appearance=card]) .sui-integration-switch__title{font-size:14px;line-height:20px;letter-spacing:-.006em}:host([data-sui-appearance=list]) .sui-integration-switch__title{font-size:16px;line-height:24px;letter-spacing:-.011em}.sui-integration-switch__description{margin:0;color:var(--sui-text-sub-600);font-weight:400;word-break:break-word}:host([data-sui-appearance=card]) .sui-integration-switch__description{font-size:12px;line-height:16px}:host([data-sui-appearance=list]) .sui-integration-switch__description{font-size:14px;line-height:20px;letter-spacing:-.006em}.sui-integration-switch__badge{flex-shrink:0}.sui-integration-switch__manage{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;gap:4px;padding:8px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);border-radius:8px;box-shadow:0 1px 2px #0a0d1408;color:var(--sui-text-sub-600);font-family:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color .15s ease,transform .12s ease}.sui-integration-switch__manage:hover:not(:disabled){background:var(--sui-bg-weak-50)}.sui-integration-switch__manage:active:not(:disabled){transform:scale(.97)}.sui-integration-switch__manage:focus-visible{outline:2px solid var(--sui-primary-base);outline-offset:2px}.sui-integration-switch__manage:disabled{opacity:.4;cursor:not-allowed}.sui-integration-switch__manage-label{padding:0 4px;font-size:14px;font-weight:500;line-height:20px;letter-spacing:-.006em}:host([data-sui-type=vertical]) .sui-integration-switch__manage{width:100%}.sui-integration-switch__toggle{flex-shrink:0}:host([data-sui-type=vertical]) .sui-integration-switch__toggle{position:absolute;top:19px;right:19px}:host([data-sui-type=vertical][data-sui-appearance=list]) .sui-integration-switch__toggle{top:12px;right:12px}:host([data-sui-disabled]){opacity:.5;pointer-events:none}\n"] }]
|
|
9830
|
+
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], brandIconSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandIconSrc", required: false }] }], brandIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandIcon", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], showManage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showManage", required: false }] }], manageLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "manageLabel", required: false }] }], manageIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "manageIcon", required: false }] }], showToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToggle", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], activeChange: [{ type: i0.Output, args: ["activeChange"] }], manage: [{ type: i0.Output, args: ["manage"] }] } });
|
|
9831
9831
|
|
|
9832
9832
|
/** Set de los 9 colores SUI 2.0 para iterar desde el consumer (previews, demos). */
|
|
9833
9833
|
const SUI_KEY_ICON_COLORS = [
|
|
@@ -11926,10 +11926,13 @@ class SuiRadioCard {
|
|
|
11926
11926
|
* label. Para los otros types se ignora.
|
|
11927
11927
|
*/
|
|
11928
11928
|
imageUrl = input(null, ...(ngDevMode ? [{ debugName: "imageUrl" }] : /* istanbul ignore next */ []));
|
|
11929
|
-
/**
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11929
|
+
/** Badge junto al label — string shorthand ('NEW') o SuiBadgeConfig
|
|
11930
|
+
(label + color/variant/size, tipado como sui-badge). null = sin badge. */
|
|
11931
|
+
badge = input(null, ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
|
|
11932
|
+
badgeCfg = computed(() => {
|
|
11933
|
+
const b = this.badge();
|
|
11934
|
+
return b ? (typeof b === 'string' ? { label: b } : b) : null;
|
|
11935
|
+
}, ...(ngDevMode ? [{ debugName: "badgeCfg" }] : /* istanbul ignore next */ []));
|
|
11933
11936
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
11934
11937
|
/** Standalone mode (no group): two-way binding del estado checked. */
|
|
11935
11938
|
checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
@@ -11986,13 +11989,13 @@ class SuiRadioCard {
|
|
|
11986
11989
|
this._disabledByForm.set(isDisabled);
|
|
11987
11990
|
}
|
|
11988
11991
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiRadioCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11989
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiRadioCard, isStandalone: true, selector: "sui-radio-card", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, emoji: { classPropertyName: "emoji", publicName: "emoji", isSignal: true, isRequired: false, transformFunction: null }, iconSrc: { classPropertyName: "iconSrc", publicName: "iconSrc", isSignal: true, isRequired: false, transformFunction: null }, imageUrl: { classPropertyName: "imageUrl", publicName: "imageUrl", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null },
|
|
11992
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiRadioCard, isStandalone: true, selector: "sui-radio-card", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, emoji: { classPropertyName: "emoji", publicName: "emoji", isSignal: true, isRequired: false, transformFunction: null }, iconSrc: { classPropertyName: "iconSrc", publicName: "iconSrc", isSignal: true, isRequired: false, transformFunction: null }, imageUrl: { classPropertyName: "imageUrl", publicName: "imageUrl", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", selected: "selected" }, host: { listeners: { "click": "onToggle($event)", "keydown.space": "onToggle($event)", "keydown.enter": "onToggle($event)", "touchstart": "$event.currentTarget", "touchend": "$any($event.currentTarget).blur()" }, properties: { "attr.data-sui-type": "type()", "attr.data-sui-checked": "isChecked() ? \"\" : null", "attr.data-sui-disabled": "isDisabled() ? \"\" : null", "attr.data-sui-leading-fill": "iconSrc() ? \"\" : null", "attr.role": "\"radio\"", "attr.aria-checked": "isChecked() ? \"true\" : \"false\"", "attr.aria-disabled": "isDisabled() ? \"true\" : null", "attr.aria-label": "label() || null", "attr.tabindex": "isDisabled() ? \"-1\" : \"0\"" } }, providers: [
|
|
11990
11993
|
{
|
|
11991
11994
|
provide: NG_VALUE_ACCESSOR,
|
|
11992
11995
|
useExisting: forwardRef(() => SuiRadioCard),
|
|
11993
11996
|
multi: true,
|
|
11994
11997
|
},
|
|
11995
|
-
], ngImport: i0, template: "<!-- Leading slot \u2014 solo basic / left-icon / avatar (Figma 515:4356/4365) -->\n@if (type() === 'left-icon') {\n <div class=\"sui-radio-card__leading sui-radio-card__leading--icon\" aria-hidden=\"true\">\n @if (icon()) {\n <sui-icon [name]=\"icon()!\" [size]=\"20\" />\n } @else if (emoji()) {\n <sui-emoji [name]=\"emoji()\" size=\"md\" />\n } @else if (iconSrc()) {\n <sui-emoji [src]=\"iconSrc()\" size=\"full\" />\n }\n </div>\n} @else if (type() === 'avatar') {\n <!-- sui-avatar maneja fallback autom\u00E1tico a iniciales si la imagen falla. -->\n <sui-avatar\n class=\"sui-radio-card__leading sui-radio-card__leading--avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n}\n\n<!-- Texto: Title row + description -->\n<div class=\"sui-radio-card__text\">\n <div class=\"sui-radio-card__title\">\n @if (label()) {\n <span class=\"sui-radio-card__label\">{{ label() }}</span>\n }\n @if (sublabel()) {\n <span class=\"sui-radio-card__sublabel\">{{ sublabel() }}</span>\n }\n @if (
|
|
11998
|
+
], ngImport: i0, template: "<!-- Leading slot \u2014 solo basic / left-icon / avatar (Figma 515:4356/4365) -->\n@if (type() === 'left-icon') {\n <div class=\"sui-radio-card__leading sui-radio-card__leading--icon\" aria-hidden=\"true\">\n @if (icon()) {\n <sui-icon [name]=\"icon()!\" [size]=\"20\" />\n } @else if (emoji()) {\n <sui-emoji [name]=\"emoji()\" size=\"md\" />\n } @else if (iconSrc()) {\n <sui-emoji [src]=\"iconSrc()\" size=\"full\" />\n }\n </div>\n} @else if (type() === 'avatar') {\n <!-- sui-avatar maneja fallback autom\u00E1tico a iniciales si la imagen falla. -->\n <sui-avatar\n class=\"sui-radio-card__leading sui-radio-card__leading--avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n}\n\n<!-- Texto: Title row + description -->\n<div class=\"sui-radio-card__text\">\n <div class=\"sui-radio-card__title\">\n @if (label()) {\n <span class=\"sui-radio-card__label\">{{ label() }}</span>\n }\n @if (sublabel()) {\n <span class=\"sui-radio-card__sublabel\">{{ sublabel() }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <span class=\"sui-radio-card__badge\">{{ bcfg.label }}</span>\n }\n </div>\n @if (description()) {\n <p class=\"sui-radio-card__description\">{{ description() }}</p>\n }\n</div>\n\n<!-- Radio dot 20\u00D720 (Figma 515:4243 \u2192 515:4244 bg + 515:4245 box) -->\n<span class=\"sui-radio-card__radio\" aria-hidden=\"true\" [style.width.px]=\"radioPx()\" [style.height.px]=\"radioPx()\">\n <span class=\"sui-radio-card__radio-bg\"></span>\n <span class=\"sui-radio-card__radio-box\"></span>\n</span>\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;box-sizing:border-box;align-items:flex-start;gap:14px;padding:16px;width:100%;background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);border-radius:var(--sui-radius-12, 12px);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(10, 13, 20, .031372549));cursor:pointer;outline:none;-webkit-user-select:none;user-select:none;font-family:var(--sui-font-sans, var(--font-sans, sans-serif));touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:background-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),border-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),box-shadow var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),transform var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}@media(hover:hover)and (pointer:fine){:host(:hover:not([data-sui-disabled]):not([data-sui-checked])){background:var(--sui-bg-weak-50, #f7f7f7);border-color:transparent;box-shadow:none}}:host([data-sui-checked]){border-color:var(--sui-primary-base, #fa7319);box-shadow:none;background:var(--sui-bg-white-0, #fff)}@media(hover:hover)and (pointer:fine){:host([data-sui-checked]:hover:not([data-sui-disabled])){background:var(--sui-bg-weak-50, #f7f7f7)}}:host(:focus-visible:not([data-sui-disabled])){border-color:var(--sui-primary-base, #fa7319);box-shadow:0 0 0 3px color-mix(in oklab,var(--sui-primary-base, #fa7319) 16%,transparent)}:host([data-sui-disabled]){cursor:not-allowed;background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);box-shadow:none}:host([data-sui-disabled]) .sui-radio-card__label{color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-disabled]) .sui-radio-card__sublabel,:host([data-sui-disabled]) .sui-radio-card__description{color:var(--sui-text-soft-400, #a3a3a3)}:host([data-sui-disabled]) .sui-radio-card__badge{background:transparent;border:1px solid var(--sui-stroke-soft-200, #ebebeb);color:var(--sui-text-disabled-300, #d1d1d1)}:host([data-sui-disabled]) .sui-radio-card__radio-bg,:host([data-sui-disabled][data-sui-checked]) .sui-radio-card__radio-bg{background:var(--sui-bg-soft-200, #ebebeb)}:host([data-sui-disabled]:not([data-sui-checked])) .sui-radio-card__radio-box{display:none}:host(:active:not([data-sui-disabled])){transform:scale(.99)}.sui-radio-card__leading{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}.sui-radio-card__leading--icon{box-sizing:border-box;width:40px;height:40px;padding:10px;border-radius:var(--sui-radius-full, 999px);background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(10, 13, 20, .031372549));color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-leading-fill]) .sui-radio-card__leading--icon{padding:0;border:none;background:none;box-shadow:none;border-radius:0;overflow:visible;display:flex;align-items:center;justify-content:center}:host([data-sui-leading-fill]) .sui-radio-card__leading--icon sui-emoji{display:block;width:100%;height:100%}:host([data-sui-type=avatar]) .sui-radio-card__leading--avatar{width:40px;height:40px}.sui-radio-card__text{display:flex;flex-direction:column;gap:4px;align-items:flex-start;flex:1 1 auto;min-width:0;align-self:stretch}.sui-radio-card__text:not(:has(.sui-radio-card__description)){justify-content:center}.sui-radio-card__title{display:flex;gap:4px;align-items:center;flex-wrap:wrap}.sui-radio-card__label{font-size:14px;font-weight:500;line-height:20px;letter-spacing:-.006em;color:var(--sui-text-strong-950, #171717);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-radio-card__sublabel{font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600, #5c5c5c);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-radio-card__description{margin:0;font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600, #5c5c5c);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-radio-card__badge{display:inline-flex;align-items:center;justify-content:center;padding:2px 8px;border-radius:var(--sui-radius-full, 999px);background:var(--sui-state-information-light, #c0d5ff);color:var(--sui-state-information-dark, #122368);font-size:11px;font-weight:500;line-height:12px;letter-spacing:.22px;text-transform:uppercase;font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0;white-space:nowrap}.sui-radio-card__radio{position:relative;flex-shrink:0;width:20px;height:20px;align-self:flex-start}.sui-radio-card__radio-bg{position:absolute;inset:10%;border-radius:var(--sui-radius-full, 999px);background:var(--sui-bg-soft-200, #ebebeb);transition:background-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}.sui-radio-card__radio-box{position:absolute;inset:17.5%;border-radius:var(--sui-radius-full, 999px);background:var(--sui-bg-white-0, #fff);box-shadow:0 2px 4px -2px #1b1c1d1f;transition:inset var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),box-shadow var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}@media(hover:hover)and (pointer:fine){:host(:hover:not([data-sui-disabled]):not([data-sui-checked])) .sui-radio-card__radio-bg{background:var(--sui-bg-sub-300, #d1d1d1)}}:host([data-sui-checked]) .sui-radio-card__radio-bg{background:var(--sui-primary-base, #fa7319)}:host([data-sui-checked]) .sui-radio-card__radio-box{inset:30%;box-shadow:none;background:var(--sui-static-white, #ffffff)}\n"], dependencies: [{ kind: "component", type: SuiIcon, selector: "sui-icon", inputs: ["name", "size", "color"] }, { kind: "component", type: SuiEmoji, selector: "sui-emoji", inputs: ["name", "src", "size", "ariaLabel"] }, { kind: "component", type: SuiAvatar, selector: "sui-avatar", inputs: ["size", "src", "alt", "initials", "color", "status", "memojiSrc", "illustrationSrc", "icon", "companyLogoSrc", "topBadge", "bgColor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
11996
11999
|
}
|
|
11997
12000
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiRadioCard, decorators: [{
|
|
11998
12001
|
type: Component,
|
|
@@ -12022,8 +12025,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
12022
12025
|
/* iOS WKWebView fix — sin esto :active stickea 300-500ms en standalone pages */
|
|
12023
12026
|
'(touchstart)': '$event.currentTarget',
|
|
12024
12027
|
'(touchend)': '$any($event.currentTarget).blur()',
|
|
12025
|
-
}, template: "<!-- Leading slot \u2014 solo basic / left-icon / avatar (Figma 515:4356/4365) -->\n@if (type() === 'left-icon') {\n <div class=\"sui-radio-card__leading sui-radio-card__leading--icon\" aria-hidden=\"true\">\n @if (icon()) {\n <sui-icon [name]=\"icon()!\" [size]=\"20\" />\n } @else if (emoji()) {\n <sui-emoji [name]=\"emoji()\" size=\"md\" />\n } @else if (iconSrc()) {\n <sui-emoji [src]=\"iconSrc()\" size=\"full\" />\n }\n </div>\n} @else if (type() === 'avatar') {\n <!-- sui-avatar maneja fallback autom\u00E1tico a iniciales si la imagen falla. -->\n <sui-avatar\n class=\"sui-radio-card__leading sui-radio-card__leading--avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n}\n\n<!-- Texto: Title row + description -->\n<div class=\"sui-radio-card__text\">\n <div class=\"sui-radio-card__title\">\n @if (label()) {\n <span class=\"sui-radio-card__label\">{{ label() }}</span>\n }\n @if (sublabel()) {\n <span class=\"sui-radio-card__sublabel\">{{ sublabel() }}</span>\n }\n @if (
|
|
12026
|
-
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], emoji: [{ type: i0.Input, args: [{ isSignal: true, alias: "emoji", required: false }] }], iconSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSrc", required: false }] }], imageUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUrl", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }],
|
|
12028
|
+
}, template: "<!-- Leading slot \u2014 solo basic / left-icon / avatar (Figma 515:4356/4365) -->\n@if (type() === 'left-icon') {\n <div class=\"sui-radio-card__leading sui-radio-card__leading--icon\" aria-hidden=\"true\">\n @if (icon()) {\n <sui-icon [name]=\"icon()!\" [size]=\"20\" />\n } @else if (emoji()) {\n <sui-emoji [name]=\"emoji()\" size=\"md\" />\n } @else if (iconSrc()) {\n <sui-emoji [src]=\"iconSrc()\" size=\"full\" />\n }\n </div>\n} @else if (type() === 'avatar') {\n <!-- sui-avatar maneja fallback autom\u00E1tico a iniciales si la imagen falla. -->\n <sui-avatar\n class=\"sui-radio-card__leading sui-radio-card__leading--avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n}\n\n<!-- Texto: Title row + description -->\n<div class=\"sui-radio-card__text\">\n <div class=\"sui-radio-card__title\">\n @if (label()) {\n <span class=\"sui-radio-card__label\">{{ label() }}</span>\n }\n @if (sublabel()) {\n <span class=\"sui-radio-card__sublabel\">{{ sublabel() }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <span class=\"sui-radio-card__badge\">{{ bcfg.label }}</span>\n }\n </div>\n @if (description()) {\n <p class=\"sui-radio-card__description\">{{ description() }}</p>\n }\n</div>\n\n<!-- Radio dot 20\u00D720 (Figma 515:4243 \u2192 515:4244 bg + 515:4245 box) -->\n<span class=\"sui-radio-card__radio\" aria-hidden=\"true\" [style.width.px]=\"radioPx()\" [style.height.px]=\"radioPx()\">\n <span class=\"sui-radio-card__radio-bg\"></span>\n <span class=\"sui-radio-card__radio-box\"></span>\n</span>\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;box-sizing:border-box;align-items:flex-start;gap:14px;padding:16px;width:100%;background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);border-radius:var(--sui-radius-12, 12px);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(10, 13, 20, .031372549));cursor:pointer;outline:none;-webkit-user-select:none;user-select:none;font-family:var(--sui-font-sans, var(--font-sans, sans-serif));touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:background-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),border-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),box-shadow var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),transform var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}@media(hover:hover)and (pointer:fine){:host(:hover:not([data-sui-disabled]):not([data-sui-checked])){background:var(--sui-bg-weak-50, #f7f7f7);border-color:transparent;box-shadow:none}}:host([data-sui-checked]){border-color:var(--sui-primary-base, #fa7319);box-shadow:none;background:var(--sui-bg-white-0, #fff)}@media(hover:hover)and (pointer:fine){:host([data-sui-checked]:hover:not([data-sui-disabled])){background:var(--sui-bg-weak-50, #f7f7f7)}}:host(:focus-visible:not([data-sui-disabled])){border-color:var(--sui-primary-base, #fa7319);box-shadow:0 0 0 3px color-mix(in oklab,var(--sui-primary-base, #fa7319) 16%,transparent)}:host([data-sui-disabled]){cursor:not-allowed;background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);box-shadow:none}:host([data-sui-disabled]) .sui-radio-card__label{color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-disabled]) .sui-radio-card__sublabel,:host([data-sui-disabled]) .sui-radio-card__description{color:var(--sui-text-soft-400, #a3a3a3)}:host([data-sui-disabled]) .sui-radio-card__badge{background:transparent;border:1px solid var(--sui-stroke-soft-200, #ebebeb);color:var(--sui-text-disabled-300, #d1d1d1)}:host([data-sui-disabled]) .sui-radio-card__radio-bg,:host([data-sui-disabled][data-sui-checked]) .sui-radio-card__radio-bg{background:var(--sui-bg-soft-200, #ebebeb)}:host([data-sui-disabled]:not([data-sui-checked])) .sui-radio-card__radio-box{display:none}:host(:active:not([data-sui-disabled])){transform:scale(.99)}.sui-radio-card__leading{flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}.sui-radio-card__leading--icon{box-sizing:border-box;width:40px;height:40px;padding:10px;border-radius:var(--sui-radius-full, 999px);background:var(--sui-bg-white-0, #fff);border:1px solid var(--sui-stroke-soft-200, #ebebeb);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(10, 13, 20, .031372549));color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-leading-fill]) .sui-radio-card__leading--icon{padding:0;border:none;background:none;box-shadow:none;border-radius:0;overflow:visible;display:flex;align-items:center;justify-content:center}:host([data-sui-leading-fill]) .sui-radio-card__leading--icon sui-emoji{display:block;width:100%;height:100%}:host([data-sui-type=avatar]) .sui-radio-card__leading--avatar{width:40px;height:40px}.sui-radio-card__text{display:flex;flex-direction:column;gap:4px;align-items:flex-start;flex:1 1 auto;min-width:0;align-self:stretch}.sui-radio-card__text:not(:has(.sui-radio-card__description)){justify-content:center}.sui-radio-card__title{display:flex;gap:4px;align-items:center;flex-wrap:wrap}.sui-radio-card__label{font-size:14px;font-weight:500;line-height:20px;letter-spacing:-.006em;color:var(--sui-text-strong-950, #171717);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-radio-card__sublabel{font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600, #5c5c5c);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-radio-card__description{margin:0;font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600, #5c5c5c);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0}.sui-radio-card__badge{display:inline-flex;align-items:center;justify-content:center;padding:2px 8px;border-radius:var(--sui-radius-full, 999px);background:var(--sui-state-information-light, #c0d5ff);color:var(--sui-state-information-dark, #122368);font-size:11px;font-weight:500;line-height:12px;letter-spacing:.22px;text-transform:uppercase;font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0;white-space:nowrap}.sui-radio-card__radio{position:relative;flex-shrink:0;width:20px;height:20px;align-self:flex-start}.sui-radio-card__radio-bg{position:absolute;inset:10%;border-radius:var(--sui-radius-full, 999px);background:var(--sui-bg-soft-200, #ebebeb);transition:background-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}.sui-radio-card__radio-box{position:absolute;inset:17.5%;border-radius:var(--sui-radius-full, 999px);background:var(--sui-bg-white-0, #fff);box-shadow:0 2px 4px -2px #1b1c1d1f;transition:inset var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),box-shadow var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}@media(hover:hover)and (pointer:fine){:host(:hover:not([data-sui-disabled]):not([data-sui-checked])) .sui-radio-card__radio-bg{background:var(--sui-bg-sub-300, #d1d1d1)}}:host([data-sui-checked]) .sui-radio-card__radio-bg{background:var(--sui-primary-base, #fa7319)}:host([data-sui-checked]) .sui-radio-card__radio-box{inset:30%;box-shadow:none;background:var(--sui-static-white, #ffffff)}\n"] }]
|
|
12029
|
+
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], emoji: [{ type: i0.Input, args: [{ isSignal: true, alias: "emoji", required: false }] }], iconSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSrc", required: false }] }], imageUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUrl", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], selected: [{ type: i0.Output, args: ["selected"] }] } });
|
|
12027
12030
|
|
|
12028
12031
|
// large/xlarge: project extension (no-Figma)
|
|
12029
12032
|
/**
|
|
@@ -14053,10 +14056,13 @@ class SuiSwitchCard {
|
|
|
14053
14056
|
* label. Para los otros types se ignora.
|
|
14054
14057
|
*/
|
|
14055
14058
|
imageUrl = input(null, ...(ngDevMode ? [{ debugName: "imageUrl" }] : /* istanbul ignore next */ []));
|
|
14056
|
-
/**
|
|
14057
|
-
|
|
14058
|
-
|
|
14059
|
-
|
|
14059
|
+
/** Badge junto al label — string shorthand ('NEW') o SuiBadgeConfig
|
|
14060
|
+
(label + color/variant/size, tipado como sui-badge). null = sin badge. */
|
|
14061
|
+
badge = input(null, ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
|
|
14062
|
+
badgeCfg = computed(() => {
|
|
14063
|
+
const b = this.badge();
|
|
14064
|
+
return b ? (typeof b === 'string' ? { label: b } : b) : null;
|
|
14065
|
+
}, ...(ngDevMode ? [{ debugName: "badgeCfg" }] : /* istanbul ignore next */ []));
|
|
14060
14066
|
/** Estado del switch — controlled pattern (input + output, no model).
|
|
14061
14067
|
* Ver `sui-switch.ts` para la justificación (anti-loop protection bug). */
|
|
14062
14068
|
checked = input(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
@@ -14148,13 +14154,13 @@ class SuiSwitchCard {
|
|
|
14148
14154
|
this._disabledByForm.set(isDisabled);
|
|
14149
14155
|
}
|
|
14150
14156
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiSwitchCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14151
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiSwitchCard, isStandalone: true, selector: "sui-switch-card", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, emoji: { classPropertyName: "emoji", publicName: "emoji", isSignal: true, isRequired: false, transformFunction: null }, imageUrl: { classPropertyName: "imageUrl", publicName: "imageUrl", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null },
|
|
14157
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiSwitchCard, isStandalone: true, selector: "sui-switch-card", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, emoji: { classPropertyName: "emoji", publicName: "emoji", isSignal: true, isRequired: false, transformFunction: null }, imageUrl: { classPropertyName: "imageUrl", publicName: "imageUrl", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checkedChange: "checkedChange" }, host: { listeners: { "click": "onCardClick($event)", "keydown.space": "onCardKey($event)", "keydown.enter": "onCardKey($event)", "touchstart": "$event.currentTarget", "touchend": "$any($event.currentTarget).blur()" }, properties: { "attr.data-sui-type": "type()", "attr.data-sui-checked": "effectiveChecked() ? \"\" : null", "attr.data-sui-disabled": "isDisabled() ? \"\" : null", "attr.role": "\"group\"", "attr.aria-disabled": "isDisabled() ? \"true\" : null" } }, providers: [
|
|
14152
14158
|
{
|
|
14153
14159
|
provide: NG_VALUE_ACCESSOR,
|
|
14154
14160
|
useExisting: forwardRef(() => SuiSwitchCard),
|
|
14155
14161
|
multi: true,
|
|
14156
14162
|
},
|
|
14157
|
-
], ngImport: i0, template: "@if (hasLeading()) {\n <div class=\"sui-switch-card__leading\">\n @if (type() === 'avatar') {\n <sui-avatar\n class=\"sui-switch-card__leading-avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n } @else if (type() === 'left-icon' && emoji()) {\n <div class=\"sui-switch-card__leading-icon\">\n <sui-emoji class=\"sui-switch-card__leading-emoji\" [name]=\"emoji()!\" size=\"sm\" />\n </div>\n } @else if (imageUrl() && type() !== 'left-icon') {\n <!-- card-provider 32\u00D724 / brand 40\u00D740 bare / company 40\u00D740 circle \u2014 el box lo da la clase. -->\n <div [class]=\"leadingBoxClass()\">\n <img [src]=\"imageUrl()\" alt=\"\" class=\"sui-switch-card__leading-img\" />\n </div>\n } @else {\n <!-- \u00DANICO ng-content del slot: si se duplica por branch, Angular solo proyecta\n en el primero declarado y los dem\u00E1s types quedan vac\u00EDos (bug auditor\u00EDa). -->\n <div [class]=\"leadingBoxClass()\">\n <ng-content select=\"[sui-switch-card-leading]\" />\n </div>\n }\n </div>\n}\n\n<div class=\"sui-switch-card__body\">\n <div class=\"sui-switch-card__title\">\n <span class=\"sui-switch-card__label\">{{ label() }}</span>\n @if (sublabel(); as sub) {\n <span class=\"sui-switch-card__sublabel\">{{ sub }}</span>\n }\n @if (
|
|
14163
|
+
], ngImport: i0, template: "@if (hasLeading()) {\n <div class=\"sui-switch-card__leading\">\n @if (type() === 'avatar') {\n <sui-avatar\n class=\"sui-switch-card__leading-avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n } @else if (type() === 'left-icon' && emoji()) {\n <div class=\"sui-switch-card__leading-icon\">\n <sui-emoji class=\"sui-switch-card__leading-emoji\" [name]=\"emoji()!\" size=\"sm\" />\n </div>\n } @else if (imageUrl() && type() !== 'left-icon') {\n <!-- card-provider 32\u00D724 / brand 40\u00D740 bare / company 40\u00D740 circle \u2014 el box lo da la clase. -->\n <div [class]=\"leadingBoxClass()\">\n <img [src]=\"imageUrl()\" alt=\"\" class=\"sui-switch-card__leading-img\" />\n </div>\n } @else {\n <!-- \u00DANICO ng-content del slot: si se duplica por branch, Angular solo proyecta\n en el primero declarado y los dem\u00E1s types quedan vac\u00EDos (bug auditor\u00EDa). -->\n <div [class]=\"leadingBoxClass()\">\n <ng-content select=\"[sui-switch-card-leading]\" />\n </div>\n }\n </div>\n}\n\n<div class=\"sui-switch-card__body\">\n <div class=\"sui-switch-card__title\">\n <span class=\"sui-switch-card__label\">{{ label() }}</span>\n @if (sublabel(); as sub) {\n <span class=\"sui-switch-card__sublabel\">{{ sub }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <span class=\"sui-switch-card__badge\">{{ bcfg.label }}</span>\n }\n </div>\n @if (description(); as desc) {\n <p class=\"sui-switch-card__description\">{{ desc }}</p>\n }\n</div>\n\n<sui-switch\n class=\"sui-switch-card__switch\"\n [size]=\"size()\"\n [checked]=\"effectiveChecked()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onSwitchChange($event)\"\n/>\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:flex-start;gap:14px;padding:16px;border-radius:var(--sui-radius-12);background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);box-shadow:var(--sui-shadow-x-small);box-sizing:border-box;overflow:hidden;width:100%;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;outline:none;transition:background-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),border-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),box-shadow var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}:host(:hover:not([data-sui-disabled]):not([data-sui-checked])){background:var(--sui-bg-weak-50);border-color:transparent;box-shadow:none}:host([data-sui-checked]:not([data-sui-disabled])){border-color:var(--sui-primary-base);box-shadow:none}:host([data-sui-disabled]){cursor:not-allowed;box-shadow:none}:host(:focus-visible){box-shadow:0 0 0 2px var(--sui-bg-white-0),0 0 0 4px var(--sui-primary-base)}.sui-switch-card__leading{flex-shrink:0;display:flex;align-items:center;justify-content:center}.sui-switch-card__leading-icon{width:40px;height:40px;display:flex;align-items:center;justify-content:center;padding:10px;border-radius:999px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);box-shadow:var(--sui-shadow-x-small);box-sizing:border-box}.sui-switch-card__leading-emoji{width:20px;height:20px}:host([data-sui-disabled]) .sui-switch-card__leading-icon{box-shadow:none;opacity:.5}:host([data-sui-type=avatar]) .sui-switch-card__leading-avatar{width:40px;height:40px}.sui-switch-card__leading-card-provider{width:32px;height:24px;border-radius:4px;overflow:hidden;display:flex;align-items:center;justify-content:center}.sui-switch-card__leading-brand{width:40px;height:40px;overflow:hidden;display:flex;align-items:center;justify-content:center}.sui-switch-card__leading-company{width:40px;height:40px;border-radius:999px;overflow:hidden;display:flex;align-items:center;justify-content:center}.sui-switch-card__leading-img{width:100%;height:100%;object-fit:contain;display:block}:host([data-sui-disabled]) .sui-switch-card__leading{opacity:.5}.sui-switch-card__body{display:flex;flex-direction:column;gap:4px;flex:1 1 auto;min-width:0;align-self:stretch}.sui-switch-card__body:not(:has(.sui-switch-card__description)){justify-content:center}.sui-switch-card__title{display:flex;align-items:center;flex-wrap:wrap;gap:4px}.sui-switch-card__label{font-size:14px;font-weight:500;line-height:20px;letter-spacing:-.006em;color:var(--sui-text-strong-950)}:host([data-sui-disabled]) .sui-switch-card__label{color:var(--sui-text-sub-600)}.sui-switch-card__sublabel{font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600)}:host([data-sui-disabled]) .sui-switch-card__sublabel{color:var(--sui-text-soft-400)}.sui-switch-card__description{margin:0;font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600)}:host([data-sui-disabled]) .sui-switch-card__description{color:var(--sui-text-soft-400)}.sui-switch-card__badge{display:inline-flex;align-items:center;justify-content:center;padding:2px 8px;border-radius:999px;background:var(--sui-state-information-light, #c0d5ff);color:var(--sui-state-information-dark, #122368);font-size:11px;font-weight:500;line-height:12px;letter-spacing:.22px;text-transform:uppercase;white-space:nowrap}:host([data-sui-disabled]) .sui-switch-card__badge{background:transparent;border:1px solid var(--sui-stroke-soft-200);color:var(--sui-text-disabled-300)}.sui-switch-card__switch{flex-shrink:0;align-self:flex-start;margin-top:2px}\n"], dependencies: [{ kind: "component", type: SuiSwitch, selector: "sui-switch", inputs: ["size", "checked", "disabled"], outputs: ["checkedChange"] }, { kind: "component", type: SuiEmoji, selector: "sui-emoji", inputs: ["name", "src", "size", "ariaLabel"] }, { kind: "component", type: SuiAvatar, selector: "sui-avatar", inputs: ["size", "src", "alt", "initials", "color", "status", "memojiSrc", "illustrationSrc", "icon", "companyLogoSrc", "topBadge", "bgColor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
14158
14164
|
}
|
|
14159
14165
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiSwitchCard, decorators: [{
|
|
14160
14166
|
type: Component,
|
|
@@ -14176,8 +14182,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
14176
14182
|
/* iOS WKWebView fix — ver CLAUDE.md "iOS :active stuck en custom buttons". */
|
|
14177
14183
|
'(touchstart)': '$event.currentTarget',
|
|
14178
14184
|
'(touchend)': '$any($event.currentTarget).blur()',
|
|
14179
|
-
}, template: "@if (hasLeading()) {\n <div class=\"sui-switch-card__leading\">\n @if (type() === 'avatar') {\n <sui-avatar\n class=\"sui-switch-card__leading-avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n } @else if (type() === 'left-icon' && emoji()) {\n <div class=\"sui-switch-card__leading-icon\">\n <sui-emoji class=\"sui-switch-card__leading-emoji\" [name]=\"emoji()!\" size=\"sm\" />\n </div>\n } @else if (imageUrl() && type() !== 'left-icon') {\n <!-- card-provider 32\u00D724 / brand 40\u00D740 bare / company 40\u00D740 circle \u2014 el box lo da la clase. -->\n <div [class]=\"leadingBoxClass()\">\n <img [src]=\"imageUrl()\" alt=\"\" class=\"sui-switch-card__leading-img\" />\n </div>\n } @else {\n <!-- \u00DANICO ng-content del slot: si se duplica por branch, Angular solo proyecta\n en el primero declarado y los dem\u00E1s types quedan vac\u00EDos (bug auditor\u00EDa). -->\n <div [class]=\"leadingBoxClass()\">\n <ng-content select=\"[sui-switch-card-leading]\" />\n </div>\n }\n </div>\n}\n\n<div class=\"sui-switch-card__body\">\n <div class=\"sui-switch-card__title\">\n <span class=\"sui-switch-card__label\">{{ label() }}</span>\n @if (sublabel(); as sub) {\n <span class=\"sui-switch-card__sublabel\">{{ sub }}</span>\n }\n @if (
|
|
14180
|
-
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], emoji: [{ type: i0.Input, args: [{ isSignal: true, alias: "emoji", required: false }] }], imageUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUrl", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }],
|
|
14185
|
+
}, template: "@if (hasLeading()) {\n <div class=\"sui-switch-card__leading\">\n @if (type() === 'avatar') {\n <sui-avatar\n class=\"sui-switch-card__leading-avatar\"\n size=\"lg\"\n [src]=\"imageUrl()\"\n [initials]=\"initialsFromLabel()\" />\n } @else if (type() === 'left-icon' && emoji()) {\n <div class=\"sui-switch-card__leading-icon\">\n <sui-emoji class=\"sui-switch-card__leading-emoji\" [name]=\"emoji()!\" size=\"sm\" />\n </div>\n } @else if (imageUrl() && type() !== 'left-icon') {\n <!-- card-provider 32\u00D724 / brand 40\u00D740 bare / company 40\u00D740 circle \u2014 el box lo da la clase. -->\n <div [class]=\"leadingBoxClass()\">\n <img [src]=\"imageUrl()\" alt=\"\" class=\"sui-switch-card__leading-img\" />\n </div>\n } @else {\n <!-- \u00DANICO ng-content del slot: si se duplica por branch, Angular solo proyecta\n en el primero declarado y los dem\u00E1s types quedan vac\u00EDos (bug auditor\u00EDa). -->\n <div [class]=\"leadingBoxClass()\">\n <ng-content select=\"[sui-switch-card-leading]\" />\n </div>\n }\n </div>\n}\n\n<div class=\"sui-switch-card__body\">\n <div class=\"sui-switch-card__title\">\n <span class=\"sui-switch-card__label\">{{ label() }}</span>\n @if (sublabel(); as sub) {\n <span class=\"sui-switch-card__sublabel\">{{ sub }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <span class=\"sui-switch-card__badge\">{{ bcfg.label }}</span>\n }\n </div>\n @if (description(); as desc) {\n <p class=\"sui-switch-card__description\">{{ desc }}</p>\n }\n</div>\n\n<sui-switch\n class=\"sui-switch-card__switch\"\n [size]=\"size()\"\n [checked]=\"effectiveChecked()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onSwitchChange($event)\"\n/>\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:flex-start;gap:14px;padding:16px;border-radius:var(--sui-radius-12);background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);box-shadow:var(--sui-shadow-x-small);box-sizing:border-box;overflow:hidden;width:100%;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;outline:none;transition:background-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),border-color var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out),box-shadow var(--sui-motion-duration-x-fast, .12s) var(--sui-motion-ease-out, ease-out)}:host(:hover:not([data-sui-disabled]):not([data-sui-checked])){background:var(--sui-bg-weak-50);border-color:transparent;box-shadow:none}:host([data-sui-checked]:not([data-sui-disabled])){border-color:var(--sui-primary-base);box-shadow:none}:host([data-sui-disabled]){cursor:not-allowed;box-shadow:none}:host(:focus-visible){box-shadow:0 0 0 2px var(--sui-bg-white-0),0 0 0 4px var(--sui-primary-base)}.sui-switch-card__leading{flex-shrink:0;display:flex;align-items:center;justify-content:center}.sui-switch-card__leading-icon{width:40px;height:40px;display:flex;align-items:center;justify-content:center;padding:10px;border-radius:999px;background:var(--sui-bg-white-0);border:1px solid var(--sui-stroke-soft-200);box-shadow:var(--sui-shadow-x-small);box-sizing:border-box}.sui-switch-card__leading-emoji{width:20px;height:20px}:host([data-sui-disabled]) .sui-switch-card__leading-icon{box-shadow:none;opacity:.5}:host([data-sui-type=avatar]) .sui-switch-card__leading-avatar{width:40px;height:40px}.sui-switch-card__leading-card-provider{width:32px;height:24px;border-radius:4px;overflow:hidden;display:flex;align-items:center;justify-content:center}.sui-switch-card__leading-brand{width:40px;height:40px;overflow:hidden;display:flex;align-items:center;justify-content:center}.sui-switch-card__leading-company{width:40px;height:40px;border-radius:999px;overflow:hidden;display:flex;align-items:center;justify-content:center}.sui-switch-card__leading-img{width:100%;height:100%;object-fit:contain;display:block}:host([data-sui-disabled]) .sui-switch-card__leading{opacity:.5}.sui-switch-card__body{display:flex;flex-direction:column;gap:4px;flex:1 1 auto;min-width:0;align-self:stretch}.sui-switch-card__body:not(:has(.sui-switch-card__description)){justify-content:center}.sui-switch-card__title{display:flex;align-items:center;flex-wrap:wrap;gap:4px}.sui-switch-card__label{font-size:14px;font-weight:500;line-height:20px;letter-spacing:-.006em;color:var(--sui-text-strong-950)}:host([data-sui-disabled]) .sui-switch-card__label{color:var(--sui-text-sub-600)}.sui-switch-card__sublabel{font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600)}:host([data-sui-disabled]) .sui-switch-card__sublabel{color:var(--sui-text-soft-400)}.sui-switch-card__description{margin:0;font-size:12px;font-weight:400;line-height:16px;color:var(--sui-text-sub-600)}:host([data-sui-disabled]) .sui-switch-card__description{color:var(--sui-text-soft-400)}.sui-switch-card__badge{display:inline-flex;align-items:center;justify-content:center;padding:2px 8px;border-radius:999px;background:var(--sui-state-information-light, #c0d5ff);color:var(--sui-state-information-dark, #122368);font-size:11px;font-weight:500;line-height:12px;letter-spacing:.22px;text-transform:uppercase;white-space:nowrap}:host([data-sui-disabled]) .sui-switch-card__badge{background:transparent;border:1px solid var(--sui-stroke-soft-200);color:var(--sui-text-disabled-300)}.sui-switch-card__switch{flex-shrink:0;align-self:flex-start;margin-top:2px}\n"] }]
|
|
14186
|
+
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], emoji: [{ type: i0.Input, args: [{ isSignal: true, alias: "emoji", required: false }] }], imageUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUrl", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], checkedChange: [{ type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
|
|
14181
14187
|
|
|
14182
14188
|
/**
|
|
14183
14189
|
* SUI Switch Label — SUI Design System 2.0
|
|
@@ -14242,8 +14248,13 @@ class SuiSwitchLabel {
|
|
|
14242
14248
|
description = input(null, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
14243
14249
|
/** Tamaño del switch interno — lo decide el padre (componente dumb). */
|
|
14244
14250
|
size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
14245
|
-
|
|
14246
|
-
|
|
14251
|
+
/** Badge junto al label — string shorthand ('NEW') o SuiBadgeConfig
|
|
14252
|
+
(label + color/variant/size, tipado como sui-badge). null = sin badge. */
|
|
14253
|
+
badge = input(null, ...(ngDevMode ? [{ debugName: "badge" }] : /* istanbul ignore next */ []));
|
|
14254
|
+
badgeCfg = computed(() => {
|
|
14255
|
+
const b = this.badge();
|
|
14256
|
+
return b ? (typeof b === 'string' ? { label: b } : b) : null;
|
|
14257
|
+
}, ...(ngDevMode ? [{ debugName: "badgeCfg" }] : /* istanbul ignore next */ []));
|
|
14247
14258
|
linkLabel = input(null, ...(ngDevMode ? [{ debugName: "linkLabel" }] : /* istanbul ignore next */ []));
|
|
14248
14259
|
/** Si true, invierte orden: [content] [switch] (label a la izquierda). */
|
|
14249
14260
|
flip = input(false, ...(ngDevMode ? [{ debugName: "flip" }] : /* istanbul ignore next */ []));
|
|
@@ -14325,13 +14336,13 @@ class SuiSwitchLabel {
|
|
|
14325
14336
|
this._disabledByForm.set(isDisabled);
|
|
14326
14337
|
}
|
|
14327
14338
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiSwitchLabel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
14328
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiSwitchLabel, isStandalone: true, selector: "sui-switch-label", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null },
|
|
14339
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiSwitchLabel, isStandalone: true, selector: "sui-switch-label", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, sublabel: { classPropertyName: "sublabel", publicName: "sublabel", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, linkLabel: { classPropertyName: "linkLabel", publicName: "linkLabel", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "flip", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeChange: "activeChange", linkClick: "linkClick" }, host: { listeners: { "click": "onLabelClick($event)" }, properties: { "attr.data-sui-flip": "flip() ? \"\" : null", "attr.data-sui-with-description": "description() ? \"\" : null", "attr.data-sui-disabled": "isDisabled() ? \"\" : null" } }, providers: [
|
|
14329
14340
|
{
|
|
14330
14341
|
provide: NG_VALUE_ACCESSOR,
|
|
14331
14342
|
useExisting: forwardRef(() => SuiSwitchLabel),
|
|
14332
14343
|
multi: true,
|
|
14333
14344
|
},
|
|
14334
|
-
], ngImport: i0, template: "<sui-switch\n class=\"sui-switch-label__switch\"\n [size]=\"size()\"\n [checked]=\"effectiveActive()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onSwitchChange($event)\"\n/>\n\n<div class=\"sui-switch-label__content\">\n <div class=\"sui-switch-label__title\">\n <span class=\"sui-switch-label__label\">{{ label() }}</span>\n @if (sublabel(); as sl) {\n <span class=\"sui-switch-label__sublabel\">{{ sl }}</span>\n }\n @if (
|
|
14345
|
+
], ngImport: i0, template: "<sui-switch\n class=\"sui-switch-label__switch\"\n [size]=\"size()\"\n [checked]=\"effectiveActive()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onSwitchChange($event)\"\n/>\n\n<div class=\"sui-switch-label__content\">\n <div class=\"sui-switch-label__title\">\n <span class=\"sui-switch-label__label\">{{ label() }}</span>\n @if (sublabel(); as sl) {\n <span class=\"sui-switch-label__sublabel\">{{ sl }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <sui-badge\n class=\"sui-switch-label__badge\"\n [color]=\"bcfg.color ?? 'orange'\"\n [variant]=\"bcfg.variant ?? 'light'\"\n [size]=\"bcfg.size ?? 'small'\"\n >{{ bcfg.label }}</sui-badge>\n }\n </div>\n\n @if (description(); as desc) {\n <p class=\"sui-switch-label__description\">{{ desc }}</p>\n\n @if (linkLabel(); as link) {\n <button\n type=\"button\"\n class=\"sui-switch-label__link\"\n [disabled]=\"isDisabled()\"\n (click)=\"onLinkClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n >{{ link }}</button>\n }\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;align-items:flex-start;gap:8px;cursor:pointer;font-family:var(--sui-font-sans, \"Inter\", system-ui, sans-serif);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0;-webkit-tap-highlight-color:transparent}:host([data-sui-flip]) .sui-switch-label__switch{order:2}:host([data-sui-flip]) .sui-switch-label__content{order:1}:host([data-sui-disabled]){cursor:not-allowed}:host([data-sui-disabled]) .sui-switch-label__content{opacity:.5}:host([data-sui-disabled]) .sui-switch-label__switch{opacity:.5}.sui-switch-label__switch{flex-shrink:0}.sui-switch-label__content{display:flex;flex:1 0 0;min-width:0;flex-direction:column;align-items:flex-start;gap:4px}:host([data-sui-with-description]) .sui-switch-label__content{gap:10px}.sui-switch-label__title{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.sui-switch-label__label{font-size:14px;font-weight:400;line-height:20px;letter-spacing:-.006em;color:var(--sui-text-strong-950)}:host([data-sui-with-description]) .sui-switch-label__label{font-weight:500}.sui-switch-label__sublabel{font-size:12px;font-weight:400;line-height:16px;letter-spacing:0;color:var(--sui-text-sub-600)}.sui-switch-label__badge{flex-shrink:0}.sui-switch-label__description{margin:0;font-size:12px;font-weight:400;line-height:16px;letter-spacing:0;color:var(--sui-text-sub-600);word-break:break-word}.sui-switch-label__link{appearance:none;background:transparent;border:0;padding:0;font-family:inherit;font-size:12px;font-weight:500;line-height:16px;color:var(--sui-primary-base);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:color .15s ease}.sui-switch-label__link:hover{text-decoration:underline;text-underline-offset:2px;color:var(--sui-primary-dark, var(--sui-primary-base))}.sui-switch-label__link:focus-visible{outline:2px solid var(--sui-primary-base);outline-offset:2px;border-radius:2px}.sui-switch-label__link:disabled{color:var(--sui-text-disabled-300);cursor:not-allowed;pointer-events:none}\n"], dependencies: [{ kind: "component", type: SuiSwitch, selector: "sui-switch", inputs: ["size", "checked", "disabled"], outputs: ["checkedChange"] }, { kind: "component", type: SuiBadge, selector: "sui-badge", inputs: ["color", "variant", "size", "type", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
14335
14346
|
}
|
|
14336
14347
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiSwitchLabel, decorators: [{
|
|
14337
14348
|
type: Component,
|
|
@@ -14346,8 +14357,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
14346
14357
|
'[attr.data-sui-with-description]': 'description() ? "" : null',
|
|
14347
14358
|
'[attr.data-sui-disabled]': 'isDisabled() ? "" : null',
|
|
14348
14359
|
'(click)': 'onLabelClick($event)',
|
|
14349
|
-
}, template: "<sui-switch\n class=\"sui-switch-label__switch\"\n [size]=\"size()\"\n [checked]=\"effectiveActive()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onSwitchChange($event)\"\n/>\n\n<div class=\"sui-switch-label__content\">\n <div class=\"sui-switch-label__title\">\n <span class=\"sui-switch-label__label\">{{ label() }}</span>\n @if (sublabel(); as sl) {\n <span class=\"sui-switch-label__sublabel\">{{ sl }}</span>\n }\n @if (
|
|
14350
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }],
|
|
14360
|
+
}, template: "<sui-switch\n class=\"sui-switch-label__switch\"\n [size]=\"size()\"\n [checked]=\"effectiveActive()\"\n [disabled]=\"isDisabled()\"\n (checkedChange)=\"onSwitchChange($event)\"\n/>\n\n<div class=\"sui-switch-label__content\">\n <div class=\"sui-switch-label__title\">\n <span class=\"sui-switch-label__label\">{{ label() }}</span>\n @if (sublabel(); as sl) {\n <span class=\"sui-switch-label__sublabel\">{{ sl }}</span>\n }\n @if (badgeCfg(); as bcfg) {\n <sui-badge\n class=\"sui-switch-label__badge\"\n [color]=\"bcfg.color ?? 'orange'\"\n [variant]=\"bcfg.variant ?? 'light'\"\n [size]=\"bcfg.size ?? 'small'\"\n >{{ bcfg.label }}</sui-badge>\n }\n </div>\n\n @if (description(); as desc) {\n <p class=\"sui-switch-label__description\">{{ desc }}</p>\n\n @if (linkLabel(); as link) {\n <button\n type=\"button\"\n class=\"sui-switch-label__link\"\n [disabled]=\"isDisabled()\"\n (click)=\"onLinkClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\"\n >{{ link }}</button>\n }\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:inline-flex;align-items:flex-start;gap:8px;cursor:pointer;font-family:var(--sui-font-sans, \"Inter\", system-ui, sans-serif);font-feature-settings:\"ss11\" 1,\"calt\" 0,\"liga\" 0;-webkit-tap-highlight-color:transparent}:host([data-sui-flip]) .sui-switch-label__switch{order:2}:host([data-sui-flip]) .sui-switch-label__content{order:1}:host([data-sui-disabled]){cursor:not-allowed}:host([data-sui-disabled]) .sui-switch-label__content{opacity:.5}:host([data-sui-disabled]) .sui-switch-label__switch{opacity:.5}.sui-switch-label__switch{flex-shrink:0}.sui-switch-label__content{display:flex;flex:1 0 0;min-width:0;flex-direction:column;align-items:flex-start;gap:4px}:host([data-sui-with-description]) .sui-switch-label__content{gap:10px}.sui-switch-label__title{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.sui-switch-label__label{font-size:14px;font-weight:400;line-height:20px;letter-spacing:-.006em;color:var(--sui-text-strong-950)}:host([data-sui-with-description]) .sui-switch-label__label{font-weight:500}.sui-switch-label__sublabel{font-size:12px;font-weight:400;line-height:16px;letter-spacing:0;color:var(--sui-text-sub-600)}.sui-switch-label__badge{flex-shrink:0}.sui-switch-label__description{margin:0;font-size:12px;font-weight:400;line-height:16px;letter-spacing:0;color:var(--sui-text-sub-600);word-break:break-word}.sui-switch-label__link{appearance:none;background:transparent;border:0;padding:0;font-family:inherit;font-size:12px;font-weight:500;line-height:16px;color:var(--sui-primary-base);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:color .15s ease}.sui-switch-label__link:hover{text-decoration:underline;text-underline-offset:2px;color:var(--sui-primary-dark, var(--sui-primary-base))}.sui-switch-label__link:focus-visible{outline:2px solid var(--sui-primary-base);outline-offset:2px;border-radius:2px}.sui-switch-label__link:disabled{color:var(--sui-text-disabled-300);cursor:not-allowed;pointer-events:none}\n"] }]
|
|
14361
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], sublabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabel", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], linkLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "linkLabel", required: false }] }], flip: [{ type: i0.Input, args: [{ isSignal: true, alias: "flip", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], activeChange: [{ type: i0.Output, args: ["activeChange"] }], linkClick: [{ type: i0.Output, args: ["linkClick"] }] } });
|
|
14351
14362
|
|
|
14352
14363
|
/**
|
|
14353
14364
|
* SUI Tab Chips — chips horizontales scrollables (estilo "category nav" de
|
|
@@ -14603,8 +14614,13 @@ class SuiTable {
|
|
|
14603
14614
|
let sx = 0, sy = 0, lx = 0, ly = 0;
|
|
14604
14615
|
let axis = null;
|
|
14605
14616
|
let pageScroller = null;
|
|
14606
|
-
/* Velocidad vertical (px/ms)
|
|
14607
|
-
|
|
14617
|
+
/* Velocidad vertical (px/ms) para el fling. CRÍTICO: se estima con una
|
|
14618
|
+
ventana de samples (~100ms) tipo VelocityTracker de Android — NO con el
|
|
14619
|
+
último move suelto: el dedo siempre desacelera antes de soltar, así que
|
|
14620
|
+
la velocidad instantánea final es ~0 y el fling moría → scroll "lento". */
|
|
14621
|
+
let vy = 0, momentumRaf = 0, momentumTs = 0;
|
|
14622
|
+
const samples = [];
|
|
14623
|
+
const VELOCITY_WINDOW_MS = 100;
|
|
14608
14624
|
const findPageScroller = () => {
|
|
14609
14625
|
let n = el.parentElement;
|
|
14610
14626
|
while (n && n !== this.doc.body) {
|
|
@@ -14631,7 +14647,8 @@ class SuiTable {
|
|
|
14631
14647
|
sy = ly = t.clientY;
|
|
14632
14648
|
axis = null;
|
|
14633
14649
|
vy = 0;
|
|
14634
|
-
|
|
14650
|
+
samples.length = 0;
|
|
14651
|
+
samples.push({ y: t.clientY, t: e.timeStamp });
|
|
14635
14652
|
pageScroller = findPageScroller();
|
|
14636
14653
|
};
|
|
14637
14654
|
const onMove = (e) => {
|
|
@@ -14657,22 +14674,27 @@ class SuiTable {
|
|
|
14657
14674
|
el.scrollLeft -= t.clientX - lx;
|
|
14658
14675
|
}
|
|
14659
14676
|
else if (pageScroller) {
|
|
14660
|
-
|
|
14661
|
-
|
|
14662
|
-
|
|
14663
|
-
|
|
14664
|
-
vy = dy / dt; // px/ms (positivo = dedo bajando)
|
|
14677
|
+
pageScroller.scrollTop -= t.clientY - ly;
|
|
14678
|
+
samples.push({ y: t.clientY, t: e.timeStamp });
|
|
14679
|
+
while (samples.length > 1 && e.timeStamp - samples[0].t > VELOCITY_WINDOW_MS)
|
|
14680
|
+
samples.shift();
|
|
14665
14681
|
}
|
|
14666
14682
|
e.preventDefault();
|
|
14667
14683
|
lx = t.clientX;
|
|
14668
14684
|
ly = t.clientY;
|
|
14669
|
-
lastT = e.timeStamp;
|
|
14670
14685
|
};
|
|
14671
14686
|
const onEnd = () => {
|
|
14672
14687
|
/* Fling: continúa el scroll de la página con la velocidad de salida y
|
|
14673
14688
|
fricción exponencial frame-rate-independent (para que en 120Hz no vuele).
|
|
14674
14689
|
Replica el momentum nativo que el manejo manual del touch pierde. */
|
|
14675
|
-
if (axis !== 'y' || !pageScroller
|
|
14690
|
+
if (axis !== 'y' || !pageScroller)
|
|
14691
|
+
return;
|
|
14692
|
+
/* Velocidad de salida = promedio de la ventana (primer→último sample). */
|
|
14693
|
+
const first = samples[0];
|
|
14694
|
+
const last = samples[samples.length - 1];
|
|
14695
|
+
const win = last && first ? last.t - first.t : 0;
|
|
14696
|
+
vy = win > 0 ? (last.y - first.y) / win : 0;
|
|
14697
|
+
if (Math.abs(vy) < 0.05)
|
|
14676
14698
|
return;
|
|
14677
14699
|
const scroller = pageScroller;
|
|
14678
14700
|
momentumTs = 0;
|