@atlaskit/button 16.1.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 (113) hide show
  1. package/CHANGELOG.md +1485 -0
  2. package/LICENSE +13 -0
  3. package/README.md +13 -0
  4. package/__perf__/button.tsx +19 -0
  5. package/__perf__/custom.tsx +19 -0
  6. package/__perf__/customised.tsx +11 -0
  7. package/__perf__/default.tsx +5 -0
  8. package/__perf__/loading.tsx +5 -0
  9. package/__perf__/utils/example-runner.tsx +48 -0
  10. package/__perf__/utils/interaction-tasks.tsx +98 -0
  11. package/button-group/package.json +7 -0
  12. package/codemods/15.0.0-lite-mode.ts +49 -0
  13. package/codemods/15.1.1-data-testid.ts +173 -0
  14. package/codemods/__tests__/15.0.0-lite-mode/optimistic.ts +646 -0
  15. package/codemods/__tests__/15.0.0-lite-mode/safe.ts +223 -0
  16. package/codemods/__tests__/15.0.0-lite-mode/shared.ts +257 -0
  17. package/codemods/__tests__/15.1.1-data-testid/rename-data-testid.ts +186 -0
  18. package/codemods/__tests__/_framework.ts +47 -0
  19. package/codemods/helpers/15.0.0-runner.ts +169 -0
  20. package/codemods/helpers/helpers-generic.ts +662 -0
  21. package/codemods/optimistic-15.0.0-lite-mode.ts +279 -0
  22. package/codemods/readme.md +1 -0
  23. package/custom-theme-button/package.json +7 -0
  24. package/dist/cjs/button-group.js +50 -0
  25. package/dist/cjs/button.js +104 -0
  26. package/dist/cjs/custom-theme-button/custom-theme-button-types.js +5 -0
  27. package/dist/cjs/custom-theme-button/custom-theme-button.js +229 -0
  28. package/dist/cjs/custom-theme-button/index.js +23 -0
  29. package/dist/cjs/custom-theme-button/theme.js +108 -0
  30. package/dist/cjs/entry-points/button-group.js +15 -0
  31. package/dist/cjs/entry-points/custom-theme-button.js +25 -0
  32. package/dist/cjs/entry-points/loading-button.js +15 -0
  33. package/dist/cjs/entry-points/standard-button.js +15 -0
  34. package/dist/cjs/entry-points/types.js +5 -0
  35. package/dist/cjs/index.js +51 -0
  36. package/dist/cjs/loading-button.js +34 -0
  37. package/dist/cjs/shared/block-events.js +44 -0
  38. package/dist/cjs/shared/button-base.js +158 -0
  39. package/dist/cjs/shared/colors.js +409 -0
  40. package/dist/cjs/shared/css.js +265 -0
  41. package/dist/cjs/shared/get-is-only-single-icon.js +26 -0
  42. package/dist/cjs/shared/loading-spinner.js +45 -0
  43. package/dist/cjs/types.js +5 -0
  44. package/dist/cjs/version.json +5 -0
  45. package/dist/es2019/button-group.js +36 -0
  46. package/dist/es2019/button.js +69 -0
  47. package/dist/es2019/custom-theme-button/custom-theme-button-types.js +1 -0
  48. package/dist/es2019/custom-theme-button/custom-theme-button.js +164 -0
  49. package/dist/es2019/custom-theme-button/index.js +2 -0
  50. package/dist/es2019/custom-theme-button/theme.js +81 -0
  51. package/dist/es2019/entry-points/button-group.js +1 -0
  52. package/dist/es2019/entry-points/custom-theme-button.js +1 -0
  53. package/dist/es2019/entry-points/loading-button.js +1 -0
  54. package/dist/es2019/entry-points/standard-button.js +1 -0
  55. package/dist/es2019/entry-points/types.js +1 -0
  56. package/dist/es2019/index.js +6 -0
  57. package/dist/es2019/loading-button.js +17 -0
  58. package/dist/es2019/shared/block-events.js +37 -0
  59. package/dist/es2019/shared/button-base.js +127 -0
  60. package/dist/es2019/shared/colors.js +393 -0
  61. package/dist/es2019/shared/css.js +249 -0
  62. package/dist/es2019/shared/get-is-only-single-icon.js +19 -0
  63. package/dist/es2019/shared/loading-spinner.js +33 -0
  64. package/dist/es2019/types.js +1 -0
  65. package/dist/es2019/version.json +5 -0
  66. package/dist/esm/button-group.js +35 -0
  67. package/dist/esm/button.js +79 -0
  68. package/dist/esm/custom-theme-button/custom-theme-button-types.js +1 -0
  69. package/dist/esm/custom-theme-button/custom-theme-button.js +203 -0
  70. package/dist/esm/custom-theme-button/index.js +2 -0
  71. package/dist/esm/custom-theme-button/theme.js +90 -0
  72. package/dist/esm/entry-points/button-group.js +1 -0
  73. package/dist/esm/entry-points/custom-theme-button.js +1 -0
  74. package/dist/esm/entry-points/loading-button.js +1 -0
  75. package/dist/esm/entry-points/standard-button.js +1 -0
  76. package/dist/esm/entry-points/types.js +1 -0
  77. package/dist/esm/index.js +6 -0
  78. package/dist/esm/loading-button.js +19 -0
  79. package/dist/esm/shared/block-events.js +36 -0
  80. package/dist/esm/shared/button-base.js +135 -0
  81. package/dist/esm/shared/colors.js +393 -0
  82. package/dist/esm/shared/css.js +245 -0
  83. package/dist/esm/shared/get-is-only-single-icon.js +19 -0
  84. package/dist/esm/shared/loading-spinner.js +35 -0
  85. package/dist/esm/types.js +1 -0
  86. package/dist/esm/version.json +5 -0
  87. package/dist/types/button-group.d.ts +18 -0
  88. package/dist/types/button.d.ts +8 -0
  89. package/dist/types/custom-theme-button/custom-theme-button-types.d.ts +21 -0
  90. package/dist/types/custom-theme-button/custom-theme-button.d.ts +6 -0
  91. package/dist/types/custom-theme-button/index.d.ts +2 -0
  92. package/dist/types/custom-theme-button/theme.d.ts +21 -0
  93. package/dist/types/entry-points/button-group.d.ts +1 -0
  94. package/dist/types/entry-points/custom-theme-button.d.ts +2 -0
  95. package/dist/types/entry-points/loading-button.d.ts +2 -0
  96. package/dist/types/entry-points/standard-button.d.ts +2 -0
  97. package/dist/types/entry-points/types.d.ts +4 -0
  98. package/dist/types/index.d.ts +8 -0
  99. package/dist/types/loading-button.d.ts +11 -0
  100. package/dist/types/shared/block-events.d.ts +3 -0
  101. package/dist/types/shared/button-base.d.ts +10 -0
  102. package/dist/types/shared/colors.d.ts +31 -0
  103. package/dist/types/shared/css.d.ts +22 -0
  104. package/dist/types/shared/get-is-only-single-icon.d.ts +2 -0
  105. package/dist/types/shared/loading-spinner.d.ts +4 -0
  106. package/dist/types/types.d.ts +51 -0
  107. package/extract-react-types/custom-theme-button-props.tsx +7 -0
  108. package/extract-react-types/loading-button-props.tsx +5 -0
  109. package/extract-react-types/shared-props.tsx +5 -0
  110. package/loading-button/package.json +7 -0
  111. package/package.json +83 -0
  112. package/standard-button/package.json +7 -0
  113. 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
+ # Button
2
+
3
+ A button triggers an event or action. They let users know what will happen next.
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ yarn add @atlaskit/button
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Detailed docs and example usage can be found [here](https://atlassian.design/components/button/).
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+
3
+ import Button from '../src';
4
+
5
+ import Example from './utils/example-runner';
6
+ import { interactionTasks } from './utils/interaction-tasks';
7
+
8
+ const button = () => <Example Component={Button} />;
9
+
10
+ button.story = {
11
+ name: 'Button',
12
+ parameters: {
13
+ performance: {
14
+ interactions: interactionTasks,
15
+ },
16
+ },
17
+ };
18
+
19
+ export default button;
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+
3
+ import { CustomThemeButton } from '../src';
4
+
5
+ import Example from './utils/example-runner';
6
+ import { interactionTasks } from './utils/interaction-tasks';
7
+
8
+ const customThemeButton = () => <Example Component={CustomThemeButton} />;
9
+
10
+ customThemeButton.story = {
11
+ name: 'CustomThemeButton',
12
+ parameters: {
13
+ performance: {
14
+ interactions: interactionTasks,
15
+ },
16
+ },
17
+ };
18
+
19
+ export default customThemeButton;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+
3
+ import AddIcon from '@atlaskit/icon/glyph/editor/add';
4
+
5
+ import { CustomThemeButton } from '../src';
6
+
7
+ export default () => (
8
+ <CustomThemeButton iconBefore={<AddIcon label="add" />}>
9
+ Button
10
+ </CustomThemeButton>
11
+ );
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ import Button from '../src';
4
+
5
+ export default () => <Button>Default button</Button>;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ import { LoadingButton } from '../src';
4
+
5
+ export default () => <LoadingButton isLoading>Loading button</LoadingButton>;
@@ -0,0 +1,48 @@
1
+ import React, { useLayoutEffect, useRef, useState } from 'react';
2
+
3
+ import type { ButtonProps } from '../../src';
4
+
5
+ export default function Example({
6
+ Component,
7
+ }: {
8
+ Component: ButtonProps['component'];
9
+ }) {
10
+ const [isSelected, setIsSelected] = useState<boolean>(false);
11
+ const [isDisabled, setIsDisabled] = useState<boolean>(false);
12
+ const ref = useRef<HTMLElement>(null);
13
+
14
+ useLayoutEffect(() => {
15
+ function toggleSelect() {
16
+ setIsSelected((value) => !value);
17
+ }
18
+ function toggleDisabled() {
19
+ setIsDisabled((value) => !value);
20
+ }
21
+
22
+ const el: HTMLElement | null = ref.current;
23
+ if (!el) {
24
+ throw new Error('Could not find button ref');
25
+ }
26
+
27
+ el.addEventListener('toggle-select', toggleSelect);
28
+ el.addEventListener('toggle-disabled', toggleDisabled);
29
+
30
+ return () => {
31
+ el.removeEventListener('toggle-select', toggleSelect);
32
+ el.removeEventListener('toggle-disabled', toggleDisabled);
33
+ };
34
+ }, []);
35
+
36
+ return (
37
+ // @ts-ignore
38
+ <Component
39
+ ref={ref}
40
+ testId="my-button"
41
+ isSelected={isSelected}
42
+ isDisabled={isDisabled}
43
+ data-is-selected={isSelected}
44
+ >
45
+ Hello world
46
+ </Component>
47
+ );
48
+ }
@@ -0,0 +1,98 @@
1
+ import { fireEvent } from '@testing-library/react';
2
+ import {
3
+ InteractionTaskArgs,
4
+ PublicInteractionTask,
5
+ } from 'storybook-addon-performance';
6
+
7
+ export const interactionTasks: PublicInteractionTask[] = [
8
+ {
9
+ name: 'Click a button',
10
+ description:
11
+ 'Recording how long a mousedown + click event take to be processed',
12
+ run: async ({ container }: InteractionTaskArgs): Promise<void> => {
13
+ const button: HTMLElement | null = container.querySelector(
14
+ '[data-testid="my-button"]',
15
+ );
16
+ if (button == null) {
17
+ throw new Error('Could not find button element');
18
+ }
19
+
20
+ fireEvent.mouseDown(button);
21
+ fireEvent.click(button);
22
+ },
23
+ },
24
+ {
25
+ name: 'Focus on button',
26
+ description: 'Focus on a button and wait for layout and paint to finish',
27
+ run: async ({
28
+ container,
29
+ controls,
30
+ }: InteractionTaskArgs): Promise<void> => {
31
+ const button: HTMLElement | null = container.querySelector(
32
+ '[data-testid="my-button"]',
33
+ );
34
+ if (button == null) {
35
+ throw new Error('Could not find button element');
36
+ }
37
+
38
+ await controls.time(async () => {
39
+ fireEvent.focus(button);
40
+ fireEvent.blur(button);
41
+ });
42
+ },
43
+ },
44
+ {
45
+ name: 'Select button',
46
+ description: 'Trigger the selection of a button',
47
+ run: async ({
48
+ container,
49
+ controls,
50
+ }: InteractionTaskArgs): Promise<void> => {
51
+ const button: HTMLElement | null = container.querySelector(
52
+ '[data-testid="my-button"]',
53
+ );
54
+ if (button == null) {
55
+ throw new Error('Could not find button element');
56
+ }
57
+
58
+ if (button.getAttribute('data-is-selected') !== 'false') {
59
+ throw new Error('Should not start selected');
60
+ }
61
+
62
+ await controls.time(async () => {
63
+ fireEvent(button, new Event('toggle-select'));
64
+ });
65
+
66
+ if (button.getAttribute('data-is-selected') !== 'true') {
67
+ throw new Error('Should now be selected');
68
+ }
69
+ },
70
+ },
71
+ {
72
+ name: 'Disable button',
73
+ description: 'Trigger the disabling of a button',
74
+ run: async ({
75
+ container,
76
+ controls,
77
+ }: InteractionTaskArgs): Promise<void> => {
78
+ const button: HTMLElement | null = container.querySelector(
79
+ '[data-testid="my-button"]',
80
+ );
81
+ if (button == null) {
82
+ throw new Error('Could not find button element');
83
+ }
84
+
85
+ if (button.hasAttribute('disabled')) {
86
+ throw new Error('Should not start disabled');
87
+ }
88
+
89
+ await controls.time(async () => {
90
+ fireEvent(button, new Event('toggle-disabled'));
91
+ });
92
+
93
+ if (!button.hasAttribute('disabled')) {
94
+ throw new Error('Should now be disabled');
95
+ }
96
+ },
97
+ },
98
+ ];
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@atlaskit/button/button-group",
3
+ "main": "../dist/cjs/entry-points/button-group.js",
4
+ "module": "../dist/esm/entry-points/button-group.js",
5
+ "module:es2019": "../dist/es2019/entry-points/button-group.js",
6
+ "types": "../dist/types/entry-points/button-group.d.ts"
7
+ }
@@ -0,0 +1,49 @@
1
+ import { API, FileInfo, Options } from 'jscodeshift';
2
+ import { Collection } from 'jscodeshift/src/Collection';
3
+
4
+ import { changeType, transformButton } from './helpers/15.0.0-runner';
5
+ import {
6
+ getDefaultSpecifierName,
7
+ Nullable,
8
+ shiftDefaultImport,
9
+ } from './helpers/helpers-generic';
10
+
11
+ export default function transformer(
12
+ file: FileInfo,
13
+ { jscodeshift: j }: API,
14
+ options: Options,
15
+ ) {
16
+ return transformButton({
17
+ file,
18
+ j,
19
+ custom: (base: Collection<any>) => {
20
+ changeType({
21
+ j,
22
+ base,
23
+ oldName: 'ButtonProps',
24
+ newName: 'CustomThemeButtonProps',
25
+ fallbackNameAlias: 'DSCustomThemeButtonProps',
26
+ });
27
+
28
+ const defaultName: Nullable<string> = getDefaultSpecifierName({
29
+ j,
30
+ base,
31
+ packageName: '@atlaskit/button',
32
+ });
33
+ if (defaultName == null) {
34
+ return;
35
+ }
36
+
37
+ shiftDefaultImport({
38
+ j,
39
+ base,
40
+ defaultName,
41
+ oldPackagePath: '@atlaskit/button',
42
+ newPackagePath: '@atlaskit/button/custom-theme-button',
43
+ });
44
+ },
45
+ });
46
+ }
47
+
48
+ // Note: not exporting a 'parser' because doing so
49
+ // will prevent consumers overriding it
@@ -0,0 +1,173 @@
1
+ import core, { API, FileInfo, Options } from 'jscodeshift';
2
+ import { Collection } from 'jscodeshift/src/Collection';
3
+
4
+ import {
5
+ addCommentToStartOfFile,
6
+ getDefaultSpecifierName,
7
+ getJSXAttributesByName,
8
+ hasImportDeclaration,
9
+ Nullable,
10
+ } from './helpers/helpers-generic';
11
+ const relevantEntryPoints = [
12
+ '@atlaskit/button',
13
+ '@atlaskit/button/standard-button',
14
+ '@atlaskit/button/loading-button',
15
+ '@atlaskit/button/custom-theme-button',
16
+ ];
17
+
18
+ function isRelevant(j: core.JSCodeshift, source: string): boolean {
19
+ return relevantEntryPoints.some((entryPoint) =>
20
+ hasImportDeclaration(j, source, entryPoint),
21
+ );
22
+ }
23
+
24
+ function renameProp({
25
+ j,
26
+ base,
27
+ component,
28
+ attributeFrom,
29
+ attributeTo,
30
+ }: {
31
+ j: core.JSCodeshift;
32
+ base: Collection<any>;
33
+ component: string;
34
+ attributeFrom: string;
35
+ attributeTo: string;
36
+ }) {
37
+ base.findJSXElements(component).forEach((element) => {
38
+ const first = getJSXAttributesByName({
39
+ j,
40
+ element: element.value,
41
+ attributeName: attributeFrom,
42
+ });
43
+
44
+ // not using attribute
45
+ if (!first.length) {
46
+ return;
47
+ }
48
+
49
+ // let's check to see if they are using the to attribute
50
+ const second = getJSXAttributesByName({
51
+ j,
52
+ element: element.value,
53
+ attributeName: attributeTo,
54
+ });
55
+
56
+ // if the attribute we are moving to already exists we are in trouble
57
+ if (second.length) {
58
+ addCommentToStartOfFile({
59
+ j,
60
+ base,
61
+ message: `
62
+ Cannot rename ${attributeFrom} to ${attributeTo} on ${component}.
63
+ A ${component} was detected with both ${attributeFrom} and ${attributeTo} props.
64
+ Please remove the ${attributeFrom} prop and check your tests`,
65
+ });
66
+ return;
67
+ }
68
+
69
+ first.find(j.JSXIdentifier).replaceWith(j.jsxIdentifier(attributeTo));
70
+ });
71
+ }
72
+
73
+ export function getNamedImportName({
74
+ j,
75
+ base,
76
+ importPath,
77
+ originalName,
78
+ }: {
79
+ j: core.JSCodeshift;
80
+ base: Collection<any>;
81
+ originalName: string;
82
+ importPath: string;
83
+ }): Nullable<string> {
84
+ const name: Nullable<string> =
85
+ base
86
+ .find(j.ImportDeclaration)
87
+ .filter((path) => path.node.source.value === importPath)
88
+ .find(j.ImportSpecifier)
89
+ .nodes()
90
+ .map(
91
+ (specifier): Nullable<string> => {
92
+ if (specifier.imported.name === originalName) {
93
+ // aliased
94
+ if (specifier.local) {
95
+ return specifier.local.name;
96
+ }
97
+ // not aliased
98
+ return originalName;
99
+ }
100
+
101
+ return null;
102
+ },
103
+ )
104
+ .filter(Boolean)[0] || null;
105
+ return name;
106
+ }
107
+
108
+ export default function transformer(
109
+ file: FileInfo,
110
+ { jscodeshift: j }: API,
111
+ options: Options,
112
+ ) {
113
+ if (!isRelevant(j, file.source)) {
114
+ return file.source;
115
+ }
116
+
117
+ const base: Collection<any> = j(file.source);
118
+
119
+ // renaming default imports for entry points
120
+ relevantEntryPoints.forEach((importPath) => {
121
+ const defaultName: Nullable<string> = getDefaultSpecifierName({
122
+ j,
123
+ base,
124
+ packageName: importPath,
125
+ });
126
+
127
+ if (defaultName != null) {
128
+ renameProp({
129
+ j,
130
+ base,
131
+ component: defaultName,
132
+ attributeFrom: 'data-testid',
133
+ attributeTo: 'testId',
134
+ });
135
+ }
136
+ });
137
+
138
+ // named imports
139
+ const standard = getNamedImportName({
140
+ j,
141
+ base,
142
+ importPath: '@atlaskit/button',
143
+ originalName: 'StandardButton',
144
+ });
145
+ const loading = getNamedImportName({
146
+ j,
147
+ base,
148
+ importPath: '@atlaskit/button',
149
+ originalName: 'LoadingButton',
150
+ });
151
+ const customTheme = getNamedImportName({
152
+ j,
153
+ base,
154
+ importPath: '@atlaskit/button',
155
+ originalName: 'CustomThemeButton',
156
+ });
157
+ [standard, loading, customTheme].forEach((name) => {
158
+ if (name != null) {
159
+ renameProp({
160
+ j,
161
+ base,
162
+ component: name,
163
+ attributeFrom: 'data-testid',
164
+ attributeTo: 'testId',
165
+ });
166
+ }
167
+ });
168
+
169
+ return base.toSource({ quote: 'single' });
170
+ }
171
+
172
+ // Note: not exporting a 'parser' because doing so
173
+ // will prevent consumers overriding it