Skip to content

Commit

Permalink
chore(website): Updated a few menu demos
Browse files Browse the repository at this point in the history
  • Loading branch information
mlaursen committed Jan 30, 2022
1 parent 0cdeff7 commit c43cd31
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 42 deletions.
Expand Up @@ -21,6 +21,9 @@ export default function FloatingActionButtonMenus(): ReactElement {
aria-label="Options..."
floating={position}
buttonChildren={<MoreVertSVGIcon />}
fixedPositionOptions={{
disableSwapping: true,
}}
/>
))}
</>
Expand Down
Expand Up @@ -8,3 +8,7 @@
overflow: auto;
padding: 0 0.5rem;
}

.dialog {
width: 30rem;
}
Expand Up @@ -2,8 +2,27 @@
// https://www.w3.org/TR/wai-aria-practices/examples/menubar/menubar-editor.html
import { ReactElement, useState } from "react";
import { AppBar } from "@react-md/app-bar";
import { MenuItemCheckbox, MenuItemRadio, TextArea } from "@react-md/form";
import { AddSVGIcon, RemoveSVGIcon } from "@react-md/material-icons";
import { Button } from "@react-md/button";
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@react-md/dialog";
import {
Form,
MenuItemCheckbox,
MenuItemRadio,
TextArea,
TextFieldWithMessage,
useNumberField,
} from "@react-md/form";
import {
AddSVGIcon,
BuildSVGIcon,
RemoveSVGIcon,
} from "@react-md/material-icons";
import {
DropdownMenu,
MenuBar,
Expand All @@ -12,8 +31,11 @@ import {
MenuItemSeparator,
} from "@react-md/menu";
import scssVariables from "@react-md/theme/dist/scssVariables";
import { Typography } from "@react-md/typography";
import type { CalculateFixedPositionOptions } from "@react-md/utils";

import Code from "components/Code";

import styles from "./HoverableMenus.module.scss";
import InfiniteDropdownMenu from "./InfiniteDropdownMenu";

Expand Down Expand Up @@ -87,6 +109,13 @@ export default function HoverableMenus(): ReactElement {
return FONT_SIZES[nextIndex].value;
});
};
const [visible, setVisible] = useState(false);
const onRequestClose = (): void => setVisible(false);
const [hoverTimeout, textFieldProps, { reset }] = useNumberField({
id: "hoverable-menus-hover-timeout",
min: 0,
max: 3000,
});

return (
<div className={styles.container}>
Expand All @@ -99,7 +128,7 @@ export default function HoverableMenus(): ReactElement {
// will update the behavior so the "hover mode" behavior will be
// active after the user has hovered over one of the `DropdownMenu`s
// for that amount of time in milliseconds
// hoverTimeout={0}
hoverTimeout={hoverTimeout}
>
<DropdownMenu
id="menubar-item-1"
Expand Down Expand Up @@ -240,6 +269,64 @@ export default function HoverableMenus(): ReactElement {
}}
defaultValue={EXAMPLE_TEXT}
/>
<Button
theme="warning"
floating="bottom-left"
aria-label="Configure"
onClick={() => setVisible((prevVisible) => !prevVisible)}
>
<BuildSVGIcon />
</Button>
<Dialog
id="configure-dialog"
aria-labelledby="configure-dialog-title"
modal
visible={visible}
onRequestClose={onRequestClose}
className={styles.dialog}
>
<DialogHeader>
<DialogTitle id="configure-dialog-title">
Configure Hover Timeout
</DialogTitle>
</DialogHeader>
<DialogContent>
<Form
id="configure-form"
onSubmit={onRequestClose}
onReset={() => {
reset();
onRequestClose();
}}
>
<TextFieldWithMessage
{...textFieldProps}
label="Hover Timeout"
placeholder="0"
/>
</Form>
<Typography>
The amount of time the user must over over a menu in milliseconds
before the hover mode behavior is enabled.
</Typography>
<Typography>
If this is <Code>undefined</Code>, the user must click one of the
dropdown buttons before the hover mode is enabled.
</Typography>
<Typography>
If this is set to <Code>0</Code>, the menus will become visible
immediately on hover.
</Typography>
</DialogContent>
<DialogFooter>
<Button form="configure-form" type="reset" theme="warning">
Reset
</Button>
<Button form="configure-form" type="submit" theme="primary">
Confirm
</Button>
</DialogFooter>
</Dialog>
</div>
);
}
Expand Up @@ -5,21 +5,20 @@ import {
MenuItemRadio,
MenuItemSwitch,
MenuItemTextField,
Select,
useIndeterminateChecked,
useSelectState,
} from "@react-md/form";
import { SearchSVGIcon } from "@react-md/material-icons";
import { DropdownMenu, MenuItemGroup, MenuItemSeparator } from "@react-md/menu";
import {
DropdownMenu,
MenuConfigurationProvider,
MenuItemGroup,
MenuItemSeparator,
RenderMenuAsSheet,
} from "@react-md/menu";
import { TextDecoration, Typography } from "@react-md/typography";

type Decoration = "none" | "underline" | "overline" | "strike-through";

const decorations: readonly Decoration[] = [
"none",
"underline",
"overline",
"strike-through",
];

const values = ["a", "b", "c", "d"] as const;
const labels = {
a: "Label 1",
Expand All @@ -28,33 +27,19 @@ const labels = {
d: "Label 4",
} as const;

const getDecoration = (decoration: Decoration): TextDecoration | undefined => {
if (decoration == "none") {
return undefined;
}

return decoration === "strike-through" ? "line-through" : decoration;
};

export default function MenusWithFormComponents(): ReactElement {
function CheckboxesDropdown(): ReactElement {
const [bold, setBold] = useState(false);
const [italic, setItalic] = useState(false);
const [decoration, setDecoration] = useState<Decoration>("none");
const [checked, setChecked] = useState(false);
const { rootProps, getProps } = useIndeterminateChecked(values, {
menu: true,
});

return (
<DropdownMenu
id="dropdown-menu-with-form-components"
buttonChildren="Dropdown"
id="dropdown-menu-with-form-components-1"
buttonChildren="Checkboxes"
themeType="outline"
>
<MenuItemTextField
id="dropdown-menu-text-field"
placeholder="Search..."
rightChildren={<SearchSVGIcon />}
/>
<MenuItemSeparator />
<MenuItemCheckbox id="some-group-id-root" {...rootProps}>
Toggle All
</MenuItemCheckbox>
Expand Down Expand Up @@ -82,7 +67,37 @@ export default function MenusWithFormComponents(): ReactElement {
>
Italic
</MenuItemCheckbox>
<MenuItemSeparator />
</DropdownMenu>
);
}

type Decoration = "none" | "underline" | "overline" | "strike-through";

const decorations: readonly Decoration[] = [
"none",
"underline",
"overline",
"strike-through",
];

const getDecoration = (decoration: Decoration): TextDecoration | undefined => {
if (decoration == "none") {
return undefined;
}

return decoration === "strike-through" ? "line-through" : decoration;
};

function RadioAndSwitchDropdown(): ReactElement {
const [decoration, setDecoration] = useState<Decoration>("none");
const [checked, setChecked] = useState(false);

return (
<DropdownMenu
id="dropdown-menu-with-form-components-2"
buttonChildren="Switch/Radio"
themeType="outline"
>
{/* see https://www.w3.org/TR/wai-aria-1.1/#menuitemradio why this is */}
{/* wrapped in a group */}
<MenuItemGroup aria-label="Font Decoration">
Expand All @@ -107,6 +122,23 @@ export default function MenusWithFormComponents(): ReactElement {
>
Do Stuff?
</MenuItemSwitch>
</DropdownMenu>
);
}

function TextFieldAndFileInputDropdown(): ReactElement {
return (
<DropdownMenu
id="dropdown-menu-with-form-components-3"
buttonChildren="Inputs"
themeType="outline"
>
<MenuItemTextField
aria-label="Search"
id="dropdown-menu-search-field"
placeholder="Search..."
rightChildren={<SearchSVGIcon />}
/>
<MenuItemSeparator />
<MenuItemFileInput
id="upload-file-menu-item"
Expand All @@ -121,3 +153,33 @@ export default function MenusWithFormComponents(): ReactElement {
</DropdownMenu>
);
}

const choices = ["phone", "true", "false"] as const;
type Choices = typeof choices[number];

export default function MenusWithFormComponents(): ReactElement {
const [choice, handleChoiceChange] = useSelectState<Choices>("phone");
let renderAsSheet: RenderMenuAsSheet;
if (choice === "phone") {
renderAsSheet = choice;
} else {
renderAsSheet = choice === "true";
}
return (
<MenuConfigurationProvider renderAsSheet={renderAsSheet}>
<Select
id="menu-form-component-sheet"
options={choices}
value={choice}
onChange={handleChoiceChange}
label="renderAsSheet"
style={{ marginBottom: "2rem" }}
/>
<div style={{ display: "flex", gap: "0.5rem", flexWrap: "wrap" }}>
<CheckboxesDropdown />
<RadioAndSwitchDropdown />
<TextFieldAndFileInputDropdown />
</div>
</MenuConfigurationProvider>
);
}
19 changes: 10 additions & 9 deletions packages/documentation/src/components/Demos/Menu/index.tsx
Expand Up @@ -13,12 +13,12 @@ import README from "./README.md";
import SimpleExample from "./SimpleExample";
import simpleExample from "./SimpleExample.md";

import FloatingActionButtonMenus from "./FloatingActionButtonMenus";
import floatingActionButtonMenus from "./FloatingActionButtonMenus.md";

import ConfigurableDropdownMenu from "./ConfigurableDropdownMenu";
import configurableDropdownMenu from "./ConfigurableDropdownMenu.md";

import FloatingActionButtonMenus from "./FloatingActionButtonMenus";
import floatingActionButtonMenus from "./FloatingActionButtonMenus.md";

import SimpleContextMenu from "./SimpleContextMenu";
import simpleContextMenu from "./SimpleContextMenu.md";

Expand All @@ -40,17 +40,18 @@ const demos: DemoConfig[] = [
description: simpleExample,
children: <SimpleExample />,
},
{
name: "Floating Action Button Menus",
description: floatingActionButtonMenus,
children: <FloatingActionButtonMenus />,
emulated: true,
},
{
name: "Configurable Dropdown Menu",
description: configurableDropdownMenu,
children: <ConfigurableDropdownMenu />,
},
{
name: "Floating Action Button Menus",
description: floatingActionButtonMenus,
children: <FloatingActionButtonMenus />,
emulated: { fabOffset: true },
disableCard: true,
},
{
name: "Simple Context Menu",
description: simpleContextMenu,
Expand Down

0 comments on commit c43cd31

Please sign in to comment.