Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/components/ui/tables/ColumnSelector.tsx
T

88 lines
3.4 KiB
TypeScript

import { Transition } from "@headlessui/react";
import clsx from "clsx";
import { Fragment, useState } from "react";
import { useTranslation } from "react-i18next";
import { Form } from "react-router";
import { ColumnDto } from "~/application/dtos/data/ColumnDto";
import { useOuterClick } from "~/utils/shared/KeypressUtils";
import { updateItemByIdx } from "~/utils/shared/ObjectUtils";
import DotsHorizontalFilledIcon from "../icons/DotsHorizontalFilledIcon";
import InputCheckboxInline from "../input/InputCheckboxInline";
import { translateLabel } from "~/utils/i18n/translateLabel";
interface Props {
items: ColumnDto[];
setItems: React.Dispatch<React.SetStateAction<ColumnDto[]>>;
onClear: () => void;
className?: string;
}
export default function ColumnSelector({ items, setItems, onClear, className }: Props) {
const { t, i18n } = useTranslation();
const [opened, setOpened] = useState(false);
const clickOutside = useOuterClick(() => setOpened(false));
return (
<div ref={clickOutside} className={clsx("relative", className)}>
<button
type="button"
aria-label={t("shared.columns")}
onClick={() => setOpened(!opened)}
className="hover:bg-surface-neutral-secondary focus:border-border-default focus:shadow-focus relative z-0 inline-flex rounded-md text-sm shadow-2xs focus:z-10 focus:outline-hidden"
>
<span
className={clsx(
"border-border-default text-text-neutral-tertiary bg-surface-neutral-primary relative inline-flex items-center space-x-2 rounded-md border px-2 py-3 font-medium"
)}
>
<div>
<DotsHorizontalFilledIcon className="h-3 w-3" />
</div>
</span>
</button>
<Transition
as={Fragment}
show={opened}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Form
method="get"
className="divide-border-default bg-surface-neutral-primary absolute right-0 z-40 mt-2 w-64 origin-top-right divide-y overflow-visible rounded-md shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-hidden"
>
<div className="bg-surface-neutral-secondary flex items-center justify-between px-2 py-2 text-sm">
<div className="font-bold">{t("shared.columns")}</div>
</div>
<div className="divide-border-default divide-y text-sm">
{items.map((filter, idx) => {
return (
<div key={filter.name} className="divide-border-default divide-y">
<div className="divide-y divide-gray-300 px-2 py-2">
<InputCheckboxInline
name={filter.name}
title={translateLabel(t, i18n, filter.title)}
value={filter.visible}
setValue={(e) => {
updateItemByIdx(items, setItems, idx, {
visible: Boolean(e),
});
}}
/>
</div>
</div>
);
})}
</div>
</Form>
</Transition>
</div>
);
}