All files / src/ahuora-design-system/ui tabs-content.tsx

100% Statements 12/12
80% Branches 8/10
100% Functions 6/6
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164                                              33x             159x         159x                                                                             33x             82x                 246x 246x   246x                                                             33x         53x               159x                       159x                            
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./tabs";
import { ScrollArea } from "./scroll-area";
import * as React from "react";
import { ReactNode } from "react";
import { TabsListProps } from "@radix-ui/react-tabs";
 
type TabItem = string | { value: string; label: string };
export interface TabsContentUIProps {
  header?: ReactNode | (() => ReactNode);
  tabTriggerValue: string;
  value: ReactNode | (() => ReactNode);
  subTabHeader?: TabListComponentProps;
}
export type TabsConfig = Record<string, TabsContentUIProps>;
//These tabs are mainly used in sidebars
//TODO: make this more dynamic
/**
 * @header - these could be specific controls for that tab
 * @tabtriggervalue - this is the value of the tab
 * @value - this is the content of the tab
 * @subtabheader - Use this when there is a tab within a tab e.g., flowsheet panel
 * @returns a tab content
 */
const TabsContentComponent: React.FC<TabsContentUIProps> = ({
  header,
  tabTriggerValue,
  value,
  subTabHeader,
}) => {
  const mainContent = (
    <div className="flex flex-col gap-2 flex-1 min-h-full">
      {header && <div>{header}</div>}
      <ScrollArea className="h-full">{value}</ScrollArea>
    </div>
  );
  return (
    <TabsContent
      key={tabTriggerValue}
      value={tabTriggerValue}
      className="h-full shrink w-full"
    >
      {subTabHeader ? (
        <Tabs
          defaultValue={subTabHeader.tabValues[0].toLowerCase()}
          onValueChange={subTabHeader.onChangeValue}
          className="h-full flex flex-col"
        >
          <div>
            <TabListComponent
              tabValues={subTabHeader.tabValues}
              bg={subTabHeader.bg}
              rounded={subTabHeader.rounded}
              type={subTabHeader.type}
            />
          </div>
          {mainContent}
        </Tabs>
      ) : (
        mainContent
      )}
    </TabsContent>
  );
};
export { TabsContentComponent };
 
interface TabListComponentProps extends TabsListProps {
  tabValues: TabItem[];
  bg?: "default" | "blend" | null | undefined;
  rounded?: "yes" | "no" | null | undefined;
  type?: "vFull" | "vShort" | "hFull" | "hShort" | null | undefined;
 
  onChangeValue?: (value: string) => void;
}
 
const TabListComponent: React.FC<TabListComponentProps> = ({
  tabValues,
  bg,
  rounded,
  type,
  ...props
}) => {
  return (
    <TabsList
      bg={bg}
      rounded={rounded}
      type={type}
      className="w-full p-0 flex justify-between"
      {...props}
    >
      {tabValues.map((tab, index) => {
        const value = typeof tab === "string" ? tab : tab.value;
        const label = typeof tab === "string" ? tab : tab.label;
 
        return (
          <TabsTrigger
            key={`tab-trigger-${index}`}
            value={value.toLowerCase()} // if your values are expected to be lowercased
            className="capitalize bg-muted p-1"
            bg={bg}
          >
            {label}
          </TabsTrigger>
        );
      })}
    </TabsList>
  );
};
 
export { TabListComponent };
interface TabsComponentProps {
  tabData: TabsConfig;
  hideTrigger?: boolean;
  tabSize?: "vFull" | "vShort" | "hFull" | "hShort";
  tabBackGround?: "default" | "blend";
}
 
/**
 * Utilise this component instead of TabsPrimitive.Root
 * This minimises issues in regards to scolling and just simplifies tab creation
 * Example usage are in flowsheetobjectpanel and RightSideBarData
 * @param tabData
 * @param hideTrigger
 * @returns tabs
 */
const TabsComponent: React.FC<TabsComponentProps> = ({
  tabData,
  hideTrigger,
  tabSize,
}) => {
  return (
    <Tabs
      defaultValue={Object.keys(tabData)[0]}
      className="w-full flex flex-col flex-1"
    >
      {!hideTrigger && (
        <TabsList type={tabSize}>
          {Object.keys(tabData).map((key) => {
            return (
              <TabsTrigger key={key} value={key}>
                {key}
              </TabsTrigger>
            );
          })}
        </TabsList>
      )}
 
      <div className="flex-1">
        {Object.entries(tabData).map(
          ([key, { header, value, subTabHeader }]) => (
            <TabsContentComponent
              key={key}
              tabTriggerValue={key}
              value={value}
              header={header}
              subTabHeader={subTabHeader}
            />
          ),
        )}
      </div>
    </Tabs>
  );
};
export { TabsComponent };