Skip to content

Commit 89681a6

Browse files
zhouLioncwandev
authored andcommitted
feat: add artifact component and its sub components
1 parent d0878dd commit 89681a6

File tree

10 files changed

+258
-0
lines changed

10 files changed

+258
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<script setup lang="ts">
2+
import type { ArtifactProps } from './props'
3+
import { cn } from '@repo/shadcn-vue/lib/utils'
4+
import { computed } from 'vue'
5+
6+
const props = defineProps<ArtifactProps>()
7+
8+
const classes = computed(() => cn(
9+
'flex flex-col overflow-hidden rounded-lg border bg-background shadow-sm',
10+
props.class,
11+
))
12+
</script>
13+
14+
<template>
15+
<div
16+
v-bind="{
17+
...props,
18+
class: classes,
19+
}"
20+
>
21+
<slot />
22+
</div>
23+
</template>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<script setup lang="ts">
2+
import type { ArtifactActionProps } from './props'
3+
import { Button } from '@repo/shadcn-vue/components/ui/button'
4+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@repo/shadcn-vue/components/ui/tooltip'
5+
import { cn } from '@repo/shadcn-vue/lib/utils'
6+
import { computed } from 'vue'
7+
8+
const props = withDefaults(defineProps<ArtifactActionProps>(), {
9+
variant: 'ghost',
10+
size: 'sm',
11+
})
12+
13+
const classes = computed(() => cn(
14+
'size-8 p-0 text-muted-foreground hover:text-foreground',
15+
props.class,
16+
))
17+
</script>
18+
19+
<template>
20+
<TooltipProvider v-if="props.tooltip">
21+
<Tooltip>
22+
<TooltipTrigger as-child>
23+
<Button
24+
type="button"
25+
v-bind="{
26+
...props,
27+
class: classes,
28+
}"
29+
>
30+
<component
31+
:is="props.icon"
32+
v-if="props.icon"
33+
class="size-4"
34+
/>
35+
<slot v-else />
36+
<span class="sr-only">{{ props.label || props.tooltip }}</span>
37+
</Button>
38+
</TooltipTrigger>
39+
<TooltipContent>
40+
<p>{{ props.tooltip }}</p>
41+
</TooltipContent>
42+
</Tooltip>
43+
</TooltipProvider>
44+
45+
<Button
46+
v-else
47+
type="button"
48+
v-bind="{
49+
...props,
50+
class: classes,
51+
}"
52+
>
53+
<component
54+
:is="props.icon"
55+
v-if="props.icon"
56+
class="size-4"
57+
/>
58+
<slot v-else />
59+
<span class="sr-only">{{ props.label || props.tooltip }}</span>
60+
</Button>
61+
</template>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script setup lang="ts">
2+
import type { ArtifactActionsProps } from './props'
3+
import { cn } from '@repo/shadcn-vue/lib/utils'
4+
import { computed } from 'vue'
5+
6+
const props = defineProps<ArtifactActionsProps>()
7+
8+
const classes = computed(() => cn('flex items-center gap-1', props.class))
9+
</script>
10+
11+
<template>
12+
<div
13+
v-bind="{
14+
...props,
15+
class: classes,
16+
}"
17+
>
18+
<slot />
19+
</div>
20+
</template>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<script setup lang="ts">
2+
import type { ArtifactCloseProps } from './props'
3+
import { Button } from '@repo/shadcn-vue/components/ui/button'
4+
import { cn } from '@repo/shadcn-vue/lib/utils'
5+
import { X } from 'lucide-vue-next'
6+
import { computed } from 'vue'
7+
8+
const props = withDefaults(defineProps<ArtifactCloseProps>(), {
9+
variant: 'ghost',
10+
size: 'sm',
11+
})
12+
13+
const classes = computed(() => cn(
14+
'size-8 p-0 text-muted-foreground hover:text-foreground',
15+
props.class,
16+
))
17+
</script>
18+
19+
<template>
20+
<Button
21+
type="button"
22+
v-bind="{
23+
...props,
24+
class: classes,
25+
}"
26+
>
27+
<slot>
28+
<X class="size-4" />
29+
</slot>
30+
<span class="sr-only">Close</span>
31+
</Button>
32+
</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 { cn } from '@repo/shadcn-vue/lib/utils'
3+
import { computed, useAttrs } from 'vue'
4+
5+
interface Props {
6+
class?: string
7+
}
8+
9+
const props = defineProps<Props>()
10+
const attrs = useAttrs()
11+
12+
const classes = computed(() => cn('flex-1 overflow-auto p-4', props.class))
13+
</script>
14+
15+
<template>
16+
<div
17+
:class="classes"
18+
v-bind="attrs"
19+
>
20+
<slot />
21+
</div>
22+
</template>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script setup lang="ts">
2+
import type { ArtifactDescriptionProps } from './props'
3+
import { cn } from '@repo/shadcn-vue/lib/utils'
4+
import { computed } from 'vue'
5+
6+
const props = defineProps<ArtifactDescriptionProps>()
7+
8+
const classes = computed(() => cn('text-muted-foreground text-sm', props.class))
9+
</script>
10+
11+
<template>
12+
<p
13+
v-bind="{
14+
...props,
15+
class: classes,
16+
}"
17+
>
18+
<slot />
19+
</p>
20+
</template>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script setup lang="ts">
2+
import type { ArtifactHeaderProps } from './props'
3+
import { cn } from '@repo/shadcn-vue/lib/utils'
4+
import { computed } from 'vue'
5+
6+
const props = defineProps<ArtifactHeaderProps>()
7+
8+
const classes = computed(() => cn(
9+
'flex items-center justify-between border-b bg-muted/50 px-4 py-3',
10+
props.class,
11+
))
12+
</script>
13+
14+
<template>
15+
<div
16+
:class="classes"
17+
v-bind="{
18+
...props,
19+
class: classes,
20+
}"
21+
>
22+
<slot />
23+
</div>
24+
</template>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script setup lang="ts">
2+
import type { ArtifactTitleProps } from './props'
3+
import { cn } from '@repo/shadcn-vue/lib/utils'
4+
import { computed } from 'vue'
5+
6+
const props = defineProps<ArtifactTitleProps>()
7+
8+
const classes = computed(() => cn('font-medium text-foreground text-sm', props.class))
9+
</script>
10+
11+
<template>
12+
<p
13+
v-bind="{
14+
...props,
15+
class: classes,
16+
}"
17+
>
18+
<slot />
19+
</p>
20+
</template>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export { default as Artifact } from './Artifact.vue'
2+
export { default as ArtifactAction } from './ArtifactAction.vue'
3+
export { default as ArtifactActions } from './ArtifactActions.vue'
4+
export { default as ArtifactClose } from './ArtifactClose.vue'
5+
export { default as ArtifactContent } from './ArtifactContent.vue'
6+
export { default as ArtifactDescription } from './ArtifactDescription.vue'
7+
export { default as ArtifactHeader } from './ArtifactHeader.vue'
8+
export { default as ArtifactTitle } from './ArtifactTitle.vue'
9+
10+
export type {
11+
ArtifactActionProps,
12+
ArtifactActionsProps,
13+
ArtifactCloseProps,
14+
ArtifactContentProps,
15+
ArtifactDescriptionProps,
16+
ArtifactHeaderProps,
17+
ArtifactProps,
18+
ArtifactTitleProps,
19+
} from './props'
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type Button from '@repo/shadcn-vue/components/ui/button/Button.vue'
2+
import type { LucideIcon } from 'lucide-vue-next'
3+
import type { HTMLAttributes } from 'vue'
4+
5+
export type ArtifactProps = HTMLAttributes
6+
export type ArtifactHeaderProps = HTMLAttributes
7+
export type ArtifactCloseProps = InstanceType<typeof Button>
8+
export type ArtifactTitleProps = HTMLAttributes
9+
export type ArtifactDescriptionProps = HTMLAttributes
10+
export type ArtifactActionsProps = HTMLAttributes
11+
export type ArtifactActionProps = InstanceType<typeof Button> & {
12+
tooltip?: string
13+
label?: string
14+
icon?: LucideIcon
15+
}
16+
17+
export type ArtifactContentProps = HTMLAttributes

0 commit comments

Comments
 (0)