-
Notifications
You must be signed in to change notification settings - Fork 380
Expand file tree
/
Copy pathCopyButton.stories.tsx
More file actions
126 lines (111 loc) · 3.15 KB
/
CopyButton.stories.tsx
File metadata and controls
126 lines (111 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import type { Meta, StoryObj } from '@storybook/react-vite'
import { expect, userEvent, waitFor, within, fn } from 'storybook/test'
import { CopyButton } from './CopyButton'
import { Check, Copy } from 'lucide-react'
const meta: Meta<typeof CopyButton> = {
title: 'Components/CopyButton',
component: CopyButton,
}
export default meta
type Story = StoryObj<typeof CopyButton>
export const Default: Story = {
args: {
text: 'Hello, World!',
children: copied => (copied ? 'Copied!' : 'Copy'),
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement)
const button = canvas.getByRole('button')
await expect(button).toHaveTextContent('Copy')
await expect(button).toBeEnabled()
const writeTextSpy = fn().mockResolvedValue(undefined)
if (navigator.clipboard) {
navigator.clipboard.writeText = writeTextSpy
} else {
Object.defineProperty(navigator, 'clipboard', {
writable: true,
value: {
writeText: writeTextSpy,
},
})
}
const user = userEvent.setup()
await user.click(button)
await expect(writeTextSpy).toHaveBeenCalledWith('Hello, World!')
await waitFor(() => {
expect(button).toHaveTextContent('Copied!')
})
await expect(button).toBeDisabled()
},
}
export const WithIcons: Story = {
args: {
text: 'Copy this text with icon feedback',
children: copied => (
<>
{copied ? (
<>
<Check size={14} />
Copied!
</>
) : (
<>
<Copy size={14} />
Copy
</>
)}
</>
),
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement)
const button = canvas.getByRole('button')
// Initial state with Copy icon
await expect(button).toHaveTextContent('Copy')
// Mock clipboard API
Object.defineProperty(navigator, 'clipboard', {
writable: true,
value: {
writeText: fn().mockResolvedValue(undefined),
},
})
const user = userEvent.setup()
await user.click(button)
// Should switch to Check icon and Copied text
await waitFor(() => {
expect(button).toHaveTextContent('Copied!')
})
},
}
export const IconOnly: Story = {
args: {
text: 'This is the text to copy',
children: copied => (copied ? <Check size={16} /> : <Copy size={16} />),
},
}
export const CustomDelay: Story = {
args: {
text: 'This stays copied for 5 seconds',
delay: 5000,
children: copied => (copied ? 'Copied! (5s delay)' : 'Copy (5s feedback)'),
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement)
const button = canvas.getByRole('button')
// Mock clipboard API
Object.defineProperty(navigator, 'clipboard', {
writable: true,
value: {
writeText: fn().mockResolvedValue(undefined),
},
})
const user = userEvent.setup()
await user.click(button)
// Should show copied state
await waitFor(() => {
expect(button).toHaveTextContent('Copied! (5s delay)')
})
// Button should remain disabled for custom delay
await expect(button).toBeDisabled()
},
}