<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GNexus UI Kit — Vue Adapter Demo</title>
<link rel="stylesheet" href="/assets/fonts/phosphor-icons/src/css/icons.css">
<link rel="stylesheet" href="/css/kit.css">
<style>
body {
margin: 0;
padding: 2rem;
background: #16161E;
color: #C0CAF5;
font-family: "IBM Plex Mono", "Courier New", monospace;
}
.demo-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 1.5rem;
}
.demo-card {
background: #1F2335;
border: 2px solid #7AA2F7;
padding: 1.5rem;
}
.demo-card h3 {
margin-top: 0;
text-transform: uppercase;
font-size: 0.875rem;
color: #C0CAF5;
}
.demo-actions {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
margin-top: 1rem;
}
.demo-section {
margin-bottom: 2rem;
}
</style>
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3.5.13/dist/vue.esm-browser.js",
"gnexus-ui-kit/vue": "/vue/index.js"
}
}
</script>
</head>
<body>
<div id="app"></div>
<script type="module">
import { createApp, ref } from "vue";
import {
GnButton, GnIconButton, GnCopyButton,
GnBadge, GnAlert,
GnInput, GnSelect, GnTextarea, GnCheckbox, GnSwitch, GnRadioGroup, GnRange, GnCombobox, GnFileUpload,
GnTabs, GnTable, GnCard, GnHorizontalCard, GnLoginCard, GnMetricCard, GnStatusCard, GnActionCard,
GnModal, GnDrawer, GnConfirmDialog, GnPopover, GnTooltip,
GnNavList, GnSteps, GnProgress, GnProgressStages, GnTimeline, GnActivityLog,
GnDescriptionList, GnUsageMeter, GnEmptyState, GnSkeleton,
GnAvatar, GnIdentity, GnAvatarStack,
GnList, GnActionList, GnDefinitionList,
GnChip, GnChipGroup,
GnSearchField, GnPagination, GnToolbar,
GnPageHeader, GnToastProvider, useToast,
GnAccordion, GnNavigationShell, GnInputGroup
} from "gnexus-ui-kit/vue";
createApp({
components: {
GnButton, GnIconButton, GnCopyButton,
GnBadge, GnAlert,
GnInput, GnSelect, GnTextarea, GnCheckbox, GnSwitch, GnRadioGroup, GnRange, GnCombobox, GnFileUpload,
GnTabs, GnTable, GnCard, GnHorizontalCard, GnLoginCard, GnMetricCard, GnStatusCard, GnActionCard,
GnModal, GnDrawer, GnConfirmDialog, GnPopover, GnTooltip,
GnNavList, GnSteps, GnProgress, GnProgressStages, GnTimeline, GnActivityLog,
GnDescriptionList, GnUsageMeter, GnEmptyState, GnSkeleton,
GnAvatar, GnIdentity, GnAvatarStack,
GnList, GnActionList, GnDefinitionList,
GnChip, GnChipGroup,
GnSearchField, GnPagination, GnToolbar,
GnPageHeader, GnToastProvider,
GnAccordion, GnNavigationShell, GnInputGroup
},
setup() {
const toast = useToast();
const modalOpen = ref(false);
const drawerOpen = ref(false);
const confirmOpen = ref(false);
const name = ref("");
const status = ref("active");
const tab = ref("overview");
const checked = ref(true);
const switched = ref(false);
const mode = ref("auto");
const rollout = ref(72);
const assignee = ref("");
const files = ref([]);
const searchQuery = ref("");
const currentPage = ref(1);
const statusOptions = [
{ value: "active", label: "Active" },
{ value: "paused", label: "Paused" },
{ value: "archived", label: "Archived" }
];
const tabs = [
{ id: "overview", label: "Overview", icon: "ph-chart-bar" },
{ id: "activity", label: "Activity", icon: "ph-clock" }
];
const tableColumns = [
{ key: "name", label: "Name" },
{ key: "status", label: "Status" }
];
const tableRows = [
{ name: "Project Alpha", status: "Active" },
{ name: "Project Beta", status: "Paused" }
];
const modes = [
{ label: "Auto", value: "auto" },
{ label: "Manual", value: "manual" },
{ label: "Locked", value: "locked", disabled: true }
];
const people = [
{ label: "Joe", value: "joe" },
{ label: "James", value: "james" },
{ label: "Eliza", value: "eliza" },
{ label: "Emily", value: "emily" }
];
const steps = [
{ title: "Created", status: "complete" },
{ title: "Review", status: "current" },
{ title: "Deploy" },
{ title: "Done" }
];
const stages = [
{ label: "Created", status: "complete" },
{ label: "Review", status: "current" },
{ label: "Deploy" },
{ label: "Done" }
];
const details = [
{ key: "owner", term: "Owner", value: "Ops Console" },
{ key: "status", term: "Status", value: "Active" },
{ key: "region", term: "Region", value: "eu-central" }
];
const activity = [
{ key: "created", time: "10:12", title: "Workspace created" },
{ key: "synced", time: "10:18", title: "Tokens synced" }
];
const timeline = [
{ time: "09:00", title: "Started", status: "complete" },
{ time: "10:30", title: "In Progress", status: "current" },
{ time: "12:00", title: "Review" }
];
const navItems = [
{ label: "Dashboard", icon: "ph-house", href: "#" },
{ label: "Projects", icon: "ph-folder", href: "#" },
{ label: "Settings", icon: "ph-gear", href: "#" }
];
const accordionItems = [
{ id: "overview", label: "Overview", icon: "ph-info", content: "Overview panel content." },
{ id: "details", label: "Details", icon: "ph-list-dashes", content: "Details panel content." },
{ id: "settings", label: "Settings", icon: "ph-gear", content: "Settings panel content." }
];
const listItems = [
{ label: "First item", meta: "Meta text" },
{ label: "Second item", meta: "More info" }
];
const actionListItems = [
{ label: "Edit", icon: "ph-pencil-simple" },
{ label: "Duplicate", icon: "ph-copy" },
{ label: "Delete", icon: "ph-trash", danger: true }
];
const definitionItems = [
{ term: "Term A", description: "Definition for A" },
{ term: "Term B", description: "Definition for B" }
];
function save() {
toast.success({ title: "Saved", text: name.value || "Changes applied" });
modalOpen.value = false;
}
function confirmAction() {
toast.success({ title: "Confirmed", text: "Action was confirmed" });
confirmOpen.value = false;
}
return {
modalOpen, drawerOpen, confirmOpen,
name, status, tab, checked, switched, mode, rollout, assignee, files, searchQuery, currentPage,
statusOptions, tabs, tableColumns, tableRows, modes, people, steps, stages,
details, activity, timeline, navItems, listItems, actionListItems, definitionItems, accordionItems,
save, confirmAction, toast
};
},
template: `
<GnToastProvider>
<div class="container">
<GnPageHeader title="Vue Adapter Demo" subtitle="Official components in action">
<template #actions>
<GnButton variant="accent" icon="ph-plus" @click="modalOpen = true">Create</GnButton>
<GnIconButton icon="ph-gear" label="Settings" />
<GnCopyButton text="Copied text" />
</template>
</GnPageHeader>
<div class="demo-section">
<h3>Buttons</h3>
<div class="demo-actions">
<GnButton variant="primary" icon="ph-house">Primary</GnButton>
<GnButton variant="secondary">Secondary</GnButton>
<GnButton variant="accent" loading>Loading</GnButton>
<GnButton variant="danger" disabled>Disabled</GnButton>
</div>
</div>
<div class="demo-section">
<h3>Badges & Alerts</h3>
<div class="demo-actions">
<GnBadge variant="success">Online</GnBadge>
<GnBadge variant="warning" outline>Pending</GnBadge>
<GnBadge variant="danger">Error</GnBadge>
</div>
<div class="mt-4">
<GnAlert variant="info">This is an informational alert.</GnAlert>
</div>
<div class="mt-4">
<GnAlert variant="danger">Something went wrong.</GnAlert>
</div>
</div>
<div class="demo-section">
<h3>Form Controls</h3>
<div class="demo-grid">
<div class="demo-card">
<h3>Input & Select</h3>
<GnInput v-model="name" label="Project name" icon="ph-pencil-simple" />
<GnSelect v-model="status" label="Status" :options="statusOptions" />
</div>
<div class="demo-card">
<h3>Textarea & Checkbox</h3>
<GnTextarea v-model="name" label="Description" />
<GnCheckbox v-model="checked" label="Enable feature" />
<GnSwitch v-model="switched" label="Toggle mode" />
</div>
<div class="demo-card">
<h3>Radio & Range</h3>
<GnRadioGroup v-model="mode" label="Mode" :options="modes" />
<GnRange v-model="rollout" label="Rollout" />
</div>
<div class="demo-card">
<h3>Combobox</h3>
<GnCombobox v-model="assignee" label="Assignee" icon="ph-user" :options="people" />
</div>
</div>
</div>
<div class="demo-section">
<h3>File Upload</h3>
<GnFileUpload v-model="files" badge="Max 12 MB" />
</div>
<div class="demo-section">
<h3>Accordion</h3>
<GnAccordion :items="accordionItems" v-model="tab" />
</div>
<div class="demo-section">
<h3>Input Group</h3>
<GnInputGroup addon="@" icon="ph-magnifying-glass">
<GnInput v-model="name" placeholder="Search" />
<template #action>
<GnButton variant="primary" icon="ph-arrow-right">Go</GnButton>
</template>
</GnInputGroup>
</div>
<div class="demo-section">
<h3>Tabs</h3>
<GnTabs v-model="tab" :items="tabs">
<template #overview>
<GnDescriptionList :items="details" />
<div class="mt-4">
<GnProgress label="Rollout" :value="Number(rollout)" animated />
</div>
</template>
<template #activity>
<GnActivityLog :items="activity" />
</template>
</GnTabs>
</div>
<div class="demo-section">
<h3>Table</h3>
<GnTable :columns="tableColumns" :rows="tableRows">
<template #cell-status="{ value }">
<GnBadge :variant="value === 'Active' ? 'success' : 'warning'">{{ value }}</GnBadge>
</template>
</GnTable>
</div>
<div class="demo-section">
<h3>Cards</h3>
<div class="demo-grid">
<GnCard title="Example Card">
Card content goes here.
<template #footer>
<GnButton variant="secondary" size="sm">Action</GnButton>
</template>
</GnCard>
<GnMetricCard label="Usage" value="84.2%" icon="ph-chart-line-up" delta="+12.8%" meta="vs previous period" />
<GnStatusCard variant="success" title="Online" meta="All systems operational" />
<GnActionCard kicker="Quick action" title="Create workflow" text="Action cards keep primary next steps consistent.">
<template #actions>
<GnButton variant="secondary" size="sm">Preview</GnButton>
<GnButton variant="accent" size="sm">Create</GnButton>
</template>
</GnActionCard>
</div>
</div>
<div class="demo-section">
<h3>Horizontal & Login Cards</h3>
<div class="demo-grid">
<GnHorizontalCard image="/assets/imgs/gnexus-mark.svg" title="Project Alpha" title-href="#" icon="ph-arrow-right">
<p>Compact horizontal layout for content listings.</p>
<template #footer>
<span>Updated 2h ago</span>
<GnBadge variant="success">Active</GnBadge>
</template>
</GnHorizontalCard>
<GnLoginCard
title="Sign in"
username-label="Username"
password-label="Password"
submit-text="Sign in"
@submit="toast.success({ title: 'Login', text: 'Form submitted' })"
/>
</div>
</div>
<div class="demo-section">
<h3>Navigation & Progress</h3>
<div class="demo-grid">
<div class="demo-card">
<h3>Nav List</h3>
<GnNavList :items="navItems" />
</div>
<div class="demo-card">
<h3>Steps</h3>
<GnSteps :items="steps" :current="1" />
</div>
<div class="demo-card">
<h3>Progress</h3>
<GnProgress label="Task progress" :value="72" animated />
<div class="mt-4">
<GnProgressStages :items="stages" />
</div>
</div>
<div class="demo-card">
<h3>Timeline</h3>
<GnTimeline :items="timeline" />
</div>
</div>
</div>
<div class="demo-section">
<h3>Data Display</h3>
<div class="demo-grid">
<div class="demo-card">
<h3>Description List</h3>
<GnDescriptionList :items="details" />
</div>
<div class="demo-card">
<h3>Usage Meter</h3>
<GnUsageMeter title="Capacity" :value="Number(rollout)" meta="Shared workspace capacity" />
</div>
<div class="demo-card">
<h3>Lists</h3>
<GnList :items="listItems" />
<div class="mt-4">
<GnActionList :items="actionListItems" />
</div>
<div class="mt-4">
<GnDefinitionList :items="definitionItems" />
</div>
</div>
</div>
</div>
<div class="demo-section">
<h3>Identity</h3>
<div class="demo-actions">
<GnAvatar initials="GN" status="online" />
<GnAvatar icon="ph-user" status="offline" />
<GnIdentity title="Jane Doe" meta="Admin" :avatar="{ initials: 'JD', status: 'online' }" />
<GnAvatarStack :items="[{ initials: 'A' }, { initials: 'B' }, { initials: 'C' }]" />
</div>
</div>
<div class="demo-section">
<h3>Chips & Toolbar</h3>
<div class="demo-actions">
<GnChipGroup>
<GnChip variant="secondary" selected>Vue</GnChip>
<GnChip variant="success">Stable</GnChip>
<GnChip variant="danger">Contract</GnChip>
</GnChipGroup>
</div>
<div class="mt-4">
<GnToolbar title="Projects" meta="2 records">
<template #actions>
<GnSearchField v-model="searchQuery" placeholder="Search projects" />
<GnPagination page="1" total-pages="5" />
</template>
</GnToolbar>
</div>
</div>
<div class="demo-section">
<h3>Overlays</h3>
<div class="demo-actions">
<GnButton variant="primary" @click="modalOpen = true">Open Modal</GnButton>
<GnButton variant="secondary" @click="drawerOpen = true">Open Drawer</GnButton>
<GnButton variant="accent" @click="confirmOpen = true">Confirm Dialog</GnButton>
<GnPopover title="Context" text="Popover keeps short metadata near the action." />
<GnTooltip text="Short contextual hint">
<GnButton variant="primary" icon="ph-question">Help</GnButton>
</GnTooltip>
</div>
</div>
<div class="demo-section">
<h3>Empty State & Skeleton</h3>
<div class="demo-grid">
<GnEmptyState title="No blocking issues" text="Vue adapter components keep project markup consistent.">
<template #actions>
<GnAvatar initials="GN" status="online" />
<GnBadge variant="success">Ready</GnBadge>
</template>
</GnEmptyState>
<div class="demo-card">
<h3>Skeleton</h3>
<GnSkeleton />
</div>
</div>
</div>
<div class="demo-section">
<h3>Toasts</h3>
<div class="demo-actions">
<GnButton variant="success" @click="toast.success({ title: 'Success', text: 'Operation completed' })">Success Toast</GnButton>
<GnButton variant="danger" @click="toast.error({ title: 'Error', text: 'Something failed' })">Error Toast</GnButton>
<GnButton variant="warning" @click="toast.warning({ title: 'Warning', text: 'Check your input' })">Warning Toast</GnButton>
<GnButton variant="info" @click="toast.info({ title: 'Info', text: 'Just so you know' })">Info Toast</GnButton>
</div>
</div>
<GnModal v-model:open="modalOpen" title="Create Project">
<GnInput v-model="name" label="Name" icon="ph-pencil-simple" />
<template #actions>
<GnButton variant="secondary" @click="modalOpen = false">Cancel</GnButton>
<GnButton variant="success" @click="save">Save</GnButton>
</template>
</GnModal>
<GnDrawer v-model:open="drawerOpen" title="Settings" position="right">
<p>Drawer content goes here.</p>
<GnNavList :items="navItems" />
</GnDrawer>
<GnConfirmDialog
v-model:open="confirmOpen"
title="Delete project?"
message="This action cannot be undone."
confirm-variant="danger"
@confirm="confirmAction"
/>
</div>
</GnToastProvider>
`
}).mount("#app");
</script>
</body>
</html>