Skip to content

Commit 3125aa4

Browse files
author
Lasim
committed
feat(frontend): implement item components with variants and slots
1 parent 6635348 commit 3125aa4

File tree

12 files changed

+270
-9
lines changed

12 files changed

+270
-9
lines changed

services/frontend/src/components/ui/card/Card.vue

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,38 @@
11
<script setup lang="ts">
22
import type { HTMLAttributes } from 'vue'
3+
import { cva, type VariantProps } from 'class-variance-authority'
34
import { cn } from '@/lib/utils'
45
5-
const props = defineProps<{
6-
class?: HTMLAttributes['class']
7-
}>()
6+
const cardVariants = cva(
7+
'text-card-foreground flex flex-col gap-6 rounded-xl border py-6',
8+
{
9+
variants: {
10+
variant: {
11+
default: 'bg-card',
12+
gray: 'bg-stone-200',
13+
},
14+
},
15+
defaultVariants: {
16+
variant: 'default',
17+
},
18+
}
19+
)
20+
21+
const props = withDefaults(
22+
defineProps<{
23+
variant?: VariantProps<typeof cardVariants>['variant']
24+
class?: HTMLAttributes['class']
25+
}>(),
26+
{
27+
variant: 'default',
28+
}
29+
)
830
</script>
931

1032
<template>
1133
<div
1234
data-slot="card"
13-
:class="
14-
cn(
15-
'bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6',
16-
props.class,
17-
)
18-
"
35+
:class="cn(cardVariants({ variant }), props.class)"
1936
>
2037
<slot />
2138
</div>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script setup lang="ts">
2+
import type { PrimitiveProps } from "reka-ui"
3+
import type { HTMLAttributes } from "vue"
4+
import type { ItemVariants } from "."
5+
import { Primitive } from "reka-ui"
6+
import { cn } from "@/lib/utils"
7+
import { itemVariants } from "."
8+
9+
const props = withDefaults(defineProps<PrimitiveProps & {
10+
class?: HTMLAttributes["class"]
11+
variant?: ItemVariants["variant"]
12+
size?: ItemVariants["size"]
13+
}>(), {
14+
as: "div",
15+
})
16+
</script>
17+
18+
<template>
19+
<Primitive
20+
data-slot="item"
21+
:as="as"
22+
:as-child="asChild"
23+
:class="cn(itemVariants({ variant, size }), props.class)"
24+
>
25+
<slot />
26+
</Primitive>
27+
</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+
<div
12+
data-slot="item-actions"
13+
:class="cn('flex items-center gap-2', props.class)"
14+
>
15+
<slot />
16+
</div>
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+
<div
12+
data-slot="item-content"
13+
:class="cn('flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none', props.class)"
14+
>
15+
<slot />
16+
</div>
17+
</template>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
<p
12+
data-slot="item-description"
13+
:class="cn(
14+
'text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance',
15+
'[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',
16+
props.class,
17+
)"
18+
>
19+
<slot />
20+
</p>
21+
</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+
<div
12+
data-slot="item-footer"
13+
:class="cn('flex basis-full items-center justify-between gap-2', props.class)"
14+
>
15+
<slot />
16+
</div>
17+
</template>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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
12+
role="list"
13+
data-slot="item-group"
14+
:class="cn('group/item-group flex flex-col', props.class)"
15+
>
16+
<slot />
17+
</div>
18+
</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+
<div
12+
data-slot="item-header"
13+
:class="cn('flex basis-full items-center justify-between gap-2', props.class)"
14+
>
15+
<slot />
16+
</div>
17+
</template>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script setup lang="ts">
2+
import type { HTMLAttributes } from "vue"
3+
import type { ItemMediaVariants } from "."
4+
import { cn } from "@/lib/utils"
5+
import { itemMediaVariants } from "."
6+
7+
const props = defineProps<{
8+
class?: HTMLAttributes["class"]
9+
variant?: ItemMediaVariants["variant"]
10+
}>()
11+
</script>
12+
13+
<template>
14+
<div
15+
data-slot="item-media"
16+
:data-variant="props.variant"
17+
:class="cn(itemMediaVariants({ variant }), props.class)"
18+
>
19+
<slot />
20+
</div>
21+
</template>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script setup lang="ts">
2+
import type { SeparatorProps } from "reka-ui"
3+
import type { HTMLAttributes } from "vue"
4+
import { cn } from "@/lib/utils"
5+
import { Separator } from '@/components/ui/separator'
6+
7+
const props = defineProps<
8+
SeparatorProps & { class?: HTMLAttributes["class"] }
9+
>()
10+
</script>
11+
12+
<template>
13+
<Separator
14+
data-slot="item-separator"
15+
orientation="horizontal"
16+
:class="cn('my-0', props.class)"
17+
/>
18+
</template>

0 commit comments

Comments
 (0)