1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-19 05:19:39 +02:00
portainer/app/react/components/NavTabs/NavTabs.tsx
Chaim Lev-Ari eb6d251a73
Some checks failed
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Has been cancelled
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Has been cancelled
ci / build_images (map[arch:arm platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Has been cancelled
ci / build_images (map[arch:s390x platform:linux version:]) (push) Has been cancelled
/ triage (push) Has been cancelled
Lint / Run linters (push) Has been cancelled
Test / test-client (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:linux]) (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Has been cancelled
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Has been cancelled
Test / test-server (map[arch:arm64 platform:linux]) (push) Has been cancelled
ci / build_manifests (push) Has been cancelled
feat(edge/jobs): migrate item view to react [EE-2220] (#11887)
2024-06-06 21:07:39 +03:00

80 lines
2 KiB
TypeScript

import clsx from 'clsx';
import { ComponentProps, ReactNode } from 'react';
import { Button } from '@@/buttons';
import styles from './NavTabs.module.css';
export interface Option<T extends string | number = string> {
label: ReactNode;
children?: ReactNode;
id: T;
hidden?: boolean;
icon?: ComponentProps<typeof Button>['icon'];
}
interface Props<T extends string | number> {
options: Array<Option<T>> | ReadonlyArray<Option<T>>;
selectedId?: T;
onSelect?(id: T): void;
disabled?: boolean;
type?: 'tabs' | 'pills';
justified?: boolean;
}
export function NavTabs<T extends string | number = string>({
options,
selectedId,
onSelect = () => {},
disabled,
type = 'tabs',
justified = false,
}: Props<T>) {
const selected = options.find((option) => option.id === selectedId);
return (
<div>
<ul
className={clsx('nav', `nav-${type}`, { 'nav-justified': justified })}
>
{options.map(
(option) =>
!option.hidden && (
<li
className={clsx({
active: option.id === selectedId,
[styles.parent]: !option.children,
disabled,
})}
key={option.id}
>
{/* rule disabled because `nav-tabs` requires an anchor */}
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<Button
color="none"
onClick={() => handleSelect(option)}
as="a"
data-cy="nav-tab-button"
className="!flex"
icon={option.icon}
>
{option.label}
</Button>
</li>
)
)}
</ul>
{selected && selected.children && (
<div className="tab-content mt-3">{selected.children}</div>
)}
</div>
);
function handleSelect(option: Option<T>) {
if (disabled) {
return;
}
onSelect(option.id);
}
}