Skip to content

Commit aab07f5

Browse files
author
Ricardo Lüders
committed
feat(theme): accordion theme component
1 parent 32f337b commit aab07f5

File tree

5 files changed

+69
-34
lines changed

5 files changed

+69
-34
lines changed

src/lib/components/Accordion/Accordion.spec.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ describe('Components / Accordion', () => {
115115
it('should use custom `base` classes', () => {
116116
const theme = {
117117
accordion: {
118-
base: 'text-4xl',
118+
root: {
119+
base: 'text-4xl',
120+
},
119121
},
120122
};
121123

@@ -131,9 +133,11 @@ describe('Components / Accordion', () => {
131133
it('should use custom `flush` classes', () => {
132134
const theme = {
133135
accordion: {
134-
flush: {
135-
off: 'text-4xl',
136-
on: 'text-3xl',
136+
root: {
137+
flush: {
138+
off: 'text-4xl',
139+
on: 'text-3xl',
140+
},
137141
},
138142
},
139143
};

src/lib/components/Accordion/Accordion.tsx

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,32 @@ import classNames from 'classnames';
22
import type { ComponentProps, FC, PropsWithChildren, ReactElement } from 'react';
33
import { Children, cloneElement, useMemo, useState } from 'react';
44
import { HiChevronDown } from 'react-icons/hi';
5+
import { DeepPartial } from '..';
6+
import { mergeDeep } from '../../helpers/mergeDeep';
57
import { FlowbiteBoolean } from '../Flowbite/FlowbiteTheme';
68
import { useTheme } from '../Flowbite/ThemeContext';
7-
import { AccordionContent } from './AccordionContent';
9+
import { AccordionContent, FlowbiteAccordionComponentTheme } from './AccordionContent';
810
import type { AccordionPanelProps } from './AccordionPanel';
911
import { AccordionPanel } from './AccordionPanel';
10-
import { AccordionTitle } from './AccordionTitle';
12+
import { AccordionTitle, FlowbiteAccordionTitleTheme } from './AccordionTitle';
1113

1214
export interface FlowbiteAccordionTheme {
15+
root: FlowbiteAccordionRootTheme;
16+
content: FlowbiteAccordionComponentTheme;
17+
title: FlowbiteAccordionTitleTheme;
18+
}
19+
20+
export interface FlowbiteAccordionRootTheme {
1321
base: string;
14-
content: {
15-
base: string;
16-
};
1722
flush: FlowbiteBoolean;
18-
title: {
19-
arrow: {
20-
base: string;
21-
open: {
22-
off: string;
23-
on: string;
24-
};
25-
};
26-
base: string;
27-
flush: FlowbiteBoolean;
28-
heading: string;
29-
open: FlowbiteBoolean;
30-
};
3123
}
3224

3325
export interface AccordionProps extends PropsWithChildren<ComponentProps<'div'>> {
3426
alwaysOpen?: boolean;
3527
arrowIcon?: FC<ComponentProps<'svg'>>;
3628
children: ReactElement<AccordionPanelProps> | ReactElement<AccordionPanelProps>[];
3729
flush?: boolean;
30+
theme?: DeepPartial<FlowbiteAccordionRootTheme>;
3831
}
3932

4033
const AccordionComponent: FC<AccordionProps> = ({
@@ -43,6 +36,7 @@ const AccordionComponent: FC<AccordionProps> = ({
4336
children,
4437
flush = false,
4538
className,
39+
theme: customTheme = {},
4640
...props
4741
}): JSX.Element => {
4842
const [isOpen, setOpen] = useState(0);
@@ -53,7 +47,8 @@ const AccordionComponent: FC<AccordionProps> = ({
5347
),
5448
[alwaysOpen, arrowIcon, children, flush, isOpen],
5549
);
56-
const theme = useTheme().theme.accordion;
50+
51+
const theme = mergeDeep(useTheme().theme.accordion.root, customTheme);
5752

5853
return (
5954
<div

src/lib/components/Accordion/AccordionContent.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
11
import classNames from 'classnames';
2-
import type { ComponentProps, FC } from 'react';
2+
import type { ComponentProps, FC, PropsWithChildren } from 'react';
3+
import { DeepPartial } from '..';
4+
import { mergeDeep } from '../../helpers/mergeDeep';
35
import { useTheme } from '../Flowbite/ThemeContext';
46
import { useAccordionContext } from './AccordionPanelContext';
57

6-
export const AccordionContent: FC<ComponentProps<'div'>> = ({ children, className, ...props }): JSX.Element => {
8+
export interface FlowbiteAccordionComponentTheme {
9+
base: string;
10+
}
11+
12+
export interface AccordionContentProps extends PropsWithChildren<ComponentProps<'div'>> {
13+
theme?: DeepPartial<FlowbiteAccordionComponentTheme>;
14+
}
15+
16+
export const AccordionContent: FC<AccordionContentProps> = ({
17+
children,
18+
className,
19+
theme: customTheme = {},
20+
...props
21+
}): JSX.Element => {
722
const { isOpen } = useAccordionContext();
8-
const theme = useTheme().theme.accordion.content;
23+
24+
const theme = mergeDeep(useTheme().theme.accordion.content, customTheme);
925

1026
return (
1127
<div

src/lib/components/Accordion/AccordionTitle.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,43 @@
11
import classNames from 'classnames';
22
import type { ComponentProps, FC } from 'react';
3-
import type { FlowbiteHeadingLevel } from '../Flowbite/FlowbiteTheme';
3+
import { DeepPartial } from '..';
4+
import { mergeDeep } from '../../helpers/mergeDeep';
5+
import type { FlowbiteBoolean, FlowbiteHeadingLevel } from '../Flowbite/FlowbiteTheme';
46
import { useTheme } from '../Flowbite/ThemeContext';
57
import { useAccordionContext } from './AccordionPanelContext';
68

9+
export interface FlowbiteAccordionTitleTheme {
10+
arrow: {
11+
base: string;
12+
open: {
13+
off: string;
14+
on: string;
15+
};
16+
};
17+
base: string;
18+
flush: FlowbiteBoolean;
19+
heading: string;
20+
open: FlowbiteBoolean;
21+
}
22+
723
export interface AccordionTitleProps extends ComponentProps<'button'> {
824
arrowIcon?: FC<ComponentProps<'svg'>>;
925
as?: FlowbiteHeadingLevel;
26+
theme?: DeepPartial<FlowbiteAccordionTitleTheme>;
1027
}
1128

1229
export const AccordionTitle: FC<AccordionTitleProps> = ({
1330
as: Heading = 'h2',
1431
children,
1532
className,
33+
theme: customTheme = {},
1634
...props
1735
}): JSX.Element => {
1836
const { arrowIcon: ArrowIcon, flush, isOpen, setOpen } = useAccordionContext();
19-
const theme = useTheme().theme.accordion.title;
20-
2137
const onClick = () => typeof setOpen !== 'undefined' && setOpen();
2238

39+
const theme = mergeDeep(useTheme().theme.accordion.title, customTheme);
40+
2341
return (
2442
<button
2543
className={classNames(

src/lib/theme/default.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import type { FlowbiteTheme } from '../components';
22

33
const theme: FlowbiteTheme = {
44
accordion: {
5-
base: 'divide-y divide-gray-200 border-gray-200 dark:divide-gray-700 dark:border-gray-700',
5+
root: {
6+
base: 'divide-y divide-gray-200 border-gray-200 dark:divide-gray-700 dark:border-gray-700',
7+
flush: {
8+
off: 'rounded-lg border',
9+
on: 'border-b',
10+
},
11+
},
612
content: {
713
base: 'py-5 px-5 last:rounded-b-lg dark:bg-gray-900 first:rounded-t-lg',
814
},
9-
flush: {
10-
off: 'rounded-lg border',
11-
on: 'border-b',
12-
},
1315
title: {
1416
arrow: {
1517
base: 'h-6 w-6 shrink-0',

0 commit comments

Comments
 (0)