import { n as __exportAll } from "./chunk-B-1-B7_t.js";
import { n as cn } from "./utils-DXzSsU1e.js";
import { n as Button_default } from "./button-B9CnnuTu.js";
import { o as CardContent_default, s as Card_default } from "./card-X74FuL7B.js";
import { t as FieldFrame_default } from "./field-frame-DhCOWcMP.js";
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, mergeModels, normalizeClass, openBlock, ref, renderList, toDisplayString, unref, useModel, watch, withCtx, withKeys, withModifiers } from "vue";
import { UploadCloud, X } from "@lucide/vue";
//#region src/components/compositions/elements/file/DropzoneFile.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = [
	"data-drag-over",
	"data-element-name",
	"onKeydown"
];
var _hoisted_2 = { class: "text-sm font-medium" };
var _hoisted_3 = {
	key: 0,
	class: "text-xs text-muted-foreground"
};
var _hoisted_4 = [
	"accept",
	"multiple",
	"disabled",
	"required",
	"name"
];
var _hoisted_5 = {
	key: 0,
	class: "flex flex-col gap-2"
};
var _hoisted_6 = { class: "flex flex-col" };
var _hoisted_7 = { class: "text-sm font-medium" };
var _hoisted_8 = { class: "text-xs text-muted-foreground" };
var DropzoneFile_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({
	__name: "DropzoneFile",
	props: /* @__PURE__ */ mergeModels({
		modelValue: {},
		id: {},
		name: {},
		label: {},
		hideLabel: { type: Boolean },
		placeholder: {},
		accept: {},
		acceptedFileTypes: { default: () => [] },
		multiple: { type: Boolean },
		maxFileSize: {},
		required: { type: Boolean },
		readonly: { type: Boolean },
		disabled: { type: Boolean },
		helpText: {},
		errors: { default: () => [] }
	}, {
		"modelValue": {},
		"modelModifiers": {}
	}),
	emits: ["update:modelValue"],
	setup(__props) {
		/**
		* Props-driven dropzone composition.
		*
		* Drag-and-drop target backed by a hidden `<input type="file">` for
		* click-to-browse. Same value contract as `UploadFile` — single `File`
		* or `File[]` when `multiple` is true.
		*
		*   <DropzoneFile v-model="doc" label="Document" accept="application/pdf" />
		*/
		const props = __props;
		const model = useModel(__props, "modelValue");
		const fileInput = ref(null);
		const dragOver = ref(false);
		const files = ref([]);
		watch(() => model.value, (next) => {
			if (next instanceof File) files.value = [next];
			else if (Array.isArray(next) && next.every((f) => f instanceof File)) files.value = next;
			else files.value = [];
		}, { immediate: true });
		const accept = computed(() => {
			if (props.accept) return props.accept;
			const list = props.acceptedFileTypes;
			return Array.isArray(list) && list.length ? list.join(",") : "";
		});
		const maxBytes = computed(() => props.maxFileSize);
		function emitFiles() {
			if (props.multiple) model.value = files.value.slice();
			else model.value = files.value[0] ?? null;
		}
		function ingest(incoming) {
			if (!incoming.length) return;
			if (maxBytes.value ? incoming.find((f) => f.size > maxBytes.value) : void 0) return;
			if (props.multiple) files.value = [...files.value, ...incoming];
			else files.value = [incoming[0]];
			emitFiles();
		}
		function onChange(event) {
			const target = event.target;
			ingest(target.files ? Array.from(target.files) : []);
			target.value = "";
		}
		function onDrop(event) {
			event.preventDefault();
			dragOver.value = false;
			if (props.disabled || props.readonly) return;
			ingest(event.dataTransfer ? Array.from(event.dataTransfer.files) : []);
		}
		function onDragOver(event) {
			event.preventDefault();
			if (!props.disabled && !props.readonly) dragOver.value = true;
		}
		function onDragLeave(event) {
			event.preventDefault();
			dragOver.value = false;
		}
		function openPicker() {
			fileInput.value?.click();
		}
		function removeFile(index) {
			files.value.splice(index, 1);
			emitFiles();
		}
		function formatBytes(bytes) {
			if (bytes < 1024) return `${bytes} B`;
			if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
			return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
		}
		return (_ctx, _cache) => {
			return openBlock(), createBlock(unref(FieldFrame_default), {
				label: __props.label,
				required: __props.required,
				"hide-label": __props.hideLabel,
				"help-text": __props.helpText,
				errors: __props.errors
			}, {
				default: withCtx(() => [createElementVNode("div", {
					class: normalizeClass(unref(cn)("flex flex-col items-center justify-center gap-2 rounded-md border-2 border-dashed border-input bg-background px-6 py-10 text-center transition-colors", dragOver.value && "border-primary bg-primary/5", (__props.disabled || __props.readonly) && "cursor-not-allowed opacity-50")),
					role: "button",
					tabindex: "0",
					"data-testid": "dropzone-target",
					"data-drag-over": dragOver.value || void 0,
					"data-element-name": __props.name ?? void 0,
					onClick: openPicker,
					onKeydown: [withKeys(withModifiers(openPicker, ["prevent"]), ["enter"]), withKeys(withModifiers(openPicker, ["prevent"]), ["space"])],
					onDrop,
					onDragover: onDragOver,
					onDragleave: onDragLeave
				}, [
					createVNode(unref(UploadCloud), { class: "size-8 text-muted-foreground" }),
					createElementVNode("p", _hoisted_2, toDisplayString(__props.placeholder ?? "Drop files here, or click to browse"), 1),
					accept.value ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(accept.value), 1)) : createCommentVNode("", true),
					createElementVNode("input", {
						ref_key: "fileInput",
						ref: fileInput,
						type: "file",
						class: "sr-only",
						accept: accept.value || void 0,
						multiple: __props.multiple,
						disabled: __props.disabled || __props.readonly,
						required: __props.required,
						name: __props.name ?? void 0,
						"data-testid": "dropzone-input",
						onChange
					}, null, 40, _hoisted_4)
				], 42, _hoisted_1), files.value.length ? (openBlock(), createElementBlock("div", _hoisted_5, [(openBlock(true), createElementBlock(Fragment, null, renderList(files.value, (file, i) => {
					return openBlock(), createBlock(unref(Card_default), {
						key: `${file.name}-${i}`,
						class: "border"
					}, {
						default: withCtx(() => [createVNode(unref(CardContent_default), { class: "flex items-center justify-between gap-3 py-3" }, {
							default: withCtx(() => [createElementVNode("div", _hoisted_6, [createElementVNode("span", _hoisted_7, toDisplayString(file.name), 1), createElementVNode("span", _hoisted_8, toDisplayString(formatBytes(file.size)), 1)]), createVNode(unref(Button_default), {
								type: "button",
								variant: "ghost",
								size: "icon-sm",
								"aria-label": "Remove file",
								disabled: __props.disabled || __props.readonly,
								"data-testid": "dropzone-remove",
								onClick: withModifiers(($event) => removeFile(i), ["stop"])
							}, {
								default: withCtx(() => [createVNode(unref(X), { class: "size-4" })]),
								_: 1
							}, 8, ["disabled", "onClick"])]),
							_: 2
						}, 1024)]),
						_: 2
					}, 1024);
				}), 128))])) : createCommentVNode("", true)]),
				_: 1
			}, 8, [
				"label",
				"required",
				"hide-label",
				"help-text",
				"errors"
			]);
		};
	}
});
//#endregion
//#region src/components/compositions/elements/file/DropzoneFile.vue
var DropzoneFile_exports = /* @__PURE__ */ __exportAll({ default: () => DropzoneFile_default });
var DropzoneFile_default = DropzoneFile_vue_vue_type_script_setup_true_lang_default;
//#endregion
export { DropzoneFile_exports as n, DropzoneFile_default as t };

//# sourceMappingURL=DropzoneFile-01wL77VY.js.map