finished up the components, added showcase view, and documentation

This commit is contained in:
2026-06-01 17:32:42 -06:00
parent d34d61458b
commit db2ddadff3
6 changed files with 833 additions and 0 deletions
+460
View File
@@ -0,0 +1,460 @@
<script setup>
import { ref } from 'vue'
import DashboardLayout from '../layouts/DashboardLayout.vue'
// Core
import MkButton from '../components/MkButton.vue'
import MkBadge from '../components/MkBadge.vue'
import MkAlert from '../components/MkAlert.vue'
import MkAvatar from '../components/MkAvatar.vue'
import MkProgress from '../components/MkProgress.vue'
import MkCheckbox from '../components/MkCheckbox.vue'
import MkSwitch from '../components/MkSwitch.vue'
import MkInput from '../components/MkInput.vue'
import MkTextArea from '../components/MkTextArea.vue'
import MkPagination from '../components/MkPagination.vue'
import MkPaginationItem from '../components/MkPaginationItem.vue'
import MkTable from '../components/MkTable.vue'
// Cards
import MkBackgroundBlogCard from '../components/cards/MkBackgroundBlogCard.vue'
import MkCenteredBlogCard from '../components/cards/MkCenteredBlogCard.vue'
import MkTransparentBlogCard from '../components/cards/MkTransparentBlogCard.vue'
import MkDefaultInfoCard from '../components/cards/MkDefaultInfoCard.vue'
import MkFilledInfoCard from '../components/cards/MkFilledInfoCard.vue'
import MkDefaultCounterCard from '../components/cards/MkDefaultCounterCard.vue'
import MkDefaultReviewCard from '../components/cards/MkDefaultReviewCard.vue'
import MkHorizontalTeamCard from '../components/cards/MkHorizontalTeamCard.vue'
import MkRotatingCard from '../components/cards/MkRotatingCard.vue'
import MkRotatingCardFront from '../components/cards/MkRotatingCardFront.vue'
import MkRotatingCardBack from '../components/cards/MkRotatingCardBack.vue'
// Layout
import MkBreadcrumbs from '../components/layout/MkBreadcrumbs.vue'
import MkNavbar from '../components/layout/MkNavbar.vue'
import MkHeader from '../components/layout/MkHeader.vue'
import MkFooterCentered from '../components/layout/MkFooterCentered.vue'
// ── Reactive state ────────────────────────────────────────────
const checkbox1 = ref(true)
const checkbox2 = ref(false)
const switch1 = ref(true)
const switch2 = ref(false)
const inputVal = ref('')
const textareaVal = ref('')
const activePage = ref(3)
// ── Data ──────────────────────────────────────────────────────
const colors = ['primary','secondary','success','warning','danger','info','dark']
const img = (seed, w = 600, h = 400) => `https://picsum.photos/seed/${seed}/${w}/${h}`
const tableRows = [
{ initials:'EC', color:'primary', name:'Esthera Carter', email:'e.carter@mk.dev', position:['Lead Designer','Creative'], status:true, date:'23/04/18', action:{label:'Edit', route:'#'} },
{ initials:'JD', color:'info', name:'James Donovan', email:'j.donovan@mk.dev',position:['Developer','Engineering'], status:true, date:'11/01/19', action:{label:'Edit', route:'#'} },
{ initials:'SR', color:'success', name:'Sofia Reyes', email:'s.reyes@mk.dev', position:['Product Manager','Operations'], status:false, date:'19/09/20', action:{label:'Edit', route:'#'} },
{ initials:'ML', color:'warning', name:'Marco Lin', email:'m.lin@mk.dev', position:['QA Engineer','Quality'], status:true, date:'24/12/21', action:{label:'Edit', route:'#'} },
{ initials:'AM', color:'secondary', name:'Ally Maria', email:'a.maria@mk.dev', position:['UX Researcher','Design'], status:false, date:'04/10/22', action:{label:'Edit', route:'#'} },
]
const navItems = [
{ label:'Home', href:'#', icon:'home' },
{ label:'Components', icon:'widgets', children:[
{ label:'Buttons', href:'#', description:'Variants, sizes and states' },
{ label:'Cards', href:'#', description:'Blog, info, counter, review' },
{ label:'Forms', href:'#', description:'Inputs, selects, checkboxes' },
]},
{ label:'Docs', href:'#', icon:'article' },
]
const breadcrumbRoutes = [
{ route:'/', label:'Dashboard' },
{ route:'/showcase', label:'Components' },
{ route:'#', label:'Showcase' },
]
</script>
<template>
<DashboardLayout>
<div class="space-y-12">
<!-- SECTION HELPER -->
<!-- Each section follows: title / subtitle / content card -->
<!-- Buttons -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Buttons</h2>
<p class="text-sm text-secondary mb-4">variant × color × size</p>
<div class="rounded-2xl bg-white p-6 shadow-soft-md space-y-6">
<!-- Gradient -->
<div>
<p class="mb-3 text-xs font-medium uppercase tracking-wide text-secondary">Gradient</p>
<div class="flex flex-wrap gap-3">
<MkButton v-for="c in colors" :key="c" variant="gradient" :color="c">{{ c }}</MkButton>
</div>
</div>
<!-- Contained -->
<div>
<p class="mb-3 text-xs font-medium uppercase tracking-wide text-secondary">Contained</p>
<div class="flex flex-wrap gap-3">
<MkButton v-for="c in colors" :key="c" variant="contained" :color="c">{{ c }}</MkButton>
</div>
</div>
<!-- Outline -->
<div>
<p class="mb-3 text-xs font-medium uppercase tracking-wide text-secondary">Outline</p>
<div class="flex flex-wrap gap-3">
<MkButton v-for="c in colors" :key="c" variant="outline" :color="c">{{ c }}</MkButton>
</div>
</div>
<!-- Sizes + states -->
<div>
<p class="mb-3 text-xs font-medium uppercase tracking-wide text-secondary">Sizes & states</p>
<div class="flex flex-wrap items-center gap-3">
<MkButton variant="gradient" color="primary" size="sm">Small</MkButton>
<MkButton variant="gradient" color="primary" size="md">Medium</MkButton>
<MkButton variant="gradient" color="primary" size="lg">Large</MkButton>
<MkButton variant="gradient" color="primary" :disabled="true">Disabled</MkButton>
<MkButton variant="outline" color="primary" :full-width="true" class="max-w-xs">Full width</MkButton>
</div>
</div>
</div>
</section>
<!-- Badges -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Badges</h2>
<p class="text-sm text-secondary mb-4">fill · gradient · sizes · rounded</p>
<div class="rounded-2xl bg-white p-6 shadow-soft-md space-y-4">
<div class="flex flex-wrap gap-2">
<MkBadge v-for="c in colors" :key="c" variant="fill" :color="c">{{ c }}</MkBadge>
</div>
<div class="flex flex-wrap gap-2">
<MkBadge v-for="c in colors" :key="c" variant="gradient" :color="c">{{ c }}</MkBadge>
</div>
<div class="flex flex-wrap items-center gap-2">
<MkBadge color="primary" size="sm" :rounded="true">sm pill</MkBadge>
<MkBadge color="primary" size="md" :rounded="true">md pill</MkBadge>
<MkBadge color="primary" size="lg" :rounded="true">lg pill</MkBadge>
</div>
</div>
</section>
<!-- Alerts -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Alerts</h2>
<p class="text-sm text-secondary mb-4">all colors · dismissible</p>
<div class="rounded-2xl bg-white p-6 shadow-soft-md space-y-3">
<MkAlert color="success">Success action completed.</MkAlert>
<MkAlert color="info">Info something you should know.</MkAlert>
<MkAlert color="warning">Warning check before proceeding.</MkAlert>
<MkAlert color="danger" :dismissible="true">Danger (dismissible) click × to close.</MkAlert>
<MkAlert color="dark">Dark a neutral message.</MkAlert>
</div>
</section>
<!-- Avatars -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Avatars</h2>
<p class="text-sm text-secondary mb-4">xxs xxl · borderRadius variants</p>
<div class="rounded-2xl bg-white p-6 shadow-soft-md">
<div class="flex flex-wrap items-end gap-4">
<div v-for="s in ['xxs','xs','sm','md','lg','xl','xxl']" :key="s" class="flex flex-col items-center gap-2">
<MkAvatar :image="img('av1',200,200)" alt="Avatar" :size="s" />
<span class="text-xs text-secondary">{{ s }}</span>
</div>
<div class="flex flex-col items-center gap-2">
<MkAvatar :image="img('av2',200,200)" alt="Circle" size="lg" border-radius="full" />
<span class="text-xs text-secondary">circle</span>
</div>
</div>
</div>
</section>
<!-- Progress -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Progress</h2>
<p class="text-sm text-secondary mb-4">contained · gradient</p>
<div class="rounded-2xl bg-white p-6 shadow-soft-md space-y-3">
<div v-for="c in colors" :key="c" class="flex items-center gap-4">
<span class="w-20 shrink-0 text-xs text-secondary">{{ c }}</span>
<div class="flex-1"><MkProgress variant="gradient" :color="c" :value="Math.round(30 + colors.indexOf(c) * 10)" /></div>
</div>
</div>
</section>
<!-- Form Controls -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Form Controls</h2>
<p class="text-sm text-secondary mb-4">input · textarea · checkbox · switch</p>
<div class="grid gap-6 lg:grid-cols-2">
<!-- Inputs -->
<div class="rounded-2xl bg-white p-6 shadow-soft-md space-y-4">
<MkInput label="Default input" v-model="inputVal" placeholder="Type something…" />
<MkInput label="With icon" icon="search" v-model="inputVal" placeholder="Search…" />
<MkInput label="Error state" v-model="inputVal" :error="true" placeholder="Required field" />
<MkInput label="Success state" v-model="inputVal" :success="true" placeholder="Looks good" />
<MkInput label="Disabled" v-model="inputVal" :is-disabled="true" placeholder="Not editable" />
<MkTextArea v-model="textareaVal" placeholder="Your message…" :rows="3">Message</MkTextArea>
</div>
<!-- Toggles -->
<div class="rounded-2xl bg-white p-6 shadow-soft-md">
<p class="mb-4 text-xs font-medium uppercase tracking-wide text-secondary">Checkboxes</p>
<div class="space-y-3 mb-6">
<MkCheckbox id="c1" v-model="checkbox1" color="primary">Primary (checked)</MkCheckbox>
<MkCheckbox id="c2" v-model="checkbox2" color="success">Success (unchecked)</MkCheckbox>
<MkCheckbox id="c3" v-model="checkbox1" color="danger">Danger</MkCheckbox>
</div>
<p class="mb-4 text-xs font-medium uppercase tracking-wide text-secondary">Switches</p>
<div class="space-y-3">
<MkSwitch id="s1" v-model="switch1" color="primary">Primary (on)</MkSwitch>
<MkSwitch id="s2" v-model="switch2" color="success">Success (off)</MkSwitch>
<MkSwitch id="s3" v-model="switch1" color="info">Info</MkSwitch>
</div>
</div>
</div>
</section>
<!-- Pagination -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Pagination</h2>
<p class="text-sm text-secondary mb-4">color variants · active state</p>
<div class="rounded-2xl bg-white p-6 shadow-soft-md space-y-4">
<div v-for="c in ['primary','success','info','danger']" :key="c">
<MkPagination :color="c">
<MkPaginationItem :prev="true" @click="activePage > 1 && activePage--" />
<MkPaginationItem v-for="n in 5" :key="n" :label="String(n)" :active="activePage === n" @click="activePage = n" />
<MkPaginationItem :next="true" @click="activePage < 5 && activePage++" />
</MkPagination>
</div>
</div>
</section>
<!-- Blog Cards -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Blog Cards</h2>
<p class="text-sm text-secondary mb-4">background · centered · transparent</p>
<div class="grid gap-6 md:grid-cols-3">
<MkBackgroundBlogCard
:image="img('bg1')"
title="Background Blog Card"
description="Full-bleed image with gradient overlay. Content sits above the image."
:action="{ route:'#', label:'Read more', color:'white' }"
/>
<MkCenteredBlogCard
:image="img('cb1')"
title="Centered Blog Card"
description="Floating image header overlaps the card top edge for a layered effect."
:action="{ color:'success', label:'Find Out More', route:'#' }"
/>
<MkTransparentBlogCard
:image="img('tb1')"
title="Transparent Blog Card"
description="No card background — just the image with a soft shadow and plain text below."
:action="{ route:'#', color:'primary', label:'Read more' }"
/>
</div>
</section>
<!-- Info Cards -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Info Cards</h2>
<p class="text-sm text-secondary mb-4">default · filled</p>
<div class="grid gap-6 md:grid-cols-2">
<div class="rounded-2xl bg-white p-6 shadow-soft-md">
<div class="grid gap-6 sm:grid-cols-2">
<MkDefaultInfoCard
v-for="item in [
{icon:{component:'bolt',color:'primary',size:'3xl'},title:'Fast Build',description:'Zero-config Vite setup with Tailwind v4.'},
{icon:{component:'palette',color:'success',size:'3xl'},title:'Design Tokens',description:'All values live in @theme CSS custom properties.'},
{icon:{component:'widgets',color:'info',size:'3xl'},title:'30+ Components',description:'Buttons, cards, forms, navbars and more.'},
{icon:{component:'devices',color:'warning',size:'3xl'},title:'Responsive',description:'Mobile-first layouts using Tailwind breakpoints.'},
]"
:key="item.title"
:icon="item.icon"
:title="item.title"
:description="item.description"
/>
</div>
</div>
<div class="space-y-4">
<MkFilledInfoCard
:color="{ background:'primary', text:'white' }"
:icon="{ component:'rocket_launch', color:'white' }"
title="Ship faster"
description="Pre-built components mean less time on UI and more time on features."
:action="{ route:'#', label:{ text:'Learn More', color:'white' } }"
/>
<MkFilledInfoCard
:color="{ background:'', text:'' }"
:icon="{ component:'verified', color:'success' }"
title="Design conformity"
description="The conformity checklist helps keep every PR on-brand."
:action="{ route:'#', label:{ text:'View Checklist', color:'success' } }"
/>
</div>
</div>
</section>
<!-- ⑩ Counter · Review · Team ───────────────────────────── -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Counter, Review & Team Cards</h2>
<p class="text-sm text-secondary mb-4">animated counters · star ratings · horizontal profile</p>
<div class="grid gap-6 lg:grid-cols-3">
<!-- Counter cards -->
<div class="rounded-2xl bg-white p-8 shadow-soft-md">
<div class="grid grid-cols-2 gap-6">
<MkDefaultCounterCard :count="240" suffix="+" color="primary" title="Projects" description="Completed this year" divider="horizontal" />
<MkDefaultCounterCard :count="4500" suffix="+" color="success" title="Users" description="Active accounts" divider="horizontal" />
<MkDefaultCounterCard :count="99" suffix="%" color="info" title="Uptime" description="Last 12 months" divider="horizontal" />
<MkDefaultCounterCard :count="18" color="warning" title="Countries" description="Worldwide reach" divider="horizontal" />
</div>
</div>
<!-- Review card -->
<MkDefaultReviewCard
:image="img('rev1',200,200)"
name="Sofia Reyes"
date="2 days ago"
review="This design system saved us weeks of setup. The components are clean and the token system makes theming trivial."
:rating="5"
/>
<!-- Team card -->
<MkHorizontalTeamCard
:image="img('team1',400,500)"
:profile="{ name:'James Donovan', link:'#' }"
:position="{ label:'Lead Engineer', color:'primary' }"
description="James leads the frontend platform team and maintains the component library. Open source contributor and design systems enthusiast."
/>
</div>
</section>
<!-- ⑪ Rotating Card ─────────────────────────────────────── -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Rotating Card</h2>
<p class="text-sm text-secondary mb-4">hover to flip — CSS 3D, no JS</p>
<div class="max-w-xs">
<div style="height: 22rem">
<MkRotatingCard color="primary" min-height="22rem">
<MkRotatingCardFront
:image="img('rot-front',600,800)"
icon="layers"
label="Design System"
title="Material Kit 2"
description="Vue 3 + Tailwind v4"
/>
<MkRotatingCardBack
:image="img('rot-back',600,800)"
title="Get Started"
description="Build beautiful interfaces with a consistent, token-driven system."
:action="[
{ route:'#', label:'Docs', color:'white' },
{ route:'#', label:'GitHub', color:'white' },
]"
/>
</MkRotatingCard>
</div>
</div>
</section>
<!-- ⑫ Table ──────────────────────────────────────────────── -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Table</h2>
<p class="text-sm text-secondary mb-4">avatar + status badge + action</p>
<MkTable :rows="tableRows">
<template #header>
<div class="flex items-center justify-between">
<h6 class="text-sm font-bold text-dark">Authors</h6>
<MkBadge color="success" :rounded="true">5 active</MkBadge>
</div>
</template>
<template #footer>
<MkPagination color="primary" size="sm">
<MkPaginationItem :prev="true" />
<MkPaginationItem label="1" :active="true" />
<MkPaginationItem label="2" />
<MkPaginationItem label="3" />
<MkPaginationItem :next="true" />
</MkPagination>
</template>
</MkTable>
</section>
<!-- ⑬ Layout Components ──────────────────────────────────── -->
<section>
<h2 class="text-lg font-bold text-dark mb-0.5">Layout Components</h2>
<p class="text-sm text-secondary mb-4">navbar · header · breadcrumbs · footer</p>
<div class="space-y-6">
<!-- Breadcrumbs -->
<div class="rounded-2xl bg-white p-6 shadow-soft-md">
<p class="mb-3 text-xs font-medium uppercase tracking-wide text-secondary">MkBreadcrumbs</p>
<MkBreadcrumbs :routes="breadcrumbRoutes" />
</div>
<!-- Navbar preview -->
<div class="rounded-2xl shadow-soft-md overflow-hidden">
<p class="bg-gray-50 px-4 py-2 text-xs font-medium text-secondary border-b border-gray-100">MkNavbar — light mode (hover items for dropdown)</p>
<MkNavbar
:brand="{ name:'MK Design', route:'#' }"
:nav-items="navItems"
:action="{ label:'Get Started', href:'#', color:'primary' }"
:sticky="false"
/>
</div>
<!-- Header preview -->
<div class="rounded-2xl shadow-soft-md overflow-hidden">
<p class="bg-gray-50 px-4 py-2 text-xs font-medium text-secondary border-b border-gray-100">MkHeader — background image + gradient mask</p>
<MkHeader
:image="img('header1',1200,600)"
:title="{ text:'Build Something Beautiful', variant:'h2' }"
description="A design system for Vue 3 and Tailwind v4."
mask="dark"
:mask-opacity="0.6"
:center="true"
min-height="200px"
/>
</div>
<!-- Footer preview -->
<div class="rounded-2xl shadow-soft-md overflow-hidden">
<p class="bg-gray-50 px-4 py-2 text-xs font-medium text-secondary border-b border-gray-100">MkFooterCentered</p>
<MkFooterCentered
:links="[
{ name:'Company', href:'#' },
{ name:'About', href:'#' },
{ name:'Blog', href:'#' },
{ name:'License', href:'#' },
]"
:socials="[
{ icon:'language', link:'#', label:'Website' },
{ icon:'code', link:'#', label:'GitHub' },
{ icon:'mail', link:'#', label:'Email' },
]"
:copyright="`© ${new Date().getFullYear()} MK Design System`"
/>
</div>
</div>
</section>
</div>
</DashboardLayout>
</template>