Skip to content

Commit 65550d9

Browse files
feat(Loading): Add a new component Loading and fix an issue with loading on component Button after upgrade to daisyui version 3 (#358)
1 parent e5161fd commit 65550d9

5 files changed

Lines changed: 177 additions & 2 deletions

File tree

src/Button/Button.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { forwardRef, ReactNode } from 'react'
22
import clsx from 'clsx'
33
import { twMerge } from 'tailwind-merge'
44

5+
import Loading from '../Loading';
56
import {
67
IComponentBaseProps,
78
ComponentColor,
@@ -23,7 +24,7 @@ export type ButtonProps = Omit<
2324
fullWidth?: boolean
2425
responsive?: boolean
2526
animation?: boolean
26-
loading?: boolean
27+
loading?: boolean
2728
active?: boolean
2829
startIcon?: ReactNode
2930
endIcon?: ReactNode
@@ -80,7 +81,6 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
8081
'no-animation': !animation,
8182
'btn-active': active,
8283
'btn-disabled': disabled,
83-
loading: loading,
8484
})
8585
)
8686

@@ -102,6 +102,7 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
102102
style={style}
103103
disabled={disabled}
104104
>
105+
{!startIcon && loading && (<Loading size={size} />)}
105106
{startIcon && !loading && startIcon}
106107
{children}
107108
{endIcon && endIcon}

src/Loading/Loading.stories.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React from 'react'
2+
import { StoryFn as Story, Meta } from '@storybook/react'
3+
4+
import Loading, { LoadingProps } from '.'
5+
6+
const meta: Meta = {
7+
title: 'Data Display/Loading',
8+
component: Loading,
9+
parameters: {
10+
controls: { expanded: true },
11+
},
12+
};
13+
14+
export default meta
15+
16+
const Template: Story<LoadingProps> = (args) => {
17+
return <Loading {...args} />
18+
}
19+
export const Default = Template.bind({})
20+
Default.args = {
21+
variant: 'spinner',
22+
}
23+
24+
export const Colors: Story<LoadingProps> = (args) => {
25+
return (
26+
<div>
27+
<div>
28+
<Loading {...args} />
29+
<Loading {...args} color="primary" />
30+
<Loading {...args} color="secondary" />
31+
<Loading {...args} color="success" />
32+
<Loading {...args} color="warning" />
33+
<Loading {...args} color="error" />
34+
<Loading {...args} color="info" />
35+
<Loading {...args} color="accent" />
36+
<Loading {...args} color="ghost" />
37+
</div>
38+
</div>
39+
)
40+
}
41+
Colors.args = {
42+
className: "m-1"
43+
}
44+
45+
export const Variants: Story<LoadingProps> = (args) => {
46+
return (
47+
<div className="flex gap-x-2">
48+
<Loading {...args} />
49+
<Loading {...args} variant="dots" />
50+
<Loading {...args} variant="ring" />
51+
<Loading {...args} variant="ball" />
52+
<Loading {...args} variant="bars" />
53+
<Loading {...args} variant="infinity" />
54+
</div>
55+
)
56+
}
57+
58+
export const Sizes: Story<LoadingProps> = (args) => {
59+
return (
60+
<div>
61+
<div>
62+
<Loading {...args} size="xs" />
63+
<Loading {...args} size="sm" />
64+
<Loading {...args} size="md" />
65+
<Loading {...args} size="lg" />
66+
</div>
67+
</div>
68+
)
69+
}

src/Loading/Loading.test.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { render } from '@testing-library/react'
2+
import Loading from '.'
3+
4+
describe('Loading', () => {
5+
it('renders a default variant', () => {
6+
const {container} = render(<Loading />)
7+
expect(container.querySelector('.loading')).toHaveClass('loading-spinner')
8+
})
9+
10+
it('renders a variant', () => {
11+
const {container} = render(<Loading variant="infinity" />)
12+
expect(container.querySelector('.loading')).toHaveClass('loading-infinity')
13+
})
14+
15+
it('renders a size', () => {
16+
const {container} = render(<Loading size="xs" />)
17+
expect(container.querySelector('.loading')).toHaveClass('loading-xs')
18+
})
19+
20+
it('renders a color', () => {
21+
const {container} = render(<Loading color="primary" />)
22+
expect(container.querySelector('.loading')).toHaveClass('text-primary')
23+
})
24+
25+
it('renders a variant and size', () => {
26+
const {container} = render(<Loading variant="dots" size="xs" />)
27+
expect(container.querySelector('.loading')).toHaveClass('loading-dots')
28+
expect(container.querySelector('.loading')).toHaveClass('loading-xs')
29+
})
30+
})

src/Loading/Loading.tsx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import React, { forwardRef, ReactNode } from 'react'
2+
import clsx from 'clsx'
3+
import { twMerge } from 'tailwind-merge'
4+
5+
import {
6+
IComponentBaseProps,
7+
ComponentColor,
8+
ComponentSize,
9+
} from '../types'
10+
11+
export type LoadingProps =
12+
React.HTMLAttributes<HTMLSpanElement>
13+
& IComponentBaseProps
14+
& {
15+
size?: ComponentSize
16+
color?: ComponentColor
17+
variant?: 'spinner' | 'dots' | 'ring' | 'ball' | 'bars' | 'infinity'
18+
}
19+
20+
const Loading = forwardRef<HTMLSpanElement, LoadingProps>(
21+
(
22+
{
23+
size,
24+
variant = 'spinner',
25+
color,
26+
dataTheme,
27+
className,
28+
style,
29+
...props
30+
},
31+
ref
32+
): JSX.Element => {
33+
const classes = twMerge(
34+
'loading',
35+
className,
36+
clsx({
37+
'loading-lg': size === 'lg',
38+
'loading-md': size === 'md',
39+
'loading-sm': size === 'sm',
40+
'loading-xs': size === 'xs',
41+
'loading-spinner': variant === 'spinner',
42+
'loading-dots': variant === 'dots',
43+
'loading-ring': variant === 'ring',
44+
'loading-ball': variant === 'ball',
45+
'loading-bars': variant === 'bars',
46+
'loading-infinity': variant === 'infinity',
47+
'text-primary': color === 'primary',
48+
'text-secondary': color === 'secondary',
49+
'text-accent': color === 'accent',
50+
'text-info': color === 'info',
51+
'text-success': color === 'success',
52+
'text-warning': color === 'warning',
53+
'text-error': color === 'error',
54+
'text-ghost': color === 'ghost',
55+
})
56+
)
57+
58+
return (
59+
<span
60+
{...props}
61+
ref={ref}
62+
data-theme={dataTheme}
63+
className={classes}
64+
style={style}
65+
/>
66+
)
67+
}
68+
)
69+
70+
Loading.displayName = 'Loading'
71+
72+
export default Loading

src/Loading/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Loading, { LoadingProps as TLoadingProps } from './Loading'
2+
export type LoadingProps = TLoadingProps
3+
export default Loading

0 commit comments

Comments
 (0)