base
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import type { ISvgIcons } from "@plane/propel/icons";
|
||||
import { DropdownIcon } from "@plane/propel/icons";
|
||||
import { cn } from "../utils";
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
title: React.ReactNode;
|
||||
hideChevron?: boolean;
|
||||
indicatorElement?: React.ReactNode;
|
||||
actionItemElement?: React.ReactNode;
|
||||
className?: string;
|
||||
titleClassName?: string;
|
||||
ChevronIcon?: React.FC<ISvgIcons>;
|
||||
};
|
||||
|
||||
export function CollapsibleButton(props: Props) {
|
||||
const {
|
||||
isOpen,
|
||||
title,
|
||||
hideChevron = false,
|
||||
indicatorElement,
|
||||
actionItemElement,
|
||||
className = "",
|
||||
titleClassName = "",
|
||||
ChevronIcon = DropdownIcon,
|
||||
} = props;
|
||||
return (
|
||||
<div className={cn("flex h-12 items-center justify-between gap-3 border-b border-subtle px-2.5 py-3", className)}>
|
||||
<div className="flex items-center gap-3.5">
|
||||
<div className="flex items-center gap-3">
|
||||
{!hideChevron && (
|
||||
<ChevronIcon
|
||||
className={cn("size-2 text-tertiary duration-300 hover:text-secondary", {
|
||||
"-rotate-90": !isOpen,
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
<span className={cn("text-14 font-medium text-primary", titleClassName)}>{title}</span>
|
||||
</div>
|
||||
{indicatorElement && indicatorElement}
|
||||
</div>
|
||||
{actionItemElement && isOpen && actionItemElement}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import { Disclosure, Transition } from "@headlessui/react";
|
||||
import React, { useState, useEffect, useCallback } from "react";
|
||||
|
||||
export type TCollapsibleProps = {
|
||||
title: string | React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
buttonRef?: React.RefObject<HTMLButtonElement>;
|
||||
className?: string;
|
||||
buttonClassName?: string;
|
||||
isOpen?: boolean;
|
||||
onToggle?: () => void;
|
||||
defaultOpen?: boolean;
|
||||
};
|
||||
|
||||
export function Collapsible(props: TCollapsibleProps) {
|
||||
const { title, children, buttonRef, className, buttonClassName, isOpen, onToggle, defaultOpen } = props;
|
||||
// state
|
||||
const [localIsOpen, setLocalIsOpen] = useState<boolean>(isOpen || defaultOpen ? true : false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen !== undefined) {
|
||||
setLocalIsOpen(isOpen);
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
// handlers
|
||||
const handleOnClick = useCallback(() => {
|
||||
if (isOpen !== undefined) {
|
||||
if (onToggle) onToggle();
|
||||
} else {
|
||||
setLocalIsOpen((prev) => !prev);
|
||||
}
|
||||
}, [isOpen, onToggle]);
|
||||
|
||||
return (
|
||||
<Disclosure as="div" className={className}>
|
||||
<Disclosure.Button ref={buttonRef} className={buttonClassName} onClick={handleOnClick}>
|
||||
{title}
|
||||
</Disclosure.Button>
|
||||
<Transition
|
||||
show={localIsOpen}
|
||||
enter="transition-all duration-300 ease-in-out"
|
||||
enterFrom="grid-rows-[0fr] opacity-0"
|
||||
enterTo="grid-rows-[1fr] opacity-100"
|
||||
leave="transition-all duration-300 ease-in-out"
|
||||
leaveFrom="grid-rows-[1fr] opacity-100"
|
||||
leaveTo="grid-rows-[0fr] opacity-0"
|
||||
className="grid overflow-hidden"
|
||||
>
|
||||
<Disclosure.Panel static className="min-h-0">
|
||||
{children}
|
||||
</Disclosure.Panel>
|
||||
</Transition>
|
||||
</Disclosure>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./collapsible";
|
||||
export * from "./collapsible-button";
|
||||
Reference in New Issue
Block a user