dashpresshq/dashpress

View on GitHub
src/frontend/components/app/list-manager/list-manager-item/index.tsx

Summary

Maintainability
A
0 mins
Test Coverage
import type { MessageDescriptor } from "@lingui/core";
import { useId } from "react";
import { SortableKnob } from "react-easy-sort";

import { cn } from "@/components/utils";
import type { SystemIconsKeys } from "@/shared/constants/Icons";

import { FormButton } from "../../button/form";
import { FormSwitch } from "../../form/input/switch";
import { GrabIcon, SystemIcon } from "../../system-icons";

export interface IListMangerItemProps {
  label: string;
  systemIcon?: SystemIconsKeys;
  disabled?: boolean;
  sortable?: boolean;
  subtle?: boolean;
  toggle?: {
    selected: boolean;
    onChange: () => void;
  };
  actionButtons?: {
    id: string;
    isInverse: boolean;
    label: MessageDescriptor;
    systemIcon: SystemIconsKeys;
    onClick: () => void;
    isMakingRequest?: boolean;
    disabled?: boolean;
  }[];
}

export function ListManagerItem({
  label,
  systemIcon,
  disabled,
  toggle,
  sortable,
  subtle,
  actionButtons = [],
}: IListMangerItemProps) {
  const id = useId();
  const content = (
    <div className="flex w-full justify-between">
      <div className="flex items-center gap-3">
        <div
          className={cn("hidden", {
            block: sortable && !subtle,
          })}
        >
          <SortableKnob>
            <GrabIcon />
          </SortableKnob>
        </div>
        {systemIcon ? (
          <SystemIcon
            className={cn("size-4 text-main", {
              "text-muted": subtle,
            })}
            icon={systemIcon}
          />
        ) : null}{" "}
        <div>
          <label htmlFor={id}>
            <p
              className={cn("truncate text-sm text-main", {
                "text-muted": subtle,
              })}
            >
              {label}
            </p>
          </label>
        </div>
      </div>
      <div className="flex justify-end gap-3">
        {actionButtons.map(
          ({
            label: buttonLabel,
            isInverse,
            onClick: onClick$1,
            isMakingRequest,
            disabled: disabled$1,
            systemIcon: systemIcon$1,
          }) => (
            <FormButton
              key={buttonLabel.id}
              text={() => buttonLabel}
              size="sm"
              systemIcon={systemIcon$1}
              disabled={disabled$1}
              isMakingRequest={!!isMakingRequest}
              variant={isInverse ? "outline" : undefined}
              onClick={(event) => {
                event.preventDefault();
                event.stopPropagation();
                onClick$1();
              }}
            />
          )
        )}
        {toggle && (
          <FormSwitch
            name={id}
            onChange={toggle.onChange}
            value={toggle.selected}
          />
        )}
      </div>
    </div>
  );

  return (
    <div
      className={cn(
        "relative flex cursor-pointer items-center justify-between border-b border-border bg-base p-2 text-main hover:bg-hover",
        {
          "text-muted bg-base pointer-events-none": disabled,
        }
      )}
    >
      {content}
    </div>
  );
}