@atlaskit/modal-dialog 15.3.1 → 16.0.1

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 CHANGED
@@ -1,5 +1,40 @@
1
1
  # @atlaskit/modal-dialog
2
2
 
3
+ ## 16.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`ee28cf33718b0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/ee28cf33718b0) -
8
+ Add @atlassian/react-compiler-gating as a runtime dependency to enable React Compiler platform
9
+ gating.
10
+ - Updated dependencies
11
+
12
+ ## 16.0.0
13
+
14
+ ### Major Changes
15
+
16
+ - [`f2dc9097319f0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f2dc9097319f0) - ###
17
+ Dropped support for _legacy_ Typescript 4 types. **Typescript 5 is now the new minimum**.
18
+
19
+ Removes the `typesVersions` property and `dist/types-ts4.5` directory from the dist.
20
+
21
+ Types are now exclusively via the `"types": "dist/types/index.d.ts"` property.
22
+
23
+ ```diff
24
+ - "typesVersions": {
25
+ - ">=4.5 <4.9": {
26
+ - "*": [
27
+ - "dist/types-ts4.5/*",
28
+ - "dist/types-ts4.5/index.d.ts"
29
+ - ]
30
+ - }
31
+ - },
32
+ ```
33
+
34
+ ### Patch Changes
35
+
36
+ - Updated dependencies
37
+
3
38
  ## 15.3.1
4
39
 
5
40
  ### Patch Changes
@@ -0,0 +1,141 @@
1
+ import { expect, test } from '@af/integration-testing';
2
+
3
+ /**
4
+ * Modal dialog: focus contract on the top-layer code path.
5
+ *
6
+ * `ModalDialog` renders as a `role="dialog"` modal. Per WCAG 2.4.3 (Focus
7
+ * Order) and the top-layer focus rules:
8
+ *
9
+ * 1. Initial focus moves to the first focusable element on open (or to the
10
+ * element marked with the native HTML `autofocus` attribute when present).
11
+ * 2. Closing the modal (Escape) restores focus to the trigger.
12
+ * 3. Tab cycles focus within the modal (focus does not escape to elements
13
+ * behind the modal).
14
+ *
15
+ * See: `platform/packages/design-system/top-layer/notes/architecture/focus.md`.
16
+ */
17
+
18
+ const featureFlag = 'platform-dst-top-layer';
19
+
20
+ test.describe('Modal dialog: top-layer focus contract', () => {
21
+ test('initial focus: focus moves to first focusable element on open', async ({ page }) => {
22
+ await page.visitExample<typeof import('../../examples/98-testing-initial-focus-matrix.tsx')>(
23
+ 'design-system',
24
+ 'modal-dialog',
25
+ 'testing-initial-focus-matrix',
26
+ { featureFlag },
27
+ );
28
+
29
+ await page.getByTestId('default-modal-trigger').click();
30
+
31
+ const modal = page.getByTestId('default-modal');
32
+ await expect(modal).toBeVisible();
33
+
34
+ // The first focusable inside the modal is the header's close button.
35
+ await expect(page.getByTestId('default-modal--close-button')).toBeFocused();
36
+ });
37
+
38
+ test('focus restoration: Escape restores focus to the trigger', async ({ page }) => {
39
+ await page.visitExample<typeof import('../../examples/98-testing-initial-focus-matrix.tsx')>(
40
+ 'design-system',
41
+ 'modal-dialog',
42
+ 'testing-initial-focus-matrix',
43
+ { featureFlag },
44
+ );
45
+
46
+ const trigger = page.getByTestId('default-modal-trigger');
47
+ await trigger.click();
48
+ await expect(page.getByTestId('default-modal')).toBeVisible();
49
+
50
+ await page.keyboard.press('Escape');
51
+ await expect(page.getByTestId('default-modal')).toBeHidden();
52
+ await expect(trigger).toBeFocused();
53
+ });
54
+
55
+ // WCAG 2.4.3 Focus Order + HTML `<dialog>` focusing steps
56
+ // (https://html.spec.whatwg.org/multipage/interactive-elements.html#dialog-focusing-steps).
57
+ // When a descendant of the dialog carries the native HTML `autofocus`
58
+ // attribute, focus must land on that element instead of the first
59
+ // focusable. This matches both `<dialog>.showModal()` and the
60
+ // WAI-ARIA APG Dialog pattern.
61
+ test('initial focus: native [autofocus] element wins over the first focusable element', async ({
62
+ page,
63
+ }) => {
64
+ await page.visitExample<typeof import('../../examples/98-testing-initial-focus-matrix.tsx')>(
65
+ 'design-system',
66
+ 'modal-dialog',
67
+ 'testing-initial-focus-matrix',
68
+ { featureFlag },
69
+ );
70
+
71
+ await page.getByTestId('native-autofocus-modal-trigger').click();
72
+
73
+ const modal = page.getByTestId('native-autofocus-modal');
74
+ await expect(modal).toBeVisible();
75
+
76
+ // The first focusable inside the modal is the header close
77
+ // button, but the body input carries `autofocus`, so focus must
78
+ // land on the input.
79
+ await expect(page.getByTestId('native-autofocus-input')).toBeFocused();
80
+ });
81
+
82
+ // WCAG 2.4.3 Focus Order. `Modal`'s `autoFocus` prop accepts a
83
+ // `RefObject` that points at a specific descendant to focus on
84
+ // open. This is the consumer-level override of the default
85
+ // first-focusable behaviour and is implemented in `modal-wrapper`
86
+ // outside `useInitialFocus`, but it shares the same WCAG / APG
87
+ // contract: the chosen element receives focus instead of the
88
+ // natural first focusable.
89
+ test('initial focus: `autoFocus` ref overrides the first focusable element', async ({ page }) => {
90
+ await page.visitExample<typeof import('../../examples/98-testing-initial-focus-matrix.tsx')>(
91
+ 'design-system',
92
+ 'modal-dialog',
93
+ 'testing-initial-focus-matrix',
94
+ { featureFlag },
95
+ );
96
+
97
+ await page.getByTestId('auto-focus-ref-modal-trigger').click();
98
+
99
+ const modal = page.getByTestId('auto-focus-ref-modal');
100
+ await expect(modal).toBeVisible();
101
+
102
+ // The header close button is the first focusable, but the
103
+ // consumer pointed `autoFocus` at the body input, so focus must
104
+ // land on the input.
105
+ await expect(page.getByTestId('auto-focus-ref-input')).toBeFocused();
106
+ });
107
+
108
+ test('focus movement: Tab cycles focus within the modal', async ({ page }) => {
109
+ await page.visitExample<typeof import('../../examples/98-testing-initial-focus-matrix.tsx')>(
110
+ 'design-system',
111
+ 'modal-dialog',
112
+ 'testing-initial-focus-matrix',
113
+ { featureFlag },
114
+ );
115
+
116
+ await page.getByTestId('default-modal-trigger').click();
117
+ const modal = page.getByTestId('default-modal');
118
+ await expect(modal).toBeVisible();
119
+
120
+ // Walk forward through every focusable element in the modal and verify
121
+ // focus never escapes the dialog surface.
122
+ const focusables = [
123
+ page.getByTestId('default-modal--close-button'),
124
+ page.getByTestId('default-modal-secondary'),
125
+ page.getByTestId('default-modal-primary'),
126
+ ];
127
+
128
+ for (const target of focusables) {
129
+ await expect(target).toBeFocused();
130
+ await page.keyboard.press('Tab');
131
+ }
132
+
133
+ // After cycling past the last focusable, focus must remain inside the
134
+ // modal (focus wrap), never on a node outside it.
135
+ const activeWithinModal = await modal.evaluate(
136
+ (modalElement) =>
137
+ document.activeElement !== null && modalElement.contains(document.activeElement),
138
+ );
139
+ expect(activeWithinModal).toBe(true);
140
+ });
141
+ });
@@ -114,7 +114,7 @@ var InternalModalWrapper = /*#__PURE__*/(0, _react.forwardRef)(function (props,
114
114
  action: 'closed',
115
115
  componentName: 'modalDialog',
116
116
  packageName: "@atlaskit/modal-dialog",
117
- packageVersion: "15.3.0"
117
+ packageVersion: "16.0.0"
118
118
  });
119
119
  var onBlanketClicked = (0, _react.useCallback)(function (e) {
120
120
  if (shouldCloseOnOverlayClick) {
@@ -100,7 +100,7 @@ const InternalModalWrapper = /*#__PURE__*/forwardRef((props, ref) => {
100
100
  action: 'closed',
101
101
  componentName: 'modalDialog',
102
102
  packageName: "@atlaskit/modal-dialog",
103
- packageVersion: "15.3.0"
103
+ packageVersion: "16.0.0"
104
104
  });
105
105
  const onBlanketClicked = useCallback(e => {
106
106
  if (shouldCloseOnOverlayClick) {
@@ -105,7 +105,7 @@ var InternalModalWrapper = /*#__PURE__*/forwardRef(function (props, ref) {
105
105
  action: 'closed',
106
106
  componentName: 'modalDialog',
107
107
  packageName: "@atlaskit/modal-dialog",
108
- packageVersion: "15.3.0"
108
+ packageVersion: "16.0.0"
109
109
  });
110
110
  var onBlanketClicked = useCallback(function (e) {
111
111
  if (shouldCloseOnOverlayClick) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/modal-dialog",
3
- "version": "15.3.1",
3
+ "version": "16.0.1",
4
4
  "description": "A modal dialog displays content that requires user interaction, in a layer above the page.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -34,21 +34,22 @@
34
34
  "watch": "tsc --watch --noEmit --project './tsconfig.json'"
35
35
  },
36
36
  "dependencies": {
37
- "@atlaskit/analytics-next": "^11.3.0",
38
- "@atlaskit/blanket": "^15.0.0",
39
- "@atlaskit/button": "^23.11.0",
40
- "@atlaskit/css": "^0.19.0",
41
- "@atlaskit/ds-lib": "^7.0.0",
42
- "@atlaskit/icon": "^35.4.0",
43
- "@atlaskit/layering": "^3.8.0",
44
- "@atlaskit/motion": "^6.2.0",
45
- "@atlaskit/platform-feature-flags": "^1.1.0",
46
- "@atlaskit/portal": "^5.5.0",
47
- "@atlaskit/pragmatic-drag-and-drop": "^1.8.0",
48
- "@atlaskit/primitives": "^19.0.0",
49
- "@atlaskit/theme": "^25.0.0",
50
- "@atlaskit/tokens": "^13.4.0",
51
- "@atlaskit/top-layer": "^0.18.0",
37
+ "@atlaskit/analytics-next": "^12.0.0",
38
+ "@atlaskit/blanket": "^16.0.0",
39
+ "@atlaskit/button": "^24.1.0",
40
+ "@atlaskit/css": "^1.0.0",
41
+ "@atlaskit/ds-lib": "^8.0.0",
42
+ "@atlaskit/icon": "^36.0.0",
43
+ "@atlaskit/layering": "^4.0.0",
44
+ "@atlaskit/motion": "^7.1.0",
45
+ "@atlaskit/platform-feature-flags": "^2.0.0",
46
+ "@atlaskit/portal": "^6.0.0",
47
+ "@atlaskit/pragmatic-drag-and-drop": "^2.0.0",
48
+ "@atlaskit/primitives": "^20.0.0",
49
+ "@atlaskit/theme": "^26.0.0",
50
+ "@atlaskit/tokens": "^15.0.0",
51
+ "@atlaskit/top-layer": "^1.0.0",
52
+ "@atlassian/react-compiler-gating": "^0.2.0",
52
53
  "@babel/runtime": "^7.0.0",
53
54
  "@compiled/react": "^0.20.0",
54
55
  "bind-event-listener": "^3.0.0",
@@ -63,28 +64,27 @@
63
64
  "@af/accessibility-testing": "workspace:^",
64
65
  "@af/integration-testing": "workspace:^",
65
66
  "@af/visual-regression": "workspace:^",
66
- "@atlaskit/avatar": "^25.15.0",
67
- "@atlaskit/avatar-group": "^12.10.0",
68
- "@atlaskit/banner": "^14.1.0",
69
- "@atlaskit/breadcrumbs": "^16.1.0",
70
- "@atlaskit/checkbox": "^17.3.0",
71
- "@atlaskit/code": "^17.5.0",
72
- "@atlaskit/datetime-picker": "^17.9.0",
73
- "@atlaskit/docs": "^11.8.0",
74
- "@atlaskit/dropdown-menu": "^16.10.0",
75
- "@atlaskit/flag": "^17.13.0",
76
- "@atlaskit/form": "^15.5.0",
77
- "@atlaskit/heading": "^5.4.0",
78
- "@atlaskit/link": "^3.4.0",
79
- "@atlaskit/popup": "^4.25.0",
80
- "@atlaskit/radio": "^8.6.0",
81
- "@atlaskit/section-message": "^8.13.0",
82
- "@atlaskit/select": "^21.12.0",
83
- "@atlaskit/spotlight": "^0.15.0",
84
- "@atlaskit/textfield": "^8.3.0",
85
- "@atlaskit/tooltip": "^22.6.0",
67
+ "@atlaskit/avatar": "^26.0.0",
68
+ "@atlaskit/avatar-group": "^13.0.0",
69
+ "@atlaskit/banner": "^15.0.0",
70
+ "@atlaskit/breadcrumbs": "^17.0.0",
71
+ "@atlaskit/checkbox": "^18.0.0",
72
+ "@atlaskit/code": "^18.0.0",
73
+ "@atlaskit/datetime-picker": "^18.0.0",
74
+ "@atlaskit/docs": "^12.0.0",
75
+ "@atlaskit/dropdown-menu": "^17.0.0",
76
+ "@atlaskit/flag": "^18.0.0",
77
+ "@atlaskit/form": "^16.0.0",
78
+ "@atlaskit/heading": "^6.0.0",
79
+ "@atlaskit/link": "^4.0.0",
80
+ "@atlaskit/popup": "^5.0.0",
81
+ "@atlaskit/radio": "^9.0.0",
82
+ "@atlaskit/section-message": "^9.1.0",
83
+ "@atlaskit/select": "^22.1.0",
84
+ "@atlaskit/spotlight": "^2.0.0",
85
+ "@atlaskit/textfield": "^9.0.0",
86
+ "@atlaskit/tooltip": "^23.0.0",
86
87
  "@atlassian/feature-flags-test-utils": "^1.1.0",
87
- "@atlassian/react-compiler-gating": "workspace:^",
88
88
  "@atlassian/ssr-tests": "workspace:^",
89
89
  "@atlassian/structured-docs-types": "workspace:^",
90
90
  "@atlassian/testing-library": "^0.6.0",
@@ -98,7 +98,7 @@
98
98
  "react-lorem-component": "^0.13.0",
99
99
  "react-sweet-state": "^2.6.5",
100
100
  "tiny-invariant": "^1.2.0",
101
- "typescript": "5.9.2"
101
+ "typescript": "5.9.3"
102
102
  },
103
103
  "keywords": [
104
104
  "atlaskit",
@@ -125,14 +125,6 @@
125
125
  ]
126
126
  }
127
127
  },
128
- "typesVersions": {
129
- ">=4.5 <4.9": {
130
- "*": [
131
- "dist/types-ts4.5/*",
132
- "dist/types-ts4.5/index.d.ts"
133
- ]
134
- }
135
- },
136
128
  "platform-feature-flags": {
137
129
  "platform_modal-dialog-heading-icon-a11y-fix": {
138
130
  "type": "boolean"