Skip to content

Commit 81aa849

Browse files
committed
docs(dropdowns menu): test story within shadowRoot
1 parent c4b0891 commit 81aa849

File tree

5 files changed

+86
-53
lines changed

5 files changed

+86
-53
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/dropdowns/demo/stories/MenuStory.tsx

Lines changed: 76 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66
*/
77

88
import React from 'react';
9+
import { createPortal } from 'react-dom';
10+
import { StyleSheetManager } from 'styled-components';
11+
912
import { StoryFn } from '@storybook/react';
1013
import LeafIcon from '@zendeskgarden/svg-icons/src/16/leaf-stroke.svg';
1114
import CartIcon from '@zendeskgarden/svg-icons/src/16/shopping-cart-stroke.svg';
1215
import { Grid } from '@zendeskgarden/react-grid';
1316
import { IMenuProps, Item, ItemGroup, Separator, Menu } from '@zendeskgarden/react-dropdowns';
17+
import { IGardenTheme, ThemeProvider } from '@zendeskgarden/react-theming';
1418
import { IconButton } from '@zendeskgarden/react-buttons';
1519
import { ButtonType, IItem, Items } from './types';
1620

@@ -29,50 +33,77 @@ interface IArgs extends IMenuProps {
2933
label: string;
3034
}
3135

32-
export const MenuStory: StoryFn<IArgs> = ({ button, items, label, ...args }) => (
33-
<Grid>
34-
<Grid.Row justifyContent="center" style={{ height: 800 }}>
35-
<Grid.Col alignSelf="center" textAlign="center">
36-
<div style={{ display: 'inline-block', position: 'relative', width: 200 }}>
37-
<Menu
38-
{...args}
39-
button={
40-
button === 'string'
41-
? label
42-
: /* eslint-disable-next-line react/no-unstable-nested-components */
43-
props => (
44-
<IconButton {...props} aria-label={label}>
45-
<LeafIcon />
46-
</IconButton>
47-
)
48-
}
49-
>
50-
{items.map(item => {
51-
if ('items' in item) {
52-
return (
53-
<ItemGroup
54-
legend={item.legend}
55-
aria-label={item['aria-label']}
56-
key={item.legend || item['aria-label']}
57-
type={item.type}
58-
icon={item.icon ? <CartIcon /> : undefined}
59-
>
60-
{item.items.map(groupItem => (
61-
<MenuItem key={groupItem.value} {...groupItem} />
62-
))}
63-
</ItemGroup>
64-
);
65-
}
36+
const Portal = ({ children, target }: any) => {
37+
if (!target) return null;
38+
39+
return createPortal(children, target);
40+
};
41+
42+
export const MenuStory: StoryFn<IArgs> = ({ button, items, label, ...args }) => {
43+
const ref = React.useRef<any>(null);
44+
const [document, setDocument] = React.useState(undefined);
45+
46+
React.useEffect(() => {
47+
if (ref.current && !ref.current.shadowRoot) {
48+
const shadowRoot = ref.current?.attachShadow({ mode: 'open' });
6649

67-
if ('isSeparator' in item) {
68-
return <Separator key={item.value} />;
69-
}
50+
setDocument(shadowRoot);
51+
}
52+
}, []);
7053

71-
return <MenuItem key={item.value} {...item} />;
72-
})}
73-
</Menu>
74-
</div>
75-
</Grid.Col>
76-
</Grid.Row>
77-
</Grid>
78-
);
54+
return (
55+
<div ref={ref}>
56+
<Portal target={document}>
57+
<StyleSheetManager target={document}>
58+
<ThemeProvider theme={(theme: IGardenTheme) => ({ ...theme, document })}>
59+
<Grid>
60+
<Grid.Row justifyContent="center" style={{ height: 800 }}>
61+
<Grid.Col alignSelf="center" textAlign="center">
62+
<div style={{ display: 'inline-block', position: 'relative', width: 200 }}>
63+
<Menu
64+
{...args}
65+
button={
66+
button === 'string'
67+
? label
68+
: /* eslint-disable-next-line react/no-unstable-nested-components */
69+
props => (
70+
<IconButton {...props} aria-label={label}>
71+
<LeafIcon />
72+
</IconButton>
73+
)
74+
}
75+
>
76+
{items.map(item => {
77+
if ('items' in item) {
78+
return (
79+
<ItemGroup
80+
legend={item.legend}
81+
aria-label={item['aria-label']}
82+
key={item.legend || item['aria-label']}
83+
type={item.type}
84+
icon={item.icon ? <CartIcon /> : undefined}
85+
>
86+
{item.items.map(groupItem => (
87+
<MenuItem key={groupItem.value} {...groupItem} />
88+
))}
89+
</ItemGroup>
90+
);
91+
}
92+
93+
if ('isSeparator' in item) {
94+
return <Separator key={item.value} />;
95+
}
96+
97+
return <MenuItem key={item.value} {...item} />;
98+
})}
99+
</Menu>
100+
</div>
101+
</Grid.Col>
102+
</Grid.Row>
103+
</Grid>
104+
</ThemeProvider>
105+
</StyleSheetManager>
106+
</Portal>
107+
</div>
108+
);
109+
};

packages/dropdowns/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"dependencies": {
2424
"@floating-ui/react-dom": "^2.0.0",
2525
"@zendeskgarden/container-combobox": "^2.0.0",
26-
"@zendeskgarden/container-menu": "^0.5.1",
26+
"@zendeskgarden/container-menu": "file:../../zendeskgarden-container-menu-0.6.0.tgz",
2727
"@zendeskgarden/container-utilities": "^2.0.0",
2828
"@zendeskgarden/react-buttons": "^9.5.4",
2929
"@zendeskgarden/react-forms": "^9.5.4",

packages/dropdowns/src/elements/menu/Menu.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import PropTypes from 'prop-types';
1010
import { mergeRefs } from 'react-merge-refs';
1111
import { ThemeContext } from 'styled-components';
1212
import { useMenu } from '@zendeskgarden/container-menu';
13-
import { DEFAULT_THEME, useWindow } from '@zendeskgarden/react-theming';
13+
import { DEFAULT_THEME, useDocument, useWindow } from '@zendeskgarden/react-theming';
1414
import { Button, IButtonProps } from '@zendeskgarden/react-buttons';
1515
import { IMenuProps, PLACEMENT } from '../../types';
1616
import { MenuContext } from '../../context/useMenuContext';
@@ -45,7 +45,8 @@ export const Menu = forwardRef<HTMLUListElement, IMenuProps>(
4545
const items = toItems(children);
4646
/* istanbul ignore next */
4747
const theme = useContext(ThemeContext) || DEFAULT_THEME;
48-
const environment = useWindow(theme);
48+
const _window = useWindow(theme);
49+
const document = useDocument(theme);
4950

5051
const {
5152
isExpanded,
@@ -56,8 +57,9 @@ export const Menu = forwardRef<HTMLUListElement, IMenuProps>(
5657
getItemGroupProps,
5758
getSeparatorProps
5859
} = useMenu({
60+
document,
5961
rtl: theme.rtl,
60-
environment,
62+
window: _window,
6163
defaultFocusedValue,
6264
focusedValue: _focusedValue,
6365
defaultExpanded,
9.13 KB
Binary file not shown.

0 commit comments

Comments
 (0)