Skip to content

Commit

Permalink
refactor: replace classNames with twMerge
Browse files Browse the repository at this point in the history
  • Loading branch information
Ricardo Lüders committed Jun 8, 2023
1 parent 43859b4 commit 04aa4a2
Show file tree
Hide file tree
Showing 80 changed files with 225 additions and 283 deletions.
9 changes: 5 additions & 4 deletions src/components/Accordion/Accordion.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,9 @@ describe('Components / Accordion', () => {
on: 'text-3xl',
},
open: {
off: 'text-gray-400',
on: 'text-gray-600',
// FIXME Overwrite class from other props is a problem
off: '!text-gray-400',
on: '!text-gray-600',
},
},
},
Expand Down Expand Up @@ -244,10 +245,10 @@ describe('Components / Accordion', () => {
expect(title).toHaveClass('text-3xl');
});
openTitles.forEach((title) => {
expect(title).toHaveClass('text-gray-600');
expect(title).toHaveClass('!text-gray-600');
});
closedTitles.forEach((title) => {
expect(title).toHaveClass('text-gray-400');
expect(title).toHaveClass('!text-gray-400');
});
});
});
Expand Down
4 changes: 2 additions & 2 deletions src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
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 { twMerge } from 'tailwind-merge';
import type { DeepPartial, FlowbiteBoolean } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand Down Expand Up @@ -62,7 +62,7 @@ const AccordionComponent: FC<AccordionProps> = ({

return (
<div
className={classNames(theme.base, theme.flush[flush ? 'on' : 'off'], className)}
className={twMerge(theme.base, theme.flush[flush ? 'on' : 'off'], className)}
data-testid="flowbite-accordion"
{...props}
>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Accordion/AccordionContent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from 'classnames';
import type { ComponentProps, FC, PropsWithChildren } from 'react';
import { twMerge } from 'tailwind-merge';
import type { DeepPartial } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand All @@ -25,7 +25,7 @@ export const AccordionContent: FC<AccordionContentProps> = ({

return (
<div
className={classNames(theme.base, className)}
className={twMerge(theme.base, className)}
data-testid="flowbite-accordion-content"
hidden={!isOpen}
{...props}
Expand Down
11 changes: 3 additions & 8 deletions src/components/Accordion/AccordionTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from 'classnames';
import type { ComponentProps, FC } from 'react';
import { twMerge } from 'tailwind-merge';
import type { DeepPartial, FlowbiteBoolean, FlowbiteHeadingLevel } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand Down Expand Up @@ -36,12 +36,7 @@ export const AccordionTitle: FC<AccordionTitleProps> = ({

return (
<button
className={classNames(
theme.base,
theme.flush[flush ? 'on' : 'off'],
theme.open[isOpen ? 'on' : 'off'],
className,
)}
className={twMerge(theme.base, theme.flush[flush ? 'on' : 'off'], theme.open[isOpen ? 'on' : 'off'], className)}
onClick={onClick}
type="button"
{...props}
Expand All @@ -52,7 +47,7 @@ export const AccordionTitle: FC<AccordionTitleProps> = ({
{ArrowIcon && (
<ArrowIcon
aria-hidden
className={classNames(theme.arrow.base, theme.arrow.open[isOpen ? 'on' : 'off'])}
className={twMerge(theme.arrow.base, theme.arrow.open[isOpen ? 'on' : 'off'])}
data-testid="flowbite-accordion-arrow"
/>
)}
Expand Down
4 changes: 3 additions & 1 deletion src/components/Alert/Alert.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ describe.concurrent('Components / Alert', () => {
it('should use custom `base` classes', () => {
const theme = {
alert: {
base: 'text-purple-100',
color: {
info: 'text-purple-100',
},
},
};
render(
Expand Down
6 changes: 3 additions & 3 deletions src/components/Alert/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import classNames from 'classnames';
import type { ComponentProps, FC, PropsWithChildren, ReactNode } from 'react';
import { HiX } from 'react-icons/hi';
import { twMerge } from 'tailwind-merge';
import type { DeepPartial, FlowbiteColors } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand Down Expand Up @@ -47,7 +47,7 @@ export const Alert: FC<AlertProps> = ({

return (
<div
className={classNames(
className={twMerge(
theme.base,
theme.color[color],
rounded && theme.rounded,
Expand All @@ -63,7 +63,7 @@ export const Alert: FC<AlertProps> = ({
{typeof onDismiss === 'function' && (
<button
aria-label="Dismiss"
className={classNames(theme.closeButton.base, theme.closeButton.color[color])}
className={twMerge(theme.closeButton.base, theme.closeButton.color[color])}
onClick={onDismiss}
type="button"
>
Expand Down
19 changes: 8 additions & 11 deletions src/components/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from 'classnames';
import type { ComponentProps, FC, PropsWithChildren, ReactElement } from 'react';
import { twMerge } from 'tailwind-merge';
import type { DeepPartial, FlowbiteBoolean, FlowbiteColors, FlowbitePositions, FlowbiteSizes } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand Down Expand Up @@ -91,7 +91,7 @@ const AvatarComponent: FC<AvatarProps> = ({
}) => {
const theme = mergeDeep(useTheme().theme.avatar, customTheme);

const imgClassName = classNames(
const imgClassName = twMerge(
bordered && theme.root.bordered,
bordered && theme.root.color[color],
rounded && theme.root.rounded,
Expand All @@ -101,11 +101,11 @@ const AvatarComponent: FC<AvatarProps> = ({
);

const imgProps = {
className: classNames(imgClassName, theme.root.img.on),
className: twMerge(imgClassName, theme.root.img.on),
'data-testid': 'flowbite-avatar-img',
};
return (
<div className={classNames(theme.root.base, className)} data-testid="flowbite-avatar" {...props}>
<div className={twMerge(theme.root.base, className)} data-testid="flowbite-avatar" {...props}>
<div className="relative">
{img ? (
typeof img === 'string' ? (
Expand All @@ -115,7 +115,7 @@ const AvatarComponent: FC<AvatarProps> = ({
)
) : placeholderInitials ? (
<div
className={classNames(
className={twMerge(
theme.root.img.off,
theme.root.initials.base,
rounded && theme.root.rounded,
Expand All @@ -126,15 +126,12 @@ const AvatarComponent: FC<AvatarProps> = ({
)}
data-testid="flowbite-avatar-initials-placeholder"
>
<span
className={classNames(theme.root.initials.text)}
data-testid="flowbite-avatar-initials-placeholder-text"
>
<span className={twMerge(theme.root.initials.text)} data-testid="flowbite-avatar-initials-placeholder-text">
{placeholderInitials}
</span>
</div>
) : (
<div className={classNames(imgClassName, theme.root.img.off)} data-testid="flowbite-avatar-img">
<div className={twMerge(imgClassName, theme.root.img.off)} data-testid="flowbite-avatar-img">
<svg
className={theme.root.img.placeholder}
fill="currentColor"
Expand All @@ -148,7 +145,7 @@ const AvatarComponent: FC<AvatarProps> = ({
{status && (
<span
data-testid="flowbite-avatar-status"
className={classNames(
className={twMerge(
theme.root.status.base,
theme.root.status[status],
theme.root.statusPosition[statusPosition],
Expand Down
4 changes: 2 additions & 2 deletions src/components/Avatar/AvatarGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import classNames from 'classnames';
import type { ComponentProps, PropsWithChildren } from 'react';
import React from 'react';
import { twMerge } from 'tailwind-merge';
import type { DeepPartial } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand All @@ -17,7 +17,7 @@ export const AvatarGroup: React.FC<AvatarGroupProps> = ({ children, className, t
const theme = mergeDeep(useTheme().theme.avatar.group, customTheme);

return (
<div data-testid="avatar-group-element" className={classNames(theme.base, className)} {...props}>
<div data-testid="avatar-group-element" className={twMerge(theme.base, className)} {...props}>
{children}
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/Avatar/AvatarGroupCounter.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from 'classnames';
import type { ComponentProps, FC, PropsWithChildren } from 'react';
import { twMerge } from 'tailwind-merge';
import type { DeepPartial } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand All @@ -23,7 +23,7 @@ export const AvatarGroupCounter: FC<AvatarGroupCounterProps> = ({
const theme = mergeDeep(useTheme().theme.avatar.groupCounter, customTheme);

return (
<a href={href} className={classNames(theme.base, className)} {...props}>
<a href={href} className={twMerge(theme.base, className)} {...props}>
+{total}
</a>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/Breadcrumb/Breadcrumb.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from 'classnames';
import type { ComponentProps, FC } from 'react';
import { twMerge } from 'tailwind-merge';
import type { DeepPartial } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand Down Expand Up @@ -29,7 +29,7 @@ const BreadcrumbComponent: FC<BreadcrumbComponentProps> = ({
const theme = mergeDeep(useTheme().theme.breadcrumb.root, customTheme);

return (
<nav aria-label="Breadcrumb" className={classNames(theme.base, className)} {...props}>
<nav aria-label="Breadcrumb" className={twMerge(theme.base, className)} {...props}>
<ol className={theme.list}>{children}</ol>
</nav>
);
Expand Down
4 changes: 2 additions & 2 deletions src/components/Breadcrumb/BreadcrumbItem.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import classNames from 'classnames';
import type { ComponentProps, FC, PropsWithChildren } from 'react';
import { forwardRef } from 'react';
import { HiOutlineChevronRight } from 'react-icons/hi';
import { twMerge } from 'tailwind-merge';
import type { DeepPartial, FlowbiteBoolean } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand All @@ -27,7 +27,7 @@ export const BreadcrumbItem = forwardRef<HTMLAnchorElement | HTMLSpanElement, Br
const theme = mergeDeep(useTheme().theme.breadcrumb.item, customTheme);

return (
<li className={classNames(theme.base, className)} {...props}>
<li className={twMerge(theme.base, className)} {...props}>
<HiOutlineChevronRight aria-hidden className={theme.chevron} data-testid="flowbite-breadcrumb-separator" />
<Component
ref={ref as never}
Expand Down
18 changes: 10 additions & 8 deletions src/components/Button/Button.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ describe('Components / Button', () => {
const theme = {
button: {
color: {
primary: 'font-extralight',
primary: 'bg-red-300',
},
},
};
Expand All @@ -137,13 +137,13 @@ describe('Components / Button', () => {
</Flowbite>,
);

expect(button()).toHaveClass('font-extralight');
expect(button()).toHaveClass('bg-red-300');
});

it('should use `disabled` classes', () => {
const theme = {
button: {
disabled: 'font-extralight',
disabled: 'opacity-10',
},
};

Expand All @@ -153,14 +153,15 @@ describe('Components / Button', () => {
</Flowbite>,
);

expect(button()).toHaveClass('font-extralight');
expect(button()).toHaveClass('opacity-10');
});

it('should use `gradient` classes', () => {
const theme = {
button: {
gradient: {
yellowToPink: 'font-extralight',
// FIXME Overwrite class from other props is a problem
yellowToPink: '!font-extralight',
},
},
};
Expand All @@ -171,14 +172,15 @@ describe('Components / Button', () => {
</Flowbite>,
);

expect(button()).toHaveClass('font-extralight');
expect(button()).toHaveClass('!font-extralight');
});

it('should use `gradientDuoTone` classes', () => {
const theme = {
button: {
gradientDuoTone: {
yellowToPink: 'font-extralight',
// FIXME Overwrite class from other props is a problem
yellowToPink: '!font-extralight',
},
},
};
Expand All @@ -189,7 +191,7 @@ describe('Components / Button', () => {
</Flowbite>,
);

expect(button()).toHaveClass('font-extralight');
expect(button()).toHaveClass('!font-extralight');
});

it('should use `inner` classes', () => {
Expand Down
10 changes: 5 additions & 5 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import classNames from 'classnames';
import { forwardRef, type ComponentProps, type ReactNode } from 'react';
import { twMerge } from 'tailwind-merge';
import type {
DeepPartial,
FlowbiteBoolean,
Expand Down Expand Up @@ -116,7 +116,7 @@ const ButtonComponent = forwardRef<HTMLButtonElement | HTMLAnchorElement, Button
href={href}
type={isLink ? undefined : 'button'}
ref={ref as never}
className={classNames(
className={twMerge(
disabled && theme.disabled,
!gradientDuoTone && !gradientMonochrome && theme.color[color],
gradientDuoTone && !gradientMonochrome && theme.gradientDuoTone[gradientDuoTone],
Expand All @@ -131,7 +131,7 @@ const ButtonComponent = forwardRef<HTMLButtonElement | HTMLAnchorElement, Button
{...theirProps}
>
<span
className={classNames(
className={twMerge(
theme.inner.base,
theme.inner.position[positionInGroup],
theme.outline[outline ? 'on' : 'off'],
Expand All @@ -142,11 +142,11 @@ const ButtonComponent = forwardRef<HTMLButtonElement | HTMLAnchorElement, Button
)}
>
<>
{isProcessing && <span className={theme.spinnerSlot}>{SpinnerComponent}</span>}
{isProcessing && <span className={twMerge(theme.spinnerSlot)}>{SpinnerComponent}</span>}
{typeof children !== 'undefined' ? (
children
) : (
<span data-testid="flowbite-button-label" className={theme.label}>
<span data-testid="flowbite-button-label" className={twMerge(theme.label)}>
{isProcessing ? processingLabel : label}
</span>
)}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Button/ButtonGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import classNames from 'classnames';
import type { ComponentProps, FC, PropsWithChildren, ReactElement } from 'react';
import { Children, cloneElement, useMemo } from 'react';
import { twMerge } from 'tailwind-merge';
import type { DeepPartial } from '../../';
import { useTheme } from '../../';
import { mergeDeep } from '../../helpers/merge-deep';
Expand Down Expand Up @@ -48,7 +48,7 @@ const ButtonGroup: FC<ButtonGroupProps> = ({
const theme = mergeDeep(useTheme().theme.buttonGroup, customTheme);

return (
<div className={classNames(theme.base, className)} role="group" {...props}>
<div className={twMerge(theme.base, className)} role="group" {...props}>
{items}
</div>
);
Expand Down
Loading

0 comments on commit 04aa4a2

Please sign in to comment.