Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 40 additions & 25 deletions src/components/tables/Table01.vue
Original file line number Diff line number Diff line change
@@ -1,40 +1,55 @@
<script setup lang="ts">
import Badge from '@/components/ui/Badge.vue'
import {
Table,
TableBody,
TableCaption,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow
} from '@/components/ui/Table'

const invoices = [
{ invoice: 'INV001', status: 'Paid', method: 'Credit Card', amount: '$250.00' },
{ invoice: 'INV002', status: 'Pending', method: 'PayPal', amount: '$150.00' },
{ invoice: 'INV003', status: 'Unpaid', method: 'Bank Transfer', amount: '$350.00' },
{ invoice: 'INV004', status: 'Paid', method: 'Credit Card', amount: '$450.00' }
const projects = [
{ project: 'Website Redesign', dot: 'bg-emerald-500', status: 'Paid', team: 'Frontend Team', budget: '$12,500' },
{ project: 'Mobile App', dot: 'bg-muted-foreground/64', status: 'Unpaid', team: 'Mobile Team', budget: '$8,750' },
{ project: 'API Integration', dot: 'bg-amber-500', status: 'Pending', team: 'Backend Team', budget: '$5,200' },
{ project: 'Database Migration', dot: 'bg-emerald-500', status: 'Paid', team: 'DevOps Team', budget: '$3,800' },
{ project: 'User Dashboard', dot: 'bg-emerald-500', status: 'Paid', team: 'UX Team', budget: '$7,200' },
{ project: 'Security Audit', dot: 'bg-red-500', status: 'Failed', team: 'Security Team', budget: '$2,100' }
]
</script>

<template>
<div class="w-full max-w-md">
<Table>
<TableHeader>
<TableRow>
<TableHead>Invoice</TableHead>
<TableHead>Status</TableHead>
<TableHead>Method</TableHead>
<TableHead class="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow v-for="invoice in invoices" :key="invoice.invoice">
<TableCell class="font-medium">{{ invoice.invoice }}</TableCell>
<TableCell>{{ invoice.status }}</TableCell>
<TableCell>{{ invoice.method }}</TableCell>
<TableCell class="text-right">{{ invoice.amount }}</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
<Table class="w-full max-w-2xl">
<TableCaption>A list of current projects.</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Project</TableHead>
<TableHead>Status</TableHead>
<TableHead>Team</TableHead>
<TableHead class="text-right">Budget</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow v-for="row in projects" :key="row.project">
<TableCell class="font-medium">{{ row.project }}</TableCell>
<TableCell>
<Badge variant="outline">
<span aria-hidden="true" :class="['size-1.5 rounded-full', row.dot]" />
{{ row.status }}
</Badge>
</TableCell>
<TableCell>{{ row.team }}</TableCell>
<TableCell class="text-right">{{ row.budget }}</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow>
<TableCell :colspan="3">Total Budget</TableCell>
<TableCell class="text-right">$39,550</TableCell>
</TableRow>
</TableFooter>
</Table>
</template>
73 changes: 38 additions & 35 deletions src/components/tables/Table02.vue
Original file line number Diff line number Diff line change
@@ -1,50 +1,53 @@
<script setup lang="ts">
import Badge from '@/components/ui/Badge.vue'
import {
Table,
TableBody,
TableCaption,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow
} from '@/components/ui/Table'
import Badge from '@/components/ui/Badge.vue'

const invoices = [
{ invoice: 'INV001', status: 'success', label: 'Paid', amount: '$250.00' },
{ invoice: 'INV002', status: 'warning', label: 'Pending', amount: '$150.00' },
{ invoice: 'INV003', status: 'error', label: 'Unpaid', amount: '$350.00' },
{ invoice: 'INV004', status: 'success', label: 'Paid', amount: '$450.00' }
] as const
const projects = [
{ project: 'Website Redesign', dot: 'bg-emerald-500', status: 'Paid', team: 'Frontend Team', budget: '$12,500' },
{ project: 'Mobile App', dot: 'bg-muted-foreground/64', status: 'Unpaid', team: 'Mobile Team', budget: '$8,750' },
{ project: 'API Integration', dot: 'bg-amber-500', status: 'Pending', team: 'Backend Team', budget: '$5,200' },
{ project: 'Database Migration', dot: 'bg-emerald-500', status: 'Paid', team: 'DevOps Team', budget: '$3,800' },
{ project: 'User Dashboard', dot: 'bg-emerald-500', status: 'Paid', team: 'UX Team', budget: '$7,200' },
{ project: 'Security Audit', dot: 'bg-red-500', status: 'Failed', team: 'Security Team', budget: '$2,100' }
]
</script>

<template>
<div class="w-full max-w-lg">
<Table>
<TableCaption>A list of your recent invoices.</TableCaption>
<TableHeader>
<TableRow>
<TableHead>Invoice</TableHead>
<TableHead>Status</TableHead>
<TableHead class="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow v-for="invoice in invoices" :key="invoice.invoice">
<TableCell class="font-medium">{{ invoice.invoice }}</TableCell>
<TableCell>
<Badge :variant="invoice.status">{{ invoice.label }}</Badge>
</TableCell>
<TableCell class="text-right">{{ invoice.amount }}</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow>
<TableCell colspan="2">Total</TableCell>
<TableCell class="text-right">$1,200.00</TableCell>
</TableRow>
</TableFooter>
</Table>
</div>
<Table variant="card" class="w-full max-w-2xl">
<TableHeader>
<TableRow>
<TableHead>Project</TableHead>
<TableHead>Status</TableHead>
<TableHead>Team</TableHead>
<TableHead class="text-right">Budget</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow v-for="row in projects" :key="row.project">
<TableCell class="font-medium">{{ row.project }}</TableCell>
<TableCell>
<Badge variant="outline">
<span aria-hidden="true" :class="['size-1.5 rounded-full', row.dot]" />
{{ row.status }}
</Badge>
</TableCell>
<TableCell>{{ row.team }}</TableCell>
<TableCell class="text-right">{{ row.budget }}</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow>
<TableCell :colspan="3">Total Budget</TableCell>
<TableCell class="text-right">$39,550</TableCell>
</TableRow>
</TableFooter>
</Table>
</template>
56 changes: 56 additions & 0 deletions src/components/tables/Table03.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup lang="ts">
import Badge from '@/components/ui/Badge.vue'
import { Frame } from '@/components/ui/Frame'
import {
Table,
TableBody,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow
} from '@/components/ui/Table'

const projects = [
{ project: 'Website Redesign', dot: 'bg-emerald-500', status: 'Paid', team: 'Frontend Team', budget: '$12,500' },
{ project: 'Mobile App', dot: 'bg-muted-foreground/64', status: 'Unpaid', team: 'Mobile Team', budget: '$8,750' },
{ project: 'API Integration', dot: 'bg-amber-500', status: 'Pending', team: 'Backend Team', budget: '$5,200' },
{ project: 'Database Migration', dot: 'bg-emerald-500', status: 'Paid', team: 'DevOps Team', budget: '$3,800' },
{ project: 'User Dashboard', dot: 'bg-emerald-500', status: 'Paid', team: 'UX Team', budget: '$7,200' },
{ project: 'Security Audit', dot: 'bg-red-500', status: 'Failed', team: 'Security Team', budget: '$2,100' }
]
</script>

<template>
<Frame class="w-full max-w-2xl">
<Table variant="card">
<TableHeader>
<TableRow>
<TableHead>Project</TableHead>
<TableHead>Status</TableHead>
<TableHead>Team</TableHead>
<TableHead class="text-right">Budget</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow v-for="row in projects" :key="row.project">
<TableCell class="font-medium">{{ row.project }}</TableCell>
<TableCell>
<Badge variant="outline">
<span aria-hidden="true" :class="['size-1.5 rounded-full', row.dot]" />
{{ row.status }}
</Badge>
</TableCell>
<TableCell>{{ row.team }}</TableCell>
<TableCell class="text-right">{{ row.budget }}</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow>
<TableCell :colspan="3">Total Budget</TableCell>
<TableCell class="text-right">$39,550</TableCell>
</TableRow>
</TableFooter>
</Table>
</Frame>
</template>
117 changes: 117 additions & 0 deletions src/components/tables/Table04.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<script setup lang="ts">
import Badge from '@/components/ui/Badge.vue'
import Checkbox from '@/components/ui/Checkbox.vue'
import { Frame } from '@/components/ui/Frame'
import {
Table,
TableBody,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow
} from '@/components/ui/Table'
import { computed, ref } from 'vue'

type Status = 'Paid' | 'Unpaid' | 'Pending' | 'Failed'
type Project = { id: string; project: string; status: Status; team: string; budget: number }

const data: Project[] = [
{ id: '1', project: 'Website Redesign', status: 'Paid', team: 'Frontend Team', budget: 12500 },
{ id: '2', project: 'Mobile App', status: 'Unpaid', team: 'Mobile Team', budget: 8750 },
{ id: '3', project: 'API Integration', status: 'Pending', team: 'Backend Team', budget: 5200 },
{ id: '4', project: 'Database Migration', status: 'Paid', team: 'DevOps Team', budget: 3800 },
{ id: '5', project: 'User Dashboard', status: 'Paid', team: 'UX Team', budget: 7200 },
{ id: '6', project: 'Security Audit', status: 'Failed', team: 'Security Team', budget: 2100 }
]

const statusColor: Record<Status, string> = {
Paid: 'bg-emerald-500',
Unpaid: 'bg-muted-foreground/64',
Pending: 'bg-amber-500',
Failed: 'bg-red-500'
}

const currency = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
maximumFractionDigits: 0,
minimumFractionDigits: 0
})

const selected = ref<Set<string>>(new Set())

const allSelected = computed(() => data.length > 0 && selected.value.size === data.length)
const someSelected = computed(() => selected.value.size > 0 && !allSelected.value)

const headerState = computed<boolean | 'indeterminate'>(() =>
allSelected.value ? true : someSelected.value ? 'indeterminate' : false
)

function toggleAll(value: boolean | 'indeterminate') {
selected.value = value === true ? new Set(data.map((d) => d.id)) : new Set()
}

function toggleRow(id: string, value: boolean | 'indeterminate') {
const next = new Set(selected.value)
if (value === true) next.add(id)
else next.delete(id)
selected.value = next
}

const formattedTotal = computed(() =>
currency.format(data.reduce((sum, p) => sum + p.budget, 0))
)
</script>

<template>
<Frame class="w-full max-w-2xl">
<Table variant="card">
<TableHeader>
<TableRow>
<TableHead>
<Checkbox
aria-label="Select all"
:model-value="headerState"
@update:model-value="toggleAll"
/>
</TableHead>
<TableHead>Project</TableHead>
<TableHead>Status</TableHead>
<TableHead>Team</TableHead>
<TableHead class="text-right">Budget</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow
v-for="row in data"
:key="row.id"
:data-state="selected.has(row.id) ? 'selected' : undefined"
>
<TableCell>
<Checkbox
aria-label="Select row"
:model-value="selected.has(row.id)"
@update:model-value="(v: boolean | 'indeterminate') => toggleRow(row.id, v)"
/>
</TableCell>
<TableCell class="font-medium">{{ row.project }}</TableCell>
<TableCell>
<Badge variant="outline">
<span aria-hidden="true" :class="['size-1.5 rounded-full', statusColor[row.status]]" />
{{ row.status }}
</Badge>
</TableCell>
<TableCell>{{ row.team }}</TableCell>
<TableCell class="text-right">{{ currency.format(row.budget) }}</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow>
<TableCell :colspan="4">Total Budget</TableCell>
<TableCell class="text-right">{{ formattedTotal }}</TableCell>
</TableRow>
</TableFooter>
</Table>
</Frame>
</template>
Loading
Loading