Adds electoral nuclei, leaderships, updates, and WhatsApp invite flows behind campaign auth, plus the consolidated schema migration that Vercel applies on deploy.
78 lines
3.4 KiB
TypeScript
78 lines
3.4 KiB
TypeScript
'use client'
|
|
|
|
import * as React from 'react'
|
|
import { cva, type VariantProps } from 'class-variance-authority'
|
|
import { Tabs as TabsPrimitive } from 'radix-ui'
|
|
|
|
import { cn } from '@/lib/utils'
|
|
|
|
const Tabs = ({
|
|
className,
|
|
orientation = 'horizontal',
|
|
...props
|
|
}: React.ComponentProps<typeof TabsPrimitive.Root>) => (
|
|
<TabsPrimitive.Root
|
|
data-slot="tabs"
|
|
data-orientation={orientation}
|
|
className={cn('group/tabs flex gap-2 data-horizontal:flex-col', className)}
|
|
{...props}
|
|
/>
|
|
)
|
|
|
|
const tabsListVariants = cva(
|
|
'group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:max-w-full group-data-horizontal/tabs:justify-start group-data-horizontal/tabs:overflow-x-auto group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none',
|
|
{
|
|
variants: {
|
|
variant: {
|
|
default: 'bg-muted',
|
|
line: 'gap-1 bg-transparent',
|
|
},
|
|
},
|
|
defaultVariants: {
|
|
variant: 'default',
|
|
},
|
|
},
|
|
)
|
|
|
|
const TabsList = ({
|
|
className,
|
|
variant = 'default',
|
|
...props
|
|
}: React.ComponentProps<typeof TabsPrimitive.List> & VariantProps<typeof tabsListVariants>) => (
|
|
<TabsPrimitive.List
|
|
data-slot="tabs-list"
|
|
data-variant={variant}
|
|
className={cn(tabsListVariants({ variant }), className)}
|
|
{...props}
|
|
/>
|
|
)
|
|
|
|
const TabsTrigger = ({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<typeof TabsPrimitive.Trigger>) => (
|
|
<TabsPrimitive.Trigger
|
|
data-slot="tabs-trigger"
|
|
className={cn(
|
|
"relative inline-flex min-h-11 flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium 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 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
'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',
|
|
className,
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
|
|
const TabsContent = ({
|
|
className,
|
|
...props
|
|
}: React.ComponentProps<typeof TabsPrimitive.Content>) => (
|
|
<TabsPrimitive.Content
|
|
data-slot="tabs-content"
|
|
className={cn('flex-1 text-sm outline-none', className)}
|
|
{...props}
|
|
/>
|
|
)
|
|
|
|
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
|