Skip to content

Commit e5c3671

Browse files
author
Lasim
committed
feat: add table component suite with header, body, footer, and cell support
1 parent 40ab50a commit e5c3671

File tree

19 files changed

+651
-35
lines changed

19 files changed

+651
-35
lines changed

package-lock.json

Lines changed: 16 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

services/frontend/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
"@tailwindcss/vite": "^4.1.8",
1818
"@tanstack/vue-table": "^8.21.3",
1919
"@vee-validate/zod": "^4.15.0",
20-
"@vueuse/core": "^13.3.0",
20+
"@vueuse/core": "^13.4.0",
2121
"class-variance-authority": "^0.7.1",
2222
"clsx": "^2.1.1",
2323
"lucide-vue-next": "^0.511.0",
2424
"pinia": "^3.0.2",
25-
"reka-ui": "^2.3.0",
25+
"reka-ui": "^2.3.1",
2626
"tailwind-merge": "^3.3.0",
2727
"tailwindcss-animate": "^1.0.7",
2828
"vee-validate": "^4.15.0",
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<script setup lang="ts">
2+
import type { PrimitiveProps } from 'reka-ui'
3+
import type { HTMLAttributes } from 'vue'
4+
import { reactiveOmit } from '@vueuse/core'
5+
import { Primitive } from 'reka-ui'
6+
import { cn } from '@/lib/utils'
7+
import { type BadgeVariants, badgeVariants } from '.'
8+
9+
const props = defineProps<PrimitiveProps & {
10+
variant?: BadgeVariants['variant']
11+
class?: HTMLAttributes['class']
12+
}>()
13+
14+
const delegatedProps = reactiveOmit(props, 'class')
15+
</script>
16+
17+
<template>
18+
<Primitive
19+
data-slot="badge"
20+
:class="cn(badgeVariants({ variant }), props.class)"
21+
v-bind="delegatedProps"
22+
>
23+
<slot />
24+
</Primitive>
25+
</template>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { cva, type VariantProps } from 'class-variance-authority'
2+
3+
export { default as Badge } from './Badge.vue'
4+
5+
export const badgeVariants = cva(
6+
'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
7+
{
8+
variants: {
9+
variant: {
10+
default:
11+
'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
12+
secondary:
13+
'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
14+
destructive:
15+
'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
16+
outline:
17+
'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
18+
},
19+
},
20+
defaultVariants: {
21+
variant: 'default',
22+
},
23+
},
24+
)
25+
export type BadgeVariants = VariantProps<typeof badgeVariants>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script setup lang="ts">
2+
import type { HTMLAttributes } from 'vue'
3+
import { cn } from '@/lib/utils'
4+
5+
const props = defineProps<{
6+
class?: HTMLAttributes['class']
7+
}>()
8+
</script>
9+
10+
<template>
11+
<div data-slot="table-container" class="relative w-full overflow-auto">
12+
<table data-slot="table" :class="cn('w-full caption-bottom text-sm', props.class)">
13+
<slot />
14+
</table>
15+
</div>
16+
</template>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script setup lang="ts">
2+
import type { HTMLAttributes } from 'vue'
3+
import { cn } from '@/lib/utils'
4+
5+
const props = defineProps<{
6+
class?: HTMLAttributes['class']
7+
}>()
8+
</script>
9+
10+
<template>
11+
<tbody
12+
data-slot="table-body"
13+
:class="cn('[&_tr:last-child]:border-0', props.class)"
14+
>
15+
<slot />
16+
</tbody>
17+
</template>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script setup lang="ts">
2+
import type { HTMLAttributes } from 'vue'
3+
import { cn } from '@/lib/utils'
4+
5+
const props = defineProps<{
6+
class?: HTMLAttributes['class']
7+
}>()
8+
</script>
9+
10+
<template>
11+
<caption
12+
data-slot="table-caption"
13+
:class="cn('text-muted-foreground mt-4 text-sm', props.class)"
14+
>
15+
<slot />
16+
</caption>
17+
</template>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<script setup lang="ts">
2+
import type { HTMLAttributes } from 'vue'
3+
import { cn } from '@/lib/utils'
4+
5+
const props = defineProps<{
6+
class?: HTMLAttributes['class']
7+
}>()
8+
</script>
9+
10+
<template>
11+
<td
12+
data-slot="table-cell"
13+
:class="
14+
cn(
15+
'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
16+
props.class,
17+
)
18+
"
19+
>
20+
<slot />
21+
</td>
22+
</template>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script setup lang="ts">
2+
import type { HTMLAttributes } from 'vue'
3+
import { reactiveOmit } from '@vueuse/core'
4+
import { cn } from '@/lib/utils'
5+
import TableCell from './TableCell.vue'
6+
import TableRow from './TableRow.vue'
7+
8+
const props = withDefaults(defineProps<{
9+
class?: HTMLAttributes['class']
10+
colspan?: number
11+
}>(), {
12+
colspan: 1,
13+
})
14+
15+
const delegatedProps = reactiveOmit(props, 'class')
16+
</script>
17+
18+
<template>
19+
<TableRow>
20+
<TableCell
21+
:class="
22+
cn(
23+
'p-4 whitespace-nowrap align-middle text-sm text-foreground',
24+
props.class,
25+
)
26+
"
27+
v-bind="delegatedProps"
28+
>
29+
<div class="flex items-center justify-center py-10">
30+
<slot />
31+
</div>
32+
</TableCell>
33+
</TableRow>
34+
</template>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<script setup lang="ts">
2+
import type { HTMLAttributes } from 'vue'
3+
import { cn } from '@/lib/utils'
4+
5+
const props = defineProps<{
6+
class?: HTMLAttributes['class']
7+
}>()
8+
</script>
9+
10+
<template>
11+
<tfoot
12+
data-slot="table-footer"
13+
:class="cn('bg-muted/50 border-t font-medium [&>tr]:last:border-b-0', props.class)"
14+
>
15+
<slot />
16+
</tfoot>
17+
</template>

0 commit comments

Comments
 (0)