@toptal/picasso-utils 1.0.1-alpha-fx-4861-find-missing-deep-imports-in-staff-portal-77646e396.4080 → 1.0.1-alpha-fx-4861-find-missing-deep-imports-in-staff-portal-25389459e.4083
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/tsconfig.tsbuildinfo +1 -0
- package/package.json +5 -9
- package/src/index.ts +1 -0
- package/src/utils/Breakpoints/story/Breakpoints.example.tsx +49 -0
- package/src/utils/Breakpoints/story/MediaQueries.example.tsx +18 -0
- package/src/utils/Breakpoints/story/index.jsx +60 -0
- package/src/utils/Breakpoints/story/useBreakpoint.example.tsx +17 -0
- package/src/utils/Breakpoints/story/useScreens.example.tsx +60 -0
- package/src/utils/Colors/index.ts +2 -0
- package/src/utils/Colors/story/Default.example.tsx +59 -0
- package/src/utils/Colors/story/HowToUse.example.tsx +14 -0
- package/src/utils/Colors/story/index.jsx +21 -0
- package/src/utils/Formatters/format-amount.ts +34 -0
- package/src/utils/Formatters/index.ts +3 -0
- package/src/utils/Formatters/story/amount.example.tsx +63 -0
- package/src/utils/Formatters/story/index.jsx +16 -0
- package/src/utils/Formatters/test.ts +102 -0
- package/src/utils/Gradients/index.ts +2 -0
- package/src/utils/Gradients/story/Default.example.tsx +30 -0
- package/src/utils/Gradients/story/HowToUse.example.tsx +26 -0
- package/src/utils/Gradients/story/index.jsx +26 -0
- package/src/utils/Modal/__snapshots__/test.tsx.snap +209 -0
- package/src/utils/Modal/index.ts +2 -0
- package/src/utils/Modal/modal-manager.ts +27 -0
- package/src/utils/Modal/test.tsx +86 -0
- package/src/utils/Modal/use-modal.tsx +17 -0
- package/src/utils/Shadows/story/Default.example.tsx +45 -0
- package/src/utils/Shadows/story/HowToUse.example.tsx +19 -0
- package/src/utils/Shadows/story/index.jsx +19 -0
- package/src/utils/Transitions/Rotate180/Rotate180.tsx +44 -0
- package/src/utils/Transitions/Rotate180/__snapshots__/test.tsx.snap +29 -0
- package/src/utils/Transitions/Rotate180/index.ts +4 -0
- package/src/utils/Transitions/Rotate180/story/Default.example.tsx +22 -0
- package/src/utils/Transitions/Rotate180/styles.ts +11 -0
- package/src/utils/Transitions/Rotate180/test.tsx +26 -0
- package/src/utils/Transitions/index.ts +2 -0
- package/src/utils/Transitions/story/index.jsx +13 -0
- package/src/utils/Utils/story/Browser.example.tsx +28 -0
- package/src/utils/Utils/story/Colors.example.tsx +29 -0
- package/src/utils/Utils/story/Generic.example.tsx +30 -0
- package/src/utils/Utils/story/React.example.tsx +32 -0
- package/src/utils/Utils/story/Strings.example.tsx +33 -0
- package/src/utils/__tests__/use-page-scroll-lock.test.tsx +117 -0
- package/src/utils/capitalize.ts +1 -0
- package/src/utils/constants.ts +1 -0
- package/src/utils/disable-unsupported-props.ts +45 -0
- package/src/utils/forward-ref.ts +38 -0
- package/src/utils/get-name-initials.ts +15 -0
- package/src/utils/get-react-node-text-content.ts +36 -0
- package/src/utils/index.ts +92 -0
- package/src/utils/is-boolean.ts +3 -0
- package/src/utils/is-number.ts +3 -0
- package/src/utils/is-overflown.ts +20 -0
- package/src/utils/is-pointer-device.ts +9 -0
- package/src/utils/is-string.ts +3 -0
- package/src/utils/is-substring.ts +4 -0
- package/src/utils/kebab-to-camel-case.ts +7 -0
- package/src/utils/loader-palette.ts +9 -0
- package/src/utils/monads.ts +1 -0
- package/src/utils/noop.ts +1 -0
- package/src/utils/sum.ts +4 -0
- package/src/utils/test.tsx +372 -0
- package/src/utils/to-title-case.ts +14 -0
- package/src/utils/unsafe-error-log.ts +5 -0
- package/src/utils/use-combined-refs.ts +26 -0
- package/src/utils/use-deprecation-warnings.ts +56 -0
- package/src/utils/use-multiple-forward-refs.ts +37 -0
- package/src/utils/use-page-scroll-lock.ts +64 -0
- package/src/utils/use-safe-state.ts +25 -0
- package/src/utils/use-width-of.ts +26 -0
- package/src/utils/useBoolean/index.ts +1 -0
- package/src/utils/useBoolean/test.tsx +25 -0
- package/src/utils/useBoolean/use-boolean.ts +30 -0
- package/src/utils/useInterval/index.ts +1 -0
- package/src/utils/useInterval/test.ts +61 -0
- package/src/utils/useInterval/use-interval.ts +46 -0
- package/src/utils/useMouseEnter/index.ts +1 -0
- package/src/utils/useMouseEnter/test.ts +51 -0
- package/src/utils/useMouseEnter/use-mouse-enter.ts +30 -0
- package/src/utils/useOnScreen/index.ts +1 -0
- package/src/utils/useOnScreen/use-on-screen.ts +50 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Modal useModal opens and closes modal 1`] = `
|
|
4
|
+
<body>
|
|
5
|
+
<div
|
|
6
|
+
id="modal-root"
|
|
7
|
+
/>
|
|
8
|
+
<div>
|
|
9
|
+
<div
|
|
10
|
+
class="Picasso-root"
|
|
11
|
+
>
|
|
12
|
+
<button
|
|
13
|
+
aria-hidden="true"
|
|
14
|
+
class="MuiButtonBase-root PicassoButton-medium PicassoButton-primary PicassoButton-root"
|
|
15
|
+
data-component-type="button"
|
|
16
|
+
tabindex="0"
|
|
17
|
+
type="button"
|
|
18
|
+
>
|
|
19
|
+
<span
|
|
20
|
+
class="PicassoContainer-centerAlignItems PicassoContainer-flex PicassoContainer-inline PicassoButton-content"
|
|
21
|
+
>
|
|
22
|
+
Show
|
|
23
|
+
</span>
|
|
24
|
+
</button>
|
|
25
|
+
<div
|
|
26
|
+
class="MuiDialog-root PicassoModal-root"
|
|
27
|
+
role="presentation"
|
|
28
|
+
style="position: fixed; z-index: 1300; right: 0px; bottom: 0px; top: 0px; left: 0px;"
|
|
29
|
+
>
|
|
30
|
+
<div
|
|
31
|
+
aria-hidden="true"
|
|
32
|
+
class="MuiBackdrop-root"
|
|
33
|
+
style="opacity: 1; webkit-transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
|
|
34
|
+
/>
|
|
35
|
+
<div
|
|
36
|
+
data-test="sentinelStart"
|
|
37
|
+
tabindex="0"
|
|
38
|
+
/>
|
|
39
|
+
<div
|
|
40
|
+
class="MuiDialog-container PicassoModal-container MuiDialog-scrollPaper"
|
|
41
|
+
role="none presentation"
|
|
42
|
+
style="opacity: 1; webkit-transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
|
|
43
|
+
tabindex="-1"
|
|
44
|
+
>
|
|
45
|
+
<div
|
|
46
|
+
class="MuiPaper-root MuiDialog-paper PicassoModal-paper PicassoModal-medium MuiDialog-paperScrollPaper MuiDialog-paperWidthFalse MuiPaper-elevation2"
|
|
47
|
+
role="dialog"
|
|
48
|
+
>
|
|
49
|
+
<p>
|
|
50
|
+
Modal content
|
|
51
|
+
</p>
|
|
52
|
+
<button
|
|
53
|
+
class="MuiButtonBase-root PicassoButton-medium PicassoButton-primary PicassoButton-root"
|
|
54
|
+
data-component-type="button"
|
|
55
|
+
tabindex="0"
|
|
56
|
+
type="button"
|
|
57
|
+
>
|
|
58
|
+
<span
|
|
59
|
+
class="PicassoContainer-centerAlignItems PicassoContainer-flex PicassoContainer-inline PicassoButton-content"
|
|
60
|
+
>
|
|
61
|
+
Hide
|
|
62
|
+
</span>
|
|
63
|
+
</button>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
<div
|
|
67
|
+
data-test="sentinelEnd"
|
|
68
|
+
tabindex="0"
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
</body>
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
exports[`Modal useModal opens and closes modal 2`] = `
|
|
77
|
+
<body>
|
|
78
|
+
<div
|
|
79
|
+
id="modal-root"
|
|
80
|
+
/>
|
|
81
|
+
<div>
|
|
82
|
+
<div
|
|
83
|
+
class="Picasso-root"
|
|
84
|
+
>
|
|
85
|
+
<button
|
|
86
|
+
class="MuiButtonBase-root PicassoButton-medium PicassoButton-primary PicassoButton-root"
|
|
87
|
+
data-component-type="button"
|
|
88
|
+
tabindex="0"
|
|
89
|
+
type="button"
|
|
90
|
+
>
|
|
91
|
+
<span
|
|
92
|
+
class="PicassoContainer-centerAlignItems PicassoContainer-flex PicassoContainer-inline PicassoButton-content"
|
|
93
|
+
>
|
|
94
|
+
Show
|
|
95
|
+
</span>
|
|
96
|
+
</button>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</body>
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
exports[`Modal useModal shows multiple modals at the same time 1`] = `
|
|
103
|
+
<body>
|
|
104
|
+
<div
|
|
105
|
+
id="modal-root"
|
|
106
|
+
/>
|
|
107
|
+
<div>
|
|
108
|
+
<div
|
|
109
|
+
class="Picasso-root"
|
|
110
|
+
>
|
|
111
|
+
<button
|
|
112
|
+
aria-hidden="true"
|
|
113
|
+
class="MuiButtonBase-root PicassoButton-medium PicassoButton-primary PicassoButton-root"
|
|
114
|
+
data-component-type="button"
|
|
115
|
+
tabindex="0"
|
|
116
|
+
type="button"
|
|
117
|
+
>
|
|
118
|
+
<span
|
|
119
|
+
class="PicassoContainer-centerAlignItems PicassoContainer-flex PicassoContainer-inline PicassoButton-content"
|
|
120
|
+
>
|
|
121
|
+
Show first
|
|
122
|
+
</span>
|
|
123
|
+
</button>
|
|
124
|
+
<button
|
|
125
|
+
aria-hidden="true"
|
|
126
|
+
class="MuiButtonBase-root PicassoButton-medium PicassoButton-primary PicassoButton-root"
|
|
127
|
+
data-component-type="button"
|
|
128
|
+
tabindex="0"
|
|
129
|
+
type="button"
|
|
130
|
+
>
|
|
131
|
+
<span
|
|
132
|
+
class="PicassoContainer-centerAlignItems PicassoContainer-flex PicassoContainer-inline PicassoButton-content"
|
|
133
|
+
>
|
|
134
|
+
Show second
|
|
135
|
+
</span>
|
|
136
|
+
</button>
|
|
137
|
+
<div
|
|
138
|
+
aria-hidden="true"
|
|
139
|
+
class="MuiDialog-root PicassoModal-root"
|
|
140
|
+
role="presentation"
|
|
141
|
+
style="position: fixed; z-index: 1300; right: 0px; bottom: 0px; top: 0px; left: 0px;"
|
|
142
|
+
>
|
|
143
|
+
<div
|
|
144
|
+
aria-hidden="true"
|
|
145
|
+
class="MuiBackdrop-root"
|
|
146
|
+
style="opacity: 1; webkit-transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
|
|
147
|
+
/>
|
|
148
|
+
<div
|
|
149
|
+
data-test="sentinelStart"
|
|
150
|
+
tabindex="0"
|
|
151
|
+
/>
|
|
152
|
+
<div
|
|
153
|
+
class="MuiDialog-container PicassoModal-container MuiDialog-scrollPaper"
|
|
154
|
+
role="none presentation"
|
|
155
|
+
style="opacity: 1; webkit-transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
|
|
156
|
+
tabindex="-1"
|
|
157
|
+
>
|
|
158
|
+
<div
|
|
159
|
+
class="MuiPaper-root MuiDialog-paper PicassoModal-paper PicassoModal-medium MuiDialog-paperScrollPaper MuiDialog-paperWidthFalse MuiPaper-elevation2"
|
|
160
|
+
role="dialog"
|
|
161
|
+
>
|
|
162
|
+
<p>
|
|
163
|
+
First modal content
|
|
164
|
+
</p>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
<div
|
|
168
|
+
data-test="sentinelEnd"
|
|
169
|
+
tabindex="0"
|
|
170
|
+
/>
|
|
171
|
+
</div>
|
|
172
|
+
<div
|
|
173
|
+
class="MuiDialog-root PicassoModal-root"
|
|
174
|
+
role="presentation"
|
|
175
|
+
style="position: fixed; z-index: 1300; right: 0px; bottom: 0px; top: 0px; left: 0px;"
|
|
176
|
+
>
|
|
177
|
+
<div
|
|
178
|
+
aria-hidden="true"
|
|
179
|
+
class="MuiBackdrop-root"
|
|
180
|
+
style="opacity: 1; webkit-transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
|
|
181
|
+
/>
|
|
182
|
+
<div
|
|
183
|
+
data-test="sentinelStart"
|
|
184
|
+
tabindex="0"
|
|
185
|
+
/>
|
|
186
|
+
<div
|
|
187
|
+
class="MuiDialog-container PicassoModal-container MuiDialog-scrollPaper"
|
|
188
|
+
role="none presentation"
|
|
189
|
+
style="opacity: 1; webkit-transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; transition: opacity 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
|
|
190
|
+
tabindex="-1"
|
|
191
|
+
>
|
|
192
|
+
<div
|
|
193
|
+
class="MuiPaper-root MuiDialog-paper PicassoModal-paper PicassoModal-medium MuiDialog-paperScrollPaper MuiDialog-paperWidthFalse MuiPaper-elevation2"
|
|
194
|
+
role="dialog"
|
|
195
|
+
>
|
|
196
|
+
<p>
|
|
197
|
+
Second modal content
|
|
198
|
+
</p>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
<div
|
|
202
|
+
data-test="sentinelEnd"
|
|
203
|
+
tabindex="0"
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
</body>
|
|
209
|
+
`;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class ModalManager {
|
|
2
|
+
modals: number[] = []
|
|
3
|
+
|
|
4
|
+
add(modalId: number) {
|
|
5
|
+
if (this.modals.includes(modalId)) {
|
|
6
|
+
return
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
this.modals.push(modalId)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
remove(modalId: number) {
|
|
13
|
+
const modalIndex = this.modals.indexOf(modalId)
|
|
14
|
+
|
|
15
|
+
if (modalIndex === -1) {
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
this.modals.splice(modalIndex, 1)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
isTopModal(modalId: number) {
|
|
23
|
+
return (
|
|
24
|
+
this.modals.length > 0 && this.modals[this.modals.length - 1] === modalId
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {
|
|
3
|
+
render,
|
|
4
|
+
fireEvent,
|
|
5
|
+
waitForElementToBeRemoved,
|
|
6
|
+
} from '@toptal/picasso-test-utils'
|
|
7
|
+
import { Button } from '@toptal/picasso-button'
|
|
8
|
+
import { Modal } from '@toptal/picasso-modal'
|
|
9
|
+
|
|
10
|
+
import { useModal } from './use-modal'
|
|
11
|
+
|
|
12
|
+
let modalRoot: HTMLElement
|
|
13
|
+
|
|
14
|
+
describe('Modal', () => {
|
|
15
|
+
beforeAll(() => {
|
|
16
|
+
modalRoot = document.createElement('div')
|
|
17
|
+
|
|
18
|
+
modalRoot.setAttribute('id', 'modal-root')
|
|
19
|
+
document.body.appendChild(modalRoot)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('useModal opens and closes modal', async () => {
|
|
23
|
+
const TestComponent = () => {
|
|
24
|
+
const { showModal, hideModal, isOpen } = useModal()
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<>
|
|
28
|
+
<Button onClick={showModal}>Show</Button>
|
|
29
|
+
|
|
30
|
+
<Modal open={isOpen}>
|
|
31
|
+
<p>Modal content</p>
|
|
32
|
+
<Button onClick={hideModal}>Hide</Button>
|
|
33
|
+
</Modal>
|
|
34
|
+
</>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const { getByText, queryByText, baseElement } = render(<TestComponent />)
|
|
39
|
+
|
|
40
|
+
const showModalButton = getByText('Show')
|
|
41
|
+
|
|
42
|
+
fireEvent.click(showModalButton)
|
|
43
|
+
|
|
44
|
+
expect(queryByText('Modal content')).toBeTruthy()
|
|
45
|
+
expect(baseElement).toMatchSnapshot()
|
|
46
|
+
|
|
47
|
+
const hideModalButton = getByText('Hide')
|
|
48
|
+
|
|
49
|
+
fireEvent.click(hideModalButton)
|
|
50
|
+
await waitForElementToBeRemoved(() => getByText('Hide'))
|
|
51
|
+
|
|
52
|
+
expect(queryByText('Modal content')).toBeFalsy()
|
|
53
|
+
expect(baseElement).toMatchSnapshot()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('useModal shows multiple modals at the same time', () => {
|
|
57
|
+
const TestComponent = () => {
|
|
58
|
+
const { showModal: showModal1, isOpen: isOpen1 } = useModal()
|
|
59
|
+
const { showModal: showModal2, isOpen: isOpen2 } = useModal()
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
<Button onClick={showModal1}>Show first</Button>
|
|
64
|
+
<Modal open={isOpen1}>
|
|
65
|
+
<p>First modal content</p>
|
|
66
|
+
</Modal>
|
|
67
|
+
|
|
68
|
+
<Button onClick={showModal2}>Show second</Button>
|
|
69
|
+
<Modal open={isOpen2}>
|
|
70
|
+
<p>Second modal content</p>
|
|
71
|
+
</Modal>
|
|
72
|
+
</>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const { getByText, queryByText, baseElement } = render(<TestComponent />)
|
|
77
|
+
|
|
78
|
+
fireEvent.click(getByText('Show first'))
|
|
79
|
+
fireEvent.click(getByText('Show second'))
|
|
80
|
+
|
|
81
|
+
expect(queryByText('First modal content')).toBeTruthy()
|
|
82
|
+
expect(queryByText('Second modal content')).toBeTruthy()
|
|
83
|
+
|
|
84
|
+
expect(baseElement).toMatchSnapshot()
|
|
85
|
+
})
|
|
86
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useCallback, useState } from 'react'
|
|
2
|
+
|
|
3
|
+
const useModal = () => {
|
|
4
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
5
|
+
|
|
6
|
+
const hideModal = useCallback(() => setIsOpen(false), [setIsOpen])
|
|
7
|
+
|
|
8
|
+
const showModal = useCallback(() => setIsOpen(true), [setIsOpen])
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
showModal,
|
|
12
|
+
hideModal,
|
|
13
|
+
isOpen,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { useModal }
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { shadows, SPACING_6, SPACING_8, SPACING_4 } from '@toptal/picasso-utils'
|
|
4
|
+
import { Container, Typography, Grid } from '@toptal/picasso'
|
|
5
|
+
|
|
6
|
+
const Example = () => (
|
|
7
|
+
<Container flex direction='column' gap={SPACING_6} top={SPACING_8}>
|
|
8
|
+
<Grid spacing={80}>
|
|
9
|
+
<ShadowBox shadow={shadows[0]} index={0} description={'none'} />
|
|
10
|
+
<ShadowBox
|
|
11
|
+
shadow={shadows[1]}
|
|
12
|
+
index={1}
|
|
13
|
+
description={'notification center, paper'}
|
|
14
|
+
/>
|
|
15
|
+
<ShadowBox shadow={shadows[2]} index={2} description={'modal'} />
|
|
16
|
+
<ShadowBox
|
|
17
|
+
shadow={shadows[3]}
|
|
18
|
+
index={3}
|
|
19
|
+
description={'notification growl'}
|
|
20
|
+
/>
|
|
21
|
+
<ShadowBox shadow={shadows[4]} index={4} description={'tooltip'} />
|
|
22
|
+
<ShadowBox shadow={shadows[5]} index={5} description={'scroll menu'} />
|
|
23
|
+
</Grid>
|
|
24
|
+
</Container>
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
interface ShadowBoxProps {
|
|
28
|
+
shadow: string
|
|
29
|
+
index: number
|
|
30
|
+
description?: ReactNode
|
|
31
|
+
}
|
|
32
|
+
const ShadowBox = ({ index, shadow, description }: ShadowBoxProps) => (
|
|
33
|
+
<Grid.Item sm={4}>
|
|
34
|
+
<Container padded={SPACING_4} style={{ boxShadow: shadow }}>
|
|
35
|
+
<Typography variant='heading' size='large' align='center'>
|
|
36
|
+
{index}
|
|
37
|
+
</Typography>
|
|
38
|
+
<Typography size='xsmall' align='center'>
|
|
39
|
+
{description}
|
|
40
|
+
</Typography>
|
|
41
|
+
</Container>
|
|
42
|
+
</Grid.Item>
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
export default Example
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { shadows, SPACING_4 } from '@toptal/picasso-utils'
|
|
3
|
+
import { Container, Typography } from '@toptal/picasso'
|
|
4
|
+
|
|
5
|
+
const Example = () => (
|
|
6
|
+
<Typography>
|
|
7
|
+
Use the shadow just directly from Picasso. For example,
|
|
8
|
+
<Container
|
|
9
|
+
padded={SPACING_4}
|
|
10
|
+
top={SPACING_4}
|
|
11
|
+
style={{ boxShadow: shadows[4] }}
|
|
12
|
+
rounded
|
|
13
|
+
>
|
|
14
|
+
I have a box-shadow like a tooltip
|
|
15
|
+
</Container>
|
|
16
|
+
</Typography>
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
export default Example
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import PicassoBook from '~/.storybook/components/PicassoBook'
|
|
2
|
+
|
|
3
|
+
const page = PicassoBook.section('Utils').createPage('Shadows')
|
|
4
|
+
|
|
5
|
+
page
|
|
6
|
+
.createChapter()
|
|
7
|
+
.addExample(
|
|
8
|
+
'utils/Shadows/story/HowToUse.example.tsx',
|
|
9
|
+
{
|
|
10
|
+
title: 'How to use',
|
|
11
|
+
takeScreenshot: false,
|
|
12
|
+
},
|
|
13
|
+
'base/Utils'
|
|
14
|
+
)
|
|
15
|
+
.addExample(
|
|
16
|
+
'utils/Shadows/story/Default.example.tsx',
|
|
17
|
+
'Shadows',
|
|
18
|
+
'base/Utils'
|
|
19
|
+
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import cx from 'classnames'
|
|
4
|
+
import type { BaseProps } from '@toptal/picasso-shared'
|
|
5
|
+
import type { Theme } from '@material-ui/core/styles'
|
|
6
|
+
import { makeStyles } from '@material-ui/core/styles'
|
|
7
|
+
|
|
8
|
+
import styles from './styles'
|
|
9
|
+
|
|
10
|
+
export interface Props extends BaseProps {
|
|
11
|
+
/** Flag for transition execution. */
|
|
12
|
+
on: boolean
|
|
13
|
+
/** Element to apply transitions. */
|
|
14
|
+
children: ReactNode
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const useStyles = makeStyles<Theme>(styles, {
|
|
18
|
+
name: 'Rotate180',
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
export const Rotate180 = (props: Props) => {
|
|
22
|
+
const { children, style, className, on, ...rest } = props
|
|
23
|
+
const classes = useStyles()
|
|
24
|
+
|
|
25
|
+
const childProps = {
|
|
26
|
+
className: cx(className, classes.transition, {
|
|
27
|
+
[classes.rotate180]: on,
|
|
28
|
+
}),
|
|
29
|
+
style,
|
|
30
|
+
...rest,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
{React.Children.map(children, child =>
|
|
36
|
+
React.cloneElement(child as ReactElement, childProps)
|
|
37
|
+
)}
|
|
38
|
+
</>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
Rotate180.displayName = 'Rotate180'
|
|
43
|
+
|
|
44
|
+
export default Rotate180
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Rotate180 render with transformation 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="Picasso-root"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="Rotate180-transition Rotate180-rotate180"
|
|
10
|
+
>
|
|
11
|
+
Rotating component
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
exports[`Rotate180 render without transformation 1`] = `
|
|
18
|
+
<div>
|
|
19
|
+
<div
|
|
20
|
+
class="Picasso-root"
|
|
21
|
+
>
|
|
22
|
+
<div
|
|
23
|
+
class="Rotate180-transition"
|
|
24
|
+
>
|
|
25
|
+
Rotating component
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
`;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import { Transitions, SPACING_6 } from '@toptal/picasso-utils'
|
|
3
|
+
import { Button, Container } from '@toptal/picasso'
|
|
4
|
+
import { ArrowDownMinor24 } from '@toptal/picasso-icons'
|
|
5
|
+
|
|
6
|
+
const Example = () => {
|
|
7
|
+
const [isRotated, setIsRotated] = useState(false)
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<Button onClick={() => setIsRotated(!isRotated)}>Rotate</Button>
|
|
12
|
+
|
|
13
|
+
<Container top={SPACING_6}>
|
|
14
|
+
<Transitions.Rotate180 on={isRotated}>
|
|
15
|
+
<ArrowDownMinor24 />
|
|
16
|
+
</Transitions.Rotate180>
|
|
17
|
+
</Container>
|
|
18
|
+
</>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default Example
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render } from '@toptal/picasso-test-utils'
|
|
3
|
+
|
|
4
|
+
import { Rotate180 } from './Rotate180'
|
|
5
|
+
|
|
6
|
+
describe('Rotate180', () => {
|
|
7
|
+
it('render without transformation', () => {
|
|
8
|
+
const { container } = render(
|
|
9
|
+
<Rotate180 on={false}>
|
|
10
|
+
<div>Rotating component</div>
|
|
11
|
+
</Rotate180>
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
expect(container).toMatchSnapshot()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('render with transformation', () => {
|
|
18
|
+
const { container } = render(
|
|
19
|
+
<Rotate180 on>
|
|
20
|
+
<div>Rotating component</div>
|
|
21
|
+
</Rotate180>
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
expect(container).toMatchSnapshot()
|
|
25
|
+
})
|
|
26
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import PicassoBook from '~/.storybook/components/PicassoBook'
|
|
2
|
+
|
|
3
|
+
const page = PicassoBook.section('Utils').createPage('Transitions')
|
|
4
|
+
|
|
5
|
+
page.createChapter().addExample(
|
|
6
|
+
'utils/Transitions/Rotate180/story/Default.example.tsx',
|
|
7
|
+
{
|
|
8
|
+
title: 'Rotate180',
|
|
9
|
+
description: 'Transition for 180 deg rotation',
|
|
10
|
+
takeScreenshot: false,
|
|
11
|
+
},
|
|
12
|
+
'base/Utils'
|
|
13
|
+
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Table } from '@toptal/picasso'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
const data = {
|
|
5
|
+
isPointerDevice: `Checks if the primary input mechanism includes an accurate pointing device`,
|
|
6
|
+
isBrowser: `Checks if there is a browser or not.`,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const Example = () => (
|
|
10
|
+
<Table>
|
|
11
|
+
<Table.Head>
|
|
12
|
+
<Table.Row>
|
|
13
|
+
<Table.Cell>Name</Table.Cell>
|
|
14
|
+
<Table.Cell>Description</Table.Cell>
|
|
15
|
+
</Table.Row>
|
|
16
|
+
</Table.Head>
|
|
17
|
+
<Table.Body>
|
|
18
|
+
{Object.entries(data).map(([name, description]) => (
|
|
19
|
+
<Table.Row key={name}>
|
|
20
|
+
<Table.Cell>{name}</Table.Cell>
|
|
21
|
+
<Table.Cell>{description}</Table.Cell>
|
|
22
|
+
</Table.Row>
|
|
23
|
+
))}
|
|
24
|
+
</Table.Body>
|
|
25
|
+
</Table>
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
export default Example
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Table } from '@toptal/picasso'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
const data = {
|
|
5
|
+
'colorUtils.alpha': `Sets the alpha channel for the color and returns the hex color format`,
|
|
6
|
+
'colorUtils.lighten': `Sets the lightness of the color and returns the hex color format`,
|
|
7
|
+
'colorUtils.darken': `Sets the darkness of the color and returns the hex color format`,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const Example = () => (
|
|
11
|
+
<Table>
|
|
12
|
+
<Table.Head>
|
|
13
|
+
<Table.Row>
|
|
14
|
+
<Table.Cell>Name</Table.Cell>
|
|
15
|
+
<Table.Cell>Description</Table.Cell>
|
|
16
|
+
</Table.Row>
|
|
17
|
+
</Table.Head>
|
|
18
|
+
<Table.Body>
|
|
19
|
+
{Object.entries(data).map(([name, description]) => (
|
|
20
|
+
<Table.Row key={name}>
|
|
21
|
+
<Table.Cell>{name}</Table.Cell>
|
|
22
|
+
<Table.Cell>{description}</Table.Cell>
|
|
23
|
+
</Table.Row>
|
|
24
|
+
))}
|
|
25
|
+
</Table.Body>
|
|
26
|
+
</Table>
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
export default Example
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Table } from '@toptal/picasso'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
|
|
4
|
+
const data = {
|
|
5
|
+
noop: `A function that does nothing, a replacement for () => {}`,
|
|
6
|
+
isBoolean: `Checks if the provided value is a boolean`,
|
|
7
|
+
isNumber: `Checks if the provided value is a number`,
|
|
8
|
+
isString: `Checks if the provided value is a string`,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const Example = () => (
|
|
12
|
+
<Table>
|
|
13
|
+
<Table.Head>
|
|
14
|
+
<Table.Row>
|
|
15
|
+
<Table.Cell>Name</Table.Cell>
|
|
16
|
+
<Table.Cell>Description</Table.Cell>
|
|
17
|
+
</Table.Row>
|
|
18
|
+
</Table.Head>
|
|
19
|
+
<Table.Body>
|
|
20
|
+
{Object.entries(data).map(([name, description]) => (
|
|
21
|
+
<Table.Row key={name}>
|
|
22
|
+
<Table.Cell>{name}</Table.Cell>
|
|
23
|
+
<Table.Cell>{description}</Table.Cell>
|
|
24
|
+
</Table.Row>
|
|
25
|
+
))}
|
|
26
|
+
</Table.Body>
|
|
27
|
+
</Table>
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
export default Example
|