@ajuarezso/sui-design-system 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9176,6 +9176,17 @@ const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
9176
9176
  * - errorEvent: mensaje de error de validación
9177
9177
  */
9178
9178
  class SuiImageUpload {
9179
+ /**
9180
+ * Ocupa el ancho del contenedor en vez del cuadrado fijo de `size`.
9181
+ *
9182
+ * Por defecto el componente es un cuadrado de lado `size` —pensado para
9183
+ * avatares y logos, donde eso es lo correcto—. Pero para subir un documento
9184
+ * (un comprobante de pago, una licencia) el cuadrado desperdicia el ancho
9185
+ * disponible y recorta imágenes verticales, que es la forma natural de una
9186
+ * captura de celular. En fluido el alto lo da el contenido, así que el botón
9187
+ * de quitar deja de desbordarse.
9188
+ */
9189
+ fluid = input(false, ...(ngDevMode ? [{ debugName: "fluid" }] : /* istanbul ignore next */ []));
9179
9190
  shape = input('circle', ...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
9180
9191
  size = input('lg', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
9181
9192
  src = model(null, ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
@@ -9303,7 +9314,7 @@ class SuiImageUpload {
9303
9314
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
9304
9315
  }
9305
9316
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiImageUpload, deps: [], target: i0.ɵɵFactoryTarget.Component });
9306
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiImageUpload, isStandalone: true, selector: "sui-image-upload", inputs: { shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, maxSize: { classPropertyName: "maxSize", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { src: "srcChange", imageSelected: "imageSelected", removed: "removed", editRequested: "editRequested", errorEvent: "errorEvent" }, host: { listeners: { "touchstart": "$event.currentTarget", "touchend": "$any($event.currentTarget).blur()", "click": "onHostClick()", "keydown.enter": "onHostClick()", "keydown.space": "onHostClick(); $event.preventDefault()", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" }, properties: { "attr.title": "null", "attr.data-sui-shape": "shape()", "attr.data-sui-size": "size()", "attr.data-sui-state": "state()", "attr.data-sui-disabled": "disabled() ? \"\" : null", "attr.role": "\"button\"", "attr.tabindex": "disabled() ? -1 : 0", "style.width.px": "sizePx()", "style.height.px": "sizePx()" } }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["imgInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Estado: sin imagen (empty / dragover) -->\n@if (!hasSrc()) {\n <div class=\"sui-image-upload__empty\">\n <!-- Icono c\u00E1mara \u2014 sui-icon (DS), no SVG inline -->\n <div class=\"sui-image-upload__icon\">\n <sui-icon name=\"image-add-line\" [size]=\"iconSize()\" aria-hidden=\"true\" />\n </div>\n\n <div class=\"sui-image-upload__text\">\n <p class=\"sui-image-upload__title\">{{ resolvedTitle() }}</p>\n <p class=\"sui-image-upload__subtitle\">{{ resolvedSubtitle() }}</p>\n </div>\n\n @if (internalError()) {\n <p class=\"sui-image-upload__error\">{{ internalError() }}</p>\n }\n </div>\n}\n\n<!-- Estado: con imagen (filled) -->\n@if (hasSrc()) {\n <div class=\"sui-image-upload__preview\" [class.sui-image-upload__preview--editable]=\"editable()\">\n <img\n class=\"sui-image-upload__img\"\n [src]=\"src()\"\n alt=\"Preview\"\n draggable=\"false\" />\n\n @if (editable()) {\n <!-- Modo editable: controles de \u00EDcono en esquina (editar + tacho). -->\n <div class=\"sui-image-upload__controls\">\n <button\n type=\"button\"\n class=\"sui-image-upload__ctrl\"\n aria-label=\"Editar imagen\"\n [disabled]=\"disabled()\"\n (click)=\"onEditClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\">\n <sui-icon name=\"pencil-line\" [size]=\"16\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"sui-image-upload__ctrl sui-image-upload__ctrl--danger\"\n aria-label=\"Quitar imagen\"\n [disabled]=\"disabled()\"\n (click)=\"onRemoveClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\">\n <sui-icon name=\"delete-bin-line\" [size]=\"16\" aria-hidden=\"true\" />\n </button>\n </div>\n } @else {\n <!-- Overlay hover con icono lapiz (re-subir) -->\n <div class=\"sui-image-upload__overlay\" (click)=\"onChangeClick($event)\">\n <div class=\"sui-image-upload__overlay-icon\">\n <sui-icon name=\"pencil-line\" [size]=\"16\" aria-hidden=\"true\" />\n </div>\n </div>\n }\n </div>\n\n @if (!editable()) {\n <!-- Bot\u00F3n Quitar debajo del preview \u2014 sui-button stroke (DS), no <button> custom.\n Figma node 452:699 \"Remove\" = stroke error; aqu\u00ED usamos color=error para\n que el affordance de borrado sea consistente con el DS. -->\n <sui-button\n class=\"sui-image-upload__remove\"\n variant=\"stroke\"\n color=\"error\"\n size=\"2xsmall\"\n [disabled]=\"disabled()\"\n (click)=\"onRemoveClick($event)\">\n Quitar\n </sui-button>\n }\n}\n\n<!-- Input file oculto (siempre presente para el click) -->\n<input\n #imgInput\n type=\"file\"\n class=\"sui-image-upload__input\"\n accept=\"image/jpeg,image/png,image/webp,image/gif\"\n [disabled]=\"disabled()\"\n (change)=\"onInputChange($event)\" />\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:inline-flex;flex-direction:column;align-items:center;gap:8px;font-family:var(--sui-font-sans, var(--font-sans, sans-serif));cursor:pointer;flex-shrink:0}:host([data-sui-disabled]){cursor:not-allowed;opacity:.5}.sui-image-upload__empty{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;border:1px dashed var(--sui-stroke-soft-200, #ebebeb);background:var(--sui-bg-white-0, #fff);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(0, 0, 0, .06));text-align:center;padding:12px 8px;box-sizing:border-box;transition:border-color var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1)),background var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1))}:host([data-sui-shape=circle]) .sui-image-upload__empty{border-radius:999px}:host([data-sui-shape=rect]) .sui-image-upload__empty{border-radius:var(--sui-radius-12, 12px)}:host(:hover:not([data-sui-disabled])) .sui-image-upload__empty{border-color:var(--sui-stroke-sub-300, #d1d1d1);background:var(--sui-bg-weak-50, #f7f7f7)}:host([data-sui-state=dragover]) .sui-image-upload__empty{border-color:var(--sui-primary-base, #fa7319);background:var(--sui-primary-alpha-10, rgba(250, 115, 25, .1019607843))}.sui-image-upload__icon{width:32px;height:32px;border-radius:999px;background:var(--sui-bg-weak-50, #f7f7f7);display:flex;align-items:center;justify-content:center;color:var(--sui-icon-sub-600, #5c5c5c);flex-shrink:0}:host([data-sui-size=xl]) .sui-image-upload__icon{width:40px;height:40px}:host([data-sui-state=dragover]) .sui-image-upload__icon{background:var(--sui-primary-alpha-16, rgba(250, 115, 25, .1607843137));color:var(--sui-primary-base, #fa7319)}.sui-image-upload__text{display:flex;flex-direction:column;gap:2px;align-items:center}.sui-image-upload__title{margin:0;font-size:12px;font-weight:500;line-height:16px;color:var(--sui-text-strong-950, #171717)}:host([data-sui-size=xl]) .sui-image-upload__title{font-size:13px;line-height:18px}.sui-image-upload__subtitle{margin:0;font-size:11px;font-weight:400;line-height:15px;color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-size=sm]) .sui-image-upload__subtitle{display:none}:host([data-sui-size=xl]) .sui-image-upload__subtitle{font-size:12px;line-height:16px}.sui-image-upload__error{margin:2px 0 0;font-size:10px;line-height:14px;color:var(--sui-state-error-base, #fb3748);text-align:center}.sui-image-upload__preview{position:relative;width:100%;height:100%;overflow:hidden;box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(0, 0, 0, .06));flex-shrink:0}:host([data-sui-shape=circle]) .sui-image-upload__preview{border-radius:999px}:host([data-sui-shape=rect]) .sui-image-upload__preview{border-radius:var(--sui-radius-12, 12px)}.sui-image-upload__img{width:100%;height:100%;object-fit:cover;display:block;pointer-events:none;-webkit-user-select:none;user-select:none}.sui-image-upload__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#0006;opacity:0;transition:opacity var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1));cursor:pointer}:host(:hover:not([data-sui-disabled])) .sui-image-upload__overlay{opacity:1}.sui-image-upload__overlay-icon{width:32px;height:32px;border-radius:999px;background:#fff3;display:flex;align-items:center;justify-content:center;color:var(--sui-static-white, #fff)}.sui-image-upload__preview--editable{cursor:default}.sui-image-upload__controls{position:absolute;top:8px;right:8px;display:flex;gap:6px;z-index:2}.sui-image-upload__ctrl{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;border:none;background:#0000008c;color:var(--sui-static-white, #fff);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color .15s ease,transform .12s ease}.sui-image-upload__ctrl:active{transform:scale(.92)}.sui-image-upload__ctrl:disabled{opacity:.5;cursor:not-allowed}.sui-image-upload__ctrl--danger:active{background:var(--sui-state-error-base, #fb3748)}.sui-image-upload__remove{flex-shrink:0}.sui-image-upload__input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: SuiButton, selector: "sui-button", inputs: ["variant", "color", "size", "onlyIcon", "disabled", "leftIcon", "rightIcon", "type"] }, { kind: "component", type: SuiIcon, selector: "sui-icon", inputs: ["name", "size", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9317
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: SuiImageUpload, isStandalone: true, selector: "sui-image-upload", inputs: { fluid: { classPropertyName: "fluid", publicName: "fluid", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, maxSize: { classPropertyName: "maxSize", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { src: "srcChange", imageSelected: "imageSelected", removed: "removed", editRequested: "editRequested", errorEvent: "errorEvent" }, host: { listeners: { "touchstart": "$event.currentTarget", "touchend": "$any($event.currentTarget).blur()", "click": "onHostClick()", "keydown.enter": "onHostClick()", "keydown.space": "onHostClick(); $event.preventDefault()", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" }, properties: { "attr.title": "null", "attr.data-sui-shape": "shape()", "attr.data-sui-size": "size()", "attr.data-sui-state": "state()", "attr.data-sui-disabled": "disabled() ? \"\" : null", "attr.role": "\"button\"", "attr.tabindex": "disabled() ? -1 : 0", "attr.data-sui-fluid": "fluid() ? \"\" : null", "style.width.px": "fluid() ? null : sizePx()", "style.height.px": "fluid() ? null : sizePx()" } }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["imgInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Estado: sin imagen (empty / dragover) -->\n@if (!hasSrc()) {\n <div class=\"sui-image-upload__empty\">\n <!-- Icono c\u00E1mara \u2014 sui-icon (DS), no SVG inline -->\n <div class=\"sui-image-upload__icon\">\n <sui-icon name=\"image-add-line\" [size]=\"iconSize()\" aria-hidden=\"true\" />\n </div>\n\n <div class=\"sui-image-upload__text\">\n <p class=\"sui-image-upload__title\">{{ resolvedTitle() }}</p>\n <p class=\"sui-image-upload__subtitle\">{{ resolvedSubtitle() }}</p>\n </div>\n\n @if (internalError()) {\n <p class=\"sui-image-upload__error\">{{ internalError() }}</p>\n }\n </div>\n}\n\n<!-- Estado: con imagen (filled) -->\n@if (hasSrc()) {\n <div class=\"sui-image-upload__preview\" [class.sui-image-upload__preview--editable]=\"editable()\">\n <img\n class=\"sui-image-upload__img\"\n [src]=\"src()\"\n alt=\"Preview\"\n draggable=\"false\" />\n\n @if (editable()) {\n <!-- Modo editable: controles de \u00EDcono en esquina (editar + tacho). -->\n <div class=\"sui-image-upload__controls\">\n <button\n type=\"button\"\n class=\"sui-image-upload__ctrl\"\n aria-label=\"Editar imagen\"\n [disabled]=\"disabled()\"\n (click)=\"onEditClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\">\n <sui-icon name=\"pencil-line\" [size]=\"16\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"sui-image-upload__ctrl sui-image-upload__ctrl--danger\"\n aria-label=\"Quitar imagen\"\n [disabled]=\"disabled()\"\n (click)=\"onRemoveClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\">\n <sui-icon name=\"delete-bin-line\" [size]=\"16\" aria-hidden=\"true\" />\n </button>\n </div>\n } @else {\n <!-- Overlay hover con icono lapiz (re-subir) -->\n <div class=\"sui-image-upload__overlay\" (click)=\"onChangeClick($event)\">\n <div class=\"sui-image-upload__overlay-icon\">\n <sui-icon name=\"pencil-line\" [size]=\"16\" aria-hidden=\"true\" />\n </div>\n </div>\n }\n </div>\n\n @if (!editable()) {\n <!-- Bot\u00F3n Quitar debajo del preview \u2014 sui-button stroke (DS), no <button> custom.\n Figma node 452:699 \"Remove\" = stroke error; aqu\u00ED usamos color=error para\n que el affordance de borrado sea consistente con el DS. -->\n <sui-button\n class=\"sui-image-upload__remove\"\n variant=\"stroke\"\n color=\"error\"\n size=\"2xsmall\"\n [disabled]=\"disabled()\"\n (click)=\"onRemoveClick($event)\">\n Quitar\n </sui-button>\n }\n}\n\n<!-- Input file oculto (siempre presente para el click) -->\n<input\n #imgInput\n type=\"file\"\n class=\"sui-image-upload__input\"\n accept=\"image/jpeg,image/png,image/webp,image/gif\"\n [disabled]=\"disabled()\"\n (change)=\"onInputChange($event)\" />\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:inline-flex;flex-direction:column;align-items:center;gap:8px;font-family:var(--sui-font-sans, var(--font-sans, sans-serif));cursor:pointer;flex-shrink:0}:host([data-sui-fluid]){display:block;width:100%}:host([data-sui-fluid]) .sui-image-upload__empty{height:auto;min-height:132px;padding:20px 16px}:host([data-sui-fluid]) .sui-image-upload__preview{height:auto;max-height:320px}:host([data-sui-fluid]) .sui-image-upload__img{height:auto;max-height:320px;object-fit:contain;background:var(--sui-bg-weak-50, #f7f7f7)}:host([data-sui-fluid]) .sui-image-upload__remove{margin-top:8px}:host([data-sui-disabled]){cursor:not-allowed;opacity:.5}.sui-image-upload__empty{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;border:1px dashed var(--sui-stroke-soft-200, #ebebeb);background:var(--sui-bg-white-0, #fff);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(0, 0, 0, .06));text-align:center;padding:12px 8px;box-sizing:border-box;transition:border-color var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1)),background var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1))}:host([data-sui-shape=circle]) .sui-image-upload__empty{border-radius:999px}:host([data-sui-shape=rect]) .sui-image-upload__empty{border-radius:var(--sui-radius-12, 12px)}:host(:hover:not([data-sui-disabled])) .sui-image-upload__empty{border-color:var(--sui-stroke-sub-300, #d1d1d1);background:var(--sui-bg-weak-50, #f7f7f7)}:host([data-sui-state=dragover]) .sui-image-upload__empty{border-color:var(--sui-primary-base, #fa7319);background:var(--sui-primary-alpha-10, rgba(250, 115, 25, .1019607843))}.sui-image-upload__icon{width:32px;height:32px;border-radius:999px;background:var(--sui-bg-weak-50, #f7f7f7);display:flex;align-items:center;justify-content:center;color:var(--sui-icon-sub-600, #5c5c5c);flex-shrink:0}:host([data-sui-size=xl]) .sui-image-upload__icon{width:40px;height:40px}:host([data-sui-state=dragover]) .sui-image-upload__icon{background:var(--sui-primary-alpha-16, rgba(250, 115, 25, .1607843137));color:var(--sui-primary-base, #fa7319)}.sui-image-upload__text{display:flex;flex-direction:column;gap:2px;align-items:center}.sui-image-upload__title{margin:0;font-size:12px;font-weight:500;line-height:16px;color:var(--sui-text-strong-950, #171717)}:host([data-sui-size=xl]) .sui-image-upload__title{font-size:13px;line-height:18px}.sui-image-upload__subtitle{margin:0;font-size:11px;font-weight:400;line-height:15px;color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-size=sm]) .sui-image-upload__subtitle{display:none}:host([data-sui-size=xl]) .sui-image-upload__subtitle{font-size:12px;line-height:16px}.sui-image-upload__error{margin:2px 0 0;font-size:10px;line-height:14px;color:var(--sui-state-error-base, #fb3748);text-align:center}.sui-image-upload__preview{position:relative;width:100%;height:100%;overflow:hidden;box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(0, 0, 0, .06));flex-shrink:0}:host([data-sui-shape=circle]) .sui-image-upload__preview{border-radius:999px}:host([data-sui-shape=rect]) .sui-image-upload__preview{border-radius:var(--sui-radius-12, 12px)}.sui-image-upload__img{width:100%;height:100%;object-fit:cover;display:block;pointer-events:none;-webkit-user-select:none;user-select:none}.sui-image-upload__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#0006;opacity:0;transition:opacity var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1));cursor:pointer}:host(:hover:not([data-sui-disabled])) .sui-image-upload__overlay{opacity:1}.sui-image-upload__overlay-icon{width:32px;height:32px;border-radius:999px;background:#fff3;display:flex;align-items:center;justify-content:center;color:var(--sui-static-white, #fff)}.sui-image-upload__preview--editable{cursor:default}.sui-image-upload__controls{position:absolute;top:8px;right:8px;display:flex;gap:6px;z-index:2}.sui-image-upload__ctrl{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;border:none;background:#0000008c;color:var(--sui-static-white, #fff);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color .15s ease,transform .12s ease}.sui-image-upload__ctrl:active{transform:scale(.92)}.sui-image-upload__ctrl:disabled{opacity:.5;cursor:not-allowed}.sui-image-upload__ctrl--danger:active{background:var(--sui-state-error-base, #fb3748)}.sui-image-upload__remove{flex-shrink:0}.sui-image-upload__input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "component", type: SuiButton, selector: "sui-button", inputs: ["variant", "color", "size", "onlyIcon", "disabled", "leftIcon", "rightIcon", "type"] }, { kind: "component", type: SuiIcon, selector: "sui-icon", inputs: ["name", "size", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9307
9318
  }
9308
9319
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SuiImageUpload, decorators: [{
9309
9320
  type: Component,
@@ -9316,8 +9327,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
9316
9327
  '[attr.data-sui-disabled]': 'disabled() ? "" : null',
9317
9328
  '[attr.role]': '"button"',
9318
9329
  '[attr.tabindex]': 'disabled() ? -1 : 0',
9319
- '[style.width.px]': 'sizePx()',
9320
- '[style.height.px]': 'sizePx()',
9330
+ '[attr.data-sui-fluid]': 'fluid() ? "" : null',
9331
+ /* En modo fluido el tamaño lo pone el contenedor, no el `size`. */
9332
+ '[style.width.px]': 'fluid() ? null : sizePx()',
9333
+ '[style.height.px]': 'fluid() ? null : sizePx()',
9321
9334
  /* iOS WKWebView :active fix — CRITICO para pages standalone */
9322
9335
  '(touchstart)': '$event.currentTarget',
9323
9336
  '(touchend)': '$any($event.currentTarget).blur()',
@@ -9327,8 +9340,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
9327
9340
  '(dragover)': 'onDragOver($event)',
9328
9341
  '(dragleave)': 'onDragLeave($event)',
9329
9342
  '(drop)': 'onDrop($event)',
9330
- }, template: "<!-- Estado: sin imagen (empty / dragover) -->\n@if (!hasSrc()) {\n <div class=\"sui-image-upload__empty\">\n <!-- Icono c\u00E1mara \u2014 sui-icon (DS), no SVG inline -->\n <div class=\"sui-image-upload__icon\">\n <sui-icon name=\"image-add-line\" [size]=\"iconSize()\" aria-hidden=\"true\" />\n </div>\n\n <div class=\"sui-image-upload__text\">\n <p class=\"sui-image-upload__title\">{{ resolvedTitle() }}</p>\n <p class=\"sui-image-upload__subtitle\">{{ resolvedSubtitle() }}</p>\n </div>\n\n @if (internalError()) {\n <p class=\"sui-image-upload__error\">{{ internalError() }}</p>\n }\n </div>\n}\n\n<!-- Estado: con imagen (filled) -->\n@if (hasSrc()) {\n <div class=\"sui-image-upload__preview\" [class.sui-image-upload__preview--editable]=\"editable()\">\n <img\n class=\"sui-image-upload__img\"\n [src]=\"src()\"\n alt=\"Preview\"\n draggable=\"false\" />\n\n @if (editable()) {\n <!-- Modo editable: controles de \u00EDcono en esquina (editar + tacho). -->\n <div class=\"sui-image-upload__controls\">\n <button\n type=\"button\"\n class=\"sui-image-upload__ctrl\"\n aria-label=\"Editar imagen\"\n [disabled]=\"disabled()\"\n (click)=\"onEditClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\">\n <sui-icon name=\"pencil-line\" [size]=\"16\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"sui-image-upload__ctrl sui-image-upload__ctrl--danger\"\n aria-label=\"Quitar imagen\"\n [disabled]=\"disabled()\"\n (click)=\"onRemoveClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\">\n <sui-icon name=\"delete-bin-line\" [size]=\"16\" aria-hidden=\"true\" />\n </button>\n </div>\n } @else {\n <!-- Overlay hover con icono lapiz (re-subir) -->\n <div class=\"sui-image-upload__overlay\" (click)=\"onChangeClick($event)\">\n <div class=\"sui-image-upload__overlay-icon\">\n <sui-icon name=\"pencil-line\" [size]=\"16\" aria-hidden=\"true\" />\n </div>\n </div>\n }\n </div>\n\n @if (!editable()) {\n <!-- Bot\u00F3n Quitar debajo del preview \u2014 sui-button stroke (DS), no <button> custom.\n Figma node 452:699 \"Remove\" = stroke error; aqu\u00ED usamos color=error para\n que el affordance de borrado sea consistente con el DS. -->\n <sui-button\n class=\"sui-image-upload__remove\"\n variant=\"stroke\"\n color=\"error\"\n size=\"2xsmall\"\n [disabled]=\"disabled()\"\n (click)=\"onRemoveClick($event)\">\n Quitar\n </sui-button>\n }\n}\n\n<!-- Input file oculto (siempre presente para el click) -->\n<input\n #imgInput\n type=\"file\"\n class=\"sui-image-upload__input\"\n accept=\"image/jpeg,image/png,image/webp,image/gif\"\n [disabled]=\"disabled()\"\n (change)=\"onInputChange($event)\" />\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:inline-flex;flex-direction:column;align-items:center;gap:8px;font-family:var(--sui-font-sans, var(--font-sans, sans-serif));cursor:pointer;flex-shrink:0}:host([data-sui-disabled]){cursor:not-allowed;opacity:.5}.sui-image-upload__empty{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;border:1px dashed var(--sui-stroke-soft-200, #ebebeb);background:var(--sui-bg-white-0, #fff);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(0, 0, 0, .06));text-align:center;padding:12px 8px;box-sizing:border-box;transition:border-color var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1)),background var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1))}:host([data-sui-shape=circle]) .sui-image-upload__empty{border-radius:999px}:host([data-sui-shape=rect]) .sui-image-upload__empty{border-radius:var(--sui-radius-12, 12px)}:host(:hover:not([data-sui-disabled])) .sui-image-upload__empty{border-color:var(--sui-stroke-sub-300, #d1d1d1);background:var(--sui-bg-weak-50, #f7f7f7)}:host([data-sui-state=dragover]) .sui-image-upload__empty{border-color:var(--sui-primary-base, #fa7319);background:var(--sui-primary-alpha-10, rgba(250, 115, 25, .1019607843))}.sui-image-upload__icon{width:32px;height:32px;border-radius:999px;background:var(--sui-bg-weak-50, #f7f7f7);display:flex;align-items:center;justify-content:center;color:var(--sui-icon-sub-600, #5c5c5c);flex-shrink:0}:host([data-sui-size=xl]) .sui-image-upload__icon{width:40px;height:40px}:host([data-sui-state=dragover]) .sui-image-upload__icon{background:var(--sui-primary-alpha-16, rgba(250, 115, 25, .1607843137));color:var(--sui-primary-base, #fa7319)}.sui-image-upload__text{display:flex;flex-direction:column;gap:2px;align-items:center}.sui-image-upload__title{margin:0;font-size:12px;font-weight:500;line-height:16px;color:var(--sui-text-strong-950, #171717)}:host([data-sui-size=xl]) .sui-image-upload__title{font-size:13px;line-height:18px}.sui-image-upload__subtitle{margin:0;font-size:11px;font-weight:400;line-height:15px;color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-size=sm]) .sui-image-upload__subtitle{display:none}:host([data-sui-size=xl]) .sui-image-upload__subtitle{font-size:12px;line-height:16px}.sui-image-upload__error{margin:2px 0 0;font-size:10px;line-height:14px;color:var(--sui-state-error-base, #fb3748);text-align:center}.sui-image-upload__preview{position:relative;width:100%;height:100%;overflow:hidden;box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(0, 0, 0, .06));flex-shrink:0}:host([data-sui-shape=circle]) .sui-image-upload__preview{border-radius:999px}:host([data-sui-shape=rect]) .sui-image-upload__preview{border-radius:var(--sui-radius-12, 12px)}.sui-image-upload__img{width:100%;height:100%;object-fit:cover;display:block;pointer-events:none;-webkit-user-select:none;user-select:none}.sui-image-upload__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#0006;opacity:0;transition:opacity var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1));cursor:pointer}:host(:hover:not([data-sui-disabled])) .sui-image-upload__overlay{opacity:1}.sui-image-upload__overlay-icon{width:32px;height:32px;border-radius:999px;background:#fff3;display:flex;align-items:center;justify-content:center;color:var(--sui-static-white, #fff)}.sui-image-upload__preview--editable{cursor:default}.sui-image-upload__controls{position:absolute;top:8px;right:8px;display:flex;gap:6px;z-index:2}.sui-image-upload__ctrl{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;border:none;background:#0000008c;color:var(--sui-static-white, #fff);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color .15s ease,transform .12s ease}.sui-image-upload__ctrl:active{transform:scale(.92)}.sui-image-upload__ctrl:disabled{opacity:.5;cursor:not-allowed}.sui-image-upload__ctrl--danger:active{background:var(--sui-state-error-base, #fb3748)}.sui-image-upload__remove{flex-shrink:0}.sui-image-upload__input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
9331
- }], propDecorators: { shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }, { type: i0.Output, args: ["srcChange"] }], maxSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSize", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], imageSelected: [{ type: i0.Output, args: ["imageSelected"] }], removed: [{ type: i0.Output, args: ["removed"] }], editRequested: [{ type: i0.Output, args: ["editRequested"] }], errorEvent: [{ type: i0.Output, args: ["errorEvent"] }], inputRef: [{ type: i0.ViewChild, args: ['imgInput', { isSignal: true }] }] } });
9343
+ }, template: "<!-- Estado: sin imagen (empty / dragover) -->\n@if (!hasSrc()) {\n <div class=\"sui-image-upload__empty\">\n <!-- Icono c\u00E1mara \u2014 sui-icon (DS), no SVG inline -->\n <div class=\"sui-image-upload__icon\">\n <sui-icon name=\"image-add-line\" [size]=\"iconSize()\" aria-hidden=\"true\" />\n </div>\n\n <div class=\"sui-image-upload__text\">\n <p class=\"sui-image-upload__title\">{{ resolvedTitle() }}</p>\n <p class=\"sui-image-upload__subtitle\">{{ resolvedSubtitle() }}</p>\n </div>\n\n @if (internalError()) {\n <p class=\"sui-image-upload__error\">{{ internalError() }}</p>\n }\n </div>\n}\n\n<!-- Estado: con imagen (filled) -->\n@if (hasSrc()) {\n <div class=\"sui-image-upload__preview\" [class.sui-image-upload__preview--editable]=\"editable()\">\n <img\n class=\"sui-image-upload__img\"\n [src]=\"src()\"\n alt=\"Preview\"\n draggable=\"false\" />\n\n @if (editable()) {\n <!-- Modo editable: controles de \u00EDcono en esquina (editar + tacho). -->\n <div class=\"sui-image-upload__controls\">\n <button\n type=\"button\"\n class=\"sui-image-upload__ctrl\"\n aria-label=\"Editar imagen\"\n [disabled]=\"disabled()\"\n (click)=\"onEditClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\">\n <sui-icon name=\"pencil-line\" [size]=\"16\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"sui-image-upload__ctrl sui-image-upload__ctrl--danger\"\n aria-label=\"Quitar imagen\"\n [disabled]=\"disabled()\"\n (click)=\"onRemoveClick($event)\"\n (touchstart)=\"$event.currentTarget\"\n (touchend)=\"$any($event.currentTarget).blur()\">\n <sui-icon name=\"delete-bin-line\" [size]=\"16\" aria-hidden=\"true\" />\n </button>\n </div>\n } @else {\n <!-- Overlay hover con icono lapiz (re-subir) -->\n <div class=\"sui-image-upload__overlay\" (click)=\"onChangeClick($event)\">\n <div class=\"sui-image-upload__overlay-icon\">\n <sui-icon name=\"pencil-line\" [size]=\"16\" aria-hidden=\"true\" />\n </div>\n </div>\n }\n </div>\n\n @if (!editable()) {\n <!-- Bot\u00F3n Quitar debajo del preview \u2014 sui-button stroke (DS), no <button> custom.\n Figma node 452:699 \"Remove\" = stroke error; aqu\u00ED usamos color=error para\n que el affordance de borrado sea consistente con el DS. -->\n <sui-button\n class=\"sui-image-upload__remove\"\n variant=\"stroke\"\n color=\"error\"\n size=\"2xsmall\"\n [disabled]=\"disabled()\"\n (click)=\"onRemoveClick($event)\">\n Quitar\n </sui-button>\n }\n}\n\n<!-- Input file oculto (siempre presente para el click) -->\n<input\n #imgInput\n type=\"file\"\n class=\"sui-image-upload__input\"\n accept=\"image/jpeg,image/png,image/webp,image/gif\"\n [disabled]=\"disabled()\"\n (change)=\"onInputChange($event)\" />\n", styles: ["@charset \"UTF-8\";:host{position:relative;display:inline-flex;flex-direction:column;align-items:center;gap:8px;font-family:var(--sui-font-sans, var(--font-sans, sans-serif));cursor:pointer;flex-shrink:0}:host([data-sui-fluid]){display:block;width:100%}:host([data-sui-fluid]) .sui-image-upload__empty{height:auto;min-height:132px;padding:20px 16px}:host([data-sui-fluid]) .sui-image-upload__preview{height:auto;max-height:320px}:host([data-sui-fluid]) .sui-image-upload__img{height:auto;max-height:320px;object-fit:contain;background:var(--sui-bg-weak-50, #f7f7f7)}:host([data-sui-fluid]) .sui-image-upload__remove{margin-top:8px}:host([data-sui-disabled]){cursor:not-allowed;opacity:.5}.sui-image-upload__empty{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;border:1px dashed var(--sui-stroke-soft-200, #ebebeb);background:var(--sui-bg-white-0, #fff);box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(0, 0, 0, .06));text-align:center;padding:12px 8px;box-sizing:border-box;transition:border-color var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1)),background var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1))}:host([data-sui-shape=circle]) .sui-image-upload__empty{border-radius:999px}:host([data-sui-shape=rect]) .sui-image-upload__empty{border-radius:var(--sui-radius-12, 12px)}:host(:hover:not([data-sui-disabled])) .sui-image-upload__empty{border-color:var(--sui-stroke-sub-300, #d1d1d1);background:var(--sui-bg-weak-50, #f7f7f7)}:host([data-sui-state=dragover]) .sui-image-upload__empty{border-color:var(--sui-primary-base, #fa7319);background:var(--sui-primary-alpha-10, rgba(250, 115, 25, .1019607843))}.sui-image-upload__icon{width:32px;height:32px;border-radius:999px;background:var(--sui-bg-weak-50, #f7f7f7);display:flex;align-items:center;justify-content:center;color:var(--sui-icon-sub-600, #5c5c5c);flex-shrink:0}:host([data-sui-size=xl]) .sui-image-upload__icon{width:40px;height:40px}:host([data-sui-state=dragover]) .sui-image-upload__icon{background:var(--sui-primary-alpha-16, rgba(250, 115, 25, .1607843137));color:var(--sui-primary-base, #fa7319)}.sui-image-upload__text{display:flex;flex-direction:column;gap:2px;align-items:center}.sui-image-upload__title{margin:0;font-size:12px;font-weight:500;line-height:16px;color:var(--sui-text-strong-950, #171717)}:host([data-sui-size=xl]) .sui-image-upload__title{font-size:13px;line-height:18px}.sui-image-upload__subtitle{margin:0;font-size:11px;font-weight:400;line-height:15px;color:var(--sui-text-sub-600, #5c5c5c)}:host([data-sui-size=sm]) .sui-image-upload__subtitle{display:none}:host([data-sui-size=xl]) .sui-image-upload__subtitle{font-size:12px;line-height:16px}.sui-image-upload__error{margin:2px 0 0;font-size:10px;line-height:14px;color:var(--sui-state-error-base, #fb3748);text-align:center}.sui-image-upload__preview{position:relative;width:100%;height:100%;overflow:hidden;box-shadow:var(--sui-shadow-x-small, 0 1px 2px 0 rgba(0, 0, 0, .06));flex-shrink:0}:host([data-sui-shape=circle]) .sui-image-upload__preview{border-radius:999px}:host([data-sui-shape=rect]) .sui-image-upload__preview{border-radius:var(--sui-radius-12, 12px)}.sui-image-upload__img{width:100%;height:100%;object-fit:cover;display:block;pointer-events:none;-webkit-user-select:none;user-select:none}.sui-image-upload__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:#0006;opacity:0;transition:opacity var(--sui-motion-duration-fast, .2s) var(--sui-motion-ease-out, cubic-bezier(0, 0, .2, 1));cursor:pointer}:host(:hover:not([data-sui-disabled])) .sui-image-upload__overlay{opacity:1}.sui-image-upload__overlay-icon{width:32px;height:32px;border-radius:999px;background:#fff3;display:flex;align-items:center;justify-content:center;color:var(--sui-static-white, #fff)}.sui-image-upload__preview--editable{cursor:default}.sui-image-upload__controls{position:absolute;top:8px;right:8px;display:flex;gap:6px;z-index:2}.sui-image-upload__ctrl{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;border-radius:999px;border:none;background:#0000008c;color:var(--sui-static-white, #fff);cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color .15s ease,transform .12s ease}.sui-image-upload__ctrl:active{transform:scale(.92)}.sui-image-upload__ctrl:disabled{opacity:.5;cursor:not-allowed}.sui-image-upload__ctrl--danger:active{background:var(--sui-state-error-base, #fb3748)}.sui-image-upload__remove{flex-shrink:0}.sui-image-upload__input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
9344
+ }], propDecorators: { fluid: [{ type: i0.Input, args: [{ isSignal: true, alias: "fluid", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }, { type: i0.Output, args: ["srcChange"] }], maxSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSize", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], imageSelected: [{ type: i0.Output, args: ["imageSelected"] }], removed: [{ type: i0.Output, args: ["removed"] }], editRequested: [{ type: i0.Output, args: ["editRequested"] }], errorEvent: [{ type: i0.Output, args: ["errorEvent"] }], inputRef: [{ type: i0.ViewChild, args: ['imgInput', { isSignal: true }] }] } });
9332
9345
 
9333
9346
  /**
9334
9347
  * SUI Inline Input — SUI Design System 2.0