Newer
Older
vmk-ui-kit / src / vue / components / GnFileAttachment.js
/**
 * GnFileAttachment - Static file attachment card.
 * Matches the Figma "Attached File" frame.
 */

import { defineComponent, h } from "vue";
import { cx, iconNode } from "../utils.js";

export default defineComponent({
	name: "GnFileAttachment",
	props: {
		name: { type: String, required: true },
		format: { type: String, default: "" },
		size: { type: String, default: "" },
		state: { type: String, default: "default" },
		previewUrl: { type: String, default: "" },
		removable: { type: Boolean, default: true }
	},
	emits: ["remove"],
	setup(props, { emit }) {
		const formatLabel = props.format ? props.format.slice(0, 6).toUpperCase() : "";
		const stateClass = ["placeholder", "error", "retry"].includes(props.state) ? `is-${props.state}` : "";

		const renderVisual = () => {
			if(props.previewUrl) {
				return h("img", { src: props.previewUrl, alt: "" });
			}

			if(props.state === "error") {
				return iconNode("ph-warning");
			}

			if(props.state === "retry") {
				return iconNode("ph-arrows-clockwise");
			}

			return h("span", { class: "file-attachment-type" }, formatLabel || "FILE");
		};

		return () => h("figure", { class: cx("file-attachment", stateClass) }, [
			h("div", { class: "file-attachment-header" }, [
				formatLabel && h("span", { class: "file-attachment-format" }, formatLabel),
				props.removable && h("button", {
					class: "file-attachment-remove",
					type: "button",
					"aria-label": `Remove ${props.name}`,
					onClick: () => emit("remove")
				}, [iconNode("ph-x")])
			]),
			h("div", { class: "file-attachment-visual" }, [renderVisual()]),
			h("figcaption", {}, [
				h("span", { class: "file-attachment-name" }, props.name),
				props.size && h("span", { class: "file-attachment-meta" }, props.size)
			])
		]);
	}
});