@atlaskit/button 17.17.2 → 17.18.0

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 (105) hide show
  1. package/CHANGELOG.md +56 -1
  2. package/__perf__/button.tsx +6 -6
  3. package/__perf__/custom.tsx +6 -6
  4. package/__perf__/customised.tsx +1 -3
  5. package/__perf__/utils/example-runner.tsx +32 -36
  6. package/__perf__/utils/interaction-tasks.tsx +65 -86
  7. package/codemods/15.0.0-lite-mode.tsx +32 -36
  8. package/codemods/15.1.1-data-testid.tsx +136 -142
  9. package/codemods/__tests__/15.0.0-lite-mode/optimistic.tsx +121 -121
  10. package/codemods/__tests__/15.0.0-lite-mode/safe.tsx +54 -54
  11. package/codemods/__tests__/15.0.0-lite-mode/shared.tsx +96 -97
  12. package/codemods/__tests__/15.1.1-data-testid/rename-data-testid.tsx +32 -32
  13. package/codemods/__tests__/_framework.tsx +32 -32
  14. package/codemods/helpers/15.0.0-runner.tsx +135 -137
  15. package/codemods/helpers/helpers-generic.tsx +524 -556
  16. package/codemods/optimistic-15.0.0-lite-mode.tsx +208 -231
  17. package/dist/cjs/containers/button-group.js +3 -1
  18. package/dist/cjs/new-button/containers/split-button/split-button.js +6 -2
  19. package/dist/cjs/new-button/variants/default/button.js +8 -1
  20. package/dist/cjs/new-button/variants/default/link.js +8 -1
  21. package/dist/cjs/new-button/variants/default/use-default-button.js +7 -1
  22. package/dist/cjs/new-button/variants/icon/button.js +6 -1
  23. package/dist/cjs/new-button/variants/icon/link.js +6 -1
  24. package/dist/cjs/new-button/variants/icon/use-icon-button.js +7 -1
  25. package/dist/cjs/new-button/variants/shared/constants.js +7 -0
  26. package/dist/cjs/new-button/variants/shared/loading-overlay.js +4 -3
  27. package/dist/cjs/new-button/variants/shared/use-button-base.js +54 -2
  28. package/dist/cjs/old-button/button.js +1 -1
  29. package/dist/cjs/old-button/custom-theme-button/custom-theme-button.js +1 -1
  30. package/dist/cjs/old-button/custom-theme-button/theme.js +1 -1
  31. package/dist/cjs/old-button/shared/button-base.js +9 -3
  32. package/dist/cjs/old-button/shared/css.js +4 -3
  33. package/dist/es2019/containers/button-group.js +3 -1
  34. package/dist/es2019/new-button/containers/split-button/split-button.js +5 -2
  35. package/dist/es2019/new-button/variants/default/button.js +7 -0
  36. package/dist/es2019/new-button/variants/default/link.js +9 -2
  37. package/dist/es2019/new-button/variants/default/use-default-button.js +7 -1
  38. package/dist/es2019/new-button/variants/icon/button.js +5 -0
  39. package/dist/es2019/new-button/variants/icon/link.js +8 -3
  40. package/dist/es2019/new-button/variants/icon/use-icon-button.js +7 -1
  41. package/dist/es2019/new-button/variants/shared/constants.js +1 -0
  42. package/dist/es2019/new-button/variants/shared/loading-overlay.js +4 -3
  43. package/dist/es2019/new-button/variants/shared/use-button-base.js +54 -2
  44. package/dist/es2019/old-button/button.js +3 -0
  45. package/dist/es2019/old-button/custom-theme-button/custom-theme-button.js +3 -0
  46. package/dist/es2019/old-button/custom-theme-button/theme.js +2 -0
  47. package/dist/es2019/old-button/shared/button-base.js +10 -3
  48. package/dist/es2019/old-button/shared/css.js +4 -2
  49. package/dist/esm/containers/button-group.js +3 -1
  50. package/dist/esm/new-button/containers/split-button/split-button.js +5 -2
  51. package/dist/esm/new-button/variants/default/button.js +8 -1
  52. package/dist/esm/new-button/variants/default/link.js +10 -3
  53. package/dist/esm/new-button/variants/default/use-default-button.js +7 -1
  54. package/dist/esm/new-button/variants/icon/button.js +6 -1
  55. package/dist/esm/new-button/variants/icon/link.js +9 -4
  56. package/dist/esm/new-button/variants/icon/use-icon-button.js +7 -1
  57. package/dist/esm/new-button/variants/shared/constants.js +1 -0
  58. package/dist/esm/new-button/variants/shared/loading-overlay.js +4 -3
  59. package/dist/esm/new-button/variants/shared/use-button-base.js +54 -2
  60. package/dist/esm/old-button/button.js +3 -0
  61. package/dist/esm/old-button/custom-theme-button/custom-theme-button.js +3 -0
  62. package/dist/esm/old-button/custom-theme-button/theme.js +2 -0
  63. package/dist/esm/old-button/shared/button-base.js +10 -3
  64. package/dist/esm/old-button/shared/css.js +4 -2
  65. package/dist/types/entry-points/loading-button.d.ts +1 -1
  66. package/dist/types/entry-points/new.d.ts +3 -3
  67. package/dist/types/entry-points/types.d.ts +2 -2
  68. package/dist/types/index.d.ts +3 -3
  69. package/dist/types/new-button/variants/default/link.d.ts +1 -1
  70. package/dist/types/new-button/variants/default/types.d.ts +1 -1
  71. package/dist/types/new-button/variants/default/use-default-button.d.ts +4 -3
  72. package/dist/types/new-button/variants/icon/link.d.ts +1 -1
  73. package/dist/types/new-button/variants/icon/use-icon-button.d.ts +4 -3
  74. package/dist/types/new-button/variants/shared/constants.d.ts +1 -0
  75. package/dist/types/new-button/variants/shared/loading-overlay.d.ts +2 -1
  76. package/dist/types/new-button/variants/shared/use-button-base.d.ts +5 -1
  77. package/dist/types/new.d.ts +3 -3
  78. package/dist/types-ts4.5/entry-points/loading-button.d.ts +1 -1
  79. package/dist/types-ts4.5/entry-points/new.d.ts +3 -3
  80. package/dist/types-ts4.5/entry-points/types.d.ts +2 -2
  81. package/dist/types-ts4.5/index.d.ts +3 -3
  82. package/dist/types-ts4.5/new-button/variants/default/link.d.ts +1 -1
  83. package/dist/types-ts4.5/new-button/variants/default/types.d.ts +1 -1
  84. package/dist/types-ts4.5/new-button/variants/default/use-default-button.d.ts +4 -3
  85. package/dist/types-ts4.5/new-button/variants/icon/link.d.ts +1 -1
  86. package/dist/types-ts4.5/new-button/variants/icon/use-icon-button.d.ts +4 -3
  87. package/dist/types-ts4.5/new-button/variants/shared/constants.d.ts +1 -0
  88. package/dist/types-ts4.5/new-button/variants/shared/loading-overlay.d.ts +2 -1
  89. package/dist/types-ts4.5/new-button/variants/shared/use-button-base.d.ts +5 -1
  90. package/dist/types-ts4.5/new.d.ts +3 -3
  91. package/extract-react-types/custom-theme-button-props.tsx +2 -4
  92. package/extract-react-types/legacy-button/custom-theme-button-props.tsx +2 -4
  93. package/extract-react-types/legacy-button/loading-button-props.tsx +1 -1
  94. package/extract-react-types/legacy-button/shared-props.tsx +1 -1
  95. package/extract-react-types/loading-button-props.tsx +1 -1
  96. package/extract-react-types/new-button/containers/split-button/split-button-props.tsx +1 -1
  97. package/extract-react-types/new-button/variants/default/button-props.tsx +1 -1
  98. package/extract-react-types/new-button/variants/default/common-default-button-props.tsx +4 -4
  99. package/extract-react-types/new-button/variants/default/link-button-props.tsx +4 -4
  100. package/extract-react-types/new-button/variants/icon-button/common-icon-button-props.tsx +4 -4
  101. package/extract-react-types/new-button/variants/icon-button/icon-button-props.tsx +1 -1
  102. package/extract-react-types/new-button/variants/icon-button/link-icon-button-props.tsx +2 -4
  103. package/extract-react-types/shared-props.tsx +1 -1
  104. package/package.json +202 -201
  105. package/report.api.md +78 -96
package/CHANGELOG.md CHANGED
@@ -1,5 +1,60 @@
1
1
  # @atlaskit/button
2
2
 
3
+ ## 17.18.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#111486](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/111486)
8
+ [`f848f651ef678`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/f848f651ef678) - ###
9
+ Accessibility improvement
10
+
11
+ New buttons now adds ", Loading" to the accessible name of loading buttons regardless of how they
12
+ are labelled. This supports labelling by text content (`children`), `aria-label`, and
13
+ `aria-labelledby`.
14
+
15
+ The ", Loading" label was previously part of the loading spinner `<svg>`, which has been relocated
16
+ because this does not support `aria-label` or `aria-labelledby`. Any test locators for loading
17
+ buttons may need to be updated.
18
+
19
+ The most robust way to find loading buttons is by role and accessible name. This accounts for
20
+ label precedence. For example:
21
+
22
+ ```
23
+ screen.findByRole("button", {
24
+ name: /, Loading/,
25
+ })
26
+ ```
27
+
28
+ To validate a loading button that is already located, use `toHaveAccessibleName()`:
29
+
30
+ ```
31
+ render(<Button testId="foo" isLoading>My label</Button>);
32
+
33
+ const button = screen.getByTestId("foo");
34
+ expect(button).toHaveAccessibleName(`My label , Loading`);
35
+ ```
36
+
37
+ For locating loading spinners, a test ID has been added that is based on the button `testId`. For
38
+ example:
39
+
40
+ ```
41
+ render(<Button isLoading testId="bar">My label</Button>);
42
+
43
+
44
+ const spinner = screen.getByTestId("bar--loading-spinner-wrapper");
45
+ expect(spinner).toBeInTheDocument();
46
+
47
+ ```
48
+
49
+ ## 17.17.3
50
+
51
+ ### Patch Changes
52
+
53
+ - [#110867](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/110867)
54
+ [`dc7e72da70ef7`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/dc7e72da70ef7) -
55
+ Migrating instances of `UNSAFE_ANCHOR` primitive imports to the new safe import `Anchor`, in
56
+ preparation of Anchor open beta and removal of the unsafe export from `@atlaskit/primitives`
57
+
3
58
  ## 17.17.2
4
59
 
5
60
  ### Patch Changes
@@ -38,7 +93,7 @@
38
93
 
39
94
  - [#99861](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/99861)
40
95
  [`452b917ff365`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/452b917ff365) -
41
- Add support for React 18.
96
+ Add support for React 18 in non-strict mode.
42
97
 
43
98
  ## 17.14.3
44
99
 
@@ -8,12 +8,12 @@ import { interactionTasks } from './utils/interaction-tasks';
8
8
  const button = () => <Example Component={Button} />;
9
9
 
10
10
  button.story = {
11
- name: 'Button',
12
- parameters: {
13
- performance: {
14
- interactions: interactionTasks,
15
- },
16
- },
11
+ name: 'Button',
12
+ parameters: {
13
+ performance: {
14
+ interactions: interactionTasks,
15
+ },
16
+ },
17
17
  };
18
18
 
19
19
  export default button;
@@ -8,12 +8,12 @@ import { interactionTasks } from './utils/interaction-tasks';
8
8
  const customThemeButton = () => <Example Component={CustomThemeButton} />;
9
9
 
10
10
  customThemeButton.story = {
11
- name: 'CustomThemeButton',
12
- parameters: {
13
- performance: {
14
- interactions: interactionTasks,
15
- },
16
- },
11
+ name: 'CustomThemeButton',
12
+ parameters: {
13
+ performance: {
14
+ interactions: interactionTasks,
15
+ },
16
+ },
17
17
  };
18
18
 
19
19
  export default customThemeButton;
@@ -5,7 +5,5 @@ import AddIcon from '@atlaskit/icon/glyph/editor/add';
5
5
  import { CustomThemeButton } from '../src';
6
6
 
7
7
  export default () => (
8
- <CustomThemeButton iconBefore={<AddIcon label="" />}>
9
- Button
10
- </CustomThemeButton>
8
+ <CustomThemeButton iconBefore={<AddIcon label="" />}>Button</CustomThemeButton>
11
9
  );
@@ -4,44 +4,40 @@ import { bindAll } from 'bind-event-listener';
4
4
 
5
5
  import type { ButtonProps } from '../../src';
6
6
 
7
- export default function Example({
8
- Component,
9
- }: {
10
- Component: ButtonProps['component'];
11
- }) {
12
- const [isSelected, setIsSelected] = useState<boolean>(false);
13
- const [isDisabled, setIsDisabled] = useState<boolean>(false);
14
- const ref = useRef<HTMLElement>(null);
7
+ export default function Example({ Component }: { Component: ButtonProps['component'] }) {
8
+ const [isSelected, setIsSelected] = useState<boolean>(false);
9
+ const [isDisabled, setIsDisabled] = useState<boolean>(false);
10
+ const ref = useRef<HTMLElement>(null);
15
11
 
16
- useLayoutEffect(() => {
17
- function toggleSelect() {
18
- setIsSelected((value) => !value);
19
- }
20
- function toggleDisabled() {
21
- setIsDisabled((value) => !value);
22
- }
12
+ useLayoutEffect(() => {
13
+ function toggleSelect() {
14
+ setIsSelected((value) => !value);
15
+ }
16
+ function toggleDisabled() {
17
+ setIsDisabled((value) => !value);
18
+ }
23
19
 
24
- const el: HTMLElement | null = ref.current;
25
- if (!el) {
26
- throw new Error('Could not find button ref');
27
- }
20
+ const el: HTMLElement | null = ref.current;
21
+ if (!el) {
22
+ throw new Error('Could not find button ref');
23
+ }
28
24
 
29
- return bindAll(el, [
30
- { type: 'toggle-select', listener: toggleSelect },
31
- { type: 'toggle-disabled', listener: toggleDisabled },
32
- ]);
33
- }, []);
25
+ return bindAll(el, [
26
+ { type: 'toggle-select', listener: toggleSelect },
27
+ { type: 'toggle-disabled', listener: toggleDisabled },
28
+ ]);
29
+ }, []);
34
30
 
35
- return (
36
- // @ts-ignore
37
- <Component
38
- ref={ref}
39
- testId="my-button"
40
- isSelected={isSelected}
41
- isDisabled={isDisabled}
42
- data-is-selected={isSelected}
43
- >
44
- Hello world
45
- </Component>
46
- );
31
+ return (
32
+ // @ts-ignore
33
+ <Component
34
+ ref={ref}
35
+ testId="my-button"
36
+ isSelected={isSelected}
37
+ isDisabled={isDisabled}
38
+ data-is-selected={isSelected}
39
+ >
40
+ Hello world
41
+ </Component>
42
+ );
47
43
  }
@@ -1,98 +1,77 @@
1
1
  import { fireEvent } from '@testing-library/react';
2
- import {
3
- type InteractionTaskArgs,
4
- type PublicInteractionTask,
5
- } from 'storybook-addon-performance';
2
+ import { type InteractionTaskArgs, type PublicInteractionTask } from 'storybook-addon-performance';
6
3
 
7
4
  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
- }
5
+ {
6
+ name: 'Click a button',
7
+ description: 'Recording how long a mousedown + click event take to be processed',
8
+ run: async ({ container }: InteractionTaskArgs): Promise<void> => {
9
+ const button: HTMLElement | null = container.querySelector('[data-testid="my-button"]');
10
+ if (button == null) {
11
+ throw new Error('Could not find button element');
12
+ }
19
13
 
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
- }
14
+ fireEvent.mouseDown(button);
15
+ fireEvent.click(button);
16
+ },
17
+ },
18
+ {
19
+ name: 'Focus on button',
20
+ description: 'Focus on a button and wait for layout and paint to finish',
21
+ run: async ({ container, controls }: InteractionTaskArgs): Promise<void> => {
22
+ const button: HTMLElement | null = container.querySelector('[data-testid="my-button"]');
23
+ if (button == null) {
24
+ throw new Error('Could not find button element');
25
+ }
37
26
 
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
- }
27
+ await controls.time(async () => {
28
+ fireEvent.focus(button);
29
+ fireEvent.blur(button);
30
+ });
31
+ },
32
+ },
33
+ {
34
+ name: 'Select button',
35
+ description: 'Trigger the selection of a button',
36
+ run: async ({ container, controls }: InteractionTaskArgs): Promise<void> => {
37
+ const button: HTMLElement | null = container.querySelector('[data-testid="my-button"]');
38
+ if (button == null) {
39
+ throw new Error('Could not find button element');
40
+ }
57
41
 
58
- if (button.getAttribute('data-is-selected') !== 'false') {
59
- throw new Error('Should not start selected');
60
- }
42
+ if (button.getAttribute('data-is-selected') !== 'false') {
43
+ throw new Error('Should not start selected');
44
+ }
61
45
 
62
- await controls.time(async () => {
63
- fireEvent(button, new Event('toggle-select'));
64
- });
46
+ await controls.time(async () => {
47
+ fireEvent(button, new Event('toggle-select'));
48
+ });
65
49
 
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
- }
50
+ if (button.getAttribute('data-is-selected') !== 'true') {
51
+ throw new Error('Should now be selected');
52
+ }
53
+ },
54
+ },
55
+ {
56
+ name: 'Disable button',
57
+ description: 'Trigger the disabling of a button',
58
+ run: async ({ container, controls }: InteractionTaskArgs): Promise<void> => {
59
+ const button: HTMLElement | null = container.querySelector('[data-testid="my-button"]');
60
+ if (button == null) {
61
+ throw new Error('Could not find button element');
62
+ }
84
63
 
85
- if (button.hasAttribute('disabled')) {
86
- throw new Error('Should not start disabled');
87
- }
64
+ if (button.hasAttribute('disabled')) {
65
+ throw new Error('Should not start disabled');
66
+ }
88
67
 
89
- await controls.time(async () => {
90
- fireEvent(button, new Event('toggle-disabled'));
91
- });
68
+ await controls.time(async () => {
69
+ fireEvent(button, new Event('toggle-disabled'));
70
+ });
92
71
 
93
- if (!button.hasAttribute('disabled')) {
94
- throw new Error('Should now be disabled');
95
- }
96
- },
97
- },
72
+ if (!button.hasAttribute('disabled')) {
73
+ throw new Error('Should now be disabled');
74
+ }
75
+ },
76
+ },
98
77
  ];
@@ -3,46 +3,42 @@ import { type Collection } from 'jscodeshift/src/Collection';
3
3
 
4
4
  import { changeType, transformButton } from './helpers/15.0.0-runner';
5
5
  import {
6
- getDefaultSpecifierName,
7
- type Nullable,
8
- shiftDefaultImport,
6
+ getDefaultSpecifierName,
7
+ type Nullable,
8
+ shiftDefaultImport,
9
9
  } from './helpers/helpers-generic';
10
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
- });
11
+ export default function transformer(file: FileInfo, { jscodeshift: j }: API, options: Options) {
12
+ return transformButton({
13
+ file,
14
+ j,
15
+ custom: (base: Collection<any>) => {
16
+ changeType({
17
+ j,
18
+ base,
19
+ oldName: 'ButtonProps',
20
+ newName: 'CustomThemeButtonProps',
21
+ fallbackNameAlias: 'DSCustomThemeButtonProps',
22
+ });
27
23
 
28
- const defaultName: Nullable<string> = getDefaultSpecifierName({
29
- j,
30
- base,
31
- packageName: '@atlaskit/button',
32
- });
33
- if (defaultName == null) {
34
- return;
35
- }
24
+ const defaultName: Nullable<string> = getDefaultSpecifierName({
25
+ j,
26
+ base,
27
+ packageName: '@atlaskit/button',
28
+ });
29
+ if (defaultName == null) {
30
+ return;
31
+ }
36
32
 
37
- shiftDefaultImport({
38
- j,
39
- base,
40
- defaultName,
41
- oldPackagePath: '@atlaskit/button',
42
- newPackagePath: '@atlaskit/button/custom-theme-button',
43
- });
44
- },
45
- });
33
+ shiftDefaultImport({
34
+ j,
35
+ base,
36
+ defaultName,
37
+ oldPackagePath: '@atlaskit/button',
38
+ newPackagePath: '@atlaskit/button/custom-theme-button',
39
+ });
40
+ },
41
+ });
46
42
  }
47
43
 
48
44
  // Note: not exporting a 'parser' because doing so