File size: 3,424 Bytes
0bfe2e3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { cva } from 'class-variance-authority';
import * as React from 'react';
import { cn, ComponentAnatomy, defineStyleAnatomy } from '../core/styling';
import Link from 'next/link';

/* -------------------------------------------------------------------------------------------------
 * Anatomy
 * -----------------------------------------------------------------------------------------------*/

export const StaticTabsAnatomy = defineStyleAnatomy({
  root: cva([
    'UI-StaticTabs__root',
    'flex w-full overflow-hidden overflow-x-auto',
  ]),
  trigger: cva([
    'UI-StaticTabs__trigger',
    'group/staticTabs__trigger inline-flex flex-none shrink-0 basis-auto items-center font-medium text-sm transition outline-none min-w-0 justify-center',
    'text-[--muted] hover:text-[--foreground]',
    'h-10 px-4 rounded-full',
    'data-[current=true]:bg-[--subtle] data-[current=true]:font-semibold data-[current=true]:text-[--foreground]',
    'focus-visible:bg-[--subtle]',
  ]),
  icon: cva(['UI-StaticTabs__icon', '-ml-0.5 mr-2 h-4 w-4']),
});

/* -------------------------------------------------------------------------------------------------
 * StaticTabs
 * -----------------------------------------------------------------------------------------------*/

export type StaticTabsItem = {
  name: string;
  href?: string | null | undefined;
  iconType?: React.ElementType;
  onClick?: () => void;
  isCurrent: boolean;
};

export type StaticTabsProps = React.ComponentPropsWithRef<'nav'> &
  ComponentAnatomy<typeof StaticTabsAnatomy> & {
    items: StaticTabsItem[];
  };

export const StaticTabs = React.forwardRef<HTMLElement, StaticTabsProps>(
  (props, ref) => {
    const { children, className, triggerClass, iconClass, items, ...rest } =
      props;

    return (
      <nav
        ref={ref}
        className={cn(StaticTabsAnatomy.root(), className)}
        role="navigation"
        {...rest}
      >
        {items.map((tab) =>
          !!tab.href ? (
            <Link
              key={tab.name}
              href={tab.href ?? '#'}
              className={cn(
                'cursor-pointer',
                StaticTabsAnatomy.trigger(),
                triggerClass
              )}
              aria-current={tab.isCurrent ? 'page' : undefined}
              data-current={tab.isCurrent}
            >
              {tab.iconType && (
                <tab.iconType
                  className={cn(StaticTabsAnatomy.icon(), iconClass)}
                  aria-hidden="true"
                  data-current={tab.isCurrent}
                />
              )}
              <span>{tab.name}</span>
            </Link>
          ) : (
            <div
              key={tab.name}
              className={cn(
                StaticTabsAnatomy.trigger(),
                'cursor-pointer',
                triggerClass
              )}
              aria-current={tab.isCurrent ? 'page' : undefined}
              data-current={tab.isCurrent}
              onClick={tab.onClick}
            >
              {tab.iconType && (
                <tab.iconType
                  className={cn(StaticTabsAnatomy.icon(), iconClass)}
                  aria-hidden="true"
                  data-current={tab.isCurrent}
                />
              )}
              <span>{tab.name}</span>
            </div>
          )
        )}
      </nav>
    );
  }
);

StaticTabs.displayName = 'StaticTabs';