@atlaskit/modal-dialog 12.0.2
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/CHANGELOG.md +2111 -0
- package/LICENSE +13 -0
- package/README.md +13 -0
- package/__perf__/default.tsx +42 -0
- package/__perf__/interactions.tsx +136 -0
- package/__perf__/scroll.tsx +98 -0
- package/codemods/12.0.0-lite-mode.ts +51 -0
- package/codemods/__tests__/12.0.0-lite-mode.test.ts +493 -0
- package/codemods/__tests__/handle-prop-spread.tsx +276 -0
- package/codemods/__tests__/inline-WidthNames-declaration.test.ts +260 -0
- package/codemods/__tests__/map-actions-prop.tsx +436 -0
- package/codemods/__tests__/map-body-from-props.test.ts +645 -0
- package/codemods/__tests__/map-container-from-props.test.ts +323 -0
- package/codemods/__tests__/map-footer-from-props.test.ts +544 -0
- package/codemods/__tests__/map-header-from-props.test.ts +559 -0
- package/codemods/__tests__/map-heading-prop.tsx +438 -0
- package/codemods/__tests__/remove-appearance-prop.test.ts +79 -0
- package/codemods/__tests__/remove-component-override-props.test.ts +153 -0
- package/codemods/__tests__/remove-is-chromeless.tsx +182 -0
- package/codemods/__tests__/rename-appearance-type.test.ts +52 -0
- package/codemods/__tests__/rename-inner-component-prop-types.test.ts +82 -0
- package/codemods/__tests__/rename-scrollBehavior-to-shouldScrollInViewport.test.ts +237 -0
- package/codemods/internal/constants.tsx +41 -0
- package/codemods/internal/utils.tsx +223 -0
- package/codemods/migrations/handle-prop-spread.tsx +51 -0
- package/codemods/migrations/inline-WidthNames-declaration.ts +92 -0
- package/codemods/migrations/map-actions-prop.tsx +430 -0
- package/codemods/migrations/map-body-from-props.ts +147 -0
- package/codemods/migrations/map-container-from-props.ts +72 -0
- package/codemods/migrations/map-footer-from-props.ts +107 -0
- package/codemods/migrations/map-header-from-props.ts +101 -0
- package/codemods/migrations/map-heading-prop.tsx +193 -0
- package/codemods/migrations/remove-appearance-prop.ts +27 -0
- package/codemods/migrations/remove-component-override-props.ts +84 -0
- package/codemods/migrations/remove-is-chromeless.tsx +42 -0
- package/codemods/migrations/rename-appearance-type.ts +9 -0
- package/codemods/migrations/rename-inner-component-prop-types.ts +28 -0
- package/codemods/migrations/rename-scrollBehavior-to-shouldScrollInViewport.ts +82 -0
- package/dist/cjs/hooks.js +22 -0
- package/dist/cjs/index.js +63 -0
- package/dist/cjs/internal/components/modal-dialog.js +155 -0
- package/dist/cjs/internal/components/positioner.js +89 -0
- package/dist/cjs/internal/components/scroll-container.js +138 -0
- package/dist/cjs/internal/constants.js +48 -0
- package/dist/cjs/internal/context.js +13 -0
- package/dist/cjs/internal/hooks/use-modal-stack.js +110 -0
- package/dist/cjs/internal/hooks/use-on-motion-finish.js +24 -0
- package/dist/cjs/internal/hooks/use-prevent-programmatic-scroll.js +55 -0
- package/dist/cjs/internal/hooks/use-scroll.js +20 -0
- package/dist/cjs/internal/utils.js +35 -0
- package/dist/cjs/modal-body.js +66 -0
- package/dist/cjs/modal-footer.js +40 -0
- package/dist/cjs/modal-header.js +43 -0
- package/dist/cjs/modal-title.js +108 -0
- package/dist/cjs/modal-transition.js +21 -0
- package/dist/cjs/modal-wrapper.js +126 -0
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/version.json +5 -0
- package/dist/es2019/hooks.js +11 -0
- package/dist/es2019/index.js +7 -0
- package/dist/es2019/internal/components/modal-dialog.js +120 -0
- package/dist/es2019/internal/components/positioner.js +78 -0
- package/dist/es2019/internal/components/scroll-container.js +97 -0
- package/dist/es2019/internal/constants.js +27 -0
- package/dist/es2019/internal/context.js +3 -0
- package/dist/es2019/internal/hooks/use-modal-stack.js +85 -0
- package/dist/es2019/internal/hooks/use-on-motion-finish.js +17 -0
- package/dist/es2019/internal/hooks/use-prevent-programmatic-scroll.js +39 -0
- package/dist/es2019/internal/hooks/use-scroll.js +11 -0
- package/dist/es2019/internal/utils.js +22 -0
- package/dist/es2019/modal-body.js +50 -0
- package/dist/es2019/modal-footer.js +30 -0
- package/dist/es2019/modal-header.js +30 -0
- package/dist/es2019/modal-title.js +94 -0
- package/dist/es2019/modal-transition.js +10 -0
- package/dist/es2019/modal-wrapper.js +88 -0
- package/dist/es2019/types.js +1 -0
- package/dist/es2019/version.json +5 -0
- package/dist/esm/hooks.js +11 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/internal/components/modal-dialog.js +131 -0
- package/dist/esm/internal/components/positioner.js +76 -0
- package/dist/esm/internal/components/scroll-container.js +114 -0
- package/dist/esm/internal/constants.js +27 -0
- package/dist/esm/internal/context.js +3 -0
- package/dist/esm/internal/hooks/use-modal-stack.js +96 -0
- package/dist/esm/internal/hooks/use-on-motion-finish.js +16 -0
- package/dist/esm/internal/hooks/use-prevent-programmatic-scroll.js +44 -0
- package/dist/esm/internal/hooks/use-scroll.js +11 -0
- package/dist/esm/internal/utils.js +22 -0
- package/dist/esm/modal-body.js +49 -0
- package/dist/esm/modal-footer.js +29 -0
- package/dist/esm/modal-header.js +29 -0
- package/dist/esm/modal-title.js +93 -0
- package/dist/esm/modal-transition.js +10 -0
- package/dist/esm/modal-wrapper.js +96 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/version.json +5 -0
- package/dist/types/hooks.d.ts +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/internal/components/modal-dialog.d.ts +3 -0
- package/dist/types/internal/components/positioner.d.ts +10 -0
- package/dist/types/internal/components/scroll-container.d.ts +20 -0
- package/dist/types/internal/constants.d.ts +25 -0
- package/dist/types/internal/context.d.ts +20 -0
- package/dist/types/internal/hooks/use-modal-stack.d.ts +13 -0
- package/dist/types/internal/hooks/use-on-motion-finish.d.ts +4 -0
- package/dist/types/internal/hooks/use-prevent-programmatic-scroll.d.ts +7 -0
- package/dist/types/internal/hooks/use-scroll.d.ts +1 -0
- package/dist/types/internal/utils.d.ts +3 -0
- package/dist/types/modal-body.d.ts +16 -0
- package/dist/types/modal-footer.d.ts +16 -0
- package/dist/types/modal-header.d.ts +16 -0
- package/dist/types/modal-title.d.ts +26 -0
- package/dist/types/modal-transition.d.ts +3 -0
- package/dist/types/modal-wrapper.d.ts +5 -0
- package/dist/types/types.d.ts +90 -0
- package/extract-react-types/modal-attributes.tsx +5 -0
- package/hooks/package.json +7 -0
- package/modal-body/package.json +7 -0
- package/modal-dialog/package.json +7 -0
- package/modal-footer/package.json +7 -0
- package/modal-header/package.json +7 -0
- package/modal-title/package.json +7 -0
- package/modal-transition/package.json +7 -0
- package/package.json +113 -0
- package/types/package.json +7 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2019 Atlassian Pty Ltd
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Modal dialog
|
|
2
|
+
|
|
3
|
+
A modal dialog displays content that requires user interaction, in a layer above the page.
|
|
4
|
+
|
|
5
|
+
# Installation
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
yarn add @atlaskit/modal-dialog
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Detailed docs and example usage can be found [here](https://atlassian.design/components/modal-dialog/).
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import Button from '@atlaskit/button/standard-button';
|
|
4
|
+
|
|
5
|
+
import Modal, {
|
|
6
|
+
ModalBody,
|
|
7
|
+
ModalFooter,
|
|
8
|
+
ModalHeader,
|
|
9
|
+
ModalTitle,
|
|
10
|
+
ModalTransition,
|
|
11
|
+
} from '../src';
|
|
12
|
+
|
|
13
|
+
export default function Example() {
|
|
14
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
15
|
+
const close = () => setIsOpen(false);
|
|
16
|
+
const open = () => setIsOpen(true);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<>
|
|
20
|
+
<button onClick={open}>open modal</button>
|
|
21
|
+
|
|
22
|
+
<ModalTransition>
|
|
23
|
+
{isOpen && (
|
|
24
|
+
<Modal onClose={close}>
|
|
25
|
+
<ModalHeader>
|
|
26
|
+
<ModalTitle>Modal title</ModalTitle>
|
|
27
|
+
</ModalHeader>
|
|
28
|
+
<ModalBody>A simple Modal</ModalBody>
|
|
29
|
+
<ModalFooter>
|
|
30
|
+
<Button testId="primary" appearance="primary" onClick={close}>
|
|
31
|
+
Close
|
|
32
|
+
</Button>
|
|
33
|
+
<Button testId="secondary" appearance="subtle">
|
|
34
|
+
Secondary Action
|
|
35
|
+
</Button>
|
|
36
|
+
</ModalFooter>
|
|
37
|
+
</Modal>
|
|
38
|
+
)}
|
|
39
|
+
</ModalTransition>
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import React, { useCallback, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { findByText, fireEvent } from '@testing-library/dom';
|
|
4
|
+
import {
|
|
5
|
+
InteractionTaskArgs,
|
|
6
|
+
PublicInteractionTask,
|
|
7
|
+
} from 'storybook-addon-performance';
|
|
8
|
+
|
|
9
|
+
import Button from '@atlaskit/button/standard-button';
|
|
10
|
+
|
|
11
|
+
import Modal, {
|
|
12
|
+
ModalBody,
|
|
13
|
+
ModalFooter,
|
|
14
|
+
ModalHeader,
|
|
15
|
+
ModalTitle,
|
|
16
|
+
ModalTransition,
|
|
17
|
+
} from '../src';
|
|
18
|
+
|
|
19
|
+
const modalText = (index: number) => `Hello, world (${index})`;
|
|
20
|
+
const closeText = (index: number) => `Close (${index})`;
|
|
21
|
+
const openText = (index: number) => `Open (${index})`;
|
|
22
|
+
|
|
23
|
+
const InteractionPerformance = ({ index = 0 }: { index?: number }) => {
|
|
24
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
25
|
+
const open = useCallback(() => setIsOpen(true), []);
|
|
26
|
+
const close = useCallback(() => setIsOpen(false), []);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<>
|
|
30
|
+
<button data-testid="open-button" onClick={open}>
|
|
31
|
+
{openText(index)}
|
|
32
|
+
</button>
|
|
33
|
+
|
|
34
|
+
<ModalTransition>
|
|
35
|
+
{isOpen && (
|
|
36
|
+
<Modal onClose={close}>
|
|
37
|
+
<ModalHeader>
|
|
38
|
+
<ModalTitle>Modal dialog</ModalTitle>
|
|
39
|
+
</ModalHeader>
|
|
40
|
+
<ModalBody>
|
|
41
|
+
{modalText(index)}
|
|
42
|
+
<InteractionPerformance index={index + 1} />
|
|
43
|
+
</ModalBody>
|
|
44
|
+
<ModalFooter>
|
|
45
|
+
<Button testId="primary" appearance="primary" onClick={close}>
|
|
46
|
+
{closeText(index)}
|
|
47
|
+
</Button>
|
|
48
|
+
</ModalFooter>
|
|
49
|
+
</Modal>
|
|
50
|
+
)}
|
|
51
|
+
</ModalTransition>
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const interactionTasks: PublicInteractionTask[] = [
|
|
57
|
+
{
|
|
58
|
+
name: 'Open first',
|
|
59
|
+
description: 'Opens the modal dialog',
|
|
60
|
+
run: async ({
|
|
61
|
+
container,
|
|
62
|
+
controls,
|
|
63
|
+
}: InteractionTaskArgs): Promise<void> => {
|
|
64
|
+
const openButton = await findByText(container, openText(0));
|
|
65
|
+
|
|
66
|
+
await controls.time(async () => {
|
|
67
|
+
fireEvent.click(openButton);
|
|
68
|
+
await findByText(document.body, modalText(0));
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'Close first',
|
|
74
|
+
description: 'Closes the modal dialog',
|
|
75
|
+
run: async ({
|
|
76
|
+
container,
|
|
77
|
+
controls,
|
|
78
|
+
}: InteractionTaskArgs): Promise<void> => {
|
|
79
|
+
const openButton = await findByText(container, openText(0));
|
|
80
|
+
fireEvent.click(openButton);
|
|
81
|
+
|
|
82
|
+
await controls.time(async () => {
|
|
83
|
+
const closeButton = await findByText(document.body, closeText(0));
|
|
84
|
+
fireEvent.click(closeButton);
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'Open second',
|
|
90
|
+
description: 'Opens the a second modal',
|
|
91
|
+
run: async ({
|
|
92
|
+
container,
|
|
93
|
+
controls,
|
|
94
|
+
}: InteractionTaskArgs): Promise<void> => {
|
|
95
|
+
const openButton = await findByText(container, openText(0));
|
|
96
|
+
fireEvent.click(openButton);
|
|
97
|
+
await findByText(document.body, modalText(0));
|
|
98
|
+
const secondOpenButton = await findByText(document.body, openText(1));
|
|
99
|
+
|
|
100
|
+
await controls.time(async () => {
|
|
101
|
+
fireEvent.click(secondOpenButton);
|
|
102
|
+
await findByText(document.body, modalText(1));
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'Close second',
|
|
108
|
+
description: 'Closes the a second modal',
|
|
109
|
+
run: async ({
|
|
110
|
+
container,
|
|
111
|
+
controls,
|
|
112
|
+
}: InteractionTaskArgs): Promise<void> => {
|
|
113
|
+
const openButton = await findByText(container, openText(0));
|
|
114
|
+
fireEvent.click(openButton);
|
|
115
|
+
await findByText(document.body, modalText(0));
|
|
116
|
+
const secondOpenButton = await findByText(document.body, openText(1));
|
|
117
|
+
fireEvent.click(secondOpenButton);
|
|
118
|
+
await findByText(document.body, modalText(1));
|
|
119
|
+
|
|
120
|
+
await controls.time(async () => {
|
|
121
|
+
const closeButton = await findByText(document.body, closeText(1));
|
|
122
|
+
fireEvent.click(closeButton);
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
|
|
128
|
+
InteractionPerformance.story = {
|
|
129
|
+
parameters: {
|
|
130
|
+
performance: {
|
|
131
|
+
interactions: interactionTasks,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export default InteractionPerformance;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import React, { useCallback, useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { findByTestId, findByText, fireEvent } from '@testing-library/dom';
|
|
4
|
+
import Lorem from 'react-lorem-component';
|
|
5
|
+
import {
|
|
6
|
+
InteractionTaskArgs,
|
|
7
|
+
PublicInteractionTask,
|
|
8
|
+
} from 'storybook-addon-performance';
|
|
9
|
+
|
|
10
|
+
import Button from '@atlaskit/button/standard-button';
|
|
11
|
+
|
|
12
|
+
import Modal, {
|
|
13
|
+
ModalBody,
|
|
14
|
+
ModalFooter,
|
|
15
|
+
ModalHeader,
|
|
16
|
+
ModalTitle,
|
|
17
|
+
ModalTransition,
|
|
18
|
+
} from '../src';
|
|
19
|
+
|
|
20
|
+
const openText = 'Open modal';
|
|
21
|
+
const closeText = 'Close';
|
|
22
|
+
const scrollToBottomText = 'Scroll to bottom';
|
|
23
|
+
|
|
24
|
+
const ScrollPerformance = () => {
|
|
25
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
26
|
+
|
|
27
|
+
const bottomRef = useRef<HTMLDivElement>(null);
|
|
28
|
+
|
|
29
|
+
const open = useCallback(() => setIsOpen(true), []);
|
|
30
|
+
const close = useCallback(() => setIsOpen(false), []);
|
|
31
|
+
|
|
32
|
+
const scrollToBottom = () =>
|
|
33
|
+
bottomRef.current && bottomRef.current.scrollIntoView(true);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<>
|
|
37
|
+
<button data-testid="open" onClick={open}>
|
|
38
|
+
{openText}
|
|
39
|
+
</button>
|
|
40
|
+
|
|
41
|
+
<ModalTransition>
|
|
42
|
+
{isOpen && (
|
|
43
|
+
<Modal onClose={close} testId="modal">
|
|
44
|
+
<ModalHeader>
|
|
45
|
+
<ModalTitle>Modal dialog</ModalTitle>
|
|
46
|
+
</ModalHeader>
|
|
47
|
+
<ModalBody>
|
|
48
|
+
<Lorem count={10} />
|
|
49
|
+
<div ref={bottomRef} />
|
|
50
|
+
</ModalBody>
|
|
51
|
+
<ModalFooter>
|
|
52
|
+
<Button testId="close" appearance="primary" onClick={close}>
|
|
53
|
+
{closeText}
|
|
54
|
+
</Button>
|
|
55
|
+
<Button
|
|
56
|
+
testId="scroll-to-bottom"
|
|
57
|
+
appearance="subtle"
|
|
58
|
+
onClick={scrollToBottom}
|
|
59
|
+
>
|
|
60
|
+
{scrollToBottomText}
|
|
61
|
+
</Button>
|
|
62
|
+
</ModalFooter>
|
|
63
|
+
</Modal>
|
|
64
|
+
)}
|
|
65
|
+
</ModalTransition>
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const interactionTasks: PublicInteractionTask[] = [
|
|
71
|
+
{
|
|
72
|
+
name: 'Scroll to bottom',
|
|
73
|
+
description: 'Opens the modal dialog',
|
|
74
|
+
run: async ({
|
|
75
|
+
container,
|
|
76
|
+
controls,
|
|
77
|
+
}: InteractionTaskArgs): Promise<void> => {
|
|
78
|
+
const openButton = await findByText(container, openText);
|
|
79
|
+
fireEvent.click(openButton);
|
|
80
|
+
|
|
81
|
+
const content = await findByTestId(document.body, 'modal--scrollable');
|
|
82
|
+
|
|
83
|
+
await controls.time(async () => {
|
|
84
|
+
content.scrollTo(0, content.scrollHeight);
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
ScrollPerformance.story = {
|
|
91
|
+
parameters: {
|
|
92
|
+
performance: {
|
|
93
|
+
interactions: interactionTasks,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export default ScrollPerformance;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { JSCodeshift } from 'jscodeshift';
|
|
2
|
+
import { Collection } from 'jscodeshift/src/Collection';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
createTransformer,
|
|
6
|
+
hasImportDeclaration,
|
|
7
|
+
} from '@atlaskit/codemod-utils';
|
|
8
|
+
|
|
9
|
+
import { handlePropSpread } from './migrations/handle-prop-spread';
|
|
10
|
+
import { inlineWidthNamesDeclaration } from './migrations/inline-WidthNames-declaration';
|
|
11
|
+
import { mapActionsProp } from './migrations/map-actions-prop';
|
|
12
|
+
import { mapBodyFromProps } from './migrations/map-body-from-props';
|
|
13
|
+
import { mapContainerFromProps } from './migrations/map-container-from-props';
|
|
14
|
+
import { mapFooterFromProps } from './migrations/map-footer-from-props';
|
|
15
|
+
import { mapHeaderFromProps } from './migrations/map-header-from-props';
|
|
16
|
+
import { mapHeadingPropToModalTitle } from './migrations/map-heading-prop';
|
|
17
|
+
import { removeAppearanceProp } from './migrations/remove-appearance-prop';
|
|
18
|
+
import { removeComponentOverrideProps } from './migrations/remove-component-override-props';
|
|
19
|
+
import { removeIsChromeless } from './migrations/remove-is-chromeless';
|
|
20
|
+
import { renameAppearanceType } from './migrations/rename-appearance-type';
|
|
21
|
+
import { renameInnerComponentPropTypes } from './migrations/rename-inner-component-prop-types';
|
|
22
|
+
import { renameScrollBehaviorToShouldScrollInViewport } from './migrations/rename-scrollBehavior-to-shouldScrollInViewport';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The order of these migrations matters!
|
|
26
|
+
* Mapping the container usage, along with removal of key props
|
|
27
|
+
* such as the 'components' and 'appearance' should come last
|
|
28
|
+
* after the other migrations.
|
|
29
|
+
*/
|
|
30
|
+
const transformer = createTransformer(
|
|
31
|
+
[
|
|
32
|
+
mapBodyFromProps,
|
|
33
|
+
mapHeaderFromProps,
|
|
34
|
+
mapFooterFromProps,
|
|
35
|
+
renameScrollBehaviorToShouldScrollInViewport,
|
|
36
|
+
renameAppearanceType,
|
|
37
|
+
renameInnerComponentPropTypes,
|
|
38
|
+
inlineWidthNamesDeclaration,
|
|
39
|
+
mapHeadingPropToModalTitle,
|
|
40
|
+
mapActionsProp,
|
|
41
|
+
mapContainerFromProps,
|
|
42
|
+
removeComponentOverrideProps,
|
|
43
|
+
removeAppearanceProp,
|
|
44
|
+
removeIsChromeless,
|
|
45
|
+
handlePropSpread,
|
|
46
|
+
],
|
|
47
|
+
(j: JSCodeshift, source: Collection<Node>) =>
|
|
48
|
+
hasImportDeclaration(j, source, '@atlaskit/modal-dialog'),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
export default transformer;
|
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
import transformer from '../12.0.0-lite-mode';
|
|
2
|
+
|
|
3
|
+
const defineInlineTest = require('jscodeshift/dist/testUtils').defineInlineTest;
|
|
4
|
+
|
|
5
|
+
describe('12.0.0-lite-mode', () => {
|
|
6
|
+
['tsx', 'babylon'].forEach((parser) => {
|
|
7
|
+
describe(`parser: ${parser}`, () => {
|
|
8
|
+
defineInlineTest(
|
|
9
|
+
{ default: transformer, parser },
|
|
10
|
+
{},
|
|
11
|
+
`
|
|
12
|
+
import React, { useState } from 'react';
|
|
13
|
+
|
|
14
|
+
import ModalDialog from '@atlaskit/modal-dialog';
|
|
15
|
+
|
|
16
|
+
const Container = (props) => (<form>{props.children}</form>);
|
|
17
|
+
const Header = (props) => (<div><h1>{props.children}</h1></div>);
|
|
18
|
+
const Footer = (props) => (<div>{props.children}</div>);
|
|
19
|
+
|
|
20
|
+
export default function modalDialog() {
|
|
21
|
+
const [appearance, setAppearance] = useState(null);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<ModalDialog
|
|
25
|
+
appearance={appearance}
|
|
26
|
+
scrollBehavior="outside"
|
|
27
|
+
onClose={noop}
|
|
28
|
+
components={{ Container }}
|
|
29
|
+
header={Header}
|
|
30
|
+
footer={Footer}>
|
|
31
|
+
<p>Content #1</p>
|
|
32
|
+
<p>Content #2</p>
|
|
33
|
+
</ModalDialog>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
`,
|
|
37
|
+
`
|
|
38
|
+
/* TODO: (from codemod)\u0020
|
|
39
|
+
We have converted this file as best we could but you might still need
|
|
40
|
+
to manually complete migrating this usage of ModalDialog.
|
|
41
|
+
|
|
42
|
+
This file uses one or more of the following ModalDialog props: 'components', 'header',
|
|
43
|
+
'footer', 'body'. These props have been removed as part of moving to
|
|
44
|
+
a compositional API.
|
|
45
|
+
|
|
46
|
+
The render props that used to be exposed by the custom component APIs are
|
|
47
|
+
now accessible using the 'useModal' hook instead: 'testId', 'titleId', and 'onClose'.
|
|
48
|
+
|
|
49
|
+
We are also no longer exposing 'appearance' as render prop, so this needs to be
|
|
50
|
+
manually passed to your custom components.
|
|
51
|
+
|
|
52
|
+
If you are using the 'container' value of 'components' to wrap ModalDialog in something
|
|
53
|
+
other than a 'form', you'll need to add the style 'all: inherit;' for scrolling to function.
|
|
54
|
+
|
|
55
|
+
For a complete guide on customization using the new compositional API, refer to the docs at
|
|
56
|
+
https://atlassian.design/components/modal-dialog/examples. */
|
|
57
|
+
import React, { useState } from 'react';
|
|
58
|
+
|
|
59
|
+
import ModalDialog, { ModalBody } from "@atlaskit/modal-dialog";
|
|
60
|
+
|
|
61
|
+
const Container = (props) => (<form>{props.children}</form>);
|
|
62
|
+
const Header = (props) => (<div><h1>{props.children}</h1></div>);
|
|
63
|
+
const Footer = (props) => (<div>{props.children}</div>);
|
|
64
|
+
|
|
65
|
+
export default function modalDialog() {
|
|
66
|
+
const [appearance, setAppearance] = useState(null);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<ModalDialog shouldScrollInViewport onClose={noop}>
|
|
70
|
+
{Container({
|
|
71
|
+
children: <>
|
|
72
|
+
{Header({
|
|
73
|
+
appearance: appearance
|
|
74
|
+
})}
|
|
75
|
+
<ModalBody>
|
|
76
|
+
<p>Content #1</p>
|
|
77
|
+
<p>Content #2</p>
|
|
78
|
+
</ModalBody>
|
|
79
|
+
{Footer({
|
|
80
|
+
appearance: appearance
|
|
81
|
+
})}
|
|
82
|
+
</>
|
|
83
|
+
})}
|
|
84
|
+
</ModalDialog>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
`,
|
|
88
|
+
'should change custom usages in the appropriate order',
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
defineInlineTest(
|
|
92
|
+
{ default: transformer, parser },
|
|
93
|
+
{},
|
|
94
|
+
`
|
|
95
|
+
import React, { useState } from 'react';
|
|
96
|
+
|
|
97
|
+
import ModalDialog, {
|
|
98
|
+
AppearanceType,
|
|
99
|
+
HeaderComponentProps,
|
|
100
|
+
FooterComponentProps,
|
|
101
|
+
BodyComponentProps
|
|
102
|
+
} from '@atlaskit/modal-dialog';
|
|
103
|
+
|
|
104
|
+
const Container = (props) => (<form>{props.children}</form>);
|
|
105
|
+
const Header = (props: HeaderComponentProps) => (<div><h1>{props.children}</h1></div>);
|
|
106
|
+
const Footer = (props: FooterComponentProps) => (<div>{props.children}</div>);
|
|
107
|
+
|
|
108
|
+
export default function modalDialog() {
|
|
109
|
+
const [appearance, setAppearance] = useState<AppearanceType | null>(null);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<ModalDialog
|
|
113
|
+
appearance={appearance}
|
|
114
|
+
scrollBehavior="outside"
|
|
115
|
+
onClose={noop}
|
|
116
|
+
components={{ Container }}
|
|
117
|
+
header={Header}
|
|
118
|
+
footer={Footer} />
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
`,
|
|
122
|
+
`
|
|
123
|
+
/* TODO: (from codemod)\u0020
|
|
124
|
+
We have converted this file as best we could but you might still need
|
|
125
|
+
to manually complete migrating this usage of ModalDialog.
|
|
126
|
+
|
|
127
|
+
This file uses one or more of the following ModalDialog props: 'components', 'header',
|
|
128
|
+
'footer', 'body'. These props have been removed as part of moving to
|
|
129
|
+
a compositional API.
|
|
130
|
+
|
|
131
|
+
The render props that used to be exposed by the custom component APIs are
|
|
132
|
+
now accessible using the 'useModal' hook instead: 'testId', 'titleId', and 'onClose'.
|
|
133
|
+
|
|
134
|
+
We are also no longer exposing 'appearance' as render prop, so this needs to be
|
|
135
|
+
manually passed to your custom components.
|
|
136
|
+
|
|
137
|
+
If you are using the 'container' value of 'components' to wrap ModalDialog in something
|
|
138
|
+
other than a 'form', you'll need to add the style 'all: inherit;' for scrolling to function.
|
|
139
|
+
|
|
140
|
+
For a complete guide on customization using the new compositional API, refer to the docs at
|
|
141
|
+
https://atlassian.design/components/modal-dialog/examples. */
|
|
142
|
+
import React, { useState } from 'react';
|
|
143
|
+
|
|
144
|
+
import ModalDialog, {
|
|
145
|
+
Appearance as AppearanceType,
|
|
146
|
+
ModalHeaderProps as HeaderComponentProps,
|
|
147
|
+
ModalFooterProps as FooterComponentProps,
|
|
148
|
+
ModalBodyProps as BodyComponentProps
|
|
149
|
+
} from '@atlaskit/modal-dialog';
|
|
150
|
+
|
|
151
|
+
const Container = (props) => (<form>{props.children}</form>);
|
|
152
|
+
const Header = (props: HeaderComponentProps) => (<div><h1>{props.children}</h1></div>);
|
|
153
|
+
const Footer = (props: FooterComponentProps) => (<div>{props.children}</div>);
|
|
154
|
+
|
|
155
|
+
export default function modalDialog() {
|
|
156
|
+
const [appearance, setAppearance] = useState<AppearanceType | null>(null);
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<ModalDialog shouldScrollInViewport onClose={noop}>
|
|
160
|
+
{Container({
|
|
161
|
+
children: <>
|
|
162
|
+
{Header({
|
|
163
|
+
appearance: appearance
|
|
164
|
+
})}{Footer({
|
|
165
|
+
appearance: appearance
|
|
166
|
+
})}
|
|
167
|
+
</>
|
|
168
|
+
})}
|
|
169
|
+
</ModalDialog>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
`,
|
|
173
|
+
'should change custom usages for a self-closing modal without body',
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
defineInlineTest(
|
|
177
|
+
{ default: transformer, parser },
|
|
178
|
+
{},
|
|
179
|
+
`
|
|
180
|
+
import React, { useState } from 'react';
|
|
181
|
+
|
|
182
|
+
import ModalDialog, { ModalTransition } from '@atlaskit/modal-dialog';
|
|
183
|
+
|
|
184
|
+
export default function modalDialog(props) {
|
|
185
|
+
const [isOpen, toggleOpen] = useState<boolean>(false);
|
|
186
|
+
const { appearance, multiline, onClose } = props;
|
|
187
|
+
|
|
188
|
+
const actions = [
|
|
189
|
+
{ text: 'Close', onClick: close, testId: 'primary' },
|
|
190
|
+
{
|
|
191
|
+
text: 'Secondary Action',
|
|
192
|
+
onClick: noop,
|
|
193
|
+
testId: 'secondary',
|
|
194
|
+
},
|
|
195
|
+
];
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<ModalTransition>
|
|
199
|
+
{isOpen &&
|
|
200
|
+
<ModalDialog
|
|
201
|
+
appearance={appearance}
|
|
202
|
+
actions={actions}
|
|
203
|
+
onClose={onClose}
|
|
204
|
+
heading="Modal dialog"
|
|
205
|
+
isHeadingMultiline={multiline}
|
|
206
|
+
isChromeless={false}
|
|
207
|
+
scrollBehavior="outside"
|
|
208
|
+
{...props}
|
|
209
|
+
>
|
|
210
|
+
<div>Content #1</div>
|
|
211
|
+
<div>Content #2</div>
|
|
212
|
+
</ModalDialog>
|
|
213
|
+
}
|
|
214
|
+
</ModalTransition>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
`,
|
|
218
|
+
`
|
|
219
|
+
/* TODO: (from codemod)\u0020
|
|
220
|
+
This file is spreading props on the ModalDialog component, so we could not
|
|
221
|
+
automatically convert this usage to the new API.
|
|
222
|
+
|
|
223
|
+
The following props have been deprecated as part of moving to a compositional API:
|
|
224
|
+
|
|
225
|
+
- 'heading' prop has been replaced by ModalHeader and ModalTitle components.
|
|
226
|
+
- 'actions' prop has been replaced by ModalFooter component, with Button components from @atlaskit/button.
|
|
227
|
+
- 'scrollBehavior' prop has been replaced by 'shouldScrollInViewport', where "outside" from the previous prop maps to true in the new prop.
|
|
228
|
+
- 'isHeadingMultiline' prop has been replaced by 'isMultiline' prop on the ModalTitle component.
|
|
229
|
+
- 'appearance' prop has been moved to the ModalTitle component. To achieve the feature parity, pass the 'appearance' prop directly to ModalTitle and Button components inside ModalFooter.
|
|
230
|
+
|
|
231
|
+
Refer to the docs for the new API at https://atlassian.design/components/modal-dialog/examples
|
|
232
|
+
to complete the migration and use the new composable components. */
|
|
233
|
+
import React, { useState } from 'react';
|
|
234
|
+
|
|
235
|
+
import Button from "@atlaskit/button/standard-button";
|
|
236
|
+
import ModalDialog, { ModalTransition, ModalBody, ModalTitle, ModalHeader, ModalFooter } from "@atlaskit/modal-dialog";
|
|
237
|
+
|
|
238
|
+
export default function modalDialog(props) {
|
|
239
|
+
const [isOpen, toggleOpen] = useState<boolean>(false);
|
|
240
|
+
const { appearance, multiline, onClose } = props;
|
|
241
|
+
|
|
242
|
+
const actions = [
|
|
243
|
+
{ text: 'Close', onClick: close, testId: 'primary' },
|
|
244
|
+
{
|
|
245
|
+
text: 'Secondary Action',
|
|
246
|
+
onClick: noop,
|
|
247
|
+
testId: 'secondary',
|
|
248
|
+
},
|
|
249
|
+
];
|
|
250
|
+
|
|
251
|
+
return (
|
|
252
|
+
<ModalTransition>
|
|
253
|
+
{isOpen &&
|
|
254
|
+
<ModalDialog onClose={onClose} shouldScrollInViewport {...props}>
|
|
255
|
+
<ModalHeader>
|
|
256
|
+
<ModalTitle appearance={appearance} isMultiline={multiline}>
|
|
257
|
+
Modal dialog
|
|
258
|
+
</ModalTitle>
|
|
259
|
+
</ModalHeader>
|
|
260
|
+
|
|
261
|
+
<ModalBody>
|
|
262
|
+
<div>Content #1</div>
|
|
263
|
+
<div>Content #2</div>
|
|
264
|
+
</ModalBody>
|
|
265
|
+
<ModalFooter>
|
|
266
|
+
{actions.map((props, index) => <Button
|
|
267
|
+
{...props}
|
|
268
|
+
autoFocus={index === 0}
|
|
269
|
+
appearance={index === 0 ? appearance || "primary" : "subtle"}>{props.text}</Button>).reverse()}
|
|
270
|
+
</ModalFooter>
|
|
271
|
+
</ModalDialog>
|
|
272
|
+
}
|
|
273
|
+
</ModalTransition>
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
`,
|
|
277
|
+
'should change default usages for modal dialog',
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
defineInlineTest(
|
|
281
|
+
{ default: transformer, parser },
|
|
282
|
+
{},
|
|
283
|
+
`
|
|
284
|
+
import React, { useState } from 'react';
|
|
285
|
+
|
|
286
|
+
import ModalDialog, { ModalTransition, ModalBody } from '@atlaskit/modal-dialog';
|
|
287
|
+
|
|
288
|
+
import { getModalDialogActions } from './utils';
|
|
289
|
+
|
|
290
|
+
const Container = (props) => (<form>{props.children}</form>);
|
|
291
|
+
const CustomBody = (props) => (<div><ModalBody>{props.children}</ModalBody></div>);
|
|
292
|
+
|
|
293
|
+
export default function modalDialog(props) {
|
|
294
|
+
const [isOpen, toggleOpen] = useState<boolean>(false);
|
|
295
|
+
const { appearance, onClose } = props;
|
|
296
|
+
|
|
297
|
+
return (
|
|
298
|
+
<ModalTransition>
|
|
299
|
+
{isOpen &&
|
|
300
|
+
<ModalDialog
|
|
301
|
+
components={{ Container, Body: CustomBody }}
|
|
302
|
+
actions={getModalDialogActions(onClose)}
|
|
303
|
+
onClose={onClose}
|
|
304
|
+
heading="Modal dialog"
|
|
305
|
+
isChromeless={true}
|
|
306
|
+
scrollBehavior="outside"
|
|
307
|
+
>
|
|
308
|
+
<div>Content #1</div>
|
|
309
|
+
<div>Content #2</div>
|
|
310
|
+
</ModalDialog>
|
|
311
|
+
}
|
|
312
|
+
</ModalTransition>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
`,
|
|
316
|
+
`
|
|
317
|
+
/* TODO: (from codemod)\u0020
|
|
318
|
+
We have converted this file as best we could but you might still need
|
|
319
|
+
to manually complete migrating this usage of ModalDialog.
|
|
320
|
+
|
|
321
|
+
This file uses one or more of the following ModalDialog props: 'components', 'header',
|
|
322
|
+
'footer', 'body'. These props have been removed as part of moving to
|
|
323
|
+
a compositional API.
|
|
324
|
+
|
|
325
|
+
The render props that used to be exposed by the custom component APIs are
|
|
326
|
+
now accessible using the 'useModal' hook instead: 'testId', 'titleId', and 'onClose'.
|
|
327
|
+
|
|
328
|
+
We are also no longer exposing 'appearance' as render prop, so this needs to be
|
|
329
|
+
manually passed to your custom components.
|
|
330
|
+
|
|
331
|
+
If you are using the 'container' value of 'components' to wrap ModalDialog in something
|
|
332
|
+
other than a 'form', you'll need to add the style 'all: inherit;' for scrolling to function.
|
|
333
|
+
|
|
334
|
+
For a complete guide on customization using the new compositional API, refer to the docs at
|
|
335
|
+
https://atlassian.design/components/modal-dialog/examples. */
|
|
336
|
+
import React, { useState } from 'react';
|
|
337
|
+
|
|
338
|
+
import Button from "@atlaskit/button/standard-button";
|
|
339
|
+
import ModalDialog, { ModalTransition, ModalBody, ModalTitle, ModalHeader, ModalFooter } from "@atlaskit/modal-dialog";
|
|
340
|
+
|
|
341
|
+
import { getModalDialogActions } from './utils';
|
|
342
|
+
|
|
343
|
+
const Container = (props) => (<form>{props.children}</form>);
|
|
344
|
+
const CustomBody = (props) => (<div><ModalBody>{props.children}</ModalBody></div>);
|
|
345
|
+
|
|
346
|
+
export default function modalDialog(props) {
|
|
347
|
+
const [isOpen, toggleOpen] = useState<boolean>(false);
|
|
348
|
+
const { appearance, onClose } = props;
|
|
349
|
+
|
|
350
|
+
return (
|
|
351
|
+
<ModalTransition>
|
|
352
|
+
{isOpen &&
|
|
353
|
+
/* TODO: (from codemod)\u0020
|
|
354
|
+
ModalDialog has a new compositional API and the 'isChromeless' prop is no longer supported.
|
|
355
|
+
To have the functionality of the 'isChromeless' prop, you can choose to not use any of the default exports (ModalBody, ModalHeader and ModalFooter).
|
|
356
|
+
The only other change is that ModalDialog's children should have a border radius of 3px to match the box shadow.
|
|
357
|
+
For more information, check the documentation at https://atlassian.design/components/modal-dialog/examples */
|
|
358
|
+
<ModalDialog onClose={onClose} shouldScrollInViewport>
|
|
359
|
+
{Container({
|
|
360
|
+
children: <>
|
|
361
|
+
<ModalHeader>
|
|
362
|
+
<ModalTitle>
|
|
363
|
+
Modal dialog
|
|
364
|
+
</ModalTitle>
|
|
365
|
+
</ModalHeader>
|
|
366
|
+
|
|
367
|
+
{CustomBody({
|
|
368
|
+
children: <>
|
|
369
|
+
<div>Content #1</div>
|
|
370
|
+
<div>Content #2</div>
|
|
371
|
+
</>
|
|
372
|
+
})}
|
|
373
|
+
<ModalFooter>
|
|
374
|
+
{getModalDialogActions(onClose).map((props, index) => <Button
|
|
375
|
+
{...props}
|
|
376
|
+
appearance={index === 0 ? props.appearance || "primary" : props.appearance || "subtle"}>{props.text}</Button>)}
|
|
377
|
+
</ModalFooter>
|
|
378
|
+
</>
|
|
379
|
+
})}
|
|
380
|
+
</ModalDialog>
|
|
381
|
+
}
|
|
382
|
+
</ModalTransition>
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
`,
|
|
386
|
+
'should change mixed usages (custom + default) for modal dialog',
|
|
387
|
+
);
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
// Only support ts for this case
|
|
392
|
+
defineInlineTest(
|
|
393
|
+
{ default: transformer, parser: 'tsx' },
|
|
394
|
+
{},
|
|
395
|
+
`
|
|
396
|
+
import React, { useState } from 'react';
|
|
397
|
+
|
|
398
|
+
import ModalDialog, {
|
|
399
|
+
AppearanceType,
|
|
400
|
+
HeaderComponentProps,
|
|
401
|
+
FooterComponentProps,
|
|
402
|
+
} from '@atlaskit/modal-dialog';
|
|
403
|
+
|
|
404
|
+
import { WidthNames } from '@atlaskit/modal-dialog/shared-variables';
|
|
405
|
+
|
|
406
|
+
interface CustomHeaderProps extends HeaderComponentProps {
|
|
407
|
+
size?: WidthNames;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const Container = (props) => (<form>{props.children}</form>);
|
|
411
|
+
const Header = (props: CustomHeaderProps) => (<div><h1>{props.children}</h1></div>);
|
|
412
|
+
const Footer = (props: FooterComponentProps) => (<div>{props.children}</div>);
|
|
413
|
+
|
|
414
|
+
export default function modalDialog() {
|
|
415
|
+
const [appearance, setAppearance] = useState<AppearanceType | null>(null);
|
|
416
|
+
|
|
417
|
+
return (
|
|
418
|
+
<ModalDialog
|
|
419
|
+
appearance={appearance}
|
|
420
|
+
scrollBehavior="outside"
|
|
421
|
+
onClose={noop}
|
|
422
|
+
components={{ Container }}
|
|
423
|
+
header={Header}
|
|
424
|
+
footer={Footer}>
|
|
425
|
+
<p>Content #1</p>
|
|
426
|
+
<p>Content #2</p>
|
|
427
|
+
</ModalDialog>
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
`,
|
|
431
|
+
`
|
|
432
|
+
/* TODO: (from codemod)\u0020
|
|
433
|
+
We have converted this file as best we could but you might still need
|
|
434
|
+
to manually complete migrating this usage of ModalDialog.
|
|
435
|
+
|
|
436
|
+
This file uses one or more of the following ModalDialog props: 'components', 'header',
|
|
437
|
+
'footer', 'body'. These props have been removed as part of moving to
|
|
438
|
+
a compositional API.
|
|
439
|
+
|
|
440
|
+
The render props that used to be exposed by the custom component APIs are
|
|
441
|
+
now accessible using the 'useModal' hook instead: 'testId', 'titleId', and 'onClose'.
|
|
442
|
+
|
|
443
|
+
We are also no longer exposing 'appearance' as render prop, so this needs to be
|
|
444
|
+
manually passed to your custom components.
|
|
445
|
+
|
|
446
|
+
If you are using the 'container' value of 'components' to wrap ModalDialog in something
|
|
447
|
+
other than a 'form', you'll need to add the style 'all: inherit;' for scrolling to function.
|
|
448
|
+
|
|
449
|
+
For a complete guide on customization using the new compositional API, refer to the docs at
|
|
450
|
+
https://atlassian.design/components/modal-dialog/examples. */
|
|
451
|
+
import React, { useState } from 'react';
|
|
452
|
+
|
|
453
|
+
import ModalDialog, {
|
|
454
|
+
Appearance as AppearanceType,
|
|
455
|
+
ModalHeaderProps as HeaderComponentProps,
|
|
456
|
+
ModalFooterProps as FooterComponentProps,
|
|
457
|
+
ModalBody,
|
|
458
|
+
} from "@atlaskit/modal-dialog";
|
|
459
|
+
|
|
460
|
+
interface CustomHeaderProps extends HeaderComponentProps {
|
|
461
|
+
size?: "small" | "medium" | "large" | "x-large";
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const Container = (props) => (<form>{props.children}</form>);
|
|
465
|
+
const Header = (props: CustomHeaderProps) => (<div><h1>{props.children}</h1></div>);
|
|
466
|
+
const Footer = (props: FooterComponentProps) => (<div>{props.children}</div>);
|
|
467
|
+
|
|
468
|
+
export default function modalDialog() {
|
|
469
|
+
const [appearance, setAppearance] = useState<AppearanceType | null>(null);
|
|
470
|
+
|
|
471
|
+
return (
|
|
472
|
+
<ModalDialog shouldScrollInViewport onClose={noop}>
|
|
473
|
+
{Container({
|
|
474
|
+
children: <>
|
|
475
|
+
{Header({
|
|
476
|
+
appearance: appearance
|
|
477
|
+
})}
|
|
478
|
+
<ModalBody>
|
|
479
|
+
<p>Content #1</p>
|
|
480
|
+
<p>Content #2</p>
|
|
481
|
+
</ModalBody>
|
|
482
|
+
{Footer({
|
|
483
|
+
appearance: appearance
|
|
484
|
+
})}
|
|
485
|
+
</>
|
|
486
|
+
})}
|
|
487
|
+
</ModalDialog>
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
`,
|
|
491
|
+
'should change custom usages and types in the appropriate order',
|
|
492
|
+
);
|
|
493
|
+
});
|