primitives
Tabs
Tabs — базовый примитив RevueUI (Reka UI + shadcn-совместимый API).
Загрузка превью…
src/ui/tabs/Tabs.vue
<script setup lang="ts">
/**
* Порт базового радикс-слоя (registry/bases/radix/ui/tabs.tsx, MIT).
* Radix TabsPrimitive -> reka-ui Tabs*, один в один.
*/
import type { HTMLAttributes } from "vue"
import { TabsRoot } from "reka-ui"
import { cn } from "@/lib/utils"
const props = withDefaults(
defineProps<{
class?: HTMLAttributes["class"]
orientation?: "horizontal" | "vertical"
}>(),
{
orientation: "horizontal",
}
)
</script>
<template>
<TabsRoot
data-slot="tabs"
:data-orientation="props.orientation"
:orientation="props.orientation"
:class="cn('cn-tabs group/tabs flex data-horizontal:flex-col', props.class)"
>
<slot />
</TabsRoot>
</template>
src/ui/tabs/TabsContent.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import type { TabsContentProps } from "reka-ui"
import { TabsContent } from "reka-ui"
import { cn } from "@/lib/utils"
const props = defineProps<
TabsContentProps & { class?: HTMLAttributes["class"] }
>()
</script>
<template>
<TabsContent
data-slot="tabs-content"
:value="props.value"
:force-mount="props.forceMount"
:class="cn('cn-tabs-content flex-1 outline-none', props.class)"
>
<slot />
</TabsContent>
</template>
src/ui/tabs/TabsList.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { TabsList } from "reka-ui"
import { cn } from "@/lib/utils"
import { tabsListVariants, type TabsListVariants } from "./variants"
const props = withDefaults(
defineProps<{
class?: HTMLAttributes["class"]
variant?: TabsListVariants["variant"]
}>(),
{
variant: "default",
}
)
</script>
<template>
<TabsList
data-slot="tabs-list"
:data-variant="props.variant"
:class="cn(tabsListVariants({ variant: props.variant }), props.class)"
>
<slot />
</TabsList>
</template>
src/ui/tabs/TabsTrigger.vue
<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import type { TabsTriggerProps } from "reka-ui"
import { TabsTrigger } from "reka-ui"
import { cn } from "@/lib/utils"
const props = defineProps<
TabsTriggerProps & { class?: HTMLAttributes["class"] }
>()
</script>
<template>
<TabsTrigger
data-slot="tabs-trigger"
:value="props.value"
:disabled="props.disabled"
:class="
cn(
'cn-tabs-trigger relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0',
'group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent',
'data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground',
'after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100',
props.class
)
"
>
<slot />
</TabsTrigger>
</template>
src/ui/tabs/index.ts
export { default as Tabs } from "./Tabs.vue"
export { default as TabsContent } from "./TabsContent.vue"
export { default as TabsList } from "./TabsList.vue"
export { default as TabsTrigger } from "./TabsTrigger.vue"
export { tabsListVariants, type TabsListVariants } from "./variants"
src/ui/tabs/variants.ts
import { cva, type VariantProps } from "class-variance-authority"
/**
* Перенесено дословно из registry/bases/radix/ui/tabs.tsx (MIT).
*/
export const tabsListVariants = cva(
"cn-tabs-list group/tabs-list inline-flex w-fit items-center justify-center text-muted-foreground group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col",
{
variants: {
variant: {
default: "cn-tabs-list-variant-default bg-muted",
line: "cn-tabs-list-variant-line gap-1 bg-transparent",
},
},
defaultVariants: {
variant: "default",
},
}
)
export type TabsListVariants = VariantProps<typeof tabsListVariants>
Установка
npx shadcn-vue@latest add https://revueui.rootapi.dev/r/tabs.jsonЗависимости реестра
npm-зависимости
- class-variance-authority
- reka-ui
Источник: порт из ReUI (Keenthemes, MIT)