Skip to content

Commit

Permalink
feat(theme): accordion theme component
Browse files Browse the repository at this point in the history
  • Loading branch information
Ricardo Lüders committed Dec 23, 2022
1 parent 32f337b commit 53a0771
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 34 deletions.
12 changes: 8 additions & 4 deletions src/lib/components/Accordion/Accordion.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ describe('Components / Accordion', () => {
it('should use custom `base` classes', () => {
const theme = {
accordion: {
base: 'text-4xl',
root: {
base: 'text-4xl',
},
},
};

Expand All @@ -131,9 +133,11 @@ describe('Components / Accordion', () => {
it('should use custom `flush` classes', () => {
const theme = {
accordion: {
flush: {
off: 'text-4xl',
on: 'text-3xl',
root: {
flush: {
off: 'text-4xl',
on: 'text-3xl',
},
},
},
};
Expand Down
33 changes: 14 additions & 19 deletions src/lib/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,32 @@ import classNames from 'classnames';
import type { ComponentProps, FC, PropsWithChildren, ReactElement } from 'react';
import { Children, cloneElement, useMemo, useState } from 'react';
import { HiChevronDown } from 'react-icons/hi';
import { DeepPartial } from '..';
import { mergeDeep } from '../../helpers/mergeDeep';
import { FlowbiteBoolean } from '../Flowbite/FlowbiteTheme';
import { useTheme } from '../Flowbite/ThemeContext';
import { AccordionContent } from './AccordionContent';
import { AccordionContent, FlowbiteAccordionComponentTheme } from './AccordionContent';
import type { AccordionPanelProps } from './AccordionPanel';
import { AccordionPanel } from './AccordionPanel';
import { AccordionTitle } from './AccordionTitle';
import { AccordionTitle, FlowbiteAccordionTitleTheme } from './AccordionTitle';

export interface FlowbiteAccordionTheme {
root: FlowbiteAccordionRootTheme;
content: FlowbiteAccordionComponentTheme;
title: FlowbiteAccordionTitleTheme;
}

export interface FlowbiteAccordionRootTheme {
base: string;
content: {
base: string;
};
flush: FlowbiteBoolean;
title: {
arrow: {
base: string;
open: {
off: string;
on: string;
};
};
base: string;
flush: FlowbiteBoolean;
heading: string;
open: FlowbiteBoolean;
};
}

export interface AccordionProps extends PropsWithChildren<ComponentProps<'div'>> {
alwaysOpen?: boolean;
arrowIcon?: FC<ComponentProps<'svg'>>;
children: ReactElement<AccordionPanelProps> | ReactElement<AccordionPanelProps>[];
flush?: boolean;
theme?: DeepPartial<FlowbiteAccordionTheme>;
}

const AccordionComponent: FC<AccordionProps> = ({
Expand All @@ -43,6 +36,7 @@ const AccordionComponent: FC<AccordionProps> = ({
children,
flush = false,
className,
theme: customTheme = {},
...props
}): JSX.Element => {
const [isOpen, setOpen] = useState(0);
Expand All @@ -53,7 +47,8 @@ const AccordionComponent: FC<AccordionProps> = ({
),
[alwaysOpen, arrowIcon, children, flush, isOpen],
);
const theme = useTheme().theme.accordion;

const theme = mergeDeep(useTheme().theme.accordion.root, customTheme);

return (
<div
Expand Down
22 changes: 19 additions & 3 deletions src/lib/components/Accordion/AccordionContent.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import classNames from 'classnames';
import type { ComponentProps, FC } from 'react';
import type { ComponentProps, FC, PropsWithChildren } from 'react';
import { DeepPartial } from '..';
import { mergeDeep } from '../../helpers/mergeDeep';
import { useTheme } from '../Flowbite/ThemeContext';
import { useAccordionContext } from './AccordionPanelContext';

export const AccordionContent: FC<ComponentProps<'div'>> = ({ children, className, ...props }): JSX.Element => {
export interface FlowbiteAccordionComponentTheme {
base: string;
}

export interface AccordionContentProps extends PropsWithChildren<ComponentProps<'div'>> {
theme?: DeepPartial<FlowbiteAccordionComponentTheme>;
}

export const AccordionContent: FC<AccordionContentProps> = ({
children,
className,
theme: customTheme = {},
...props
}): JSX.Element => {
const { isOpen } = useAccordionContext();
const theme = useTheme().theme.accordion.content;

const theme = mergeDeep(useTheme().theme.accordion.content, customTheme);

return (
<div
Expand Down
24 changes: 21 additions & 3 deletions src/lib/components/Accordion/AccordionTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,43 @@
import classNames from 'classnames';
import type { ComponentProps, FC } from 'react';
import type { FlowbiteHeadingLevel } from '../Flowbite/FlowbiteTheme';
import { DeepPartial } from '..';
import { mergeDeep } from '../../helpers/mergeDeep';
import type { FlowbiteBoolean, FlowbiteHeadingLevel } from '../Flowbite/FlowbiteTheme';
import { useTheme } from '../Flowbite/ThemeContext';
import { useAccordionContext } from './AccordionPanelContext';

export interface FlowbiteAccordionTitleTheme {
arrow: {
base: string;
open: {
off: string;
on: string;
};
};
base: string;
flush: FlowbiteBoolean;
heading: string;
open: FlowbiteBoolean;
}

export interface AccordionTitleProps extends ComponentProps<'button'> {
arrowIcon?: FC<ComponentProps<'svg'>>;
as?: FlowbiteHeadingLevel;
theme?: DeepPartial<FlowbiteAccordionTitleTheme>;
}

export const AccordionTitle: FC<AccordionTitleProps> = ({
as: Heading = 'h2',
children,
className,
theme: customTheme = {},
...props
}): JSX.Element => {
const { arrowIcon: ArrowIcon, flush, isOpen, setOpen } = useAccordionContext();
const theme = useTheme().theme.accordion.title;

const onClick = () => typeof setOpen !== 'undefined' && setOpen();

const theme = mergeDeep(useTheme().theme.accordion.title, customTheme);

return (
<button
className={classNames(
Expand Down
12 changes: 7 additions & 5 deletions src/lib/theme/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ import type { FlowbiteTheme } from '../components';

const theme: FlowbiteTheme = {
accordion: {
base: 'divide-y divide-gray-200 border-gray-200 dark:divide-gray-700 dark:border-gray-700',
root: {
base: 'divide-y divide-gray-200 border-gray-200 dark:divide-gray-700 dark:border-gray-700',
flush: {
off: 'rounded-lg border',
on: 'border-b',
},
},
content: {
base: 'py-5 px-5 last:rounded-b-lg dark:bg-gray-900 first:rounded-t-lg',
},
flush: {
off: 'rounded-lg border',
on: 'border-b',
},
title: {
arrow: {
base: 'h-6 w-6 shrink-0',
Expand Down

0 comments on commit 53a0771

Please sign in to comment.