@toptal/picasso-button 1.0.13-alpha-fx-4594-migrate-griditem-c9028d1d9.30 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-package/src/Button/Button.d.ts.map +1 -1
- package/dist-package/src/Button/Button.js +39 -47
- package/dist-package/src/Button/Button.js.map +1 -1
- package/dist-package/src/Button/styles.d.ts +19 -45
- package/dist-package/src/Button/styles.d.ts.map +1 -1
- package/dist-package/src/Button/styles.js +161 -178
- package/dist-package/src/Button/styles.js.map +1 -1
- package/dist-package/src/ButtonAction/ButtonAction.d.ts.map +1 -1
- package/dist-package/src/ButtonAction/ButtonAction.js +20 -28
- package/dist-package/src/ButtonAction/ButtonAction.js.map +1 -1
- package/dist-package/src/ButtonAction/styles.d.ts +11 -3
- package/dist-package/src/ButtonAction/styles.d.ts.map +1 -1
- package/dist-package/src/ButtonAction/styles.js +36 -55
- package/dist-package/src/ButtonAction/styles.js.map +1 -1
- package/dist-package/src/ButtonBase/ButtonBase.d.ts +29 -0
- package/dist-package/src/ButtonBase/ButtonBase.d.ts.map +1 -0
- package/dist-package/src/ButtonBase/ButtonBase.js +82 -0
- package/dist-package/src/ButtonBase/ButtonBase.js.map +1 -0
- package/dist-package/src/ButtonBase/index.d.ts +5 -0
- package/dist-package/src/ButtonBase/index.d.ts.map +1 -0
- package/dist-package/src/ButtonBase/index.js +2 -0
- package/dist-package/src/ButtonBase/index.js.map +1 -0
- package/dist-package/src/ButtonBase/styles.d.ts +6 -0
- package/dist-package/src/ButtonBase/styles.d.ts.map +1 -0
- package/dist-package/src/ButtonBase/styles.js +29 -0
- package/dist-package/src/ButtonBase/styles.js.map +1 -0
- package/dist-package/src/ButtonCircular/ButtonCircular.d.ts.map +1 -1
- package/dist-package/src/ButtonCircular/ButtonCircular.js +12 -26
- package/dist-package/src/ButtonCircular/ButtonCircular.js.map +1 -1
- package/dist-package/src/ButtonCircular/styles.d.ts +15 -3
- package/dist-package/src/ButtonCircular/styles.d.ts.map +1 -1
- package/dist-package/src/ButtonCircular/styles.js +92 -57
- package/dist-package/src/ButtonCircular/styles.js.map +1 -1
- package/dist-package/src/ButtonCompound/index.d.ts +1 -1
- package/dist-package/src/ButtonControlLabel/ButtonControlLabel.d.ts.map +1 -1
- package/dist-package/src/ButtonControlLabel/ButtonControlLabel.js +4 -13
- package/dist-package/src/ButtonControlLabel/ButtonControlLabel.js.map +1 -1
- package/dist-package/src/ButtonControlLabel/styles.d.ts +2 -2
- package/dist-package/src/ButtonControlLabel/styles.d.ts.map +1 -1
- package/dist-package/src/ButtonControlLabel/styles.js +16 -25
- package/dist-package/src/ButtonControlLabel/styles.js.map +1 -1
- package/dist-package/src/ButtonGroup/ButtonGroup.d.ts +1 -1
- package/dist-package/src/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist-package/src/ButtonGroup/ButtonGroup.js +5 -27
- package/dist-package/src/ButtonGroup/ButtonGroup.js.map +1 -1
- package/dist-package/src/ButtonGroup/styles.d.ts +1 -2
- package/dist-package/src/ButtonGroup/styles.d.ts.map +1 -1
- package/dist-package/src/ButtonGroup/styles.js +20 -47
- package/dist-package/src/ButtonGroup/styles.js.map +1 -1
- package/dist-package/src/ButtonGroupItem/ButtonGroupItem.d.ts +1 -1
- package/dist-package/src/ButtonGroupItem/ButtonGroupItem.d.ts.map +1 -1
- package/dist-package/src/ButtonGroupItem/ButtonGroupItem.js +17 -12
- package/dist-package/src/ButtonGroupItem/ButtonGroupItem.js.map +1 -1
- package/dist-package/src/ButtonGroupItem/styles.d.ts +13 -3
- package/dist-package/src/ButtonGroupItem/styles.d.ts.map +1 -1
- package/dist-package/src/ButtonGroupItem/styles.js +39 -17
- package/dist-package/src/ButtonGroupItem/styles.js.map +1 -1
- package/dist-package/src/ButtonSplit/ButtonSplit.d.ts.map +1 -1
- package/dist-package/src/ButtonSplit/ButtonSplit.js +28 -24
- package/dist-package/src/ButtonSplit/ButtonSplit.js.map +1 -1
- package/dist-package/src/ButtonSplit/styles.d.ts +9 -3
- package/dist-package/src/ButtonSplit/styles.d.ts.map +1 -1
- package/dist-package/src/ButtonSplit/styles.js +13 -50
- package/dist-package/src/ButtonSplit/styles.js.map +1 -1
- package/package.json +19 -16
- package/src/Button/Button.tsx +69 -100
- package/src/Button/__snapshots__/test.tsx.snap +8 -4
- package/src/Button/styles.ts +214 -221
- package/src/Button/test.tsx +3 -1
- package/src/ButtonAction/ButtonAction.tsx +36 -48
- package/src/ButtonAction/styles.ts +57 -57
- package/src/ButtonBase/ButtonBase.tsx +186 -0
- package/src/ButtonBase/__snapshots__/test.tsx.snap +286 -0
- package/src/ButtonBase/index.ts +5 -0
- package/src/ButtonBase/styles.ts +36 -0
- package/src/ButtonBase/test.tsx +230 -0
- package/src/ButtonCheckbox/__snapshots__/test.tsx.snap +4 -3
- package/src/ButtonCircular/ButtonCircular.tsx +22 -37
- package/src/ButtonCircular/styles.ts +127 -75
- package/src/ButtonControlLabel/ButtonControlLabel.tsx +7 -16
- package/src/ButtonControlLabel/styles.ts +30 -26
- package/src/ButtonGroup/ButtonGroup.tsx +9 -44
- package/src/ButtonGroup/__snapshots__/test.tsx.snap +13 -7
- package/src/ButtonGroup/styles.ts +21 -63
- package/src/ButtonGroupItem/ButtonGroupItem.tsx +24 -15
- package/src/ButtonGroupItem/styles.ts +62 -28
- package/src/ButtonRadio/__snapshots__/test.tsx.snap +4 -3
- package/src/ButtonSplit/ButtonSplit.tsx +46 -42
- package/src/ButtonSplit/__snapshots__/test.tsx.snap +13 -9
- package/src/ButtonSplit/styles.ts +37 -56
- package/LICENSE +0 -20
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, fireEvent } from '@toptal/picasso-test-utils'
|
|
3
|
+
import type { OmitInternalProps } from '@toptal/picasso-shared'
|
|
4
|
+
import { useTitleCase } from '@toptal/picasso-shared'
|
|
5
|
+
import { Link } from '@toptal/picasso-link'
|
|
6
|
+
import { toTitleCase } from '@toptal/picasso-utils'
|
|
7
|
+
|
|
8
|
+
import type { Props } from './ButtonBase'
|
|
9
|
+
import { ButtonBase } from './ButtonBase'
|
|
10
|
+
|
|
11
|
+
jest.mock('@toptal/picasso-shared', () => ({
|
|
12
|
+
__esModule: true,
|
|
13
|
+
...jest.requireActual('@toptal/picasso-shared'),
|
|
14
|
+
useTitleCase: jest.fn(value => value),
|
|
15
|
+
}))
|
|
16
|
+
|
|
17
|
+
jest.mock('@toptal/picasso-utils', () => ({
|
|
18
|
+
__esModule: true,
|
|
19
|
+
...jest.requireActual('@toptal/picasso-utils'),
|
|
20
|
+
noop: jest.fn(),
|
|
21
|
+
toTitleCase: jest.fn(value => `__TITLE_CASE__${value}`),
|
|
22
|
+
}))
|
|
23
|
+
|
|
24
|
+
const useTitleCaseMocked = useTitleCase as jest.Mocked<typeof useTitleCase>
|
|
25
|
+
const toTitleCaseMocked = toTitleCase as jest.Mocked<typeof toTitleCase>
|
|
26
|
+
|
|
27
|
+
const renderButton = (props: OmitInternalProps<Props>) => {
|
|
28
|
+
const { children, disabled, loading, onClick, titleCase, as, href, ...rest } =
|
|
29
|
+
props
|
|
30
|
+
|
|
31
|
+
return render(
|
|
32
|
+
<ButtonBase
|
|
33
|
+
disabled={disabled}
|
|
34
|
+
loading={loading}
|
|
35
|
+
onClick={onClick}
|
|
36
|
+
titleCase={titleCase}
|
|
37
|
+
as={as}
|
|
38
|
+
href={href}
|
|
39
|
+
{...rest}
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
</ButtonBase>,
|
|
43
|
+
undefined
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
describe('ButtonBase', () => {
|
|
48
|
+
beforeEach(() => {
|
|
49
|
+
useTitleCaseMocked.mockReturnValue(false)
|
|
50
|
+
toTitleCaseMocked.mockImplementation(value => {
|
|
51
|
+
return `__TITLE_CASE__${value}`
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
afterEach(() => {
|
|
56
|
+
useTitleCaseMocked.mockRestore()
|
|
57
|
+
toTitleCaseMocked.mockRestore()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
describe('when "as" prop is passed', () => {
|
|
61
|
+
describe('when "as" prop equals "a"', () => {
|
|
62
|
+
it('renders Button as a', () => {
|
|
63
|
+
const { container } = renderButton({
|
|
64
|
+
children: 'Click me!',
|
|
65
|
+
as: 'a',
|
|
66
|
+
href: '/',
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
expect(container).toMatchSnapshot()
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe('when "as" prop equals "Link" component', () => {
|
|
74
|
+
it('renders Button as a', () => {
|
|
75
|
+
const onClick = jest.fn()
|
|
76
|
+
const { container, getByText } = renderButton({
|
|
77
|
+
children: 'Click me!',
|
|
78
|
+
as: Link,
|
|
79
|
+
href: 'URL',
|
|
80
|
+
onClick,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
expect(container).toMatchSnapshot()
|
|
84
|
+
|
|
85
|
+
fireEvent.click(getByText('Click me!'))
|
|
86
|
+
|
|
87
|
+
expect(onClick).toHaveBeenCalled()
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
describe('when "href" prop is empty', () => {
|
|
91
|
+
it('renders Button as a', () => {
|
|
92
|
+
const onClick = jest.fn()
|
|
93
|
+
const { container, getByText } = renderButton({
|
|
94
|
+
children: 'Click me!',
|
|
95
|
+
as: Link,
|
|
96
|
+
href: '',
|
|
97
|
+
onClick,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
expect(container).toMatchSnapshot()
|
|
101
|
+
|
|
102
|
+
fireEvent.click(getByText('Click me!'))
|
|
103
|
+
|
|
104
|
+
expect(onClick).toHaveBeenCalled()
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
describe('when "disabled" prop is true', () => {
|
|
109
|
+
it('renders Button as a and does not trigger onClick handler', () => {
|
|
110
|
+
const onClick = jest.fn()
|
|
111
|
+
const { container, getByText } = renderButton({
|
|
112
|
+
children: 'Click me!',
|
|
113
|
+
as: Link,
|
|
114
|
+
href: 'URL',
|
|
115
|
+
onClick,
|
|
116
|
+
disabled: true,
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
expect(container).toMatchSnapshot()
|
|
120
|
+
|
|
121
|
+
fireEvent.click(getByText('Click me!'))
|
|
122
|
+
|
|
123
|
+
expect(onClick).not.toHaveBeenCalled()
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
describe('when "as" prop does not equal "button"', () => {
|
|
129
|
+
describe('when "href" prop is passed', () => {
|
|
130
|
+
it('renders Button as a link', () => {
|
|
131
|
+
const { container } = renderButton({
|
|
132
|
+
children: 'Click me!',
|
|
133
|
+
as: 'span',
|
|
134
|
+
href: '/',
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
expect(container).toMatchSnapshot()
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
describe('when "to" prop is passed', () => {
|
|
142
|
+
it('renders Button as a link', () => {
|
|
143
|
+
const { container } = renderButton({
|
|
144
|
+
children: 'Click me!',
|
|
145
|
+
as: 'span',
|
|
146
|
+
to: '/',
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
expect(container).toMatchSnapshot()
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
describe('when "role" prop is passed', () => {
|
|
156
|
+
it('renders Button with a custom role', () => {
|
|
157
|
+
const { container } = renderButton({
|
|
158
|
+
children: 'Click me!',
|
|
159
|
+
role: 'custom',
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
expect(container).toMatchSnapshot()
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
describe('when "disabled" prop is true', () => {
|
|
167
|
+
it('renders Button and does not trigger onClick handler', () => {
|
|
168
|
+
const onClick = jest.fn()
|
|
169
|
+
const { container, getByText } = renderButton({
|
|
170
|
+
children: 'Click me!',
|
|
171
|
+
onClick,
|
|
172
|
+
disabled: true,
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
expect(container).toMatchSnapshot()
|
|
176
|
+
|
|
177
|
+
fireEvent.click(getByText('Click me!'))
|
|
178
|
+
|
|
179
|
+
expect(onClick).not.toHaveBeenCalled()
|
|
180
|
+
})
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
describe('when "disabled" prop is false', () => {
|
|
184
|
+
it('renders Button and does not trigger onClick handler', () => {
|
|
185
|
+
const onClick = jest.fn()
|
|
186
|
+
const { container, getByText } = renderButton({
|
|
187
|
+
children: 'Click me!',
|
|
188
|
+
onClick,
|
|
189
|
+
disabled: false,
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
expect(container).toMatchSnapshot()
|
|
193
|
+
|
|
194
|
+
fireEvent.click(getByText('Click me!'))
|
|
195
|
+
|
|
196
|
+
expect(onClick).toHaveBeenCalledTimes(1)
|
|
197
|
+
})
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
describe('when "loading" prop is true', () => {
|
|
201
|
+
it('renders Button with loading state and does not trigger onClick handler', () => {
|
|
202
|
+
const onClick = jest.fn()
|
|
203
|
+
const { container, getByText } = renderButton({
|
|
204
|
+
children: 'Click me!',
|
|
205
|
+
onClick,
|
|
206
|
+
loading: true,
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
expect(container).toMatchSnapshot()
|
|
210
|
+
|
|
211
|
+
fireEvent.click(getByText('Click me!'))
|
|
212
|
+
|
|
213
|
+
expect(onClick).toHaveBeenCalledTimes(0)
|
|
214
|
+
})
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
describe('when "titleCase" prop is true', () => {
|
|
218
|
+
it('renders Button with transformed text to title case', () => {
|
|
219
|
+
useTitleCaseMocked.mockReturnValue(true)
|
|
220
|
+
const TEXT_CONTENT = 'Test bk9'
|
|
221
|
+
|
|
222
|
+
const { container } = renderButton({
|
|
223
|
+
children: TEXT_CONTENT,
|
|
224
|
+
titleCase: true,
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
expect(container).toMatchSnapshot()
|
|
228
|
+
})
|
|
229
|
+
})
|
|
230
|
+
})
|
|
@@ -7,13 +7,14 @@ exports[`ButtonCheckbox renders 1`] = `
|
|
|
7
7
|
>
|
|
8
8
|
<label
|
|
9
9
|
aria-disabled="false"
|
|
10
|
-
class="
|
|
10
|
+
class="base-Button text-lg inline-flex items-center justify-center select-none appearance-none m-0 relative normal-case align-middle transition-colors duration-350 ease-out shrink-0 outline-none [&+&]:ml-4 cursor-pointer no-underline rounded-sm shadow-none focus-visible:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] focus-within:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] border border-solid text-black hover:border-black visited:text-black active:bg-gray active:border-black bg-white border-gray min-w h-8 px-4 text-center py-2 pr-6 pl-4"
|
|
11
11
|
data-component-type="button"
|
|
12
12
|
role="button"
|
|
13
13
|
tabindex="0"
|
|
14
|
+
type="button"
|
|
14
15
|
>
|
|
15
16
|
<span
|
|
16
|
-
class="PicassoContainer-centerAlignItems PicassoContainer-flex PicassoContainer-inline
|
|
17
|
+
class="PicassoContainer-centerAlignItems PicassoContainer-flex PicassoContainer-inline font-semibold whitespace-nowrap text-button"
|
|
17
18
|
>
|
|
18
19
|
<span
|
|
19
20
|
class="PicassoContainer-flex PicassoContainer-inline PicassoCheckbox-checkboxWrapper"
|
|
@@ -38,7 +39,7 @@ exports[`ButtonCheckbox renders 1`] = `
|
|
|
38
39
|
</span>
|
|
39
40
|
</span>
|
|
40
41
|
<div
|
|
41
|
-
class="
|
|
42
|
+
class="min-w"
|
|
42
43
|
style="margin-left: 0.5rem;"
|
|
43
44
|
>
|
|
44
45
|
Click me!
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import type { ReactElement, MouseEvent, ElementType } from 'react'
|
|
2
2
|
import React, { forwardRef } from 'react'
|
|
3
3
|
import cx from 'classnames'
|
|
4
|
-
import type { Theme } from '@material-ui/core/styles'
|
|
5
|
-
import { makeStyles } from '@material-ui/core/styles'
|
|
6
4
|
import type {
|
|
7
5
|
BaseProps,
|
|
8
6
|
ButtonOrAnchorProps,
|
|
9
7
|
OverridableComponent,
|
|
10
8
|
} from '@toptal/picasso-shared'
|
|
11
|
-
import { kebabToCamelCase } from '@toptal/picasso-utils'
|
|
12
9
|
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
10
|
+
import { ButtonBase } from '../ButtonBase'
|
|
11
|
+
import { createRootClassNames, createVariantClassNames } from './styles'
|
|
15
12
|
|
|
16
13
|
export type VariantType = 'primary' | 'flat' | 'transparent'
|
|
17
14
|
|
|
@@ -40,14 +37,6 @@ export interface Props extends BaseProps, ButtonOrAnchorProps {
|
|
|
40
37
|
responsive?: boolean
|
|
41
38
|
}
|
|
42
39
|
|
|
43
|
-
// Using { index: -1 } to inject CSS link to the bottom of the head
|
|
44
|
-
// in order to prevent Button's styles to override ButtonCircular's ones
|
|
45
|
-
// Related Jira issue: https://toptal-core.atlassian.net/browse/FX-1520
|
|
46
|
-
const useStyles = makeStyles<Theme>(styles, {
|
|
47
|
-
name: 'PicassoButtonCircular',
|
|
48
|
-
index: -1,
|
|
49
|
-
})
|
|
50
|
-
|
|
51
40
|
export const ButtonCircular: OverridableComponent<Props> = forwardRef<
|
|
52
41
|
HTMLButtonElement,
|
|
53
42
|
Props
|
|
@@ -60,39 +49,35 @@ export const ButtonCircular: OverridableComponent<Props> = forwardRef<
|
|
|
60
49
|
hovered,
|
|
61
50
|
disabled,
|
|
62
51
|
responsive,
|
|
52
|
+
loading,
|
|
63
53
|
...rest
|
|
64
54
|
} = props
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
const variantClassNames = createVariantClassNames(variant, {
|
|
56
|
+
disabled,
|
|
57
|
+
focused,
|
|
58
|
+
hovered,
|
|
59
|
+
active,
|
|
60
|
+
})
|
|
68
61
|
|
|
69
|
-
const
|
|
62
|
+
const finalClassName = cx(
|
|
63
|
+
createRootClassNames({ responsive, active, disabled, focused, hovered }),
|
|
64
|
+
variantClassNames,
|
|
65
|
+
className
|
|
66
|
+
)
|
|
70
67
|
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
[classes.hovered]: hovered,
|
|
76
|
-
[classes.disabled]: disabled,
|
|
77
|
-
[classes.responsive]: responsive,
|
|
78
|
-
},
|
|
79
|
-
variantClassName,
|
|
80
|
-
rootClass
|
|
68
|
+
const contentClassName = cx(
|
|
69
|
+
'font-semibold whitespace-nowrap',
|
|
70
|
+
'text-button-small',
|
|
71
|
+
loading ? 'opacity-0' : ''
|
|
81
72
|
)
|
|
82
73
|
|
|
83
74
|
return (
|
|
84
|
-
<
|
|
75
|
+
<ButtonBase
|
|
85
76
|
{...rest}
|
|
86
77
|
ref={ref}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}}
|
|
91
|
-
className={className}
|
|
92
|
-
size='small'
|
|
93
|
-
active={active}
|
|
94
|
-
hovered={hovered}
|
|
95
|
-
focused={focused}
|
|
78
|
+
loading={loading}
|
|
79
|
+
className={finalClassName}
|
|
80
|
+
contentClassName={contentClassName}
|
|
96
81
|
disabled={disabled}
|
|
97
82
|
/>
|
|
98
83
|
)
|
|
@@ -1,75 +1,127 @@
|
|
|
1
|
-
import type {
|
|
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
|
-
|
|
1
|
+
import type { VariantType } from './ButtonCircular'
|
|
2
|
+
|
|
3
|
+
export const createRootClassNames = ({
|
|
4
|
+
responsive,
|
|
5
|
+
}: {
|
|
6
|
+
disabled?: boolean
|
|
7
|
+
focused?: boolean
|
|
8
|
+
hovered?: boolean
|
|
9
|
+
active?: boolean
|
|
10
|
+
loading?: boolean
|
|
11
|
+
responsive?: boolean
|
|
12
|
+
}) => {
|
|
13
|
+
const classNames = ['rounded-full', 'p-0']
|
|
14
|
+
|
|
15
|
+
if (responsive) {
|
|
16
|
+
classNames.push('w-[2.5em] h-[2.5em] xl:w-[1.5em] xl:h-[1.5em]')
|
|
17
|
+
} else {
|
|
18
|
+
classNames.push('w-[1.5em] h-[1.5em]')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return classNames
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const createVariantClassNames = (
|
|
25
|
+
variant: VariantType,
|
|
26
|
+
{
|
|
27
|
+
disabled,
|
|
28
|
+
focused,
|
|
29
|
+
hovered,
|
|
30
|
+
active,
|
|
31
|
+
}: {
|
|
32
|
+
disabled?: boolean
|
|
33
|
+
focused?: boolean
|
|
34
|
+
hovered?: boolean
|
|
35
|
+
active?: boolean
|
|
36
|
+
}
|
|
37
|
+
): string[] => {
|
|
38
|
+
const variantClassNames = []
|
|
39
|
+
|
|
40
|
+
switch (variant) {
|
|
41
|
+
case 'primary':
|
|
42
|
+
variantClassNames.push('border-none')
|
|
43
|
+
variantClassNames.push('text-white')
|
|
44
|
+
variantClassNames.push('visited:text-white')
|
|
45
|
+
|
|
46
|
+
if (disabled) {
|
|
47
|
+
variantClassNames.push('bg-gray-400')
|
|
48
|
+
} else {
|
|
49
|
+
variantClassNames.push('hover:bg-[#4269D6]')
|
|
50
|
+
variantClassNames.push('active:bg-[#1A41AB]')
|
|
51
|
+
|
|
52
|
+
variantClassNames.push(
|
|
53
|
+
'focus-visible:shadow-[0_0_0_3px_rgba(32,78,207,0.48)]'
|
|
54
|
+
)
|
|
55
|
+
if (focused) {
|
|
56
|
+
variantClassNames.push('shadow-[0_0_0_3px_rgba(32,78,207,0.48)]')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (hovered) {
|
|
60
|
+
variantClassNames.push('bg-[#4269D6]')
|
|
61
|
+
} else if (active) {
|
|
62
|
+
variantClassNames.push('bg-[#1A41AB]')
|
|
63
|
+
} else {
|
|
64
|
+
variantClassNames.push('bg-blue-500')
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
break
|
|
68
|
+
case 'flat':
|
|
69
|
+
variantClassNames.push('border-none')
|
|
70
|
+
variantClassNames.push('text-graphite-700')
|
|
71
|
+
|
|
72
|
+
if (disabled) {
|
|
73
|
+
variantClassNames.push('text-graphite-700')
|
|
74
|
+
variantClassNames.push('opacity-[0.48]')
|
|
75
|
+
variantClassNames.push('bg-transparent')
|
|
76
|
+
} else {
|
|
77
|
+
variantClassNames.push('hover:bg-gray-200')
|
|
78
|
+
variantClassNames.push('active:bg-gray-400')
|
|
79
|
+
|
|
80
|
+
variantClassNames.push(
|
|
81
|
+
'focus-visible:shadow-[0_0_0_3px_rgba(32,78,207,0.48)]'
|
|
82
|
+
)
|
|
83
|
+
if (focused) {
|
|
84
|
+
variantClassNames.push('shadow-[0_0_0_3px_rgba(32,78,207,0.48)]')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (hovered) {
|
|
88
|
+
variantClassNames.push('bg-gray-200')
|
|
89
|
+
} else if (active) {
|
|
90
|
+
variantClassNames.push('bg-gray-400')
|
|
91
|
+
} else {
|
|
92
|
+
variantClassNames.push('bg-transparent')
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
break
|
|
96
|
+
case 'transparent':
|
|
97
|
+
variantClassNames.push('border-none')
|
|
98
|
+
variantClassNames.push('text-white')
|
|
99
|
+
|
|
100
|
+
if (disabled) {
|
|
101
|
+
variantClassNames.push('text-white/[0.48]')
|
|
102
|
+
variantClassNames.push('bg-transparent')
|
|
103
|
+
} else {
|
|
104
|
+
variantClassNames.push('hover:bg-white/[0.08]')
|
|
105
|
+
variantClassNames.push('active:bg-white/[0.16]')
|
|
106
|
+
|
|
107
|
+
variantClassNames.push(
|
|
108
|
+
'focus-visible:shadow-[0_0_0_3px_rgba(255,255,255,0.48)]'
|
|
109
|
+
)
|
|
110
|
+
if (focused) {
|
|
111
|
+
variantClassNames.push('shadow-[0_0_0_3px_rgba(255,255,255,0.48)]')
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (hovered) {
|
|
115
|
+
variantClassNames.push('bg-white/[0.08]')
|
|
116
|
+
} else if (active) {
|
|
117
|
+
variantClassNames.push('bg-white/[0.16]')
|
|
118
|
+
} else {
|
|
119
|
+
variantClassNames.push('bg-transparent')
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
break
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return variantClassNames
|
|
127
|
+
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import type { ReactElement, ReactNode } from 'react'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import type { BaseProps, SizeType } from '@toptal/picasso-shared'
|
|
4
|
-
import
|
|
5
|
-
import { makeStyles } from '@material-ui/core'
|
|
6
|
-
import cx from 'classnames'
|
|
4
|
+
import { twMerge } from 'tailwind-merge'
|
|
7
5
|
import { Container } from '@toptal/picasso-container'
|
|
8
6
|
|
|
9
7
|
import { Button } from '../Button'
|
|
10
|
-
import
|
|
8
|
+
import { createSizeClassNames, createContentSizeClassNames } from './styles'
|
|
11
9
|
|
|
12
10
|
export interface Props extends BaseProps {
|
|
13
11
|
/** Show the control initially as checked */
|
|
@@ -37,14 +35,6 @@ export interface Props extends BaseProps {
|
|
|
37
35
|
control: ReactElement
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
// Using { index: -1 } to inject CSS link to the bottom of the head
|
|
41
|
-
// in order to prevent Button's styles to override ButtonAction's ones
|
|
42
|
-
// Related Jira issue: https://toptal-core.atlassian.net/browse/FX-1520
|
|
43
|
-
const useStyles = makeStyles<Theme>(styles, {
|
|
44
|
-
name: 'PicassoButtonControlLabel',
|
|
45
|
-
index: -1,
|
|
46
|
-
})
|
|
47
|
-
|
|
48
38
|
const ButtonControlLabel = ({
|
|
49
39
|
children,
|
|
50
40
|
size = 'medium',
|
|
@@ -57,14 +47,12 @@ const ButtonControlLabel = ({
|
|
|
57
47
|
disabled,
|
|
58
48
|
...props
|
|
59
49
|
}: Props) => {
|
|
60
|
-
const classes = useStyles()
|
|
61
|
-
|
|
62
50
|
const contentLeftSpacing = size === 'large' ? 1 : 0.5
|
|
63
51
|
|
|
64
52
|
return (
|
|
65
53
|
<Button
|
|
66
54
|
{...props}
|
|
67
|
-
className={
|
|
55
|
+
className={twMerge('text-center', createSizeClassNames(size), className)}
|
|
68
56
|
variant='secondary'
|
|
69
57
|
size={size}
|
|
70
58
|
as='label'
|
|
@@ -72,7 +60,10 @@ const ButtonControlLabel = ({
|
|
|
72
60
|
disabled={disabled}
|
|
73
61
|
>
|
|
74
62
|
{React.cloneElement(control, { id, checked, value, onChange, disabled })}
|
|
75
|
-
<Container
|
|
63
|
+
<Container
|
|
64
|
+
className={createContentSizeClassNames(size)}
|
|
65
|
+
left={contentLeftSpacing}
|
|
66
|
+
>
|
|
76
67
|
{children}
|
|
77
68
|
</Container>
|
|
78
69
|
</Button>
|
|
@@ -1,27 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { SizeType } from '@toptal/picasso-shared'
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
3
|
+
export const createSizeClassNames = (
|
|
4
|
+
size: 'small' | 'medium' | 'large'
|
|
5
|
+
): string => {
|
|
6
|
+
const sizeClassNames: Record<
|
|
7
|
+
SizeType<'small' | 'medium' | 'large'>,
|
|
8
|
+
string
|
|
9
|
+
> = {
|
|
10
|
+
small: 'py-1 pr-4 pl-2',
|
|
11
|
+
medium: 'py-2 pr-6 pl-4',
|
|
12
|
+
large: 'py-4 pr-8 pl-4',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return sizeClassNames[size]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const createContentSizeClassNames = (
|
|
19
|
+
size: 'small' | 'medium' | 'large'
|
|
20
|
+
): string => {
|
|
21
|
+
const sizeClassNames: Record<
|
|
22
|
+
SizeType<'small' | 'medium' | 'large'>,
|
|
23
|
+
string
|
|
24
|
+
> = {
|
|
25
|
+
small: 'min-w-12',
|
|
26
|
+
medium: 'min-w-16',
|
|
27
|
+
large: 'min-w-[5.25rem]',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return sizeClassNames[size]
|
|
31
|
+
}
|