@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
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import core, { ASTPath, JSXElement } from 'jscodeshift';
|
|
2
|
+
import { Collection } from 'jscodeshift/src/Collection';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
addDynamicImport,
|
|
6
|
+
getDefaultSpecifier,
|
|
7
|
+
getDynamicImportName,
|
|
8
|
+
getNamedSpecifier,
|
|
9
|
+
getSafeImportName,
|
|
10
|
+
} from '@atlaskit/codemod-utils';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
BODY_PROP_NAME,
|
|
14
|
+
COMPONENTS_PROP_NAME,
|
|
15
|
+
MODAL_BODY_COMPONENT_FALLBACK_NAME,
|
|
16
|
+
MODAL_BODY_COMPONENT_NAME,
|
|
17
|
+
MODAL_BODY_ENDPOINT,
|
|
18
|
+
PACKAGE_NAME,
|
|
19
|
+
} from '../internal/constants';
|
|
20
|
+
import {
|
|
21
|
+
addToImport,
|
|
22
|
+
getComponentImportName,
|
|
23
|
+
getOverrideFromComponentsProp,
|
|
24
|
+
getOverrideFromIndividualProp,
|
|
25
|
+
getVariableDeclarationPathByName,
|
|
26
|
+
replaceChildren,
|
|
27
|
+
} from '../internal/utils';
|
|
28
|
+
|
|
29
|
+
export const mapBodyFromProps = (
|
|
30
|
+
j: core.JSCodeshift,
|
|
31
|
+
source: Collection<Node>,
|
|
32
|
+
) => {
|
|
33
|
+
const defaultSpecifier = getDefaultSpecifier(j, source, PACKAGE_NAME);
|
|
34
|
+
const dynamicImportSpecifier = getDynamicImportName(j, source, PACKAGE_NAME);
|
|
35
|
+
const modalDialogComponentName = defaultSpecifier || dynamicImportSpecifier;
|
|
36
|
+
|
|
37
|
+
if (!modalDialogComponentName) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let shouldImportModalBody;
|
|
42
|
+
|
|
43
|
+
const modalBodySpecifier = getNamedSpecifier(
|
|
44
|
+
j,
|
|
45
|
+
source,
|
|
46
|
+
PACKAGE_NAME,
|
|
47
|
+
MODAL_BODY_COMPONENT_NAME,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const modalBodyComponentName =
|
|
51
|
+
modalBodySpecifier ||
|
|
52
|
+
getSafeImportName({
|
|
53
|
+
j,
|
|
54
|
+
base: source,
|
|
55
|
+
currentDefaultSpecifierName: null,
|
|
56
|
+
desiredName: MODAL_BODY_COMPONENT_NAME,
|
|
57
|
+
fallbackName: MODAL_BODY_COMPONENT_FALLBACK_NAME,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
source
|
|
61
|
+
.findJSXElements(modalDialogComponentName)
|
|
62
|
+
.forEach((element: ASTPath<JSXElement>) => {
|
|
63
|
+
const bodyFromIndividualProp = getOverrideFromIndividualProp(
|
|
64
|
+
j,
|
|
65
|
+
element,
|
|
66
|
+
BODY_PROP_NAME,
|
|
67
|
+
);
|
|
68
|
+
const bodyFromComponentsProp = getOverrideFromComponentsProp(
|
|
69
|
+
j,
|
|
70
|
+
element,
|
|
71
|
+
COMPONENTS_PROP_NAME,
|
|
72
|
+
'Body',
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* If both overrides are declared, use the body passed to the components prop
|
|
77
|
+
* to replicate the logic in the source code (pre-lite mode).
|
|
78
|
+
*/
|
|
79
|
+
const body = bodyFromComponentsProp || bodyFromIndividualProp;
|
|
80
|
+
|
|
81
|
+
if (!body) {
|
|
82
|
+
const isSelfClosing = j(element)
|
|
83
|
+
.find(j.JSXOpeningElement)
|
|
84
|
+
.at(0)
|
|
85
|
+
.get('selfClosing').value;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* We only wrap the default ModalBody around the remaining children
|
|
89
|
+
* if the consumer hasn't already imported/used it, and if
|
|
90
|
+
* their ModalDialog is not self-closing (because that means
|
|
91
|
+
* there's no children to be wrapped around).
|
|
92
|
+
*/
|
|
93
|
+
if (isSelfClosing || modalBodySpecifier) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
shouldImportModalBody = true;
|
|
98
|
+
|
|
99
|
+
const wrappedChildren = j.jsxElement(
|
|
100
|
+
j.jsxOpeningElement(j.jsxIdentifier(modalBodyComponentName)),
|
|
101
|
+
j.jsxClosingElement(j.jsxIdentifier(modalBodyComponentName)),
|
|
102
|
+
element.value.children,
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
replaceChildren(j, element, modalDialogComponentName, wrappedChildren);
|
|
106
|
+
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const props = j.objectExpression([
|
|
111
|
+
j.objectProperty(
|
|
112
|
+
j.identifier('children'),
|
|
113
|
+
j.jsxFragment(
|
|
114
|
+
j.jsxOpeningFragment(),
|
|
115
|
+
j.jsxClosingFragment(),
|
|
116
|
+
element.value.children,
|
|
117
|
+
),
|
|
118
|
+
),
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
replaceChildren(
|
|
122
|
+
j,
|
|
123
|
+
element,
|
|
124
|
+
modalDialogComponentName,
|
|
125
|
+
j.jsxExpressionContainer(j.callExpression(body, [props])),
|
|
126
|
+
);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
if (shouldImportModalBody) {
|
|
130
|
+
if (defaultSpecifier) {
|
|
131
|
+
addToImport(j, source, [
|
|
132
|
+
getComponentImportName(
|
|
133
|
+
j,
|
|
134
|
+
modalBodyComponentName,
|
|
135
|
+
MODAL_BODY_COMPONENT_NAME,
|
|
136
|
+
),
|
|
137
|
+
]);
|
|
138
|
+
} else if (dynamicImportSpecifier) {
|
|
139
|
+
addDynamicImport(
|
|
140
|
+
j,
|
|
141
|
+
getVariableDeclarationPathByName(j, source, dynamicImportSpecifier),
|
|
142
|
+
modalBodyComponentName,
|
|
143
|
+
MODAL_BODY_ENDPOINT,
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import core, { ASTPath, JSXElement, StringLiteral } from 'jscodeshift';
|
|
2
|
+
import { Collection } from 'jscodeshift/src/Collection';
|
|
3
|
+
|
|
4
|
+
import { getDefaultSpecifier } from '@atlaskit/codemod-utils';
|
|
5
|
+
|
|
6
|
+
import { COMPONENTS_PROP_NAME, PACKAGE_NAME } from '../internal/constants';
|
|
7
|
+
import {
|
|
8
|
+
getOverrideFromComponentsProp,
|
|
9
|
+
replaceChildren,
|
|
10
|
+
} from '../internal/utils';
|
|
11
|
+
|
|
12
|
+
export const mapContainerFromProps = (
|
|
13
|
+
j: core.JSCodeshift,
|
|
14
|
+
source: Collection<Node>,
|
|
15
|
+
) => {
|
|
16
|
+
const defaultSpecifier = getDefaultSpecifier(j, source, PACKAGE_NAME);
|
|
17
|
+
|
|
18
|
+
if (!defaultSpecifier) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
source
|
|
23
|
+
.findJSXElements(defaultSpecifier)
|
|
24
|
+
.forEach((element: ASTPath<JSXElement>) => {
|
|
25
|
+
const container = getOverrideFromComponentsProp(
|
|
26
|
+
j,
|
|
27
|
+
element,
|
|
28
|
+
COMPONENTS_PROP_NAME,
|
|
29
|
+
'Container',
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
if (!container) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if ((container as StringLiteral).type === 'StringLiteral') {
|
|
37
|
+
const wrappedChildren = j.jsxElement(
|
|
38
|
+
j.jsxOpeningElement(
|
|
39
|
+
j.jsxIdentifier((container as StringLiteral).value),
|
|
40
|
+
),
|
|
41
|
+
j.jsxClosingElement(
|
|
42
|
+
j.jsxIdentifier((container as StringLiteral).value),
|
|
43
|
+
),
|
|
44
|
+
element.value.children,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
replaceChildren(j, element, defaultSpecifier, wrappedChildren);
|
|
48
|
+
|
|
49
|
+
return;
|
|
50
|
+
} else {
|
|
51
|
+
const props = j.objectExpression([
|
|
52
|
+
j.objectProperty(
|
|
53
|
+
j.identifier('children'),
|
|
54
|
+
j.jsxFragment(
|
|
55
|
+
j.jsxOpeningFragment(),
|
|
56
|
+
j.jsxClosingFragment(),
|
|
57
|
+
element.value.children,
|
|
58
|
+
),
|
|
59
|
+
),
|
|
60
|
+
]);
|
|
61
|
+
|
|
62
|
+
replaceChildren(
|
|
63
|
+
j,
|
|
64
|
+
element,
|
|
65
|
+
defaultSpecifier,
|
|
66
|
+
j.jsxExpressionContainer(j.callExpression(container, [props])),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import core, {
|
|
2
|
+
ASTPath,
|
|
3
|
+
JSXElement,
|
|
4
|
+
JSXExpressionContainer,
|
|
5
|
+
JSXFragment,
|
|
6
|
+
JSXSpreadChild,
|
|
7
|
+
} from 'jscodeshift';
|
|
8
|
+
import { Collection } from 'jscodeshift/src/Collection';
|
|
9
|
+
|
|
10
|
+
import { getDefaultSpecifier } from '@atlaskit/codemod-utils';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
APPEARANCE_PROP_NAME,
|
|
14
|
+
COMPONENTS_PROP_NAME,
|
|
15
|
+
FOOTER_PROP_NAME,
|
|
16
|
+
PACKAGE_NAME,
|
|
17
|
+
} from '../internal/constants';
|
|
18
|
+
import {
|
|
19
|
+
getAppearanceFromProp,
|
|
20
|
+
getOverrideFromComponentsProp,
|
|
21
|
+
getOverrideFromIndividualProp,
|
|
22
|
+
} from '../internal/utils';
|
|
23
|
+
|
|
24
|
+
export const mapFooterFromProps = (
|
|
25
|
+
j: core.JSCodeshift,
|
|
26
|
+
source: Collection<Node>,
|
|
27
|
+
) => {
|
|
28
|
+
const defaultSpecifier = getDefaultSpecifier(j, source, PACKAGE_NAME);
|
|
29
|
+
|
|
30
|
+
if (!defaultSpecifier) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
source
|
|
35
|
+
.findJSXElements(defaultSpecifier)
|
|
36
|
+
.forEach((element: ASTPath<JSXElement>) => {
|
|
37
|
+
const footerFromIndividualProp = getOverrideFromIndividualProp(
|
|
38
|
+
j,
|
|
39
|
+
element,
|
|
40
|
+
FOOTER_PROP_NAME,
|
|
41
|
+
);
|
|
42
|
+
const footerFromComponentsProp = getOverrideFromComponentsProp(
|
|
43
|
+
j,
|
|
44
|
+
element,
|
|
45
|
+
COMPONENTS_PROP_NAME,
|
|
46
|
+
'Footer',
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* If declared, use the footer passed to the components prop
|
|
51
|
+
* to replicate the logic in the source code (pre-lite mode).
|
|
52
|
+
*/
|
|
53
|
+
const footer = footerFromComponentsProp || footerFromIndividualProp;
|
|
54
|
+
|
|
55
|
+
if (!footer) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const appearance = getAppearanceFromProp(j, element);
|
|
60
|
+
const props = appearance
|
|
61
|
+
? [
|
|
62
|
+
j.objectExpression([
|
|
63
|
+
j.objectProperty(j.identifier(APPEARANCE_PROP_NAME), appearance),
|
|
64
|
+
]),
|
|
65
|
+
]
|
|
66
|
+
: [];
|
|
67
|
+
|
|
68
|
+
appendFooterAsLastChild(
|
|
69
|
+
j,
|
|
70
|
+
element,
|
|
71
|
+
defaultSpecifier,
|
|
72
|
+
j.jsxExpressionContainer(j.callExpression(footer, props)),
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const appendFooterAsLastChild = (
|
|
78
|
+
j: core.JSCodeshift,
|
|
79
|
+
element: ASTPath<JSXElement>,
|
|
80
|
+
specifier: string,
|
|
81
|
+
footer: JSXElement | JSXExpressionContainer | JSXFragment | JSXSpreadChild,
|
|
82
|
+
) => {
|
|
83
|
+
const children = element.node.children
|
|
84
|
+
? element.node.children.concat([footer, j.jsxText('\n')])
|
|
85
|
+
: [footer, j.jsxText('\n')];
|
|
86
|
+
|
|
87
|
+
j(element)
|
|
88
|
+
.find(j.JSXOpeningElement)
|
|
89
|
+
.forEach((openingElement) => {
|
|
90
|
+
const openingElementName = openingElement.value.name;
|
|
91
|
+
if (
|
|
92
|
+
openingElementName.type === 'JSXIdentifier' &&
|
|
93
|
+
openingElementName.name === specifier
|
|
94
|
+
) {
|
|
95
|
+
j(element).replaceWith(
|
|
96
|
+
j.jsxElement(
|
|
97
|
+
j.jsxOpeningElement(
|
|
98
|
+
j.jsxIdentifier(specifier),
|
|
99
|
+
openingElement.value.attributes,
|
|
100
|
+
),
|
|
101
|
+
j.jsxClosingElement(j.jsxIdentifier(specifier)),
|
|
102
|
+
children,
|
|
103
|
+
),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import core, { ASTPath, JSXElement } from 'jscodeshift';
|
|
2
|
+
import { Collection } from 'jscodeshift/src/Collection';
|
|
3
|
+
|
|
4
|
+
import { getDefaultSpecifier } from '@atlaskit/codemod-utils';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
APPEARANCE_PROP_NAME,
|
|
8
|
+
COMPONENTS_PROP_NAME,
|
|
9
|
+
HEADER_PROP_NAME,
|
|
10
|
+
PACKAGE_NAME,
|
|
11
|
+
} from '../internal/constants';
|
|
12
|
+
import {
|
|
13
|
+
getAppearanceFromProp,
|
|
14
|
+
getOverrideFromComponentsProp,
|
|
15
|
+
getOverrideFromIndividualProp,
|
|
16
|
+
} from '../internal/utils';
|
|
17
|
+
|
|
18
|
+
export const mapHeaderFromProps = (
|
|
19
|
+
j: core.JSCodeshift,
|
|
20
|
+
source: Collection<Node>,
|
|
21
|
+
) => {
|
|
22
|
+
const defaultSpecifier = getDefaultSpecifier(j, source, PACKAGE_NAME);
|
|
23
|
+
|
|
24
|
+
if (!defaultSpecifier) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
source
|
|
29
|
+
.findJSXElements(defaultSpecifier)
|
|
30
|
+
.forEach((element: ASTPath<JSXElement>) => {
|
|
31
|
+
const headerFromIndividualProp = getOverrideFromIndividualProp(
|
|
32
|
+
j,
|
|
33
|
+
element,
|
|
34
|
+
HEADER_PROP_NAME,
|
|
35
|
+
);
|
|
36
|
+
const headerFromComponentsProp = getOverrideFromComponentsProp(
|
|
37
|
+
j,
|
|
38
|
+
element,
|
|
39
|
+
COMPONENTS_PROP_NAME,
|
|
40
|
+
'Header',
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* If declared, use the header passed to the components prop
|
|
45
|
+
* to replicate the logic in the source code (pre-lite mode).
|
|
46
|
+
*/
|
|
47
|
+
const header = headerFromComponentsProp || headerFromIndividualProp;
|
|
48
|
+
|
|
49
|
+
if (!header) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const appearance = getAppearanceFromProp(j, element);
|
|
54
|
+
const props = appearance
|
|
55
|
+
? [
|
|
56
|
+
j.objectExpression([
|
|
57
|
+
j.objectProperty(j.identifier(APPEARANCE_PROP_NAME), appearance),
|
|
58
|
+
]),
|
|
59
|
+
]
|
|
60
|
+
: [];
|
|
61
|
+
|
|
62
|
+
appendHeaderAsFirstChild(
|
|
63
|
+
j,
|
|
64
|
+
element,
|
|
65
|
+
defaultSpecifier,
|
|
66
|
+
j.jsxExpressionContainer(j.callExpression(header, props)),
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const appendHeaderAsFirstChild = (
|
|
72
|
+
j: core.JSCodeshift,
|
|
73
|
+
element: ASTPath<JSXElement>,
|
|
74
|
+
specifier: string,
|
|
75
|
+
header: any,
|
|
76
|
+
) => {
|
|
77
|
+
const children = element.node.children
|
|
78
|
+
? [j.jsxText('\n'), header].concat(element.node.children)
|
|
79
|
+
: [j.jsxText('\n'), header];
|
|
80
|
+
|
|
81
|
+
j(element)
|
|
82
|
+
.find(j.JSXOpeningElement)
|
|
83
|
+
.forEach((openingElement) => {
|
|
84
|
+
const openingElementName = openingElement.value.name;
|
|
85
|
+
if (
|
|
86
|
+
openingElementName.type === 'JSXIdentifier' &&
|
|
87
|
+
openingElementName.name === specifier
|
|
88
|
+
) {
|
|
89
|
+
j(element).replaceWith(
|
|
90
|
+
j.jsxElement(
|
|
91
|
+
j.jsxOpeningElement(
|
|
92
|
+
j.jsxIdentifier(specifier),
|
|
93
|
+
openingElement.value.attributes,
|
|
94
|
+
),
|
|
95
|
+
j.jsxClosingElement(j.jsxIdentifier(specifier)),
|
|
96
|
+
children,
|
|
97
|
+
),
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import core, {
|
|
2
|
+
ASTPath,
|
|
3
|
+
Collection,
|
|
4
|
+
JSXAttribute,
|
|
5
|
+
JSXElement,
|
|
6
|
+
StringLiteral,
|
|
7
|
+
} from 'jscodeshift/src/core';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
addDynamicImport,
|
|
11
|
+
getDefaultSpecifier,
|
|
12
|
+
getDynamicImportName,
|
|
13
|
+
getJSXAttributesByName,
|
|
14
|
+
getSafeImportName,
|
|
15
|
+
} from '@atlaskit/codemod-utils';
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
APPEARANCE_PROP_NAME,
|
|
19
|
+
HEADING_PROP_NAME,
|
|
20
|
+
IS_MULTILINE_PROP_NAME,
|
|
21
|
+
MODAL_HEADER_COMPONENT_FALLBACK_NAME,
|
|
22
|
+
MODAL_HEADER_COMPONENT_NAME,
|
|
23
|
+
MODAL_HEADER_ENDPOINT,
|
|
24
|
+
MODAL_TITLE_COMPONENT_FALLBACK_NAME,
|
|
25
|
+
MODAL_TITLE_COMPONENT_NAME,
|
|
26
|
+
MODAL_TITLE_ENDPOINT,
|
|
27
|
+
PACKAGE_NAME,
|
|
28
|
+
} from '../internal/constants';
|
|
29
|
+
import {
|
|
30
|
+
addToImport,
|
|
31
|
+
getAppearanceFromProp,
|
|
32
|
+
getComponentImportName,
|
|
33
|
+
getIsMultilineFromProp,
|
|
34
|
+
getVariableDeclarationPathByName,
|
|
35
|
+
} from '../internal/utils';
|
|
36
|
+
|
|
37
|
+
export const mapHeadingPropToModalTitle = (
|
|
38
|
+
j: core.JSCodeshift,
|
|
39
|
+
source: Collection<Node>,
|
|
40
|
+
) => {
|
|
41
|
+
let doesHeadingPropExist;
|
|
42
|
+
const defaultSpecifierName = getDefaultSpecifier(j, source, PACKAGE_NAME);
|
|
43
|
+
const dynamicImportName = getDynamicImportName(j, source, PACKAGE_NAME);
|
|
44
|
+
const modalDialogComponentName = defaultSpecifierName || dynamicImportName;
|
|
45
|
+
|
|
46
|
+
if (!modalDialogComponentName) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const modalHeaderComponentName = getSafeImportName({
|
|
51
|
+
j,
|
|
52
|
+
base: source,
|
|
53
|
+
currentDefaultSpecifierName: null,
|
|
54
|
+
desiredName: MODAL_HEADER_COMPONENT_NAME,
|
|
55
|
+
fallbackName: MODAL_HEADER_COMPONENT_FALLBACK_NAME,
|
|
56
|
+
});
|
|
57
|
+
const modalTitleComponentName = getSafeImportName({
|
|
58
|
+
j,
|
|
59
|
+
base: source,
|
|
60
|
+
currentDefaultSpecifierName: null,
|
|
61
|
+
desiredName: MODAL_TITLE_COMPONENT_NAME,
|
|
62
|
+
fallbackName: MODAL_TITLE_COMPONENT_FALLBACK_NAME,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
source
|
|
66
|
+
.findJSXElements(modalDialogComponentName)
|
|
67
|
+
.forEach((element: ASTPath<JSXElement>) => {
|
|
68
|
+
getJSXAttributesByName(j, element, HEADING_PROP_NAME).forEach(
|
|
69
|
+
(attribute: ASTPath<JSXAttribute>) => {
|
|
70
|
+
const headingPropValue = attribute.node.value;
|
|
71
|
+
doesHeadingPropExist = true;
|
|
72
|
+
|
|
73
|
+
j(attribute).remove();
|
|
74
|
+
element.node.openingElement.selfClosing = false;
|
|
75
|
+
element.node.closingElement = j.jsxClosingElement(
|
|
76
|
+
j.jsxIdentifier(modalDialogComponentName),
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const headerComponent = getHeaderComponent(
|
|
80
|
+
j,
|
|
81
|
+
element,
|
|
82
|
+
modalHeaderComponentName,
|
|
83
|
+
modalTitleComponentName,
|
|
84
|
+
headingPropValue,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
if (element.node.children) {
|
|
88
|
+
element.node.children.unshift(
|
|
89
|
+
j.jsxText('\n'),
|
|
90
|
+
headerComponent,
|
|
91
|
+
j.jsxText('\n'),
|
|
92
|
+
);
|
|
93
|
+
} else {
|
|
94
|
+
element.node.children = [
|
|
95
|
+
j.jsxText('\n'),
|
|
96
|
+
headerComponent,
|
|
97
|
+
j.jsxText('\n'),
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (doesHeadingPropExist) {
|
|
105
|
+
if (defaultSpecifierName) {
|
|
106
|
+
addToImport(j, source, [
|
|
107
|
+
getComponentImportName(
|
|
108
|
+
j,
|
|
109
|
+
modalTitleComponentName,
|
|
110
|
+
MODAL_TITLE_COMPONENT_NAME,
|
|
111
|
+
),
|
|
112
|
+
getComponentImportName(
|
|
113
|
+
j,
|
|
114
|
+
modalHeaderComponentName,
|
|
115
|
+
MODAL_HEADER_COMPONENT_NAME,
|
|
116
|
+
),
|
|
117
|
+
]);
|
|
118
|
+
} else if (dynamicImportName) {
|
|
119
|
+
addDynamicImport(
|
|
120
|
+
j,
|
|
121
|
+
getVariableDeclarationPathByName(j, source, dynamicImportName),
|
|
122
|
+
modalHeaderComponentName,
|
|
123
|
+
MODAL_HEADER_ENDPOINT,
|
|
124
|
+
);
|
|
125
|
+
addDynamicImport(
|
|
126
|
+
j,
|
|
127
|
+
getVariableDeclarationPathByName(j, source, dynamicImportName),
|
|
128
|
+
modalTitleComponentName,
|
|
129
|
+
MODAL_TITLE_ENDPOINT,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const getModalTitleAttributes = (
|
|
136
|
+
j: core.JSCodeshift,
|
|
137
|
+
element: ASTPath<JSXElement>,
|
|
138
|
+
) => {
|
|
139
|
+
const appearance = getAppearanceFromProp(j, element);
|
|
140
|
+
const isMultiline = getIsMultilineFromProp(j, element);
|
|
141
|
+
|
|
142
|
+
const attributes = [];
|
|
143
|
+
|
|
144
|
+
if (appearance !== undefined) {
|
|
145
|
+
const appearanceValue =
|
|
146
|
+
(appearance as StringLiteral).type === 'StringLiteral'
|
|
147
|
+
? appearance
|
|
148
|
+
: j.jsxExpressionContainer(appearance);
|
|
149
|
+
|
|
150
|
+
const appearanceAttr = j.jsxAttribute(
|
|
151
|
+
j.jsxIdentifier(APPEARANCE_PROP_NAME),
|
|
152
|
+
appearanceValue,
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
attributes.push(appearanceAttr);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (isMultiline !== undefined) {
|
|
159
|
+
const isMultilineAttr = j.jsxAttribute(
|
|
160
|
+
j.jsxIdentifier(IS_MULTILINE_PROP_NAME),
|
|
161
|
+
isMultiline ? j.jsxExpressionContainer(isMultiline) : isMultiline,
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
attributes.push(isMultilineAttr);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return attributes;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const getHeaderComponent = (
|
|
171
|
+
j: core.JSCodeshift,
|
|
172
|
+
element: ASTPath<JSXElement>,
|
|
173
|
+
headerComponentName: string,
|
|
174
|
+
titleComponentName: string,
|
|
175
|
+
heading: any,
|
|
176
|
+
) => {
|
|
177
|
+
return j.jsxElement(
|
|
178
|
+
j.jsxOpeningElement(j.jsxIdentifier(headerComponentName)),
|
|
179
|
+
j.jsxClosingElement(j.jsxIdentifier(headerComponentName)),
|
|
180
|
+
[
|
|
181
|
+
j.jsxText('\n'),
|
|
182
|
+
j.jsxElement(
|
|
183
|
+
j.jsxOpeningElement(
|
|
184
|
+
j.jsxIdentifier(titleComponentName),
|
|
185
|
+
getModalTitleAttributes(j, element),
|
|
186
|
+
),
|
|
187
|
+
j.jsxClosingElement(j.jsxIdentifier(titleComponentName)),
|
|
188
|
+
[j.jsxText('\n'), heading, j.jsxText('\n')],
|
|
189
|
+
),
|
|
190
|
+
j.jsxText('\n'),
|
|
191
|
+
],
|
|
192
|
+
);
|
|
193
|
+
};
|