import * as i0 from '@angular/core';
import { input, booleanAttribute, model, output, viewChild, computed, ChangeDetectionStrategy, Component } from '@angular/core';
import { SdInput } from '@sdcorejs/angular/forms/input';
import { SdSuffixDefDirective } from '@sdcorejs/angular/forms/directives';
import { sdViewedTransform } from '@sdcorejs/angular/forms/models';

// why: matches #RGB, #RRGGBB, #RRGGBBAA. Capital + lowercase hex allowed.
// Native <input type="color"> only emits #RRGGBB, so we canonicalize before
// feeding the picker (expand 3-char, strip alpha) and let the swatch render
// the raw model value when it's a valid hex.
const SD_INPUT_COLOR_HEX_PATTERN = '^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$';
class SdInputColor {
    hexPattern = SD_INPUT_COLOR_HEX_PATTERN;
    #hexRegex = new RegExp(SD_INPUT_COLOR_HEX_PATTERN);
    // ==========================================
    // Inputs (forwarded to <sd-input>)
    // ==========================================
    label = input(...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
    helperText = input(...(ngDevMode ? [undefined, { debugName: "helperText" }] : /* istanbul ignore next */ []));
    placeholder = input('#RRGGBB', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
    size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
    appearance = input(undefined, ...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
    // why: type as `any` — the inner <sd-input> applies the FormGroup|NgForm transform.
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    form = input(undefined, ...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
    name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : /* istanbul ignore next */ []));
    autoId = input(...(ngDevMode ? [undefined, { debugName: "autoId" }] : /* istanbul ignore next */ []));
    required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    /** Display mode — forwarded to the inner `<sd-input>`. `'inline'` = borderless inline-edit; disabled `'inline'` → static. */
    viewed = input(false, { ...(ngDevMode ? { debugName: "viewed" } : /* istanbul ignore next */ {}), transform: sdViewedTransform });
    // Two-way model — same alias as <sd-input>
    valueModel = model(undefined, { ...(ngDevMode ? { debugName: "valueModel" } : /* istanbul ignore next */ {}), alias: 'model' });
    // ==========================================
    // Outputs
    // ==========================================
    sdChange = output();
    // ==========================================
    // ViewChild
    // ==========================================
    picker = viewChild('picker', ...(ngDevMode ? [{ debugName: "picker" }] : /* istanbul ignore next */ []));
    // ==========================================
    // Derived state
    // ==========================================
    // why: <input type="color"> only accepts #RRGGBB. Expand 3-char hex; strip
    // alpha from 8-char. Fallback to #000000 for empty/invalid so the OS picker
    // always opens on something.
    pickerSafeValue = computed(() => {
        const v = this.valueModel();
        if (!v)
            return '#000000';
        if (/^#[0-9A-Fa-f]{6}$/.test(v))
            return v;
        if (/^#[0-9A-Fa-f]{3}$/.test(v)) {
            const r = v[1];
            const g = v[2];
            const b = v[3];
            return `#${r}${r}${g}${g}${b}${b}`;
        }
        if (/^#[0-9A-Fa-f]{8}$/.test(v))
            return v.slice(0, 7);
        return '#000000';
    }, ...(ngDevMode ? [{ debugName: "pickerSafeValue" }] : /* istanbul ignore next */ []));
    // Swatch shows the raw model value when valid; otherwise transparent so the
    // user gets visual feedback that the hex string is malformed.
    swatchColor = computed(() => {
        const v = this.valueModel();
        if (!v)
            return 'transparent';
        return this.#hexRegex.test(v) ? v : 'transparent';
    }, ...(ngDevMode ? [{ debugName: "swatchColor" }] : /* istanbul ignore next */ []));
    // ==========================================
    // Handlers
    // ==========================================
    // why: <sd-input> built-in clear bắn null khi clear (thao tác chủ động) → coi
    // như "không có màu". Chuỗi rỗng cũng quy về null. Set model = null (không phải
    // undefined): undefined chỉ dành cho trạng thái pristine chưa từng thao tác.
    onInputChange = (v) => {
        const str = v == null || v === '' ? null : String(v);
        this.valueModel.set(str);
        this.sdChange.emit(str);
    };
    openPicker = () => {
        if (this.disabled() || this.readonly() || this.viewed())
            return;
        this.picker()?.nativeElement.click();
    };
    onPickerChange = (ev) => {
        const v = ev.target.value;
        this.valueModel.set(v);
        this.sdChange.emit(v);
    };
    // why: nút clear hiển thị giờ do <sd-input> render. Giữ method public này cho
    // consumer gọi tay (programmatic). No-op khi không sửa được hoặc đã rỗng.
    clear = (ev) => {
        ev?.stopPropagation();
        if (this.required() || this.disabled() || this.readonly() || this.viewed())
            return;
        const v = this.valueModel();
        if (v == null || v === '')
            return;
        this.valueModel.set(null);
        this.sdChange.emit(null);
    };
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdInputColor, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.17", type: SdInputColor, isStandalone: true, selector: "sd-input-color", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, helperText: { classPropertyName: "helperText", publicName: "helperText", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, autoId: { classPropertyName: "autoId", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, viewed: { classPropertyName: "viewed", publicName: "viewed", isSignal: true, isRequired: false, transformFunction: null }, valueModel: { classPropertyName: "valueModel", publicName: "model", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueModel: "modelChange", sdChange: "sdChange" }, viewQueries: [{ propertyName: "picker", first: true, predicate: ["picker"], descendants: true, isSignal: true }], ngImport: i0, template: "<sd-input\n  [label]=\"label()\"\n  [helperText]=\"helperText()\"\n  [placeholder]=\"placeholder()\"\n  [size]=\"size()\"\n  [appearance]=\"appearance() ?? undefined\"\n  [form]=\"form()\"\n  [name]=\"name() ?? ''\"\n  [autoId]=\"autoId()\"\n  [required]=\"required()\"\n  [disabled]=\"disabled()\"\n  [readonly]=\"readonly()\"\n  [viewed]=\"viewed()\"\n  [pattern]=\"hexPattern\"\n  patternErrorMessage=\"M\u00E3 m\u00E0u HEX kh\u00F4ng h\u1EE3p l\u1EC7 (vd #1565C0)\"\n  [model]=\"valueModel()\"\n  (sdChange)=\"onInputChange($event)\">\n\n  <ng-template sdSuffixDef>\n    <div class=\"sd-input-color__suffix\">\n      <!-- why: n\u00FAt clear do <sd-input> t\u1EF1 render (built-in, hover-gated). \u1EDE \u0111\u00E2y\n           ch\u1EC9 chi\u1EBFu swatch + native picker. onInputChange coerce '' \u2192 null n\u00EAn\n           clear c\u1EE7a sd-input v\u1EABn cho ra model r\u1ED7ng \u0111\u00FAng ngh\u0129a. -->\n      <button\n        type=\"button\"\n        class=\"sd-input-color__swatch\"\n        [style.background]=\"swatchColor()\"\n        [class.sd-input-color__swatch--empty]=\"swatchColor() === 'transparent'\"\n        [disabled]=\"disabled() || readonly() || viewed() === true\"\n        (click)=\"openPicker()\"\n        title=\"M\u1EDF b\u1EA3ng ch\u1ECDn m\u00E0u\"\n        aria-label=\"M\u1EDF b\u1EA3ng ch\u1ECDn m\u00E0u\">\n      </button>\n      <input\n        #picker\n        type=\"color\"\n        class=\"sd-input-color__hidden-picker\"\n        tabindex=\"-1\"\n        aria-hidden=\"true\"\n        [value]=\"pickerSafeValue()\"\n        (input)=\"onPickerChange($event)\" />\n    </div>\n  </ng-template>\n</sd-input>\n", styles: [":host{display:block;--sd-input-color-swatch-size: 22px;--sd-input-color-swatch-border: rgba(0, 0, 0, .12);--sd-input-color-swatch-checker: linear-gradient(45deg, #ddd 25%, transparent 25%), linear-gradient(-45deg, #ddd 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ddd 75%), linear-gradient(-45deg, transparent 75%, #ddd 75%)}.sd-input-color__suffix{position:relative;display:inline-flex;align-items:center;gap:4px}.sd-input-color__swatch{width:var(--sd-input-color-swatch-size);height:var(--sd-input-color-swatch-size);border-radius:4px;border:1px solid var(--sd-input-color-swatch-border);padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;background:transparent;transition:transform 80ms ease,box-shadow 80ms ease;position:relative;overflow:hidden}.sd-input-color__swatch:hover:not(:disabled){transform:scale(1.06);box-shadow:0 0 0 2px #1565c02e}.sd-input-color__swatch:disabled{cursor:not-allowed;opacity:.5}.sd-input-color__swatch.sd-input-color__swatch--empty{background-color:#fff;background-image:var(--sd-input-color-swatch-checker);background-size:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.sd-input-color__hidden-picker{position:absolute;width:0;height:0;padding:0;border:0;opacity:0;pointer-events:none;right:0;top:50%}\n"], dependencies: [{ kind: "component", type: SdInput, selector: "sd-input", inputs: ["autoId", "name", "appearance", "floatLabel", "size", "form", "label", "helperText", "placeholder", "type", "hideInlineError", "blurOnEnter", "required", "readonly", "disabled", "viewed", "minlength", "maxlength", "pattern", "patternErrorMessage", "validator", "inlineError", "hyperlink", "model"], outputs: ["modelChange", "sdChange", "sdFocus", "sdBlur", "keyupEnter", "cleared", "sdFocusForceBlur"] }, { kind: "directive", type: SdSuffixDefDirective, selector: "[sdSuffixDef]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: SdInputColor, decorators: [{
            type: Component,
            args: [{ selector: 'sd-input-color', standalone: true, imports: [SdInput, SdSuffixDefDirective], changeDetection: ChangeDetectionStrategy.OnPush, template: "<sd-input\n  [label]=\"label()\"\n  [helperText]=\"helperText()\"\n  [placeholder]=\"placeholder()\"\n  [size]=\"size()\"\n  [appearance]=\"appearance() ?? undefined\"\n  [form]=\"form()\"\n  [name]=\"name() ?? ''\"\n  [autoId]=\"autoId()\"\n  [required]=\"required()\"\n  [disabled]=\"disabled()\"\n  [readonly]=\"readonly()\"\n  [viewed]=\"viewed()\"\n  [pattern]=\"hexPattern\"\n  patternErrorMessage=\"M\u00E3 m\u00E0u HEX kh\u00F4ng h\u1EE3p l\u1EC7 (vd #1565C0)\"\n  [model]=\"valueModel()\"\n  (sdChange)=\"onInputChange($event)\">\n\n  <ng-template sdSuffixDef>\n    <div class=\"sd-input-color__suffix\">\n      <!-- why: n\u00FAt clear do <sd-input> t\u1EF1 render (built-in, hover-gated). \u1EDE \u0111\u00E2y\n           ch\u1EC9 chi\u1EBFu swatch + native picker. onInputChange coerce '' \u2192 null n\u00EAn\n           clear c\u1EE7a sd-input v\u1EABn cho ra model r\u1ED7ng \u0111\u00FAng ngh\u0129a. -->\n      <button\n        type=\"button\"\n        class=\"sd-input-color__swatch\"\n        [style.background]=\"swatchColor()\"\n        [class.sd-input-color__swatch--empty]=\"swatchColor() === 'transparent'\"\n        [disabled]=\"disabled() || readonly() || viewed() === true\"\n        (click)=\"openPicker()\"\n        title=\"M\u1EDF b\u1EA3ng ch\u1ECDn m\u00E0u\"\n        aria-label=\"M\u1EDF b\u1EA3ng ch\u1ECDn m\u00E0u\">\n      </button>\n      <input\n        #picker\n        type=\"color\"\n        class=\"sd-input-color__hidden-picker\"\n        tabindex=\"-1\"\n        aria-hidden=\"true\"\n        [value]=\"pickerSafeValue()\"\n        (input)=\"onPickerChange($event)\" />\n    </div>\n  </ng-template>\n</sd-input>\n", styles: [":host{display:block;--sd-input-color-swatch-size: 22px;--sd-input-color-swatch-border: rgba(0, 0, 0, .12);--sd-input-color-swatch-checker: linear-gradient(45deg, #ddd 25%, transparent 25%), linear-gradient(-45deg, #ddd 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ddd 75%), linear-gradient(-45deg, transparent 75%, #ddd 75%)}.sd-input-color__suffix{position:relative;display:inline-flex;align-items:center;gap:4px}.sd-input-color__swatch{width:var(--sd-input-color-swatch-size);height:var(--sd-input-color-swatch-size);border-radius:4px;border:1px solid var(--sd-input-color-swatch-border);padding:0;margin:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;background:transparent;transition:transform 80ms ease,box-shadow 80ms ease;position:relative;overflow:hidden}.sd-input-color__swatch:hover:not(:disabled){transform:scale(1.06);box-shadow:0 0 0 2px #1565c02e}.sd-input-color__swatch:disabled{cursor:not-allowed;opacity:.5}.sd-input-color__swatch.sd-input-color__swatch--empty{background-color:#fff;background-image:var(--sd-input-color-swatch-checker);background-size:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.sd-input-color__hidden-picker{position:absolute;width:0;height:0;padding:0;border:0;opacity:0;pointer-events:none;right:0;top:50%}\n"] }]
        }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], helperText: [{ type: i0.Input, args: [{ isSignal: true, alias: "helperText", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], autoId: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], viewed: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewed", required: false }] }], valueModel: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: false }] }, { type: i0.Output, args: ["modelChange"] }], sdChange: [{ type: i0.Output, args: ["sdChange"] }], picker: [{ type: i0.ViewChild, args: ['picker', { isSignal: true }] }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { SD_INPUT_COLOR_HEX_PATTERN, SdInputColor };
//# sourceMappingURL=sdcorejs-angular-forms-input-color.mjs.map
