/**
* GnOptionCard — search-result / listing card.
*
* Figma: Option Card, Campaign search card, Contact search card.
*/
import { defineComponent, h } from "vue";
import { cx, iconNode } from "../utils.js";
import GnChip from "./GnChip.js";
export default defineComponent({
name: "GnOptionCard",
inheritAttrs: false,
props: {
layout: { type: String, default: "vertical" }, // vertical | horizontal
image: { type: String, default: "" },
match: { type: [String, Number], default: "" },
price: { type: String, default: "" },
area: { type: String, default: "" },
title: { type: String, default: "" },
badges: { type: Array, default: () => [] },
expanded: { type: Boolean, default: false },
stats: { type: Array, default: () => [] },
details: { type: Array, default: () => [] },
actions: { type: Array, default: () => [] }
},
emits: ["action", "select"],
setup(props, { attrs, slots, emit }) {
const mediaNode = () => h("div", { class: "option-card-media" }, [
props.image
? h("img", { src: props.image, alt: "" })
: h("span", { class: "option-card-media-placeholder" }, iconNode("ph-image")),
props.match && h("span", { class: "option-card-match" }, [
iconNode("ph-thumbs-up"),
`${props.match}%`
]),
slots.mediaCount?.() || (props.image && h("span", { class: "option-card-media-count" }, "1/5")),
slots.dots?.()
]);
const headerNode = () => h("div", { class: "option-card-header" }, [
h("p", { class: "option-card-price" }, [
props.price,
props.area && h("span", { class: "option-card-area" }, props.area)
]),
slots.actionsTop?.()
]);
const badgesNode = () => props.badges.length > 0 && h("div", { class: "option-card-badges" },
props.badges.map(badge => h(GnChip, {
variant: badge.variant || "default",
removable: badge.removable,
onRemove: () => emit("action", { type: "remove-badge", badge })
}, () => badge.label))
.concat(slots.badges?.() || [])
);
const actionsNode = () => (props.actions.length || slots.actions) && h("div", { class: "option-card-actions" }, [
slots.actions?.(),
props.actions.map(action => h("button", {
class: cx("btn", `btn-${action.variant || "secondary"}`, action.size ? `btn-${action.size}` : "btn-sm"),
type: "button",
onClick: () => emit("action", { type: action.key || action.label, action })
}, action.icon && iconNode(action.icon), action.label))
]);
const statsNode = () => props.expanded && props.stats.length > 0 && h("div", { class: "option-card-stats" },
props.stats.map(stat => h("div", { class: "option-card-stat" }, [
iconNode(stat.icon),
h("span", null, [stat.label, " ", h("strong", null, stat.value)])
]))
);
const detailsNode = () => props.expanded && props.details.length > 0 && h("div", { class: "option-card-details" }, [
h("ul", { class: "option-card-detail-list" }, props.details.map(item => h("li", { class: "option-card-detail-item" }, [
h("span", null, [item.icon && iconNode(item.icon), item.label]),
h("strong", null, item.value)
])))
]);
return () => h("article", {
...attrs,
class: cx(
"option-card",
`option-card-${props.layout}`,
{ "option-card-expanded": props.expanded },
attrs.class
),
onClick: () => emit("select")
}, [
mediaNode(),
h("div", { class: "option-card-body" }, [
headerNode(),
props.title && h("h3", { class: "option-card-title" }, props.title),
slots.default?.(),
badgesNode(),
actionsNode()
]),
statsNode(),
detailsNode()
]);
}
});