import * as i0 from '@angular/core';
import { output, input, model, signal, computed, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { zTransform, zMergeClasses, zCreateEvent } from '@shival99/z-ui/utils';
import { cva } from 'class-variance-authority';

const zRadioVariants = cva([
    'relative inline-flex items-center justify-center shrink-0 cursor-pointer align-middle leading-none',
    'rounded-full border border-input bg-background dark:border-border dark:bg-input/25',
    'transition-colors duration-150',
    'hover:border-primary/70 hover:bg-primary/5 dark:hover:bg-primary/15',
    'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
    'disabled:cursor-not-allowed disabled:opacity-50',
    'data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:hover:bg-primary/90',
], {
    variants: {
        zSize: {
            sm: 'size-4',
            default: 'size-5',
            lg: 'size-6',
        },
    },
    defaultVariants: {
        zSize: 'default',
    },
});
const zRadioIndicatorVariants = cva('rounded-full bg-white transition-[opacity,transform] duration-150', {
    variants: {
        zSize: {
            sm: 'size-2',
            default: 'size-2.5',
            lg: 'size-3',
        },
    },
    defaultVariants: {
        zSize: 'default',
    },
});
const zRadioLabelVariants = cva('select-none cursor-pointer leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', {
    variants: {
        zSize: {
            sm: 'text-xs',
            default: 'text-sm',
            lg: 'text-base',
        },
    },
    defaultVariants: {
        zSize: 'default',
    },
});

class ZRadioComponent {
    zChange = output();
    zOnBlur = output();
    zOnFocus = output();
    zEvent = output();
    class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
    zType = input('default', ...(ngDevMode ? [{ debugName: "zType" }] : []));
    zSize = input('default', ...(ngDevMode ? [{ debugName: "zSize" }] : []));
    zLabel = input('', ...(ngDevMode ? [{ debugName: "zLabel" }] : []));
    zText = input('', ...(ngDevMode ? [{ debugName: "zText" }] : []));
    zDisabled = input(false, { ...(ngDevMode ? { debugName: "zDisabled" } : {}), transform: zTransform });
    zValue = input('', ...(ngDevMode ? [{ debugName: "zValue" }] : []));
    zOptions = input([], ...(ngDevMode ? [{ debugName: "zOptions" }] : []));
    zOrientation = input('vertical', ...(ngDevMode ? [{ debugName: "zOrientation" }] : []));
    zSelectedValue = model(null, ...(ngDevMode ? [{ debugName: "zSelectedValue" }] : []));
    _disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
    isDisabled = computed(() => this.zDisabled() || this._disabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
    hostClasses = computed(() => {
        const hasLabel = !!this.zLabel();
        if (this.zType() === 'group') {
            return zMergeClasses('flex flex-col gap-2', this.class());
        }
        if (hasLabel) {
            return zMergeClasses('flex flex-col gap-2', this.class());
        }
        return zMergeClasses('inline-flex items-center gap-2', this.class());
    }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
    groupClasses = computed(() => {
        const orientation = this.zOrientation() === 'horizontal' ? 'flex-row flex-wrap' : 'flex-col';
        return `flex ${orientation} gap-2`;
    }, ...(ngDevMode ? [{ debugName: "groupClasses" }] : []));
    radioClasses = computed(() => zRadioVariants({ zSize: this.zSize() }), ...(ngDevMode ? [{ debugName: "radioClasses" }] : []));
    indicatorClasses = computed(() => zRadioIndicatorVariants({ zSize: this.zSize() }), ...(ngDevMode ? [{ debugName: "indicatorClasses" }] : []));
    labelClasses = computed(() => zRadioLabelVariants({ zSize: this.zSize() }), ...(ngDevMode ? [{ debugName: "labelClasses" }] : []));
    _onChange = () => { };
    _onTouched = () => { };
    writeValue(value) {
        this.zSelectedValue.set(value);
    }
    registerOnChange(fn) {
        this._onChange = fn;
    }
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    setDisabledState(isDisabled) {
        this._disabled.set(isDisabled);
    }
    onFocus(event) {
        this.zOnFocus.emit(event);
        this.zEvent.emit(zCreateEvent('focus', event));
    }
    onBlur(event) {
        this.zOnBlur.emit(event);
        this.zEvent.emit(zCreateEvent('blur', event));
        this._onTouched();
    }
    onRadioClick() {
        if (this.isDisabled()) {
            return;
        }
        const value = this.zValue();
        this.zSelectedValue.set(value);
        this.zChange.emit(value);
        this._onChange(value);
        this._onTouched();
    }
    onOptionClick(option) {
        if (this.isDisabled() || option.disabled) {
            return;
        }
        this.zSelectedValue.set(option.value);
        this.zChange.emit(option.value);
        this._onChange(option.value);
        this._onTouched();
    }
    isOptionChecked(option) {
        return this.zSelectedValue() === option.value;
    }
    isChecked() {
        return this.zSelectedValue() === this.zValue();
    }
    getRadioState() {
        return this.isChecked() ? 'checked' : 'unchecked';
    }
    getOptionState(option) {
        return this.isOptionChecked(option) ? 'checked' : 'unchecked';
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZRadioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ZRadioComponent, isStandalone: true, selector: "z-radio", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zType: { classPropertyName: "zType", publicName: "zType", isSignal: true, isRequired: false, transformFunction: null }, zSize: { classPropertyName: "zSize", publicName: "zSize", isSignal: true, isRequired: false, transformFunction: null }, zLabel: { classPropertyName: "zLabel", publicName: "zLabel", isSignal: true, isRequired: false, transformFunction: null }, zText: { classPropertyName: "zText", publicName: "zText", isSignal: true, isRequired: false, transformFunction: null }, zDisabled: { classPropertyName: "zDisabled", publicName: "zDisabled", isSignal: true, isRequired: false, transformFunction: null }, zValue: { classPropertyName: "zValue", publicName: "zValue", isSignal: true, isRequired: false, transformFunction: null }, zOptions: { classPropertyName: "zOptions", publicName: "zOptions", isSignal: true, isRequired: false, transformFunction: null }, zOrientation: { classPropertyName: "zOrientation", publicName: "zOrientation", isSignal: true, isRequired: false, transformFunction: null }, zSelectedValue: { classPropertyName: "zSelectedValue", publicName: "zSelectedValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zChange: "zChange", zOnBlur: "zOnBlur", zOnFocus: "zOnFocus", zEvent: "zEvent", zSelectedValue: "zSelectedValueChange" }, host: { properties: { "class": "hostClasses()" } }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => ZRadioComponent),
                multi: true,
            },
        ], ngImport: i0, template: "<!-- Group Mode -->\n@if (zType() === 'group') {\n  <!-- Label above group -->\n  @if (zLabel()) {\n    <label class=\"text-xs leading-none font-medium\">{{ zLabel() }}</label>\n  }\n\n  <div [class]=\"groupClasses()\">\n    @for (option of zOptions(); track option.value) {\n      <label\n        class=\"inline-flex cursor-pointer items-center gap-2 align-middle\"\n        [class.opacity-40]=\"option.disabled || isDisabled()\"\n        [class.dark:opacity-50]=\"option.disabled || isDisabled()\"\n        [class.cursor-not-allowed]=\"option.disabled || isDisabled()\">\n        <button\n          type=\"button\"\n          role=\"radio\"\n          [class]=\"radioClasses()\"\n          [attr.aria-checked]=\"isOptionChecked(option)\"\n          [attr.data-state]=\"getOptionState(option)\"\n          [disabled]=\"isDisabled() || option.disabled\"\n          (click)=\"onOptionClick(option)\"\n          (focus)=\"onFocus($event)\"\n          (blur)=\"onBlur($event)\">\n          <span\n            [class]=\"indicatorClasses()\"\n            [class.opacity-0]=\"!isOptionChecked(option)\"\n            [class.scale-75]=\"!isOptionChecked(option)\"></span>\n        </button>\n        <span [class]=\"labelClasses()\" [class.text-muted-foreground]=\"option.disabled\">{{ option.label }}</span>\n      </label>\n    }\n  </div>\n}\n\n<!-- Default Mode (single radio) -->\n@if (zType() === 'default') {\n  <!-- Label above -->\n  @if (zLabel()) {\n    <label class=\"text-xs leading-none font-medium\">{{ zLabel() }}</label>\n  }\n\n  <div class=\"inline-flex items-center gap-2 align-middle\">\n    <button\n      type=\"button\"\n      role=\"radio\"\n      [class]=\"radioClasses()\"\n      [attr.aria-checked]=\"isChecked()\"\n      [attr.data-state]=\"getRadioState()\"\n      [disabled]=\"isDisabled()\"\n      (click)=\"onRadioClick()\"\n      (focus)=\"onFocus($event)\"\n      (blur)=\"onBlur($event)\">\n      <span [class]=\"indicatorClasses()\" [class.opacity-0]=\"!isChecked()\" [class.scale-75]=\"!isChecked()\"></span>\n    </button>\n    @if (zText()) {\n      <label [class]=\"labelClasses()\" (click)=\"onRadioClick()\">{{ zText() }}</label>\n    }\n  </div>\n}\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZRadioComponent, decorators: [{
            type: Component,
            args: [{ selector: 'z-radio', imports: [], standalone: true, providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => ZRadioComponent),
                            multi: true,
                        },
                    ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        '[class]': 'hostClasses()',
                    }, template: "<!-- Group Mode -->\n@if (zType() === 'group') {\n  <!-- Label above group -->\n  @if (zLabel()) {\n    <label class=\"text-xs leading-none font-medium\">{{ zLabel() }}</label>\n  }\n\n  <div [class]=\"groupClasses()\">\n    @for (option of zOptions(); track option.value) {\n      <label\n        class=\"inline-flex cursor-pointer items-center gap-2 align-middle\"\n        [class.opacity-40]=\"option.disabled || isDisabled()\"\n        [class.dark:opacity-50]=\"option.disabled || isDisabled()\"\n        [class.cursor-not-allowed]=\"option.disabled || isDisabled()\">\n        <button\n          type=\"button\"\n          role=\"radio\"\n          [class]=\"radioClasses()\"\n          [attr.aria-checked]=\"isOptionChecked(option)\"\n          [attr.data-state]=\"getOptionState(option)\"\n          [disabled]=\"isDisabled() || option.disabled\"\n          (click)=\"onOptionClick(option)\"\n          (focus)=\"onFocus($event)\"\n          (blur)=\"onBlur($event)\">\n          <span\n            [class]=\"indicatorClasses()\"\n            [class.opacity-0]=\"!isOptionChecked(option)\"\n            [class.scale-75]=\"!isOptionChecked(option)\"></span>\n        </button>\n        <span [class]=\"labelClasses()\" [class.text-muted-foreground]=\"option.disabled\">{{ option.label }}</span>\n      </label>\n    }\n  </div>\n}\n\n<!-- Default Mode (single radio) -->\n@if (zType() === 'default') {\n  <!-- Label above -->\n  @if (zLabel()) {\n    <label class=\"text-xs leading-none font-medium\">{{ zLabel() }}</label>\n  }\n\n  <div class=\"inline-flex items-center gap-2 align-middle\">\n    <button\n      type=\"button\"\n      role=\"radio\"\n      [class]=\"radioClasses()\"\n      [attr.aria-checked]=\"isChecked()\"\n      [attr.data-state]=\"getRadioState()\"\n      [disabled]=\"isDisabled()\"\n      (click)=\"onRadioClick()\"\n      (focus)=\"onFocus($event)\"\n      (blur)=\"onBlur($event)\">\n      <span [class]=\"indicatorClasses()\" [class.opacity-0]=\"!isChecked()\" [class.scale-75]=\"!isChecked()\"></span>\n    </button>\n    @if (zText()) {\n      <label [class]=\"labelClasses()\" (click)=\"onRadioClick()\">{{ zText() }}</label>\n    }\n  </div>\n}\n" }]
        }], propDecorators: { zChange: [{ type: i0.Output, args: ["zChange"] }], zOnBlur: [{ type: i0.Output, args: ["zOnBlur"] }], zOnFocus: [{ type: i0.Output, args: ["zOnFocus"] }], zEvent: [{ type: i0.Output, args: ["zEvent"] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zType: [{ type: i0.Input, args: [{ isSignal: true, alias: "zType", required: false }] }], zSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSize", required: false }] }], zLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLabel", required: false }] }], zText: [{ type: i0.Input, args: [{ isSignal: true, alias: "zText", required: false }] }], zDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDisabled", required: false }] }], zValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "zValue", required: false }] }], zOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "zOptions", required: false }] }], zOrientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "zOrientation", required: false }] }], zSelectedValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSelectedValue", required: false }] }, { type: i0.Output, args: ["zSelectedValueChange"] }] } });

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

export { ZRadioComponent, zRadioIndicatorVariants, zRadioLabelVariants, zRadioVariants };
//# sourceMappingURL=shival99-z-ui-components-z-radio.mjs.map
