@atlaskit/navigation-system 0.177.2 → 0.178.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.
- package/CHANGELOG.md +36 -0
- package/dist/cjs/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.js +16 -3
- package/dist/cjs/ui/menu-item/menu-item.compiled.css +2 -2
- package/dist/cjs/ui/menu-item/menu-item.js +5 -4
- package/dist/es2019/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.js +17 -4
- package/dist/es2019/ui/menu-item/menu-item.compiled.css +2 -2
- package/dist/es2019/ui/menu-item/menu-item.js +4 -3
- package/dist/esm/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.js +17 -4
- package/dist/esm/ui/menu-item/menu-item.compiled.css +2 -2
- package/dist/esm/ui/menu-item/menu-item.js +5 -4
- package/dist/types/components/skip-links/skip-link.d.ts +1 -1
- package/dist/types/components/skip-links/skip-links-container.d.ts +1 -2
- package/dist/types/context/skip-links/skip-links-context.d.ts +15 -2
- package/dist/types/context/skip-links/skip-links-data-context.d.ts +0 -1
- package/dist/types/context/top-nav-start/top-nav-start-context.d.ts +0 -1
- package/dist/types/ui/menu-item/button-menu-item.d.ts +4 -4
- package/dist/types/ui/menu-item/container-avatar.d.ts +0 -1
- package/dist/types/ui/menu-item/drag-handle.d.ts +0 -1
- package/dist/types/ui/menu-item/expandable-menu-item/expandable-menu-item-context.d.ts +1 -2
- package/dist/types/ui/menu-item/expandable-menu-item/expandable-menu-item-level-context.d.ts +0 -1
- package/dist/types/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.d.ts +5 -5
- package/dist/types/ui/menu-item/flyout-menu-item/flyout-menu-item-context.d.ts +0 -1
- package/dist/types/ui/menu-item/flyout-menu-item/flyout-menu-item-trigger.d.ts +2 -2
- package/dist/types/ui/menu-item/link-menu-item.d.ts +6 -11
- package/dist/types/ui/menu-item/menu-item.d.ts +16 -11
- package/dist/types/ui/menu-item/menu-list-item.d.ts +1 -2
- package/dist/types/ui/menu-item/menu-list.d.ts +0 -1
- package/dist/types/ui/menu-item/top-level-spacer.d.ts +0 -1
- package/dist/types/ui/menu-item/use-scroll-menu-item-into-view.d.ts +0 -1
- package/dist/types/ui/menu-section/divider.d.ts +0 -1
- package/dist/types/ui/menu-section/menu-section-context.d.ts +0 -1
- package/dist/types/ui/page-layout/aside.d.ts +0 -1
- package/dist/types/ui/page-layout/banner.d.ts +0 -1
- package/dist/types/ui/page-layout/hoist-slot-sizes-context.d.ts +0 -1
- package/dist/types/ui/page-layout/hoist-utils.d.ts +2 -2
- package/dist/types/ui/page-layout/main/main-sticky-context.d.ts +0 -1
- package/dist/types/ui/page-layout/main/main.d.ts +0 -1
- package/dist/types/ui/page-layout/panel-splitter/get-width.d.ts +2 -2
- package/dist/types/ui/page-layout/panel.d.ts +0 -1
- package/dist/types/ui/page-layout/side-nav/side-nav-footer.d.ts +1 -1
- package/dist/types/ui/page-layout/side-nav/side-nav.d.ts +0 -1
- package/dist/types/ui/page-layout/side-nav/toggle-button-context.d.ts +0 -1
- package/dist/types/ui/page-layout/side-nav/toggle-button.d.ts +4 -4
- package/dist/types/ui/page-layout/top-nav/top-nav.d.ts +0 -1
- package/dist/types/ui/top-nav-items/chat-button.d.ts +3 -3
- package/dist/types/ui/top-nav-items/nav-logo/app-logo.d.ts +1 -1
- package/dist/types/ui/top-nav-items/nav-logo/custom-logo.d.ts +1 -1
- package/dist/types/ui/top-nav-items/search.d.ts +5 -5
- package/dist/types/ui/top-nav-items/themed/button.d.ts +2 -2
- package/dist/types/ui/top-nav-items/themed/has-custom-theme-context.d.ts +0 -1
- package/dist/types/ui/top-nav-items/themed/use-custom-theme.d.ts +0 -1
- package/dist/types-ts4.5/components/skip-links/skip-link.d.ts +1 -1
- package/dist/types-ts4.5/components/skip-links/skip-links-container.d.ts +1 -2
- package/dist/types-ts4.5/context/skip-links/skip-links-context.d.ts +15 -2
- package/dist/types-ts4.5/context/skip-links/skip-links-data-context.d.ts +0 -1
- package/dist/types-ts4.5/context/top-nav-start/top-nav-start-context.d.ts +0 -1
- package/dist/types-ts4.5/ui/menu-item/button-menu-item.d.ts +4 -4
- package/dist/types-ts4.5/ui/menu-item/container-avatar.d.ts +0 -1
- package/dist/types-ts4.5/ui/menu-item/drag-handle.d.ts +0 -1
- package/dist/types-ts4.5/ui/menu-item/expandable-menu-item/expandable-menu-item-context.d.ts +1 -2
- package/dist/types-ts4.5/ui/menu-item/expandable-menu-item/expandable-menu-item-level-context.d.ts +0 -1
- package/dist/types-ts4.5/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.d.ts +5 -5
- package/dist/types-ts4.5/ui/menu-item/flyout-menu-item/flyout-menu-item-context.d.ts +0 -1
- package/dist/types-ts4.5/ui/menu-item/flyout-menu-item/flyout-menu-item-trigger.d.ts +2 -2
- package/dist/types-ts4.5/ui/menu-item/link-menu-item.d.ts +6 -11
- package/dist/types-ts4.5/ui/menu-item/menu-item.d.ts +16 -11
- package/dist/types-ts4.5/ui/menu-item/menu-list-item.d.ts +1 -2
- package/dist/types-ts4.5/ui/menu-item/menu-list.d.ts +0 -1
- package/dist/types-ts4.5/ui/menu-item/top-level-spacer.d.ts +0 -1
- package/dist/types-ts4.5/ui/menu-item/use-scroll-menu-item-into-view.d.ts +0 -1
- package/dist/types-ts4.5/ui/menu-section/divider.d.ts +0 -1
- package/dist/types-ts4.5/ui/menu-section/menu-section-context.d.ts +0 -1
- package/dist/types-ts4.5/ui/page-layout/aside.d.ts +0 -1
- package/dist/types-ts4.5/ui/page-layout/banner.d.ts +0 -1
- package/dist/types-ts4.5/ui/page-layout/hoist-slot-sizes-context.d.ts +0 -1
- package/dist/types-ts4.5/ui/page-layout/hoist-utils.d.ts +2 -2
- package/dist/types-ts4.5/ui/page-layout/main/main-sticky-context.d.ts +0 -1
- package/dist/types-ts4.5/ui/page-layout/main/main.d.ts +0 -1
- package/dist/types-ts4.5/ui/page-layout/panel-splitter/get-width.d.ts +2 -2
- package/dist/types-ts4.5/ui/page-layout/panel.d.ts +0 -1
- package/dist/types-ts4.5/ui/page-layout/side-nav/side-nav-footer.d.ts +1 -1
- package/dist/types-ts4.5/ui/page-layout/side-nav/side-nav.d.ts +0 -1
- package/dist/types-ts4.5/ui/page-layout/side-nav/toggle-button-context.d.ts +0 -1
- package/dist/types-ts4.5/ui/page-layout/side-nav/toggle-button.d.ts +4 -4
- package/dist/types-ts4.5/ui/page-layout/top-nav/top-nav.d.ts +0 -1
- package/dist/types-ts4.5/ui/top-nav-items/chat-button.d.ts +3 -3
- package/dist/types-ts4.5/ui/top-nav-items/nav-logo/app-logo.d.ts +1 -1
- package/dist/types-ts4.5/ui/top-nav-items/nav-logo/custom-logo.d.ts +1 -1
- package/dist/types-ts4.5/ui/top-nav-items/search.d.ts +5 -5
- package/dist/types-ts4.5/ui/top-nav-items/themed/button.d.ts +2 -2
- package/dist/types-ts4.5/ui/top-nav-items/themed/has-custom-theme-context.d.ts +0 -1
- package/dist/types-ts4.5/ui/top-nav-items/themed/use-custom-theme.d.ts +0 -1
- package/examples/company-hub-mock.tsx +0 -4
- package/examples/confluence-mock.tsx +1 -4
- package/examples/drag-and-drop-jira-scaling-vr.tsx +25 -0
- package/examples/expandable-menu-item.tsx +1 -0
- package/examples/page-layout.tsx +0 -3
- package/package.json +5 -3
- package/src/__tests__/informational-vr-tests/__snapshots__/layering/layers-in-main-slot-short-viewport--desktop--platform-dst-nav4-layering-in-main-slot-fixes-false.png +0 -0
- package/src/__tests__/informational-vr-tests/__snapshots__/layering/layers-in-main-slot-short-viewport--desktop--platform-dst-nav4-layering-in-main-slot-fixes-true.png +0 -0
- package/src/__tests__/informational-vr-tests/__snapshots__/layering/side-nav-expanded-on-mobile--mobile.png +0 -0
- package/src/__tests__/informational-vr-tests/__snapshots__/layering/side-nav-expanded-on-mobile-without-panel--mobile.png +0 -0
- package/src/__tests__/informational-vr-tests/layering.vr.tsx +6 -0
- package/src/__tests__/vr-tests/__snapshots__/a11y-scaling/app--desktop.png +0 -0
- package/src/__tests__/vr-tests/a11y-scaling.vr.tsx +12 -0
- package/src/ui/menu-item/__tests__/playwright/scroll-into-view.spec.tsx +9 -10
- package/src/ui/menu-item/__tests__/unit/expandable-menu-item.test.tsx +88 -63
- package/src/ui/menu-item/__tests__/vr-tests/__snapshots__/menu-item/button-menu-item-example--desktop-webkit.png +0 -0
- package/src/ui/menu-item/__tests__/vr-tests/__snapshots__/menu-item/button-menu-item-rtlexample--desktop-webkit.png +0 -0
- package/src/ui/menu-item/__tests__/vr-tests/__snapshots__/menu-item/link-menu-item-example--desktop-webkit.png +0 -0
- package/src/ui/menu-item/__tests__/vr-tests/__snapshots__/menu-item/link-menu-item-rtlexample--desktop-webkit.png +0 -0
- package/src/ui/menu-item/__tests__/vr-tests/expandable.vr.tsx +8 -8
- package/src/ui/menu-item/expandable-menu-item/expandable-menu-item-trigger.tsx +19 -2
- package/src/ui/menu-item/menu-item.tsx +10 -8
- package/src/ui/page-layout/__tests__/unit/react-safety.test.tsx +0 -8
|
@@ -18,8 +18,8 @@ export declare const Search: ({ label, onClick, iconBefore: IconBefore, elemAfte
|
|
|
18
18
|
* The icon component to render before the search input.
|
|
19
19
|
*/
|
|
20
20
|
iconBefore?: React.ComponentType<NewIconProps & {
|
|
21
|
-
spacing:
|
|
22
|
-
}
|
|
21
|
+
spacing: "spacious";
|
|
22
|
+
}>;
|
|
23
23
|
/**
|
|
24
24
|
* The component to render after the search input.
|
|
25
25
|
*/
|
|
@@ -27,10 +27,10 @@ export declare const Search: ({ label, onClick, iconBefore: IconBefore, elemAfte
|
|
|
27
27
|
/**
|
|
28
28
|
* Handler called on click.
|
|
29
29
|
*/
|
|
30
|
-
onClick?: React.MouseEventHandler<HTMLButtonElement
|
|
30
|
+
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
31
31
|
/**
|
|
32
32
|
* An optional name used to identify events for [React UFO (Unified Frontend Observability) press interactions](https://developer.atlassian.com/platform/ufo/react-ufo/react-ufo/getting-started/#quick-start--press-interactions). For more information, see [React UFO integration into Design System components](https://go.atlassian.com/react-ufo-dst-integration).
|
|
33
33
|
*/
|
|
34
|
-
interactionName?: string
|
|
35
|
-
|
|
34
|
+
interactionName?: string;
|
|
35
|
+
"aria-haspopup"?: React.AriaAttributes["aria-haspopup"];
|
|
36
36
|
}) => JSX.Element;
|
|
@@ -88,7 +88,7 @@ export interface ThemedLinkButtonProps<RouterLinkConfig extends Record<string, a
|
|
|
88
88
|
*
|
|
89
89
|
* A themed link button for the top bar.
|
|
90
90
|
*/
|
|
91
|
-
export declare const ThemedLinkButton: <RouterLinkConfig extends Record<string, any> = never>(props: ThemedLinkButtonProps<RouterLinkConfig> & React.RefAttributes<HTMLAnchorElement>) => React.ReactElement
|
|
91
|
+
export declare const ThemedLinkButton: <RouterLinkConfig extends Record<string, any> = never>(props: ThemedLinkButtonProps<RouterLinkConfig> & React.RefAttributes<HTMLAnchorElement>) => React.ReactElement | null;
|
|
92
92
|
/**
|
|
93
93
|
* Props shared by `ThemedIconButtonProps` and `ThemedLinkIconButton`
|
|
94
94
|
*/
|
|
@@ -124,5 +124,5 @@ export interface ThemedLinkIconButtonProps<RouterLinkConfig extends Record<strin
|
|
|
124
124
|
*
|
|
125
125
|
* A themed link icon button for the top bar.
|
|
126
126
|
*/
|
|
127
|
-
export declare const ThemedLinkIconButton: <RouterLinkConfig extends Record<string, any> = never>(props: ThemedLinkIconButtonProps<RouterLinkConfig> & React.RefAttributes<HTMLAnchorElement>) => React.ReactElement
|
|
127
|
+
export declare const ThemedLinkIconButton: <RouterLinkConfig extends Record<string, any> = never>(props: ThemedLinkIconButtonProps<RouterLinkConfig> & React.RefAttributes<HTMLAnchorElement>) => React.ReactElement | null;
|
|
128
128
|
export {};
|
|
@@ -137,12 +137,9 @@ const contentStyles = cssMap({
|
|
|
137
137
|
paddingBlock: token('space.400'),
|
|
138
138
|
maxWidth: '760px',
|
|
139
139
|
},
|
|
140
|
-
title: {
|
|
141
|
-
marginBottom: token('space.400'),
|
|
142
|
-
},
|
|
143
140
|
});
|
|
144
141
|
|
|
145
|
-
export default function ConfluenceMockExample(
|
|
142
|
+
export default function ConfluenceMockExample() {
|
|
146
143
|
return (
|
|
147
144
|
<WithResponsiveViewport>
|
|
148
145
|
<Root testId="root">
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React, { type ReactNode, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import { App } from './drag-and-drop/jira/entry';
|
|
4
|
+
|
|
5
|
+
const FontScaleContainer = ({ children }: { children: ReactNode }) => {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const rootElement = document.querySelector('html');
|
|
8
|
+
if (rootElement) {
|
|
9
|
+
// Matches Chrome's "very large" font size setting
|
|
10
|
+
rootElement.style.fontSize = '24px';
|
|
11
|
+
}
|
|
12
|
+
}, []);
|
|
13
|
+
|
|
14
|
+
return children;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const AppScaled = () => {
|
|
18
|
+
return (
|
|
19
|
+
<FontScaleContainer>
|
|
20
|
+
<App />
|
|
21
|
+
</FontScaleContainer>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default AppScaled;
|
|
@@ -591,6 +591,7 @@ export const ExpandableMenuItemWithAllOptions = () => (
|
|
|
591
591
|
actionsOnHover={<MoreAction shouldRenderToParent />}
|
|
592
592
|
elemAfter={<Lozenge>Elem after</Lozenge>}
|
|
593
593
|
href="#"
|
|
594
|
+
testId="parent-menu-item"
|
|
594
595
|
>
|
|
595
596
|
Parent menu item
|
|
596
597
|
</ExpandableMenuItemTrigger>
|
package/examples/page-layout.tsx
CHANGED
|
@@ -70,9 +70,6 @@ const styles = cssMap({
|
|
|
70
70
|
position: 'sticky',
|
|
71
71
|
insetBlockStart: token('space.150', '12px'),
|
|
72
72
|
},
|
|
73
|
-
hidden: {
|
|
74
|
-
display: 'none',
|
|
75
|
-
},
|
|
76
73
|
legacyPositionedSibling: {
|
|
77
74
|
position: 'absolute',
|
|
78
75
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/navigation-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.178.0",
|
|
4
4
|
"description": "The latest navigation system for Atlassian apps.",
|
|
5
5
|
"repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
|
|
6
6
|
"author": "Atlassian Pty Ltd",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
"@atlaskit/button": "^23.3.0",
|
|
117
117
|
"@atlaskit/css": "^0.12.0",
|
|
118
118
|
"@atlaskit/ds-lib": "^5.0.0",
|
|
119
|
-
"@atlaskit/icon": "^27.
|
|
119
|
+
"@atlaskit/icon": "^27.11.0",
|
|
120
120
|
"@atlaskit/layering": "^3.0.0",
|
|
121
121
|
"@atlaskit/logo": "^19.6.0",
|
|
122
122
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
@@ -140,7 +140,6 @@
|
|
|
140
140
|
"devDependencies": {
|
|
141
141
|
"@af/accessibility-testing": "workspace:^",
|
|
142
142
|
"@af/integration-testing": "workspace:^",
|
|
143
|
-
"@af/react-unit-testing": "workspace:^",
|
|
144
143
|
"@af/visual-regression": "workspace:^",
|
|
145
144
|
"@atlaskit/app-provider": "^3.1.0",
|
|
146
145
|
"@atlaskit/badge": "^18.1.0",
|
|
@@ -226,6 +225,9 @@
|
|
|
226
225
|
},
|
|
227
226
|
"platform_dst_nav4_flyout_use_capture_outside": {
|
|
228
227
|
"type": "boolean"
|
|
228
|
+
},
|
|
229
|
+
"platform_dst_expandable_menu_item_elembefore_label": {
|
|
230
|
+
"type": "boolean"
|
|
229
231
|
}
|
|
230
232
|
},
|
|
231
233
|
"homepage": "https://atlassian.design/components/navigation-system"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -35,6 +35,9 @@ snapshotInformational(ScrollableVR, {
|
|
|
35
35
|
description: 'Side nav expanded on mobile',
|
|
36
36
|
prepare: async (page) => {
|
|
37
37
|
await page.getByTestId('side-nav-toggle-button').click();
|
|
38
|
+
|
|
39
|
+
// Wait for the tooltip to be displayed, to reduce flakiness
|
|
40
|
+
await page.getByRole('tooltip').waitFor();
|
|
38
41
|
},
|
|
39
42
|
});
|
|
40
43
|
|
|
@@ -43,6 +46,9 @@ snapshotInformational(ScrollableNoPanelVR, {
|
|
|
43
46
|
description: 'Side nav expanded on mobile without panel',
|
|
44
47
|
prepare: async (page) => {
|
|
45
48
|
await page.getByTestId('side-nav-toggle-button').click();
|
|
49
|
+
|
|
50
|
+
// Wait for the tooltip to be displayed, to reduce flakiness
|
|
51
|
+
await page.getByRole('tooltip').waitFor();
|
|
46
52
|
},
|
|
47
53
|
});
|
|
48
54
|
|
|
@@ -34,27 +34,26 @@ test.describe('scroll into view', () => {
|
|
|
34
34
|
}) => {
|
|
35
35
|
await page.setViewportSize(viewportSize);
|
|
36
36
|
|
|
37
|
-
await page.visitExample('design-system', 'navigation-system', 'menu-item-scroll-into-view'
|
|
37
|
+
await page.visitExample('design-system', 'navigation-system', 'menu-item-scroll-into-view', {
|
|
38
|
+
featureFlag: 'platform_dst_expandable_menu_item_elembefore_label',
|
|
39
|
+
});
|
|
38
40
|
|
|
39
41
|
// Collapse the "Teams" expandable menu item
|
|
40
42
|
// We need to click on the collapse chevron icon button (instead of the menu item), so we only toggle the menu item and
|
|
41
43
|
// don't *select* it too.
|
|
42
44
|
const teamsMenuItemContainer = page.getByTestId('teams-menu-item-trigger-container');
|
|
43
45
|
await teamsMenuItemContainer.scrollIntoViewIfNeeded();
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
await
|
|
46
|
+
const teamsMenuItemChevronButton = teamsMenuItemContainer.getByTestId(
|
|
47
|
+
'teams-menu-item-trigger--elem-before-button',
|
|
48
|
+
);
|
|
49
|
+
await teamsMenuItemChevronButton.click();
|
|
48
50
|
|
|
49
51
|
// Select the "Team 10" menu item (by clicking the button in the Main slot)
|
|
50
52
|
const navigateToTeam10MenuItemButton = page.getByTestId('navigate-to-team-10-menu-item');
|
|
51
53
|
await navigateToTeam10MenuItemButton.click();
|
|
52
54
|
|
|
53
|
-
// Expand the "Teams" expandable menu item - using the same button as before
|
|
54
|
-
|
|
55
|
-
name: /Expand/,
|
|
56
|
-
});
|
|
57
|
-
await teamsMenuItemExpandButton.click();
|
|
55
|
+
// Expand the "Teams" expandable menu item - using the same button as before
|
|
56
|
+
await teamsMenuItemChevronButton.click();
|
|
58
57
|
|
|
59
58
|
// The "Team 10" menu item should be scrolled into view
|
|
60
59
|
const team10MenuItem = page.getByRole('link', { name: /Team 10/ });
|
|
@@ -7,6 +7,7 @@ import { IconButton } from '@atlaskit/button/new';
|
|
|
7
7
|
import AddIcon from '@atlaskit/icon/core/add';
|
|
8
8
|
import HomeIcon from '@atlaskit/icon/core/home';
|
|
9
9
|
import MoreIcon from '@atlaskit/icon/core/show-more-horizontal';
|
|
10
|
+
import { ffTest } from '@atlassian/feature-flags-test-utils';
|
|
10
11
|
|
|
11
12
|
import { ButtonMenuItem } from '../../button-menu-item';
|
|
12
13
|
import { ExpandableMenuItem } from '../../expandable-menu-item/expandable-menu-item';
|
|
@@ -272,14 +273,16 @@ describe('ExpandableMenuItem', () => {
|
|
|
272
273
|
it('should show the expandable content when the chevron icon button is clicked while collapsed', async () => {
|
|
273
274
|
render(
|
|
274
275
|
<ExpandableMenuItem>
|
|
275
|
-
<ExpandableMenuItemTrigger href="/test"
|
|
276
|
+
<ExpandableMenuItemTrigger href="/test" testId="trigger-test-id">
|
|
277
|
+
Parent menu item
|
|
278
|
+
</ExpandableMenuItemTrigger>
|
|
276
279
|
<ExpandableMenuItemContent>
|
|
277
280
|
<ButtonMenuItem>Test expandable content</ButtonMenuItem>
|
|
278
281
|
</ExpandableMenuItemContent>
|
|
279
282
|
</ExpandableMenuItem>,
|
|
280
283
|
);
|
|
281
284
|
|
|
282
|
-
await userEvent.click(screen.
|
|
285
|
+
await userEvent.click(screen.getByTestId('trigger-test-id--elem-before-button'), {
|
|
283
286
|
// Skipping pointer events check as the `:not(:has(button,a))` selector
|
|
284
287
|
// to disable pointer-events when there is no interactive child element
|
|
285
288
|
// is not working correctly in our unit test environment
|
|
@@ -292,14 +295,16 @@ describe('ExpandableMenuItem', () => {
|
|
|
292
295
|
it('should hide the expandable content when the chevron icon button is clicked while expanded', async () => {
|
|
293
296
|
render(
|
|
294
297
|
<ExpandableMenuItem isDefaultExpanded>
|
|
295
|
-
<ExpandableMenuItemTrigger href="/test"
|
|
298
|
+
<ExpandableMenuItemTrigger href="/test" testId="trigger-test-id">
|
|
299
|
+
Parent menu item
|
|
300
|
+
</ExpandableMenuItemTrigger>
|
|
296
301
|
<ExpandableMenuItemContent>
|
|
297
302
|
<ButtonMenuItem>Test expandable content</ButtonMenuItem>
|
|
298
303
|
</ExpandableMenuItemContent>
|
|
299
304
|
</ExpandableMenuItem>,
|
|
300
305
|
);
|
|
301
306
|
|
|
302
|
-
await userEvent.click(screen.
|
|
307
|
+
await userEvent.click(screen.getByTestId('trigger-test-id--elem-before-button'), {
|
|
303
308
|
// Skipping pointer events check as the `:not(:has(button,a))` selector
|
|
304
309
|
// to disable pointer-events when there is no interactive child element
|
|
305
310
|
// is not working correctly in our unit test environment
|
|
@@ -344,44 +349,6 @@ describe('ExpandableMenuItem', () => {
|
|
|
344
349
|
|
|
345
350
|
expect(onClick).toHaveBeenCalled();
|
|
346
351
|
});
|
|
347
|
-
|
|
348
|
-
describe('aria-expanded', () => {
|
|
349
|
-
const itemText = 'Parent menu item';
|
|
350
|
-
const chevronExpandedText = 'Collapse';
|
|
351
|
-
const chevronCollapsedText = 'Expand';
|
|
352
|
-
|
|
353
|
-
it('should be `false` when collapsed', () => {
|
|
354
|
-
render(
|
|
355
|
-
<ExpandableMenuItem>
|
|
356
|
-
<ExpandableMenuItemTrigger href="/test">{itemText}</ExpandableMenuItemTrigger>
|
|
357
|
-
<ExpandableMenuItemContent>
|
|
358
|
-
<ButtonMenuItem>Test expandable content</ButtonMenuItem>
|
|
359
|
-
</ExpandableMenuItemContent>
|
|
360
|
-
</ExpandableMenuItem>,
|
|
361
|
-
);
|
|
362
|
-
|
|
363
|
-
expect(screen.getByRole('button', { name: chevronCollapsedText })).toHaveAttribute(
|
|
364
|
-
'aria-expanded',
|
|
365
|
-
'false',
|
|
366
|
-
);
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
it('should be `true` when expanded', () => {
|
|
370
|
-
render(
|
|
371
|
-
<ExpandableMenuItem isDefaultExpanded>
|
|
372
|
-
<ExpandableMenuItemTrigger href="/test">{itemText}</ExpandableMenuItemTrigger>
|
|
373
|
-
<ExpandableMenuItemContent>
|
|
374
|
-
<ButtonMenuItem>Test expandable content</ButtonMenuItem>
|
|
375
|
-
</ExpandableMenuItemContent>
|
|
376
|
-
</ExpandableMenuItem>,
|
|
377
|
-
);
|
|
378
|
-
|
|
379
|
-
expect(screen.getByRole('button', { name: chevronExpandedText })).toHaveAttribute(
|
|
380
|
-
'aria-expanded',
|
|
381
|
-
'true',
|
|
382
|
-
);
|
|
383
|
-
});
|
|
384
|
-
});
|
|
385
352
|
});
|
|
386
353
|
|
|
387
354
|
describe('when a href is not provided', () => {
|
|
@@ -597,36 +564,94 @@ describe('ExpandableMenuItemTrigger', () => {
|
|
|
597
564
|
});
|
|
598
565
|
|
|
599
566
|
describe('when a href is provided', () => {
|
|
600
|
-
it('should display an icon button with correct
|
|
567
|
+
it('should display an icon button with correct test id', () => {
|
|
601
568
|
render(
|
|
602
|
-
<ExpandableMenuItem
|
|
603
|
-
<ExpandableMenuItemTrigger
|
|
604
|
-
href="/test"
|
|
605
|
-
elemBefore={<HomeIcon label="" />}
|
|
606
|
-
actions={actions}
|
|
607
|
-
>
|
|
569
|
+
<ExpandableMenuItem>
|
|
570
|
+
<ExpandableMenuItemTrigger href="/test" testId="trigger-test-id">
|
|
608
571
|
Menu trigger
|
|
609
572
|
</ExpandableMenuItemTrigger>
|
|
610
573
|
</ExpandableMenuItem>,
|
|
611
574
|
);
|
|
612
575
|
|
|
613
|
-
expect(screen.
|
|
576
|
+
expect(screen.getByTestId('trigger-test-id--elem-before-button')).toBeVisible();
|
|
614
577
|
});
|
|
615
578
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
<
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
579
|
+
ffTest.on('platform_dst_expandable_menu_item_elembefore_label', 'aria-expanded', () => {
|
|
580
|
+
it('should display an icon button with correct label and aria-expanded when expanded', () => {
|
|
581
|
+
render(
|
|
582
|
+
<ExpandableMenuItem isDefaultExpanded>
|
|
583
|
+
<ExpandableMenuItemTrigger
|
|
584
|
+
href="/test"
|
|
585
|
+
elemBefore={<HomeIcon label="" />}
|
|
586
|
+
actions={actions}
|
|
587
|
+
>
|
|
588
|
+
Menu trigger
|
|
589
|
+
</ExpandableMenuItemTrigger>
|
|
590
|
+
</ExpandableMenuItem>,
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
const chevronIconButton = screen.getByRole('button', { name: /Menu trigger/ });
|
|
594
|
+
|
|
595
|
+
expect(chevronIconButton).toBeVisible();
|
|
596
|
+
expect(chevronIconButton).toHaveAttribute('aria-expanded', 'true');
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
it('should display an icon button with correct label and aria-expanded when collapsed', () => {
|
|
600
|
+
render(
|
|
601
|
+
<ExpandableMenuItem>
|
|
602
|
+
<ExpandableMenuItemTrigger
|
|
603
|
+
href="/test"
|
|
604
|
+
elemBefore={<HomeIcon label="" />}
|
|
605
|
+
actions={actions}
|
|
606
|
+
>
|
|
607
|
+
Menu trigger
|
|
608
|
+
</ExpandableMenuItemTrigger>
|
|
609
|
+
</ExpandableMenuItem>,
|
|
610
|
+
);
|
|
611
|
+
|
|
612
|
+
const chevronIconButton = screen.getByRole('button', { name: /Menu trigger/ });
|
|
613
|
+
|
|
614
|
+
expect(chevronIconButton).toBeVisible();
|
|
615
|
+
expect(chevronIconButton).toHaveAttribute('aria-expanded', 'false');
|
|
616
|
+
});
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
ffTest.off('platform_dst_expandable_menu_item_elembefore_label', 'aria-expanded', () => {
|
|
620
|
+
const itemText = 'Parent menu item';
|
|
621
|
+
const chevronExpandedText = 'Collapse';
|
|
622
|
+
const chevronCollapsedText = 'Expand';
|
|
623
|
+
|
|
624
|
+
it('should be `false` when collapsed', () => {
|
|
625
|
+
render(
|
|
626
|
+
<ExpandableMenuItem>
|
|
627
|
+
<ExpandableMenuItemTrigger href="/test">{itemText}</ExpandableMenuItemTrigger>
|
|
628
|
+
<ExpandableMenuItemContent>
|
|
629
|
+
<ButtonMenuItem>Test expandable content</ButtonMenuItem>
|
|
630
|
+
</ExpandableMenuItemContent>
|
|
631
|
+
</ExpandableMenuItem>,
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
expect(screen.getByRole('button', { name: chevronCollapsedText })).toHaveAttribute(
|
|
635
|
+
'aria-expanded',
|
|
636
|
+
'false',
|
|
637
|
+
);
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
it('should be `true` when expanded', () => {
|
|
641
|
+
render(
|
|
642
|
+
<ExpandableMenuItem isDefaultExpanded>
|
|
643
|
+
<ExpandableMenuItemTrigger href="/test">{itemText}</ExpandableMenuItemTrigger>
|
|
644
|
+
<ExpandableMenuItemContent>
|
|
645
|
+
<ButtonMenuItem>Test expandable content</ButtonMenuItem>
|
|
646
|
+
</ExpandableMenuItemContent>
|
|
647
|
+
</ExpandableMenuItem>,
|
|
648
|
+
);
|
|
628
649
|
|
|
629
|
-
|
|
650
|
+
expect(screen.getByRole('button', { name: chevronExpandedText })).toHaveAttribute(
|
|
651
|
+
'aria-expanded',
|
|
652
|
+
'true',
|
|
653
|
+
);
|
|
654
|
+
});
|
|
630
655
|
});
|
|
631
656
|
|
|
632
657
|
it('should display custom icon when not hovered over', () => {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -190,13 +190,13 @@ snapshot(ExpandableMenuItemWithAllOptions, {
|
|
|
190
190
|
{
|
|
191
191
|
state: 'hovered',
|
|
192
192
|
selector: {
|
|
193
|
-
|
|
194
|
-
options: {
|
|
195
|
-
name: 'Expand',
|
|
196
|
-
},
|
|
193
|
+
byTestId: 'parent-menu-item--elem-before-button',
|
|
197
194
|
},
|
|
198
195
|
},
|
|
199
196
|
],
|
|
197
|
+
featureFlags: {
|
|
198
|
+
platform_dst_expandable_menu_item_elembefore_label: true,
|
|
199
|
+
},
|
|
200
200
|
});
|
|
201
201
|
|
|
202
202
|
snapshot(ExpandableMenuItemWithAllOptions, {
|
|
@@ -206,13 +206,13 @@ snapshot(ExpandableMenuItemWithAllOptions, {
|
|
|
206
206
|
{
|
|
207
207
|
state: 'focused',
|
|
208
208
|
selector: {
|
|
209
|
-
|
|
210
|
-
options: {
|
|
211
|
-
name: 'Expand',
|
|
212
|
-
},
|
|
209
|
+
byTestId: 'parent-menu-item--elem-before-button',
|
|
213
210
|
},
|
|
214
211
|
},
|
|
215
212
|
],
|
|
213
|
+
featureFlags: {
|
|
214
|
+
platform_dst_expandable_menu_item_elembefore_label: true,
|
|
215
|
+
},
|
|
216
216
|
});
|
|
217
217
|
|
|
218
218
|
snapshot(ExpandableMenuItemWithAllOptions, {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @jsxRuntime classic
|
|
4
4
|
* @jsx jsx
|
|
5
5
|
*/
|
|
6
|
-
import React, { forwardRef, type ReactNode, useCallback, useRef } from 'react';
|
|
6
|
+
import React, { forwardRef, type ReactNode, useCallback, useId, useRef } from 'react';
|
|
7
7
|
|
|
8
8
|
import { cssMap, jsx } from '@compiled/react';
|
|
9
9
|
|
|
@@ -12,6 +12,7 @@ import { IconButton } from '@atlaskit/button/new';
|
|
|
12
12
|
import type { IconProps } from '@atlaskit/icon';
|
|
13
13
|
import ChevronDownIcon from '@atlaskit/icon/core/chevron-down';
|
|
14
14
|
import ChevronRightIcon from '@atlaskit/icon/core/chevron-right';
|
|
15
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
15
16
|
import { token } from '@atlaskit/tokens';
|
|
16
17
|
|
|
17
18
|
import { MenuItemBase, nestedOpenPopupCSSSelector } from '../menu-item';
|
|
@@ -229,6 +230,7 @@ export const ExpandableMenuItemTrigger = forwardRef<
|
|
|
229
230
|
},
|
|
230
231
|
forwardedRef,
|
|
231
232
|
) => {
|
|
233
|
+
const id = useId();
|
|
232
234
|
const onExpansionToggle = useOnExpansionToggle();
|
|
233
235
|
const isExpanded = useIsExpanded();
|
|
234
236
|
const setIsExpanded = useSetIsExpanded();
|
|
@@ -271,11 +273,25 @@ export const ExpandableMenuItemTrigger = forwardRef<
|
|
|
271
273
|
/>
|
|
272
274
|
)}
|
|
273
275
|
aria-expanded={isExpanded}
|
|
274
|
-
|
|
276
|
+
// We are labelling the icon button using the containing menu item's content, to provide context to
|
|
277
|
+
// screen readers on what will actually be expanded or collapsed. Screen readers will also use the
|
|
278
|
+
// `aria-expanded` attribute to indicate the expanded state of the menu item.
|
|
279
|
+
// We are not using the `aria-label` attribute here as it is not supported by the `IconButton` component.
|
|
280
|
+
aria-labelledby={fg('platform_dst_expandable_menu_item_elembefore_label') ? id : undefined}
|
|
281
|
+
// IconButton requires a label prop, however it will not be used by screen readers as we are setting
|
|
282
|
+
// `aria-labelledby`, which will be used instead.
|
|
283
|
+
label={
|
|
284
|
+
fg('platform_dst_expandable_menu_item_elembefore_label')
|
|
285
|
+
? ''
|
|
286
|
+
: isExpanded
|
|
287
|
+
? 'Collapse'
|
|
288
|
+
: 'Expand'
|
|
289
|
+
}
|
|
275
290
|
appearance="subtle"
|
|
276
291
|
spacing="compact"
|
|
277
292
|
onClick={handleIconClick}
|
|
278
293
|
interactionName={interactionName}
|
|
294
|
+
testId={testId ? `${testId}--elem-before-button` : undefined}
|
|
279
295
|
/>
|
|
280
296
|
) : (
|
|
281
297
|
<ExpandableMenuItemIcon
|
|
@@ -292,6 +308,7 @@ export const ExpandableMenuItemTrigger = forwardRef<
|
|
|
292
308
|
ref={itemRef}
|
|
293
309
|
>
|
|
294
310
|
<MenuItemBase
|
|
311
|
+
id={id}
|
|
295
312
|
actions={actions}
|
|
296
313
|
actionsOnHover={actionsOnHover}
|
|
297
314
|
elemBefore={elemBefore}
|
|
@@ -216,7 +216,8 @@ const containerStyles = cssMap({
|
|
|
216
216
|
* are unusable.
|
|
217
217
|
*/
|
|
218
218
|
minWidth: '72px',
|
|
219
|
-
|
|
219
|
+
// Using rem so it scales with browser font size and rem-based spacing/typography
|
|
220
|
+
height: '2rem',
|
|
220
221
|
alignItems: 'center',
|
|
221
222
|
userSelect: 'none',
|
|
222
223
|
borderRadius: token('border.radius'),
|
|
@@ -246,12 +247,6 @@ const containerStyles = cssMap({
|
|
|
246
247
|
showHoverActions: {
|
|
247
248
|
[actionsOnHoverDisplayVar]: 'flex',
|
|
248
249
|
},
|
|
249
|
-
removeElemAfterOnHover: {
|
|
250
|
-
// On hover of the menu item, remove the elemAfter
|
|
251
|
-
'&:hover, &:focus-within': {
|
|
252
|
-
[elemAfterDisplayVar]: 'none',
|
|
253
|
-
},
|
|
254
|
-
},
|
|
255
250
|
removeElemAfterOnHoverOrOpenNestedPopup: {
|
|
256
251
|
// On hover of the menu item, remove the elemAfter
|
|
257
252
|
'&:hover, &:focus-within': {
|
|
@@ -286,7 +281,7 @@ const containerStyles = cssMap({
|
|
|
286
281
|
},
|
|
287
282
|
hasDescription: {
|
|
288
283
|
/* Standard 32px + another 16px for the description */
|
|
289
|
-
height: '
|
|
284
|
+
height: '3rem',
|
|
290
285
|
},
|
|
291
286
|
dragging: {
|
|
292
287
|
opacity: 0.4,
|
|
@@ -524,6 +519,11 @@ function getTextColor({
|
|
|
524
519
|
*/
|
|
525
520
|
type MenuItemBaseProps<T extends HTMLAnchorElement | HTMLButtonElement> =
|
|
526
521
|
MenuItemLinkOrButtonCommonProps & {
|
|
522
|
+
/**
|
|
523
|
+
* ID attribute, passed to the interactive element (anchor/button). This is not publicly exposed, and is currently only
|
|
524
|
+
* used internally by `ExpandableMenuItemTrigger` for the `aria-labelledby` attribute.
|
|
525
|
+
*/
|
|
526
|
+
id?: string;
|
|
527
527
|
href?: string | Record<string, any>;
|
|
528
528
|
target?: HTMLAnchorElement['target'];
|
|
529
529
|
isDisabled?: boolean;
|
|
@@ -545,6 +545,7 @@ type MenuItemBaseProps<T extends HTMLAnchorElement | HTMLButtonElement> =
|
|
|
545
545
|
*/
|
|
546
546
|
const MenuItemBaseNoRef = <T extends HTMLAnchorElement | HTMLButtonElement>(
|
|
547
547
|
{
|
|
548
|
+
id,
|
|
548
549
|
testId,
|
|
549
550
|
actions,
|
|
550
551
|
actionsOnHover,
|
|
@@ -736,6 +737,7 @@ const MenuItemBaseNoRef = <T extends HTMLAnchorElement | HTMLButtonElement>(
|
|
|
736
737
|
'aria-controls': ariaControls,
|
|
737
738
|
'aria-haspopup': ariaHasPopup,
|
|
738
739
|
ref: mergeRefs([forwardedRef, tooltipProps.ref]),
|
|
740
|
+
id,
|
|
739
741
|
testId,
|
|
740
742
|
interactionName,
|
|
741
743
|
};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { toBeSuspendable, toPassStrictMode } from '@af/react-unit-testing';
|
|
4
|
-
|
|
5
3
|
import CompositionExample from '../../../../../examples/composition';
|
|
6
4
|
|
|
7
5
|
import { resetMatchMedia } from './_test-utils';
|
|
@@ -10,12 +8,6 @@ beforeEach(() => {
|
|
|
10
8
|
resetMatchMedia();
|
|
11
9
|
});
|
|
12
10
|
|
|
13
|
-
// TODO: move to `jestFrameworkSetup.js` in follow up pull request
|
|
14
|
-
expect.extend({
|
|
15
|
-
toBeSuspendable,
|
|
16
|
-
toPassStrictMode,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
11
|
it('should support being suspended', async () => {
|
|
20
12
|
await expect(() => <CompositionExample />).toBeSuspendable();
|
|
21
13
|
});
|