Skip to content

Commit c43cd31

Browse files
committed
chore(website): Updated a few menu demos
1 parent 0cdeff7 commit c43cd31

File tree

5 files changed

+199
-42
lines changed

5 files changed

+199
-42
lines changed

packages/documentation/src/components/Demos/Menu/FloatingActionButtonMenus.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ export default function FloatingActionButtonMenus(): ReactElement {
2121
aria-label="Options..."
2222
floating={position}
2323
buttonChildren={<MoreVertSVGIcon />}
24+
fixedPositionOptions={{
25+
disableSwapping: true,
26+
}}
2427
/>
2528
))}
2629
</>

packages/documentation/src/components/Demos/Menu/HoverableMenus.module.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,7 @@
88
overflow: auto;
99
padding: 0 0.5rem;
1010
}
11+
12+
.dialog {
13+
width: 30rem;
14+
}

packages/documentation/src/components/Demos/Menu/HoverableMenus.tsx

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,27 @@
22
// https://www.w3.org/TR/wai-aria-practices/examples/menubar/menubar-editor.html
33
import { ReactElement, useState } from "react";
44
import { AppBar } from "@react-md/app-bar";
5-
import { MenuItemCheckbox, MenuItemRadio, TextArea } from "@react-md/form";
6-
import { AddSVGIcon, RemoveSVGIcon } from "@react-md/material-icons";
5+
import { Button } from "@react-md/button";
6+
import {
7+
Dialog,
8+
DialogContent,
9+
DialogFooter,
10+
DialogHeader,
11+
DialogTitle,
12+
} from "@react-md/dialog";
13+
import {
14+
Form,
15+
MenuItemCheckbox,
16+
MenuItemRadio,
17+
TextArea,
18+
TextFieldWithMessage,
19+
useNumberField,
20+
} from "@react-md/form";
21+
import {
22+
AddSVGIcon,
23+
BuildSVGIcon,
24+
RemoveSVGIcon,
25+
} from "@react-md/material-icons";
726
import {
827
DropdownMenu,
928
MenuBar,
@@ -12,8 +31,11 @@ import {
1231
MenuItemSeparator,
1332
} from "@react-md/menu";
1433
import scssVariables from "@react-md/theme/dist/scssVariables";
34+
import { Typography } from "@react-md/typography";
1535
import type { CalculateFixedPositionOptions } from "@react-md/utils";
1636

37+
import Code from "components/Code";
38+
1739
import styles from "./HoverableMenus.module.scss";
1840
import InfiniteDropdownMenu from "./InfiniteDropdownMenu";
1941

@@ -87,6 +109,13 @@ export default function HoverableMenus(): ReactElement {
87109
return FONT_SIZES[nextIndex].value;
88110
});
89111
};
112+
const [visible, setVisible] = useState(false);
113+
const onRequestClose = (): void => setVisible(false);
114+
const [hoverTimeout, textFieldProps, { reset }] = useNumberField({
115+
id: "hoverable-menus-hover-timeout",
116+
min: 0,
117+
max: 3000,
118+
});
90119

91120
return (
92121
<div className={styles.container}>
@@ -99,7 +128,7 @@ export default function HoverableMenus(): ReactElement {
99128
// will update the behavior so the "hover mode" behavior will be
100129
// active after the user has hovered over one of the `DropdownMenu`s
101130
// for that amount of time in milliseconds
102-
// hoverTimeout={0}
131+
hoverTimeout={hoverTimeout}
103132
>
104133
<DropdownMenu
105134
id="menubar-item-1"
@@ -240,6 +269,64 @@ export default function HoverableMenus(): ReactElement {
240269
}}
241270
defaultValue={EXAMPLE_TEXT}
242271
/>
272+
<Button
273+
theme="warning"
274+
floating="bottom-left"
275+
aria-label="Configure"
276+
onClick={() => setVisible((prevVisible) => !prevVisible)}
277+
>
278+
<BuildSVGIcon />
279+
</Button>
280+
<Dialog
281+
id="configure-dialog"
282+
aria-labelledby="configure-dialog-title"
283+
modal
284+
visible={visible}
285+
onRequestClose={onRequestClose}
286+
className={styles.dialog}
287+
>
288+
<DialogHeader>
289+
<DialogTitle id="configure-dialog-title">
290+
Configure Hover Timeout
291+
</DialogTitle>
292+
</DialogHeader>
293+
<DialogContent>
294+
<Form
295+
id="configure-form"
296+
onSubmit={onRequestClose}
297+
onReset={() => {
298+
reset();
299+
onRequestClose();
300+
}}
301+
>
302+
<TextFieldWithMessage
303+
{...textFieldProps}
304+
label="Hover Timeout"
305+
placeholder="0"
306+
/>
307+
</Form>
308+
<Typography>
309+
The amount of time the user must over over a menu in milliseconds
310+
before the hover mode behavior is enabled.
311+
</Typography>
312+
<Typography>
313+
If this is <Code>undefined</Code>, the user must click one of the
314+
dropdown buttons before the hover mode is enabled.
315+
</Typography>
316+
<Typography>
317+
If this is set to <Code>0</Code>, the menus will become visible
318+
immediately on hover.
319+
</Typography>
320+
</DialogContent>
321+
<DialogFooter>
322+
<Button form="configure-form" type="reset" theme="warning">
323+
Reset
324+
</Button>
325+
<Button form="configure-form" type="submit" theme="primary">
326+
Confirm
327+
</Button>
328+
</DialogFooter>
329+
</Dialog>
243330
</div>
244331
);
245332
}

packages/documentation/src/components/Demos/Menu/MenusWithFormComponents.tsx

Lines changed: 92 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,20 @@ import {
55
MenuItemRadio,
66
MenuItemSwitch,
77
MenuItemTextField,
8+
Select,
89
useIndeterminateChecked,
10+
useSelectState,
911
} from "@react-md/form";
1012
import { SearchSVGIcon } from "@react-md/material-icons";
11-
import { DropdownMenu, MenuItemGroup, MenuItemSeparator } from "@react-md/menu";
13+
import {
14+
DropdownMenu,
15+
MenuConfigurationProvider,
16+
MenuItemGroup,
17+
MenuItemSeparator,
18+
RenderMenuAsSheet,
19+
} from "@react-md/menu";
1220
import { TextDecoration, Typography } from "@react-md/typography";
1321

14-
type Decoration = "none" | "underline" | "overline" | "strike-through";
15-
16-
const decorations: readonly Decoration[] = [
17-
"none",
18-
"underline",
19-
"overline",
20-
"strike-through",
21-
];
22-
2322
const values = ["a", "b", "c", "d"] as const;
2423
const labels = {
2524
a: "Label 1",
@@ -28,33 +27,19 @@ const labels = {
2827
d: "Label 4",
2928
} as const;
3029

31-
const getDecoration = (decoration: Decoration): TextDecoration | undefined => {
32-
if (decoration == "none") {
33-
return undefined;
34-
}
35-
36-
return decoration === "strike-through" ? "line-through" : decoration;
37-
};
38-
39-
export default function MenusWithFormComponents(): ReactElement {
30+
function CheckboxesDropdown(): ReactElement {
4031
const [bold, setBold] = useState(false);
4132
const [italic, setItalic] = useState(false);
42-
const [decoration, setDecoration] = useState<Decoration>("none");
43-
const [checked, setChecked] = useState(false);
4433
const { rootProps, getProps } = useIndeterminateChecked(values, {
4534
menu: true,
4635
});
36+
4737
return (
4838
<DropdownMenu
49-
id="dropdown-menu-with-form-components"
50-
buttonChildren="Dropdown"
39+
id="dropdown-menu-with-form-components-1"
40+
buttonChildren="Checkboxes"
41+
themeType="outline"
5142
>
52-
<MenuItemTextField
53-
id="dropdown-menu-text-field"
54-
placeholder="Search..."
55-
rightChildren={<SearchSVGIcon />}
56-
/>
57-
<MenuItemSeparator />
5843
<MenuItemCheckbox id="some-group-id-root" {...rootProps}>
5944
Toggle All
6045
</MenuItemCheckbox>
@@ -82,7 +67,37 @@ export default function MenusWithFormComponents(): ReactElement {
8267
>
8368
Italic
8469
</MenuItemCheckbox>
85-
<MenuItemSeparator />
70+
</DropdownMenu>
71+
);
72+
}
73+
74+
type Decoration = "none" | "underline" | "overline" | "strike-through";
75+
76+
const decorations: readonly Decoration[] = [
77+
"none",
78+
"underline",
79+
"overline",
80+
"strike-through",
81+
];
82+
83+
const getDecoration = (decoration: Decoration): TextDecoration | undefined => {
84+
if (decoration == "none") {
85+
return undefined;
86+
}
87+
88+
return decoration === "strike-through" ? "line-through" : decoration;
89+
};
90+
91+
function RadioAndSwitchDropdown(): ReactElement {
92+
const [decoration, setDecoration] = useState<Decoration>("none");
93+
const [checked, setChecked] = useState(false);
94+
95+
return (
96+
<DropdownMenu
97+
id="dropdown-menu-with-form-components-2"
98+
buttonChildren="Switch/Radio"
99+
themeType="outline"
100+
>
86101
{/* see https://www.w3.org/TR/wai-aria-1.1/#menuitemradio why this is */}
87102
{/* wrapped in a group */}
88103
<MenuItemGroup aria-label="Font Decoration">
@@ -107,6 +122,23 @@ export default function MenusWithFormComponents(): ReactElement {
107122
>
108123
Do Stuff?
109124
</MenuItemSwitch>
125+
</DropdownMenu>
126+
);
127+
}
128+
129+
function TextFieldAndFileInputDropdown(): ReactElement {
130+
return (
131+
<DropdownMenu
132+
id="dropdown-menu-with-form-components-3"
133+
buttonChildren="Inputs"
134+
themeType="outline"
135+
>
136+
<MenuItemTextField
137+
aria-label="Search"
138+
id="dropdown-menu-search-field"
139+
placeholder="Search..."
140+
rightChildren={<SearchSVGIcon />}
141+
/>
110142
<MenuItemSeparator />
111143
<MenuItemFileInput
112144
id="upload-file-menu-item"
@@ -121,3 +153,33 @@ export default function MenusWithFormComponents(): ReactElement {
121153
</DropdownMenu>
122154
);
123155
}
156+
157+
const choices = ["phone", "true", "false"] as const;
158+
type Choices = typeof choices[number];
159+
160+
export default function MenusWithFormComponents(): ReactElement {
161+
const [choice, handleChoiceChange] = useSelectState<Choices>("phone");
162+
let renderAsSheet: RenderMenuAsSheet;
163+
if (choice === "phone") {
164+
renderAsSheet = choice;
165+
} else {
166+
renderAsSheet = choice === "true";
167+
}
168+
return (
169+
<MenuConfigurationProvider renderAsSheet={renderAsSheet}>
170+
<Select
171+
id="menu-form-component-sheet"
172+
options={choices}
173+
value={choice}
174+
onChange={handleChoiceChange}
175+
label="renderAsSheet"
176+
style={{ marginBottom: "2rem" }}
177+
/>
178+
<div style={{ display: "flex", gap: "0.5rem", flexWrap: "wrap" }}>
179+
<CheckboxesDropdown />
180+
<RadioAndSwitchDropdown />
181+
<TextFieldAndFileInputDropdown />
182+
</div>
183+
</MenuConfigurationProvider>
184+
);
185+
}

packages/documentation/src/components/Demos/Menu/index.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ import README from "./README.md";
1313
import SimpleExample from "./SimpleExample";
1414
import simpleExample from "./SimpleExample.md";
1515

16-
import FloatingActionButtonMenus from "./FloatingActionButtonMenus";
17-
import floatingActionButtonMenus from "./FloatingActionButtonMenus.md";
18-
1916
import ConfigurableDropdownMenu from "./ConfigurableDropdownMenu";
2017
import configurableDropdownMenu from "./ConfigurableDropdownMenu.md";
2118

19+
import FloatingActionButtonMenus from "./FloatingActionButtonMenus";
20+
import floatingActionButtonMenus from "./FloatingActionButtonMenus.md";
21+
2222
import SimpleContextMenu from "./SimpleContextMenu";
2323
import simpleContextMenu from "./SimpleContextMenu.md";
2424

@@ -40,17 +40,18 @@ const demos: DemoConfig[] = [
4040
description: simpleExample,
4141
children: <SimpleExample />,
4242
},
43-
{
44-
name: "Floating Action Button Menus",
45-
description: floatingActionButtonMenus,
46-
children: <FloatingActionButtonMenus />,
47-
emulated: true,
48-
},
4943
{
5044
name: "Configurable Dropdown Menu",
5145
description: configurableDropdownMenu,
5246
children: <ConfigurableDropdownMenu />,
5347
},
48+
{
49+
name: "Floating Action Button Menus",
50+
description: floatingActionButtonMenus,
51+
children: <FloatingActionButtonMenus />,
52+
emulated: { fabOffset: true },
53+
disableCard: true,
54+
},
5455
{
5556
name: "Simple Context Menu",
5657
description: simpleContextMenu,

0 commit comments

Comments
 (0)