From 5e7988f0a32bef4aadb13513b3c7f91a9f05453f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20L=C3=BCders?= Date: Mon, 31 Jul 2023 15:06:06 +0200 Subject: [PATCH] feat(sidebar): add custom chevron icon to collapse --- app/docs/components/sidebar/sidebar.mdx | 100 ++++++++++++++++++++- src/components/Sidebar/Sidebar.spec.tsx | 8 +- src/components/Sidebar/SidebarCollapse.tsx | 20 ++++- src/components/Sidebar/theme.ts | 8 +- 4 files changed, 130 insertions(+), 6 deletions(-) diff --git a/app/docs/components/sidebar/sidebar.mdx b/app/docs/components/sidebar/sidebar.mdx index 96298ddb52..9d99035bc8 100644 --- a/app/docs/components/sidebar/sidebar.mdx +++ b/app/docs/components/sidebar/sidebar.mdx @@ -1,5 +1,16 @@ import { BiBuoy } from 'react-icons/bi'; -import { HiArrowSmRight, HiChartPie, HiInbox, HiShoppingBag, HiTable, HiUser, HiViewBoards } from 'react-icons/hi'; +import { + HiOutlineMinusSm, + HiOutlinePlusSm, + HiArrowSmRight, + HiChartPie, + HiInbox, + HiShoppingBag, + HiTable, + HiUser, + HiViewBoards, +} from 'react-icons/hi'; +import { twMerge } from 'tailwind-merge'; import { CodePreview } from '~/app/components/code-preview'; import { Badge, Sidebar, theme } from '~/src'; @@ -98,6 +109,93 @@ Use this example to learn how to stack multiple sidebar menu items inside one dr +## Multi-level dropdown with custom chevron + +The `chevronIcon` property offers customization for the chevron icon. Alternatively, for more complex scenarios, the `renderChevronIcon` option can be utilized. Here's an example: + + + + + + Dashboard + + { + const IconComponent = open ? HiOutlineMinusSm : HiOutlinePlusSm; + return + }} + > + Products + Sales + Refunds + Shipping + + + Inbox + + + Users + + + Products + + + Sign In + + + Sign Up + + + + `} +> + + + + + Dashboard + + { + const IconComponent = open ? HiOutlineMinusSm : HiOutlinePlusSm; + return ; + }} + > + Products + Sales + Refunds + Shipping + + + Inbox + + + Users + + + Products + + + Sign In + + + Sign Up + + + + + + ## Content separator Use this example to separate content inside of the sidebar using a horizontal line. diff --git a/src/components/Sidebar/Sidebar.spec.tsx b/src/components/Sidebar/Sidebar.spec.tsx index f853e0deac..3b8fd0cd12 100644 --- a/src/components/Sidebar/Sidebar.spec.tsx +++ b/src/components/Sidebar/Sidebar.spec.tsx @@ -169,7 +169,13 @@ describe('Theme', () => { }, label: { base: 'text-gray-300', - icon: 'text-gray-400', + icon: { + base: 'text-gray-400', + open: { + on: '', + off: '', + }, + }, }, list: 'bg-gray-300', }, diff --git a/src/components/Sidebar/SidebarCollapse.tsx b/src/components/Sidebar/SidebarCollapse.tsx index 098a6febf8..0954168428 100644 --- a/src/components/Sidebar/SidebarCollapse.tsx +++ b/src/components/Sidebar/SidebarCollapse.tsx @@ -1,4 +1,4 @@ -import type { ComponentProps, FC, PropsWithChildren } from 'react'; +import type { ComponentProps, FC, PropsWithChildren, ReactElement } from 'react'; import { useEffect, useId, useState } from 'react'; import { HiChevronDown } from 'react-icons/hi'; import { twMerge } from 'tailwind-merge'; @@ -17,7 +17,10 @@ export interface FlowbiteSidebarCollapseTheme { }; label: { base: string; - icon: string; + icon: { + base: string; + open: FlowbiteBoolean; + }; }; list: string; } @@ -28,6 +31,8 @@ export interface SidebarCollapseProps ComponentProps<'button'> { onClick?: ComponentProps<'button'>['onClick']; open?: boolean; + chevronIcon?: FC>; + renderChevronIcon?: (theme: DeepPartial, open: boolean) => ReactElement; theme?: DeepPartial; } @@ -36,6 +41,8 @@ export const SidebarCollapse: FC = ({ className, icon: Icon, label, + chevronIcon: ChevronIcon = HiChevronDown, + renderChevronIcon, open = false, theme: customTheme = {}, ...props @@ -83,7 +90,14 @@ export const SidebarCollapse: FC = ({ {label} - + {renderChevronIcon ? ( + renderChevronIcon(theme, isOpen) + ) : ( + + )} )} diff --git a/src/components/Sidebar/theme.ts b/src/components/Sidebar/theme.ts index 41da84da64..d61b367921 100644 --- a/src/components/Sidebar/theme.ts +++ b/src/components/Sidebar/theme.ts @@ -21,7 +21,13 @@ export const sidebarTheme: FlowbiteSidebarTheme = { }, label: { base: 'ml-3 flex-1 whitespace-nowrap text-left', - icon: 'h-6 w-6', + icon: { + base: 'h-6 w-6 transition ease-in-out delay-0', + open: { + on: 'rotate-180', + off: '', + }, + }, }, list: 'space-y-2 py-2', },