@atlaskit/tabs 17.2.0 → 17.2.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.
Files changed (32) hide show
  1. package/CHANGELOG.md +14 -36
  2. package/dist/cjs/components/tab-list.compiled.css +8 -2
  3. package/dist/cjs/components/tab-list.js +1 -2
  4. package/dist/cjs/components/tabs.js +1 -1
  5. package/dist/es2019/components/tab-list.compiled.css +8 -2
  6. package/dist/es2019/components/tab-list.js +1 -1
  7. package/dist/es2019/components/tabs.js +1 -1
  8. package/dist/esm/components/tab-list.compiled.css +8 -2
  9. package/dist/esm/components/tab-list.js +1 -2
  10. package/dist/esm/components/tabs.js +1 -1
  11. package/dist/types/components/tab-panel.d.ts +2 -2
  12. package/dist/types-ts4.5/components/tab-panel.d.ts +2 -2
  13. package/package.json +2 -3
  14. package/codemods/13.0.0-lite-mode.tsx +0 -31
  15. package/codemods/__tests__/13.0.0-lite-mode.tsx +0 -569
  16. package/codemods/__tests__/add-id-prop.tsx +0 -77
  17. package/codemods/__tests__/map-tabs-prop.tsx +0 -299
  18. package/codemods/__tests__/on-select-to-on-change.tsx +0 -541
  19. package/codemods/__tests__/remove-components-prop.tsx +0 -151
  20. package/codemods/__tests__/remove-is-selected-test-prop.tsx +0 -147
  21. package/codemods/__tests__/remove-tab-item-tab-content.tsx +0 -86
  22. package/codemods/__tests__/remove-types.tsx +0 -162
  23. package/codemods/__tests__/rename-is-content-persisted-to-should-unmount-tab-panel-on-change.tsx +0 -311
  24. package/codemods/migrations/add-id-prop.tsx +0 -51
  25. package/codemods/migrations/map-tabs-prop.tsx +0 -171
  26. package/codemods/migrations/on-select-to-on-change.tsx +0 -91
  27. package/codemods/migrations/remove-components-prop.tsx +0 -20
  28. package/codemods/migrations/remove-is-selected-test-prop.tsx +0 -17
  29. package/codemods/migrations/remove-tab-item-tab-content.tsx +0 -26
  30. package/codemods/migrations/remove-types.tsx +0 -45
  31. package/codemods/migrations/rename-is-content-persisted-to-should-unmount-tab-panel-on-change.tsx +0 -62
  32. package/codemods/utils.tsx +0 -39
@@ -1,51 +0,0 @@
1
- import {
2
- type ASTPath,
3
- type default as core,
4
- type JSXElement,
5
- type JSXOpeningElement,
6
- } from 'jscodeshift';
7
- import { type Collection } from 'jscodeshift/src/Collection';
8
-
9
- import { addCommentToStartOfFile, getDefaultSpecifier } from '@atlaskit/codemod-utils';
10
-
11
- const component = '@atlaskit/tabs';
12
- const newProp = 'id';
13
-
14
- function generateUniqueId() {
15
- return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
16
- }
17
-
18
- export const addIdProp = (j: core.JSCodeshift, source: Collection<Node>) => {
19
- const defaultSpecifier = getDefaultSpecifier(j, source, component);
20
-
21
- if (!defaultSpecifier) {
22
- return;
23
- }
24
-
25
- source.findJSXElements(defaultSpecifier).forEach((element: ASTPath<JSXElement>) => {
26
- j(element)
27
- .find(j.JSXOpeningElement)
28
- .filter(
29
- (openingElement: ASTPath<JSXOpeningElement>) =>
30
- openingElement.node.name.type === 'JSXIdentifier' &&
31
- openingElement.node.name.name === defaultSpecifier,
32
- )
33
- .forEach((openingElement: ASTPath<JSXOpeningElement>) => {
34
- const { attributes } = openingElement.node;
35
- const idAttribute = j.jsxAttribute(
36
- j.jsxIdentifier(newProp),
37
- j.stringLiteral(generateUniqueId()),
38
- );
39
-
40
- // @ts-ignore
41
- attributes.push(idAttribute);
42
-
43
- addCommentToStartOfFile({
44
- j,
45
- base: source,
46
- message: `We have added an "${newProp}" prop to "${defaultSpecifier}" for accessibility reasons.
47
- The codemod has added a random ID but you can add one that makes sense for your use case.`,
48
- });
49
- });
50
- });
51
- };
@@ -1,171 +0,0 @@
1
- import {
2
- type ASTPath,
3
- type default as core,
4
- type ImportDeclaration,
5
- type JSXElement,
6
- } from 'jscodeshift';
7
- import { type Collection } from 'jscodeshift/src/Collection';
8
-
9
- import {
10
- addCommentToStartOfFile,
11
- getDefaultSpecifier,
12
- getJSXAttributesByName,
13
- } from '@atlaskit/codemod-utils';
14
-
15
- import { createRemoveFuncWithDefaultSpecifierFor, doesIdentifierExist } from '../utils';
16
-
17
- const spreadComment = `
18
- This file is spreading props on the Tabs component.
19
-
20
- The API has changed to be composable and a number of props have changed.
21
- - isSelectedTest no longer exists.
22
- - onSelect is now onChange and has a different type.
23
- - components prop has been removed in favour of the hooks, useTab and useTabPanel.
24
- - isContentPersisted is now called shouldUnmountTabPanelOnChange and its behaviour is inverted.
25
-
26
- If you were using any of these props, check the docs for the new API at
27
- https://atlassian.design/components/tabs/examples
28
- `;
29
-
30
- const getImportSpecifiers = (j: core.JSCodeshift, defined: Array<string>) => {
31
- return ['Tab', 'TabList', 'TabPanel'].map((specifier) => {
32
- if (!defined.includes(specifier)) {
33
- return j.importSpecifier(j.identifier(specifier), j.identifier(`Atlaskit${specifier}`));
34
- } else {
35
- return j.importSpecifier(j.identifier(specifier));
36
- }
37
- });
38
- };
39
-
40
- const packageName = '@atlaskit/tabs';
41
- export const mapTabsProp = (j: core.JSCodeshift, source: Collection<Node>) => {
42
- const specifier = getDefaultSpecifier(j, source, packageName);
43
-
44
- if (!specifier) {
45
- return;
46
- }
47
-
48
- const tabTagName = doesIdentifierExist({ j, base: source, name: 'Tab' }) ? 'AtlaskitTab' : 'Tab';
49
- const tabListTagName = doesIdentifierExist({
50
- j,
51
- base: source,
52
- name: 'TabList',
53
- })
54
- ? 'AtlaskitTabList'
55
- : 'TabList';
56
- const tabPanelTagName = doesIdentifierExist({
57
- j,
58
- base: source,
59
- name: 'TabPanel',
60
- })
61
- ? 'AtlaskitTabPanel'
62
- : 'TabPanel';
63
-
64
- source.findJSXElements(specifier).forEach((element: ASTPath<JSXElement>) => {
65
- let tabs;
66
-
67
- getJSXAttributesByName(j, element, 'tabs').forEach((attribute: any) => {
68
- tabs = attribute.value.value.expression;
69
- });
70
- if (!tabs) {
71
- j(element)
72
- .find(j.JSXOpeningElement)
73
- .find(j.JSXSpreadAttribute)
74
- .forEach((spreadAttribute) => {
75
- // If using spread then leave a comment indicating further research being needed
76
- addCommentToStartOfFile({ j, base: source, message: spreadComment });
77
- const spreadArgument = spreadAttribute.value.argument;
78
- tabs = j.memberExpression(spreadArgument, j.identifier('tabs'));
79
- });
80
- }
81
-
82
- if (!tabs) {
83
- return;
84
- }
85
-
86
- const newLine = j.jsxText('\n');
87
-
88
- const tabList = j.jsxElement(
89
- j.jsxOpeningElement(j.jsxIdentifier(tabListTagName)),
90
- j.jsxClosingElement(j.jsxIdentifier(tabListTagName)),
91
- [
92
- j.jsxText('\n'),
93
- j.jsxExpressionContainer(
94
- j.callExpression(j.memberExpression(tabs, j.identifier('map')), [
95
- j.arrowFunctionExpression(
96
- [j.identifier('tab'), j.identifier('index')],
97
- j.jsxElement(
98
- j.jsxOpeningElement(j.jsxIdentifier(tabTagName), [
99
- j.jsxAttribute(
100
- j.jsxIdentifier('testId'),
101
- j.jsxExpressionContainer(j.identifier('tab.testId')),
102
- ),
103
- j.jsxAttribute(
104
- j.jsxIdentifier('key'),
105
- j.jsxExpressionContainer(j.identifier('index')),
106
- ),
107
- ]),
108
- j.jsxClosingElement(j.jsxIdentifier(tabTagName)),
109
- [j.jsxExpressionContainer(j.identifier('tab.label'))],
110
- ),
111
- ),
112
- ]),
113
- ),
114
- j.jsxText('\n'),
115
- ],
116
- );
117
-
118
- const tabPanels = j.jsxExpressionContainer(
119
- j.callExpression(j.memberExpression(tabs, j.identifier('map')), [
120
- j.arrowFunctionExpression(
121
- [j.identifier('tab'), j.identifier('index')],
122
- j.jsxElement(
123
- j.jsxOpeningElement(j.jsxIdentifier(tabPanelTagName), [
124
- j.jsxAttribute(
125
- j.jsxIdentifier('key'),
126
- j.jsxExpressionContainer(j.identifier('index')),
127
- ),
128
- ]),
129
- j.jsxClosingElement(j.jsxIdentifier(tabPanelTagName)),
130
- [j.jsxExpressionContainer(j.identifier('tab.content'))],
131
- ),
132
- ),
133
- ]),
134
- );
135
-
136
- const tabsChildren = [newLine, tabList, newLine, tabPanels, newLine];
137
-
138
- j(element)
139
- .find(j.JSXOpeningElement)
140
- .forEach((openingElement) => {
141
- // @ts-ignore
142
- if (openingElement.value.name.name === specifier) {
143
- j(openingElement).replaceWith(
144
- j.jsxElement(
145
- j.jsxOpeningElement(j.jsxIdentifier(specifier), openingElement.value.attributes),
146
- j.jsxClosingElement(j.jsxIdentifier(specifier)),
147
- tabsChildren,
148
- ),
149
- );
150
- }
151
- });
152
- });
153
-
154
- const specifiers = getImportSpecifiers(j, [tabTagName, tabListTagName, tabPanelTagName]);
155
-
156
- source
157
- .find(j.ImportDeclaration)
158
- .filter((path: ASTPath<ImportDeclaration>) => path.node.source.value === packageName)
159
- .forEach((path: ASTPath<ImportDeclaration>) => {
160
- j(path).replaceWith(
161
- j.importDeclaration(
162
- // @ts-ignore
163
- [...path.value.specifiers, ...specifiers],
164
-
165
- j.literal(packageName),
166
- ),
167
- );
168
- });
169
- };
170
-
171
- export const removeTabsProp = createRemoveFuncWithDefaultSpecifierFor('@atlaskit/tabs', 'tabs');
@@ -1,91 +0,0 @@
1
- import { type ASTPath, type default as core, type JSXElement } from 'jscodeshift';
2
- import { type Collection } from 'jscodeshift/src/Collection';
3
-
4
- import {
5
- addCommentToStartOfFile,
6
- getDefaultSpecifier,
7
- getJSXAttributesByName,
8
- } from '@atlaskit/codemod-utils';
9
-
10
- const comment = `
11
- This file uses onSelect and this prop has been changed names to onChange.
12
-
13
- The type of onChange has also changed from
14
- (selected: TabData, selectedIndex: number, analyticsEvent: UIAnalyticsEvent) => void;
15
- to
16
- (index: number, analyticsEvent: UIAnalyticsEvent) => void;
17
-
18
- The logic around selecting tabs has changed internally and there is no longer the concept of TabData.
19
- Tabs is now composable and the tabs prop has been removed.
20
-
21
- The codemod has changed your usage of onSelect to be one of onChange. We are using the tabs
22
- array and the selected index to pass the "selected tab" to your old onSelect function. This is
23
- functional but you may like to update your usage of tabs to fit with the new API.
24
-
25
- If you are using the selected prop you will need to ensure that you are passing in the index
26
- of the selected tab as it also doesn't accept TabData anymore.
27
- `;
28
-
29
- export const migrateOnSelectType = (j: core.JSCodeshift, source: Collection<Node>) => {
30
- const specifier = getDefaultSpecifier(j, source, '@atlaskit/tabs');
31
-
32
- if (!specifier) {
33
- return;
34
- }
35
-
36
- source.findJSXElements(specifier).forEach((element: ASTPath<JSXElement>) => {
37
- let tabs: any;
38
- getJSXAttributesByName(j, element, 'tabs').forEach((attribute: any) => {
39
- tabs = attribute.value.value.expression;
40
- });
41
-
42
- if (!tabs) {
43
- j(element)
44
- .find(j.JSXOpeningElement)
45
- .find(j.JSXSpreadAttribute)
46
- .forEach((spreadAttribute) => {
47
- const spreadArgument = spreadAttribute.value.argument;
48
- tabs = j.memberExpression(spreadArgument, j.identifier('tabs'));
49
- });
50
- }
51
-
52
- if (!tabs) {
53
- return;
54
- }
55
-
56
- getJSXAttributesByName(j, element, 'onSelect').forEach((attribute: any) => {
57
- addCommentToStartOfFile({ j, base: source, message: comment });
58
- const onChangeValue = attribute.node.value.expression;
59
-
60
- let selectedTab = j.variableDeclaration('const', [
61
- j.variableDeclarator(
62
- j.identifier('selectedTab'),
63
- j.memberExpression(tabs, j.identifier('index'), true),
64
- ),
65
- ]);
66
-
67
- // Wrap arrow functions to create an IIFE
68
- let onChangeCall = onChangeValue.name
69
- ? onChangeValue
70
- : j.parenthesizedExpression(onChangeValue);
71
-
72
- const newVersionOfFn = j.arrowFunctionExpression(
73
- [j.identifier('index'), j.identifier('analyticsEvent')],
74
- j.blockStatement([
75
- selectedTab,
76
- j.expressionStatement(
77
- j.callExpression(onChangeCall, [
78
- j.identifier('selectedTab'),
79
- j.identifier('index'),
80
- j.identifier('analyticsEvent'),
81
- ]),
82
- ),
83
- ]),
84
- );
85
-
86
- j(attribute).replaceWith(
87
- j.jsxAttribute(j.jsxIdentifier('onChange'), j.jsxExpressionContainer(newVersionOfFn)),
88
- );
89
- });
90
- });
91
- };
@@ -1,20 +0,0 @@
1
- import { createRemoveFuncWithDefaultSpecifierFor } from '../utils';
2
-
3
- const comment = `
4
- We could not automatically convert this code to the new API.
5
-
6
- This file uses \`Tabs\`’s \`component\` prop. This has been removed as part of moving to
7
- a compositional API.
8
-
9
- To create a custom tab (replacement for \`Item\` component) refer to the docs at
10
- https://atlassian.design/components/tabs/examples#customizing-tab
11
-
12
- To create a custom tab panel (replacement for \`Content\` component) refer to the docs at
13
- https://atlassian.design/components/tabs/examples#customizing-tab-panel
14
- `;
15
-
16
- export const removeComponentsProp = createRemoveFuncWithDefaultSpecifierFor(
17
- '@atlaskit/tabs',
18
- 'components',
19
- comment,
20
- );
@@ -1,17 +0,0 @@
1
- import { createRemoveFuncWithDefaultSpecifierFor } from '../utils';
2
-
3
- const comment = `
4
- We could not automatically convert this code to the new API.
5
-
6
- This file uses \`Tabs\`’s \`isSelectedTest\` prop. This has been removed as it is a second way
7
- to make \`Tabs\` controlled and is not needed.
8
-
9
- You will have to change your usage of \`tabs\` to use the \`selected\` prop.
10
- This is documented at https:atlassian.design/components/tabs/examples#controlled
11
- `;
12
-
13
- export const removeIsSelectedTestProp = createRemoveFuncWithDefaultSpecifierFor(
14
- '@atlaskit/tabs',
15
- 'isSelectedTest',
16
- comment,
17
- );
@@ -1,26 +0,0 @@
1
- import {
2
- type ASTPath,
3
- type default as core,
4
- type ImportDeclaration,
5
- type ImportSpecifier,
6
- } from 'jscodeshift';
7
- import { type Collection } from 'jscodeshift/src/Collection';
8
-
9
- const component = '@atlaskit/tabs';
10
-
11
- export const removeTabItemTabContent = (j: core.JSCodeshift, source: Collection<Node>) => {
12
- source
13
- .find(j.ImportDeclaration)
14
- .filter(
15
- (importDeclaration: ASTPath<ImportDeclaration>) =>
16
- importDeclaration.node.source.value === component,
17
- )
18
- // Tabs only exported TabItem and TabContent from base so remove them
19
- .forEach((importDeclaration) => {
20
- j(importDeclaration)
21
- .find(j.ImportSpecifier)
22
- .forEach((importSpecifier: ASTPath<ImportSpecifier>) => {
23
- j(importSpecifier).remove();
24
- });
25
- });
26
- };
@@ -1,45 +0,0 @@
1
- import {
2
- type ASTPath,
3
- type default as core,
4
- type ImportDeclaration,
5
- type ImportSpecifier,
6
- } from 'jscodeshift';
7
- import { type Collection } from 'jscodeshift/src/Collection';
8
-
9
- const component = '@atlaskit/tabs/types';
10
- const existingTypes = [
11
- 'TabProps',
12
- 'TabPanelProps',
13
- 'TabsProps',
14
- 'TabListProps',
15
- 'TabAttributesType',
16
- 'TabListAttributesType',
17
- 'TabPanelAttributesType',
18
- 'TabData',
19
- ];
20
-
21
- export const removeTypes = (j: core.JSCodeshift, source: Collection<Node>) => {
22
- source
23
- .find(j.ImportDeclaration)
24
- .filter(
25
- (importDeclaration: ASTPath<ImportDeclaration>) =>
26
- importDeclaration.node.source.value === component,
27
- )
28
- .forEach((importDeclaration) => {
29
- const specifiers = j(importDeclaration)
30
- .find(j.ImportSpecifier)
31
- .filter((importSpecifier: ASTPath<ImportSpecifier>) => {
32
- if (!existingTypes.includes(importSpecifier.node.imported.name)) {
33
- j(importSpecifier).remove();
34
-
35
- return false;
36
- }
37
-
38
- return true;
39
- });
40
-
41
- if (!specifiers.length) {
42
- j(importDeclaration).remove();
43
- }
44
- });
45
- };
@@ -1,62 +0,0 @@
1
- import {
2
- type ASTPath,
3
- type default as core,
4
- type JSXAttribute,
5
- type JSXElement,
6
- } from 'jscodeshift';
7
- import { type Collection } from 'jscodeshift/src/Collection';
8
-
9
- import { getDefaultSpecifier, getJSXAttributesByName } from '@atlaskit/codemod-utils';
10
-
11
- const component = '@atlaskit/tabs';
12
- const fromProp = 'isContentPersisted';
13
- const toProp = 'shouldUnmountTabPanelOnChange';
14
-
15
- export const renameIsContentPersistedToShouldUnmountTabPanelOnChange = (
16
- j: core.JSCodeshift,
17
- source: Collection<Node>,
18
- ) => {
19
- const defaultSpecifier = getDefaultSpecifier(j, source, component);
20
-
21
- if (!defaultSpecifier) {
22
- return;
23
- }
24
-
25
- source.findJSXElements(defaultSpecifier).forEach((element: ASTPath<JSXElement>) => {
26
- let foundUsage = false;
27
- getJSXAttributesByName(j, element, fromProp).forEach((attribute: ASTPath<JSXAttribute>) => {
28
- foundUsage = true;
29
- const { value } = attribute.node;
30
-
31
- if (!value) {
32
- // boolean attribute isContentPersisted -> removed
33
- return j(attribute).remove();
34
- }
35
-
36
- if (value.type === 'JSXExpressionContainer') {
37
- if (value.expression.type === 'BooleanLiteral') {
38
- if (value.expression.value) {
39
- // isContentPersisted={true} -> removed
40
- j(attribute).remove();
41
- } else {
42
- // isContentPersisted={false} -> shouldUnmountTabPanelOnChange
43
- j(attribute).replaceWith(j.jsxAttribute(j.jsxIdentifier(toProp), null));
44
- }
45
- } else if (value.expression.type === 'Identifier') {
46
- // isContentPersisted={isContentPersisted} -> shouldUnmountTabPanelOnChange={!isContentPersisted}
47
- j(attribute).replaceWith(
48
- j.jsxAttribute(
49
- j.jsxIdentifier(toProp),
50
- j.jsxExpressionContainer(j.unaryExpression('!', value.expression)),
51
- ),
52
- );
53
- }
54
- }
55
- });
56
- if (!foundUsage) {
57
- // No prop -> shouldUnmountTabPanelOnChange
58
- // @ts-ignore
59
- element.value.openingElement.attributes.push(j.jsxAttribute(j.jsxIdentifier(toProp), null));
60
- }
61
- });
62
- };
@@ -1,39 +0,0 @@
1
- import type core from 'jscodeshift';
2
- import { type Collection } from 'jscodeshift/src/Collection';
3
-
4
- import {
5
- addCommentToStartOfFile,
6
- getDefaultSpecifier,
7
- getJSXAttributesByName,
8
- } from '@atlaskit/codemod-utils';
9
-
10
- export const createRemoveFuncWithDefaultSpecifierFor =
11
- (component: string, prop: string, comment?: string) =>
12
- (j: core.JSCodeshift, source: Collection<Node>) => {
13
- const specifier = getDefaultSpecifier(j, source, component);
14
-
15
- if (!specifier) {
16
- return;
17
- }
18
-
19
- source.findJSXElements(specifier).forEach((element) => {
20
- getJSXAttributesByName(j, element, prop).forEach((attribute: any) => {
21
- if (comment) {
22
- addCommentToStartOfFile({ j, base: source, message: comment });
23
- }
24
- j(attribute).remove();
25
- });
26
- });
27
- };
28
-
29
- export function doesIdentifierExist({
30
- j,
31
- base,
32
- name,
33
- }: {
34
- j: core.JSCodeshift;
35
- base: Collection<any>;
36
- name: string;
37
- }): boolean {
38
- return base.find(j.Identifier).filter((identifer) => identifer.value.name === name).length > 0;
39
- }