fix: minor styling

This commit is contained in:
zernonia 2023-09-23 21:58:48 +08:00
parent a725977184
commit 6ae3679e53
4 changed files with 356 additions and 2 deletions

View File

@ -60,7 +60,7 @@ import { Textarea } from '@/lib/registry/new-york/ui/textarea'
<Select default-value="2">
<SelectTrigger
id="security-level"
class="line-clamp-1 w-[160px] truncate"
class="line-clamp-1 w-full truncate"
>
<SelectValue placeholder="Select level" />
</SelectTrigger>

View File

@ -0,0 +1,262 @@
<script setup lang="ts">
import type {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
} from '@tanstack/vue-table'
import {
FlexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useVueTable,
} from '@tanstack/vue-table'
import { h, ref } from 'vue'
import DropdownAction from '../DataTableDemoColumn.vue'
import RadixIconsCaretSort from '~icons/radix-icons/caret-sort'
import RadixIconsChevronDown from '~icons/radix-icons/chevron-down'
import { Button } from '@/lib/registry/default/ui/button'
import { Checkbox } from '@/lib/registry/default/ui/checkbox'
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuTrigger,
} from '@/lib/registry/default/ui/dropdown-menu'
import { Input } from '@/lib/registry/default/ui/input'
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/lib/registry/default/ui/table'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/lib/registry/default/ui/card'
import { valueUpdater } from '@/lib/utils'
export interface Payment {
id: string
amount: number
status: 'pending' | 'processing' | 'success' | 'failed'
email: string
}
const data: Payment[] = [
{
id: 'm5gr84i9',
amount: 316,
status: 'success',
email: 'ken99@yahoo.com',
},
{
id: '3u1reuv4',
amount: 242,
status: 'success',
email: 'Abe45@gmail.com',
},
{
id: 'derv1ws0',
amount: 837,
status: 'processing',
email: 'Monserrat44@gmail.com',
},
{
id: '5kma53ae',
amount: 874,
status: 'success',
email: 'Silas22@gmail.com',
},
{
id: 'bhqecj4p',
amount: 721,
status: 'failed',
email: 'carmella@hotmail.com',
},
]
const columns: ColumnDef<Payment>[] = [
{
id: 'select',
header: ({ table }) => h(Checkbox, {
'checked': table.getIsAllPageRowsSelected(),
'onUpdate:checked': value => table.toggleAllPageRowsSelected(!!value),
'ariaLabel': 'Select all',
}),
cell: ({ row }) => h(Checkbox, {
'checked': row.getIsSelected(),
'onUpdate:checked': value => row.toggleSelected(!!value),
'ariaLabel': 'Select row',
}),
enableSorting: false,
enableHiding: false,
},
{
accessorKey: 'status',
header: 'Status',
cell: ({ row }) => h('div', { class: 'capitalize' }, row.getValue('status')),
},
{
accessorKey: 'email',
header: ({ column }) => {
return h(Button, {
variant: 'ghost',
onClick: () => column.toggleSorting(column.getIsSorted() === 'asc'),
}, ['Email', h(RadixIconsCaretSort, { class: 'ml-2 h-4 w-4' })])
},
cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
},
{
accessorKey: 'amount',
header: () => h('div', { class: 'text-right' }, 'Amount'),
cell: ({ row }) => {
const amount = Number.parseFloat(row.getValue('amount'))
// Format the amount as a dollar amount
const formatted = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(amount)
return h('div', { class: 'text-right font-medium' }, formatted)
},
},
{
id: 'actions',
enableHiding: false,
cell: ({ row }) => {
const payment = row.original
return h(DropdownAction, {
payment,
})
},
},
]
const sorting = ref<SortingState>([])
const columnFilters = ref<ColumnFiltersState>([])
const columnVisibility = ref<VisibilityState>({})
const rowSelection = ref({})
const table = useVueTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onSortingChange: updaterOrValue => valueUpdater(updaterOrValue, sorting),
onColumnFiltersChange: updaterOrValue => valueUpdater(updaterOrValue, columnFilters),
onColumnVisibilityChange: updaterOrValue => valueUpdater(updaterOrValue, columnVisibility),
onRowSelectionChange: updaterOrValue => valueUpdater(updaterOrValue, rowSelection),
state: {
get sorting() { return sorting.value },
get columnFilters() { return columnFilters.value },
get columnVisibility() { return columnVisibility.value },
get rowSelection() { return rowSelection.value },
},
})
</script>
<template>
<Card>
<CardHeader>
<CardTitle>Payments</CardTitle>
<CardDescription>Manage your payments.</CardDescription>
</CardHeader>
<CardContent>
<div class="w-full">
<div className="mb-4 flex items-center gap-4">
<Input
class="max-w-sm"
placeholder="Filter emails..."
:model-value="table.getColumn('email')?.getFilterValue() as string"
@update:model-value=" table.getColumn('email')?.setFilterValue($event)"
/>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline" class="ml-auto">
Columns <RadixIconsChevronDown class="ml-2 h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuCheckboxItem
v-for="column in table.getAllColumns().filter((column) => column.getCanHide())"
:key="column.id"
class="capitalize"
:checked="column.getIsVisible()"
@update:checked="(value) => {
column.toggleVisibility(!!value)
}"
>
{{ column.id }}
</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
<div class="rounded-md border">
<Table>
<TableHeader>
<TableRow v-for="headerGroup in table.getHeaderGroups()" :key="headerGroup.id">
<TableHead v-for="header in headerGroup.headers" :key="header.id" class="[&:has([role=checkbox])]:pl-3">
<FlexRender v-if="!header.isPlaceholder" :render="header.column.columnDef.header" :props="header.getContext()" />
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<template v-if="table.getRowModel().rows?.length">
<TableRow
v-for="row in table.getRowModel().rows"
:key="row.id"
:data-state="row.getIsSelected() && 'selected'"
>
<TableCell v-for="cell in row.getVisibleCells()" :key="cell.id" class="[&:has([role=checkbox])]:pl-3">
<FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />
</TableCell>
</TableRow>
</template>
<TableRow v-else>
<TableCell
:col-span="columns.length"
class="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
<div class="flex items-center justify-end space-x-2 py-4">
<div class="flex-1 text-sm text-muted-foreground">
{{ table.getFilteredSelectedRowModel().rows.length }} of
{{ table.getFilteredRowModel().rows.length }} row(s) selected.
</div>
<div class="space-x-2">
<Button
variant="outline"
size="sm"
:disabled="!table.getCanPreviousPage()"
@click="table.previousPage()"
>
Previous
</Button>
<Button
variant="outline"
size="sm"
:disabled="!table.getCanNextPage()"
@click="table.nextPage()"
>
Next
</Button>
</div>
</div>
</div>
</CardContent>
</Card>
</template>

View File

@ -0,0 +1,91 @@
<script setup lang="ts">
import { VisCrosshair, VisLine, VisScatter, VisTooltip, VisXYContainer } from '@unovis/vue'
import { Line } from '@unovis/ts'
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/lib/registry/default/ui/card'
import { useConfigStore } from '@/stores/config'
const { themePrimary } = useConfigStore()
type Data = typeof data[number]
const data = [
{ average: 400, today: 240 },
{ average: 300, today: 139 },
{ average: 200, today: 980 },
{ average: 278, today: 390 },
{ average: 189, today: 480 },
{ average: 239, today: 380 },
{ average: 349, today: 430 },
]
const x = (d: Data, i: number) => i
function template(d: Data) {
return `
<div class="rounded-lg border bg-background p-2 shadow-sm">
<div class="grid grid-cols-2 gap-2">
<div class="flex flex-col">
<span class="text-[0.70rem] uppercase text-muted-foreground">
Average
</span>
<span class="font-bold text-muted-foreground">
${d.average}
</span>
</div>
<div class="flex flex-col">
<span class="text-[0.70rem] uppercase text-muted-foreground">
Today
</span>
<span class="font-bold text-white">
${d.today}
</span>
</div>
</div>
</div>`
}
function computeLineOpacity(val: any, index: number) {
if (index === 0)
return '0.5'
}
</script>
<template>
<Card>
<CardHeader>
<CardTitle>Exercise Minutes</CardTitle>
<CardDescription>
Your excercise minutes are ahead of where you normally are.
</CardDescription>
</CardHeader>
<CardContent class="pb-4">
<div class="h-[200px]">
<VisXYContainer
height="200px"
:data="data"
:margin="{
top: 5,
right: 10,
left: 10,
bottom: 0,
}"
:style="{
'--theme-primary': themePrimary,
'--vis-tooltip-padding': '0px',
'--vis-tooltip-background-color': 'transparent',
'--vis-tooltip-border-color': 'transparent',
}"
>
<VisTooltip />
<VisLine :x="x" :y="[(d: Data) => d.average, (d: Data) => d.today]" :stroke-width="2" color="var(--theme-primary)" :attributes="{ [Line.selectors.linePath]: { opacity: computeLineOpacity } }" />
<VisScatter :x="x" :y="[(d: Data) => d.average, (d: Data) => d.today]" :size="6" :stroke-width="2" stroke-color="var(--theme-primary)" color="white" />
<VisCrosshair :template="template" />
</VisXYContainer>
</div>
</CardContent>
</Card>
</template>

View File

@ -1,7 +1,8 @@
<script setup lang="ts">
import { ref } from 'vue'
import { ChevronDown, Minus, Plus, Send } from 'lucide-vue-next'
import { VisStackedBar, VisXYContainer } from '@unovis/vue'
import Minus from '~icons/radix-icons/minus'
import Plus from '~icons/radix-icons/plus'
import { Button } from '@/lib/registry/new-york/ui/button'
import {