<section class="demo-section" aria-labelledby="option-card-heading">
<h2 id="option-card-heading">Option Card & Chat</h2>
<h3>Option card vertical</h3>
<div class="option-card" style="max-width: 360px;">
<div class="option-card-media">
<img src="/assets/avatar-placeholder.jpg" alt="" />
<span class="option-card-match"><i class="ph ph-thumbs-up"></i> 95%</span>
</div>
<div class="option-card-body">
<div class="option-card-header">
<p class="option-card-price">
2 500 000 UAH
<span class="option-card-area">52,40 м²</span>
</p>
</div>
<h3 class="option-card-title">Compact apartment near city center</h3>
<div class="option-card-badges">
<span class="chip chip-secondary"><i class="ph ph-check-circle"></i> Verified</span>
<span class="chip chip-outline">Owner</span>
</div>
<div class="option-card-actions">
<button class="btn btn-sm btn-primary" type="button">Details</button>
<button class="btn btn-sm btn-secondary" type="button">Save</button>
</div>
</div>
</div>
<h3>Option card horizontal</h3>
<div class="option-card option-card-horizontal" style="max-width: 640px;">
<div class="option-card-media">
<img src="/assets/avatar-placeholder.jpg" alt="" />
</div>
<div class="option-card-body">
<div class="option-card-header">
<p class="option-card-price">
3 200 000 UAH
<span class="option-card-area">78,00 м²</span>
</p>
<button class="btn-icon btn-sm" type="button" aria-label="Open"><i class="ph ph-caret-right"></i></button>
</div>
<h3 class="option-card-title">Spacious flat with balcony and parking</h3>
<div class="option-card-badges">
<span class="chip chip-warning">Unverified</span>
<span class="chip chip-outline">Agent</span>
</div>
</div>
</div>
<h3>Vue option card</h3>
<div id="vue-option-card-app" class="vue-mount"></div>
<script type="module">
import { createApp } from "vue";
import { GnOptionCard } from "/vue/index.js";
createApp({
components: { GnOptionCard },
data() {
return {
option: {
image: "/assets/avatar-placeholder.jpg",
match: 95,
price: "1 850 000 UAH",
area: "45,20 м²",
title: "Studio in newly built complex",
badges: [{ label: "Verified", variant: "success" }, { label: "Owner", variant: "outline" }],
actions: [{ label: "Contact", variant: "primary", key: "contact" }, { label: "Save", variant: "secondary", key: "save" }]
}
};
},
template: `
<gn-option-card
:image="option.image"
:match="option.match"
:price="option.price"
:area="option.area"
:title="option.title"
:badges="option.badges"
:actions="option.actions"
style="max-width: 360px;"
/>
`
}).mount("#vue-option-card-app");
</script>
<h3>Chat messages</h3>
<div class="chat-list">
<div class="chat-message chat-message-user">
<div class="chat-bubble"><p>Show me apartments under 2 million UAH.</p></div>
<div class="chat-message-actions">
<button class="chat-message-action" type="button" aria-label="Copy"><i class="ph ph-copy"></i></button>
<button class="chat-message-action" type="button" aria-label="Edit"><i class="ph ph-pencil-simple"></i></button>
</div>
</div>
<div class="chat-message chat-message-ai">
<h4 class="chat-message-title">Found 12 options</h4>
<div class="chat-bubble">
<p>I found 12 apartments matching your budget. Most are 1-bedroom studios in the city center.</p>
</div>
<div class="chat-message-options">
<button class="chat-option" type="button"><i class="ph ph-list"></i> View list</button>
<button class="chat-option" type="button"><i class="ph ph-map-pin"></i> Show on map</button>
</div>
</div>
<div class="chat-typing" role="status" aria-label="typing">
<span></span><span></span><span></span>
</div>
</div>
<h3>Vue chat messages</h3>
<div id="vue-chat-message-app" class="vue-mount"></div>
<script type="module">
import { createApp } from "vue";
import { GnChatMessage } from "/vue/index.js";
createApp({
components: { GnChatMessage },
data() {
return {
userActions: [{ icon: "ph-copy", label: "Copy" }, { icon: "ph-pencil-simple", label: "Edit" }],
aiOptions: [{ icon: "ph-list", label: "View list" }, { icon: "ph-map-pin", label: "Show on map" }]
};
},
template: `
<div class="chat-list">
<gn-chat-message sender="user" :actions="userActions">
<p>Show me apartments under 2 million UAH.</p>
</gn-chat-message>
<gn-chat-message sender="ai" title="Found 12 options" :options="aiOptions">
<p>I found 12 apartments matching your budget.</p>
</gn-chat-message>
</div>
`
}).mount("#vue-chat-message-app");
</script>
<h3>Data rows</h3>
<div class="data-row-group" style="max-width: 720px;">
<div class="data-row">
<label class="data-row-select"><input type="checkbox" /></label>
<div class="data-row-media"><i class="ph ph-file-image"></i></div>
<div class="data-row-content">
<div class="data-row-cell data-row-cell-main">
<span class="data-row-label">File</span>
<span class="data-row-value">summer-header-1.png</span>
</div>
<div class="data-row-cell">
<span class="data-row-label">Owner</span>
<span class="data-row-value">Fikri Maulana</span>
</div>
<div class="data-row-cell">
<span class="data-row-label">Date</span>
<span class="data-row-value">Mon, Jul 15, 2025</span>
</div>
<div class="data-row-cell">
<span class="data-row-label">Size</span>
<span class="data-row-value">1.234 KB</span>
</div>
</div>
<div class="data-row-actions">
<button class="btn btn-icon btn-sm btn-secondary" type="button" aria-label="More"><i class="ph ph-dots-three"></i></button>
</div>
</div>
<div class="data-row data-row-selected">
<label class="data-row-select"><input type="checkbox" checked /></label>
<div class="data-row-media"><i class="ph ph-check"></i></div>
<div class="data-row-content">
<div class="data-row-cell data-row-cell-main">
<span class="data-row-label">File</span>
<span class="data-row-value">summer-header-1.png</span>
</div>
<div class="data-row-cell">
<span class="data-row-label">Owner</span>
<span class="data-row-value">Fikri Maulana</span>
</div>
<div class="data-row-cell">
<span class="data-row-label">Date</span>
<span class="data-row-value">Mon, Jul 15, 2025</span>
</div>
<div class="data-row-cell">
<span class="data-row-label">Size</span>
<span class="data-row-value">1.234 KB</span>
</div>
</div>
</div>
</div>
<h3>Vue data row</h3>
<div id="vue-data-row-app" class="vue-mount"></div>
<script type="module">
import { createApp } from "vue";
import { GnDataRow } from "/vue/index.js";
createApp({
components: { GnDataRow },
data() {
return {
row: {
selected: false,
icon: "ph-file-image",
columns: [
{ label: "File", value: "summer-header-1.png", main: true },
{ label: "Owner", value: "Fikri Maulana" },
{ label: "Date", value: "Mon, Jul 15, 2025" },
{ label: "Size", value: "1.234 KB" }
],
actions: [{ icon: "ph-dots-three", label: "More", variant: "secondary" }]
}
};
},
template: `
<gn-data-row
v-model:selected="row.selected"
:icon="row.icon"
:columns="row.columns"
:actions="row.actions"
style="max-width: 720px;"
/>
`
}).mount("#vue-data-row-app");
</script>
</section>