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
31 changes: 31 additions & 0 deletions app/components/Ui/Card/Action.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<Primitive
data-slot="card-action"
:class="styles({ class: normalizeClass(props.class) || undefined })"
:as="as"
:as-child="asChild"
>
<slot />
</Primitive>
</template>

<script lang="ts" setup>
import { Primitive } from "reka-ui"
import type { PrimitiveProps } from "reka-ui"
import { normalizeClass } from "vue"
import type { HTMLAttributes } from "vue"

const props = withDefaults(
defineProps<
PrimitiveProps & {
/** Custom class(es) to add to the element. */
class?: HTMLAttributes["class"]
}
>(),
{ as: "div" }
)

const styles = tv({
base: "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
})
</script>
58 changes: 58 additions & 0 deletions app/components/Ui/Card/Card.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<template>
<Primitive
data-slot="card"
:as="as"
:as-child="asChild"
:class="styles({ class: normalizeClass(props.class) || undefined })"
>
<slot>
<slot name="header">
<UiCardHeader>
<slot name="title">
<UiCardTitle v-if="title || $slots.title" :title="title" />
</slot>
<slot name="action" />
<slot name="description">
<UiCardDescription
v-if="description || $slots.description"
:description="description"
/>
</slot>
</UiCardHeader>
</slot>
<slot v-if="content || $slots.content" name="content">
<UiCardContent>
<div v-html="content" />
</UiCardContent>
</slot>
<slot name="footer" />
</slot>
</Primitive>
</template>

<script lang="ts" setup>
import { Primitive } from "reka-ui"
import type { PrimitiveProps } from "reka-ui"
import { normalizeClass } from "vue"
import type { HTMLAttributes } from "vue"

const props = withDefaults(
defineProps<
PrimitiveProps & {
/** Title that should be displayed. Passed to the `CardTitle` component. */
title?: string
/** Description that should be displayed. Passed to the `CardDescription` component. */
description?: string
/** Content that should be displayed. Passed to the `CardContent` component. */
content?: string
/** Custom class(es) to add to the element. */
class?: HTMLAttributes["class"]
}
>(),
{ as: "div" }
)

const styles = tv({
base: "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
})
</script>
34 changes: 34 additions & 0 deletions app/components/Ui/Card/Content.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<Primitive
data-slot="card-content"
:as="as"
:as-child="asChild"
:class="styles({ class: normalizeClass(props.class) || undefined })"
>
<slot>
{{ content }}
</slot>
</Primitive>
</template>

<script lang="ts" setup>
import { Primitive } from "reka-ui"
import type { PrimitiveProps } from "reka-ui"
import { normalizeClass } from "vue"
import type { HTMLAttributes } from "vue"

const props = withDefaults(
defineProps<
PrimitiveProps & {
/** Content to display in the card. */
content?: string
/** Custom class(es) to add to the element. */
class?: HTMLAttributes["class"]
}
>(),
{ as: "div" }
)
const styles = tv({
base: "px-6",
})
</script>
36 changes: 36 additions & 0 deletions app/components/Ui/Card/Description.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template>
<Primitive
data-slot="card-description"
:class="styles({ class: normalizeClass(props.class) || undefined })"
:as="as"
:as-child="asChild"
>
<slot>
{{ description }}
</slot>
</Primitive>
</template>

<script lang="ts" setup>
import { Primitive } from "reka-ui"
import type { PrimitiveProps } from "reka-ui"
import { normalizeClass } from "vue"
import type { HTMLAttributes } from "vue"

const props = withDefaults(
defineProps<
PrimitiveProps & {
/** Description to display in the card. */
description?: string
/** Custom class(es) to add to the element. */
class?: HTMLAttributes["class"]
}
>(),
{
as: "div",
}
)
const styles = tv({
base: "text-muted-foreground text-sm",
})
</script>
31 changes: 31 additions & 0 deletions app/components/Ui/Card/Footer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<Primitive
data-slot="card-footer"
:class="styles({ class: normalizeClass(props.class) || undefined })"
:as="as"
:as-child="asChild"
>
<slot />
</Primitive>
</template>

<script lang="ts" setup>
import { Primitive } from "reka-ui"
import type { PrimitiveProps } from "reka-ui"
import { normalizeClass } from "vue"
import type { HTMLAttributes } from "vue"

const props = withDefaults(
defineProps<
PrimitiveProps & {
/** Custom class(es) to add to the element. */
class?: HTMLAttributes["class"]
}
>(),
{ as: "div" }
)

const styles = tv({
base: "flex items-center px-6 [.border-t]:pt-6",
})
</script>
31 changes: 31 additions & 0 deletions app/components/Ui/Card/Header.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<template>
<Primitive
data-slot="card-header"
:class="styles({ class: normalizeClass(props.class) || undefined })"
:as="as"
:as-child="asChild"
>
<slot />
</Primitive>
</template>

<script lang="ts" setup>
import { Primitive } from "reka-ui"
import type { PrimitiveProps } from "reka-ui"
import { normalizeClass } from "vue"
import type { HTMLAttributes } from "vue"

const props = withDefaults(
defineProps<
PrimitiveProps & {
/** Custom class(es) to add to the element. */
class?: HTMLAttributes["class"]
}
>(),
{ as: "div" }
)

const styles = tv({
base: "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
})
</script>
37 changes: 37 additions & 0 deletions app/components/Ui/Card/Title.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<Primitive
data-slot="card-title"
:class="styles({ class: normalizeClass(props.class) || undefined })"
:as="as"
:as-child="asChild"
>
<slot>
{{ title }}
</slot>
</Primitive>
</template>

<script lang="ts" setup>
import { Primitive } from "reka-ui"
import type { PrimitiveProps } from "reka-ui"
import { normalizeClass } from "vue"
import type { HTMLAttributes } from "vue"

const props = withDefaults(
defineProps<
PrimitiveProps & {
/** Title to display in the card. */
title?: string
/** Custom class(es) to add to the element. */
class?: HTMLAttributes["class"]
}
>(),
{
as: "h3",
}
)

const styles = tv({
base: "leading-none font-semibold",
})
</script>
27 changes: 27 additions & 0 deletions app/components/Ui/Progress/Indicator.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<ProgressIndicator
data-slot="progress-indicator"
v-bind="forwarded"
:class="styles({ class: normalizeClass(props.class) || undefined })"
>
<slot />
</ProgressIndicator>
</template>

<script lang="ts" setup>
import { ProgressIndicator } from "reka-ui"
import type { ProgressIndicatorProps } from "reka-ui"
import { normalizeClass } from "vue"
import type { HTMLAttributes } from "vue"

const props = defineProps<
ProgressIndicatorProps & {
/** Custom class(es) to add to the parent. */
class?: HTMLAttributes["class"]
}
>()
const forwarded = reactiveOmit(props, "class")
const styles = tv({
base: "bg-primary h-full w-full flex-1 rounded-full transition-all",
})
</script>
41 changes: 41 additions & 0 deletions app/components/Ui/Progress/Progress.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<ProgressRoot
data-slot="progress"
v-bind="{ ...forwarded, ...$attrs }"
:class="styles({ class: normalizeClass(props.class) || undefined })"
>
<slot>
<UiProgressIndicator
:style="{ transform: `translateX(-${100 - ((modelValue || 0) / max) * 100}%)` }"
/>
</slot>
</ProgressRoot>
</template>

<script lang="ts" setup>
import { ProgressRoot, useForwardPropsEmits } from "reka-ui"
import type { ProgressRootEmits, ProgressRootProps } from "reka-ui"
import { normalizeClass } from "vue"
import type { HTMLAttributes } from "vue"

defineOptions({ inheritAttrs: false })
const props = withDefaults(
defineProps<
ProgressRootProps & {
/** Custom class(es) to add to the parent. */
class?: HTMLAttributes["class"]
}
>(),
{
max: 100,
modelValue: 0,
}
)

const emits = defineEmits<ProgressRootEmits>()
const forwarded = useForwardPropsEmits(reactiveOmit(props, "class"), emits)

const styles = tv({
base: "bg-primary/20 relative h-2 w-full overflow-hidden rounded-full",
})
</script>
Loading
Loading