@toptal/picasso-fade 1.0.1

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.
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { BaseProps, TransitionProps } from '@toptal/picasso-shared';
3
+ export interface Props extends TransitionProps, BaseProps {
4
+ children: React.ReactElement;
5
+ in: boolean;
6
+ onEnter?: (node: HTMLElement, isAppearing: boolean) => void;
7
+ }
8
+ export declare const Fade: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLDivElement>>;
9
+ export default Fade;
10
+ //# sourceMappingURL=Fade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Fade.d.ts","sourceRoot":"","sources":["../../../src/Fade/Fade.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiB,MAAM,OAAO,CAAA;AAErC,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAGxE,MAAM,WAAW,KAAM,SAAQ,eAAe,EAAE,SAAS;IAEvD,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAA;IAE5B,EAAE,EAAE,OAAO,CAAA;IAEX,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,KAAK,IAAI,CAAA;CAC5D;AAED,eAAO,MAAM,IAAI,8EAiDhB,CAAA;AAED,eAAe,IAAI,CAAA"}
@@ -0,0 +1,24 @@
1
+ import React, { useRef } from 'react';
2
+ import { Transition } from 'react-transition-group';
3
+ import { useMultipleForwardRefs } from '@toptal/picasso-utils';
4
+ export const Fade = React.forwardRef(({ timeout = 300, children, in: inProp, style, onEnter, onExited }, ref) => {
5
+ const nodeRef = useRef(null);
6
+ const transitionStyles = {
7
+ entering: { opacity: 1 },
8
+ entered: { opacity: 1 },
9
+ exiting: { opacity: 0 },
10
+ exited: { opacity: 0 },
11
+ };
12
+ const combinedRef = useMultipleForwardRefs([
13
+ ref,
14
+ nodeRef,
15
+ // TODO: come up with proper type for children.ref
16
+ // @ts-ignore
17
+ children.ref,
18
+ ]);
19
+ return (React.createElement(Transition, { appear: true, nodeRef: nodeRef, in: inProp, timeout: timeout, onExited: onExited, onEnter: onEnter }, (state, childProps) => {
20
+ return React.cloneElement(children, Object.assign({ style: Object.assign(Object.assign(Object.assign({ visibility: state === 'exited' && !inProp ? 'hidden' : undefined, transitionDuration: `${timeout}ms` }, transitionStyles[state]), style), children.props.style), className: `opacity-0 transition-opacity ${children.props.className || ''}`, ref: combinedRef }, childProps));
21
+ }));
22
+ });
23
+ export default Fade;
24
+ //# sourceMappingURL=Fade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Fade.js","sourceRoot":"","sources":["../../../src/Fade/Fade.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAEnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAW9D,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAClC,CAAC,EAAE,OAAO,GAAG,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE;IACzE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;IAC5B,MAAM,gBAAgB,GAAG;QACvB,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;QACxB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;QACvB,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;QACvB,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;KACvB,CAAA;IAED,MAAM,WAAW,GAAG,sBAAsB,CAAC;QACzC,GAAG;QACH,OAAO;QACP,kDAAkD;QAClD,aAAa;QACb,QAAQ,CAAC,GAAG;KACb,CAAC,CAAA;IAEF,OAAO,CACL,oBAAC,UAAU,IACT,MAAM,QACN,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,IAEf,CACC,KAAoD,EACpD,UAAc,EACd,EAAE;QACF,OAAO,KAAK,CAAC,YAAY,CAAC,QAAQ,kBAChC,KAAK,8CACH,UAAU,EAAE,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAChE,kBAAkB,EAAE,GAAG,OAAO,IAAI,IAC/B,gBAAgB,CAAC,KAAK,CAAC,GACvB,KAAK,GACL,QAAQ,CAAC,KAAK,CAAC,KAAK,GAEzB,SAAS,EAAE,gCACT,QAAQ,CAAC,KAAK,CAAC,SAAS,IAAI,EAC9B,EAAE,EACF,GAAG,EAAE,WAAW,IACb,UAAU,EACb,CAAA;IACJ,CAAC,CACU,CACd,CAAA;AACH,CAAC,CACF,CAAA;AAED,eAAe,IAAI,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { OmitInternalProps } from '@toptal/picasso-shared';
2
+ import type { Props } from './Fade';
3
+ export { default as Fade } from './Fade';
4
+ export declare type FadeProps = OmitInternalProps<Props>;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Fade/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAE/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAEnC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAA;AACxC,oBAAY,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { default as Fade } from './Fade';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/Fade/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './Fade';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './Fade';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@toptal/picasso-fade",
3
+ "version": "1.0.1",
4
+ "description": "Toptal UI components library - Fade",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "main": "./dist-package/src/index.js",
9
+ "module": "./dist-package/src/index.js",
10
+ "scripts": {
11
+ "build:package": "tsc -b tsconfig.json",
12
+ "prepublishOnly": "yarn build:package"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/toptal/picasso.git"
17
+ },
18
+ "author": "Toptal",
19
+ "license": "MIT",
20
+ "bugs": {
21
+ "url": "https://github.com/toptal/picasso/issues"
22
+ },
23
+ "homepage": "https://github.com/toptal/picasso/tree/master/packages/picasso#readme",
24
+ "dependencies": {
25
+ "@toptal/picasso-utils": "1.0.1",
26
+ "react-transition-group": "^4.4.5"
27
+ },
28
+ "sideEffects": false,
29
+ "peerDependencies": {
30
+ "@toptal/picasso-tailwind": ">2.1.0",
31
+ "react": ">=16.12.0 < 19.0.0",
32
+ "tailwindcss": ">=3"
33
+ },
34
+ "exports": {
35
+ ".": "./dist-package/src/index.js"
36
+ },
37
+ "devDependencies": {
38
+ "@toptal/picasso-test-utils": "1.0.1"
39
+ },
40
+ "files": [
41
+ "dist-package/**",
42
+ "!dist-package/tsconfig.tsbuildinfo",
43
+ "src"
44
+ ]
45
+ }
@@ -0,0 +1,66 @@
1
+ import React, { useRef } from 'react'
2
+ import { Transition } from 'react-transition-group'
3
+ import type { BaseProps, TransitionProps } from '@toptal/picasso-shared'
4
+ import { useMultipleForwardRefs } from '@toptal/picasso-utils'
5
+
6
+ export interface Props extends TransitionProps, BaseProps {
7
+ /* Element that accepts ref */
8
+ children: React.ReactElement
9
+ /* Show the component; triggers the enter or exit states */
10
+ in: boolean
11
+ /* Callback fired when the component has entered */
12
+ onEnter?: (node: HTMLElement, isAppearing: boolean) => void
13
+ }
14
+
15
+ export const Fade = React.forwardRef<HTMLDivElement, Props>(
16
+ ({ timeout = 300, children, in: inProp, style, onEnter, onExited }, ref) => {
17
+ const nodeRef = useRef(null)
18
+ const transitionStyles = {
19
+ entering: { opacity: 1 },
20
+ entered: { opacity: 1 },
21
+ exiting: { opacity: 0 },
22
+ exited: { opacity: 0 },
23
+ }
24
+
25
+ const combinedRef = useMultipleForwardRefs([
26
+ ref,
27
+ nodeRef,
28
+ // TODO: come up with proper type for children.ref
29
+ // @ts-ignore
30
+ children.ref,
31
+ ])
32
+
33
+ return (
34
+ <Transition
35
+ appear
36
+ nodeRef={nodeRef}
37
+ in={inProp}
38
+ timeout={timeout}
39
+ onExited={onExited}
40
+ onEnter={onEnter}
41
+ >
42
+ {(
43
+ state: 'entering' | 'entered' | 'exiting' | 'exited',
44
+ childProps: {}
45
+ ) => {
46
+ return React.cloneElement(children, {
47
+ style: {
48
+ visibility: state === 'exited' && !inProp ? 'hidden' : undefined,
49
+ transitionDuration: `${timeout}ms`,
50
+ ...transitionStyles[state],
51
+ ...style,
52
+ ...children.props.style,
53
+ },
54
+ className: `opacity-0 transition-opacity ${
55
+ children.props.className || ''
56
+ }`,
57
+ ref: combinedRef,
58
+ ...childProps,
59
+ })
60
+ }}
61
+ </Transition>
62
+ )
63
+ }
64
+ )
65
+
66
+ export default Fade
@@ -0,0 +1,6 @@
1
+ import type { OmitInternalProps } from '@toptal/picasso-shared'
2
+
3
+ import type { Props } from './Fade'
4
+
5
+ export { default as Fade } from './Fade'
6
+ export type FadeProps = OmitInternalProps<Props>
@@ -0,0 +1,21 @@
1
+ import { Container, Button } from '@toptal/picasso'
2
+ import { Fade } from '@toptal/picasso-fade'
3
+ import { SPACING_4 } from '@toptal/picasso-utils'
4
+ import React, { useState } from 'react'
5
+
6
+ const Example = () => {
7
+ const [faded, setFaded] = useState(false)
8
+
9
+ const handleOnClick = () => setFaded(prevFaded => !prevFaded)
10
+
11
+ return (
12
+ <Container bottom={SPACING_4}>
13
+ <Button onClick={handleOnClick}>Toggle Fade</Button>
14
+ <Fade in={faded} timeout={3000}>
15
+ <div className='bg-red-500 p-4'>Fade in</div>
16
+ </Fade>
17
+ </Container>
18
+ )
19
+ }
20
+
21
+ export default Example
@@ -0,0 +1,18 @@
1
+ import { Fade } from '../Fade'
2
+ import PicassoBook from '~/.storybook/components/PicassoBook'
3
+
4
+ const page = PicassoBook.section('Components').createPage('Fade')
5
+
6
+ page.createTabChapter('Props').addComponentDocs({
7
+ component: Fade,
8
+ name: 'Fade',
9
+ })
10
+
11
+ page.createChapter().addExample(
12
+ 'Fade/story/Default.example.tsx',
13
+ {
14
+ title: 'Default',
15
+ takeScreenshot: false,
16
+ },
17
+ 'base/Fade'
18
+ )
@@ -0,0 +1,76 @@
1
+ import React from 'react'
2
+ import { act, cleanup, render } from '@toptal/picasso-test-utils'
3
+
4
+ import Fade from './Fade'
5
+
6
+ const SomeChildComponent = React.forwardRef<HTMLDivElement>((props, ref) => (
7
+ <div ref={ref} data-testid='child-div' {...props}>
8
+ Hello, I'm child div!
9
+ </div>
10
+ ))
11
+
12
+ describe('Fade', () => {
13
+ beforeEach(() => {
14
+ jest.useFakeTimers()
15
+ })
16
+
17
+ afterEach(() => {
18
+ cleanup()
19
+ jest.useRealTimers()
20
+ })
21
+
22
+ it('renders without errors', () => {
23
+ const { getByTestId } = render(
24
+ <Fade in={true}>
25
+ <SomeChildComponent />
26
+ </Fade>
27
+ )
28
+
29
+ expect(getByTestId('child-div')).toBeInTheDocument()
30
+ })
31
+
32
+ it('transitions based on the `in` prop', () => {
33
+ const { getByTestId, rerender } = render(
34
+ <Fade in={false}>
35
+ <SomeChildComponent />
36
+ </Fade>
37
+ )
38
+
39
+ expect(getByTestId('child-div')).toHaveStyle('visibility: hidden')
40
+
41
+ act(() => {
42
+ rerender(
43
+ <Fade in={true}>
44
+ <SomeChildComponent />
45
+ </Fade>
46
+ )
47
+ jest.runAllTimers()
48
+ })
49
+
50
+ expect(getByTestId('child-div')).toHaveStyle('visibility: visible')
51
+ })
52
+
53
+ it('forwards the ref', () => {
54
+ const ref = React.createRef<HTMLDivElement>()
55
+ const { getByTestId } = render(
56
+ <Fade in={true} ref={ref}>
57
+ <SomeChildComponent />
58
+ </Fade>
59
+ )
60
+
61
+ expect(ref.current).toBe(getByTestId('child-div'))
62
+ })
63
+
64
+ it('applies transition duration style', () => {
65
+ const timeout = 500
66
+ const { getByTestId } = render(
67
+ <Fade in={true} timeout={timeout}>
68
+ <SomeChildComponent />
69
+ </Fade>
70
+ )
71
+
72
+ expect(getByTestId('child-div')).toHaveStyle({
73
+ transitionDuration: `${timeout}ms`,
74
+ })
75
+ })
76
+ })
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './Fade'