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

86.79% Statements 46/53
53.7% Branches 29/54
50% Functions 3/6
85.71% Lines 30/35

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 165 166 167 168 169 170 171 172 173 174 175 176                                                        300x             300x 438x 438x 576x     138x         138x                                   576x 576x                           33x         33x 33x   264x   33x             33x 99x 99x                           165x 198x                                           300x       100x       200x     100x                   400x   119x 100x 300x                 200x 300x 400x        
import { TabsListProps } from "@radix-ui/react-tabs";
import * as React from "react";
import { ReactNode } from "react";
import { cn } from "@/lib/utils";
import {
  AccessControlledProps,
  AccessControlledTabsTrigger,
} from "./accessControlled";
import { ScrollArea } from "./scroll-area";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "./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, AccessControlledProps {
  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,
  writeAccessOnly = true,
  hideIfNoAccess = false,
  ...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 (
          <AccessControlledTabsTrigger
            key={`tab-trigger-${index}`}
            value={value.toLowerCase()} // if your values are expected to be lowercased
            className="capitalize bg-muted p-1"
            bg={bg}
            writeAccessOnly={writeAccessOnly}
            hideIfNoAccess={hideIfNoAccess}
          >
            {label}
          </AccessControlledTabsTrigger>
        );
      })}
    </TabsList>
  );
};
 
export { TabListComponent };
interface TabsComponentProps {
  tabData: TabsConfig;
  hideTrigger?: boolean;
  tabSize?: "vFull" | "vShort" | "hFull" | "hShort";
  tabBackGround?: "default" | "blend";
  className?: string;
}
 
/**
 * 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,
  className = "",
}) => {
  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={cn("flex-1", className)}>
        {Object.entries(tabData).map(
          ([key, { header, value, subTabHeader }]) => (
            <TabsContentComponent
              key={key}
              tabTriggerValue={key}
              value={value}
              header={header}
              subTabHeader={subTabHeader}
            />
          ),
        )}
      </div>
    </Tabs>
  );
};
export { TabsComponent };