chore: icons tab interaction

This commit is contained in:
Aaryan Khandelwal 2024-02-17 23:26:42 +05:30
parent 41e812a811
commit bc60e7cb7f
5 changed files with 100 additions and 31 deletions

View File

@ -1,12 +1,13 @@
export * from "./avatar"; export * from "./avatar";
export * from "./breadcrumbs";
export * from "./badge"; export * from "./badge";
export * from "./breadcrumbs";
export * from "./button"; export * from "./button";
export * from "./control-link";
export * from "./dropdowns"; export * from "./dropdowns";
export * from "./form-fields"; export * from "./form-fields";
export * from "./icons"; export * from "./icons";
export * from "./progress"; export * from "./progress";
export * from "./spinners"; export * from "./spinners";
export * from "./tabs";
export * from "./tooltip"; export * from "./tooltip";
export * from "./loader"; export * from "./loader";
export * from "./control-link";

View File

@ -0,0 +1,84 @@
import React from "react";
// tooltip
import { Tooltip } from "../tooltip";
// helpers
import { cn } from "../../helpers";
export type TIconTabsProps = {
buttonClassName?: string;
containerClassName?: string;
hideTooltip?: boolean;
iconClassName?: string;
iconsList: {
key: string;
title: string;
icon: any;
}[];
onSelect: (key: string) => void;
overlayClassName?: string;
selectedKey: string | undefined;
};
export const IconTabs: React.FC<TIconTabsProps> = (props) => {
const {
buttonClassName,
containerClassName,
hideTooltip = false,
iconClassName,
iconsList,
onSelect,
overlayClassName,
selectedKey,
} = props;
const selectedTabIndex = iconsList.findIndex((icon) => icon.key === selectedKey);
return (
<div className={cn("relative flex items-center rounded-[5px] bg-custom-background-80 p-[2px]", containerClassName)}>
<div
className={cn(
"absolute z-0 bg-custom-background-100 top-1/2 rounded-[3px] transition-all duration-500 ease-in-out",
{
// right shadow
"shadow-[2px_0_8px_rgba(167,169,174,0.15)]": selectedTabIndex !== iconsList.length - 1,
// left shadow
"shadow-[-2px_0_8px_rgba(167,169,174,0.15)]": selectedTabIndex !== 0,
},
overlayClassName
)}
style={{
height: "calc(100% - 4px)",
width: `calc((100% - 4px)/${iconsList.length})`,
transform: `translate(${selectedTabIndex * 100}%, -50%)`,
}}
/>
{iconsList.map((icon) => (
<Tooltip key={icon.key} tooltipContent={icon.title} disabled={hideTooltip}>
<button
type="button"
className={cn(
"relative grid h-[22px] w-7 place-items-center overflow-hidden rounded-[3px] transition-all z-[1] text-custom-text-200",
{
"text-custom-text-100": selectedKey == icon.key,
},
buttonClassName
)}
onClick={() => onSelect(icon.key)}
>
<icon.icon
size={14}
strokeWidth={2}
className={cn(
"h-3.5 w-3.5 text-custom-text-200",
{
"text-custom-text-100": selectedKey == icon.key,
},
iconClassName
)}
/>
</button>
</Tooltip>
))}
</div>
);
};

View File

@ -0,0 +1 @@
export * from "./icon-tabs";

View File

@ -1,7 +1,6 @@
import React from "react"; import React from "react";
// ui // ui
import { Tooltip } from "@plane/ui"; import { IconTabs } from "@plane/ui";
// types // types
import { TIssueLayouts } from "@plane/types"; import { TIssueLayouts } from "@plane/types";
// constants // constants
@ -17,26 +16,10 @@ export const LayoutSelection: React.FC<Props> = (props) => {
const { layouts, onChange, selectedLayout } = props; const { layouts, onChange, selectedLayout } = props;
return ( return (
<div className="flex items-center gap-1 rounded bg-custom-background-80 p-1"> <IconTabs
{ISSUE_LAYOUTS.filter((l) => layouts.includes(l.key)).map((layout) => ( iconsList={ISSUE_LAYOUTS.filter((l) => layouts.includes(l.key))}
<Tooltip key={layout.key} tooltipContent={layout.title}> onSelect={(key) => onChange(key as TIssueLayouts)}
<button selectedKey={selectedLayout}
type="button"
className={`group grid h-[22px] w-7 place-items-center overflow-hidden rounded transition-all hover:bg-custom-background-100 ${
selectedLayout == layout.key ? "bg-custom-background-100 shadow-custom-shadow-2xs" : ""
}`}
onClick={() => onChange(layout.key)}
>
<layout.icon
size={14}
strokeWidth={2}
className={`h-3.5 w-3.5 ${
selectedLayout == layout.key ? "text-custom-text-100" : "text-custom-text-200"
}`}
/> />
</button>
</Tooltip>
))}
</div>
); );
}; };

View File

@ -131,11 +131,11 @@ export const ISSUE_LAYOUTS: {
title: string; title: string;
icon: any; icon: any;
}[] = [ }[] = [
{ key: "list", title: "List Layout", icon: List }, { key: "list", title: "List layout", icon: List },
{ key: "kanban", title: "Kanban Layout", icon: Kanban }, { key: "kanban", title: "Kanban layout", icon: Kanban },
{ key: "calendar", title: "Calendar Layout", icon: Calendar }, { key: "calendar", title: "Calendar layout", icon: Calendar },
{ key: "spreadsheet", title: "Spreadsheet Layout", icon: Sheet }, { key: "spreadsheet", title: "Spreadsheet layout", icon: Sheet },
{ key: "gantt_chart", title: "Gantt Chart Layout", icon: GanttChartSquare }, { key: "gantt_chart", title: "Gantt Chart layout", icon: GanttChartSquare },
]; ];
export const ISSUE_LIST_FILTERS = [ export const ISSUE_LIST_FILTERS = [