primitives
Item
Item — базовый примитив RevueUI (Reka UI + shadcn-совместимый API).
Загрузка превью…
src/ui/item/Item.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { Primitive } from "reka-ui"
import { cn } from "@/lib/utils"
import { itemVariants, type ItemVariants } from "./variants"
const props = withDefaults(
defineProps<{
class?: HTMLAttributes["class"]
variant?: ItemVariants["variant"]
size?: ItemVariants["size"]
asChild?: boolean
}>(),
{
variant: "default",
size: "default",
asChild: false,
}
)
</script>
<template>
<Primitive
data-slot="item"
:data-variant="props.variant"
:data-size="props.size"
as="div"
:as-child="props.asChild"
:class="cn(itemVariants({ variant: props.variant, size: props.size, class: props.class }))"
>
<slot />
</Primitive>
</template>
src/ui/item/ItemActions.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{
class?: HTMLAttributes["class"]
}>()
</script>
<template>
<div data-slot="item-actions" :class="cn('cn-item-actions flex items-center', props.class)">
<slot />
</div>
</template>
src/ui/item/ItemContent.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{
class?: HTMLAttributes["class"]
}>()
</script>
<template>
<div
data-slot="item-content"
:class="
cn(
'cn-item-content flex flex-1 flex-col [&+[data-slot=item-content]]:flex-none',
props.class
)
"
>
<slot />
</div>
</template>
src/ui/item/ItemDescription.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{
class?: HTMLAttributes["class"]
}>()
</script>
<template>
<p
data-slot="item-description"
:class="
cn(
'cn-item-description line-clamp-2 font-normal [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary',
props.class
)
"
>
<slot />
</p>
</template>
src/ui/item/ItemFooter.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{
class?: HTMLAttributes["class"]
}>()
</script>
<template>
<div
data-slot="item-footer"
:class="cn('cn-item-footer flex basis-full items-center justify-between', props.class)"
>
<slot />
</div>
</template>
src/ui/item/ItemGroup.vue
<script setup lang="ts">
/**
* Порт базового радикс-слоя (registry/bases/radix/ui/item.tsx, MIT).
* Презентационная композиция; `ItemSeparator` — тонкая обёртка над
* `Separator` (registry/bases/radix/ui/separator.tsx, портирован ранее).
*/
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{
class?: HTMLAttributes["class"]
}>()
</script>
<template>
<div
role="list"
data-slot="item-group"
:class="cn('cn-item-group group/item-group flex w-full flex-col', props.class)"
>
<slot />
</div>
</template>
src/ui/item/ItemHeader.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{
class?: HTMLAttributes["class"]
}>()
</script>
<template>
<div
data-slot="item-header"
:class="cn('cn-item-header flex basis-full items-center justify-between', props.class)"
>
<slot />
</div>
</template>
src/ui/item/ItemMedia.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
import { itemMediaVariants, type ItemMediaVariants } from "./variants"
const props = withDefaults(
defineProps<{
class?: HTMLAttributes["class"]
variant?: ItemMediaVariants["variant"]
}>(),
{
variant: "default",
}
)
</script>
<template>
<div
data-slot="item-media"
:data-variant="props.variant"
:class="cn(itemMediaVariants({ variant: props.variant, class: props.class }))"
>
<slot />
</div>
</template>
src/ui/item/ItemSeparator.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
import { Separator } from "@/components/ui/separator"
const props = defineProps<{
class?: HTMLAttributes["class"]
}>()
</script>
<template>
<Separator
data-slot="item-separator"
orientation="horizontal"
:class="cn('cn-item-separator', props.class)"
/>
</template>
src/ui/item/ItemTitle.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { cn } from "@/lib/utils"
const props = defineProps<{
class?: HTMLAttributes["class"]
}>()
</script>
<template>
<div
data-slot="item-title"
:class="cn('cn-item-title line-clamp-1 flex w-fit items-center', props.class)"
>
<slot />
</div>
</template>
src/ui/item/index.ts
export { default as Item } from "./Item.vue"
export { default as ItemActions } from "./ItemActions.vue"
export { default as ItemContent } from "./ItemContent.vue"
export { default as ItemDescription } from "./ItemDescription.vue"
export { default as ItemFooter } from "./ItemFooter.vue"
export { default as ItemGroup } from "./ItemGroup.vue"
export { default as ItemHeader } from "./ItemHeader.vue"
export { default as ItemMedia } from "./ItemMedia.vue"
export { default as ItemSeparator } from "./ItemSeparator.vue"
export { default as ItemTitle } from "./ItemTitle.vue"
export {
itemMediaVariants,
itemVariants,
type ItemMediaVariants,
type ItemVariants,
} from "./variants"
src/ui/item/variants.ts
import { cva, type VariantProps } from "class-variance-authority"
/**
* Перенесено дословно из registry/bases/radix/ui/item.tsx (MIT).
*/
export const itemVariants = cva(
"cn-item group/item flex w-full flex-wrap items-center transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors",
{
variants: {
variant: {
default: "cn-item-variant-default",
outline: "cn-item-variant-outline",
muted: "cn-item-variant-muted",
},
size: {
default: "cn-item-size-default",
sm: "cn-item-size-sm",
xs: "cn-item-size-xs",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export type ItemVariants = VariantProps<typeof itemVariants>
export const itemMediaVariants = cva(
"cn-item-media flex shrink-0 items-center justify-center [&_svg]:pointer-events-none",
{
variants: {
variant: {
default: "cn-item-media-variant-default",
icon: "cn-item-media-variant-icon",
image: "cn-item-media-variant-image",
},
},
defaultVariants: {
variant: "default",
},
}
)
export type ItemMediaVariants = VariantProps<typeof itemMediaVariants>