Menu: support ARIA attributes

This commit is contained in:
thislight 2024-11-04 18:03:27 +08:00
parent 8205ff661b
commit c22860a7e3
No known key found for this signature in database
GPG key ID: FCFE5192241CCD4E
2 changed files with 31 additions and 18 deletions

View file

@ -23,6 +23,11 @@
&.e4 { &.e4 {
box-shadow: var(--tutu-shadow-e12); box-shadow: var(--tutu-shadow-e12);
} }
&>.container {
background: var(--tutu-color-surface);
display: contents;
}
} }
dialog.Menu::backdrop { dialog.Menu::backdrop {

View file

@ -3,6 +3,7 @@ import { MenuList } from "@suid/material";
import { import {
createEffect, createEffect,
createSignal, createSignal,
splitProps,
type Component, type Component,
type JSX, type JSX,
type ParentProps, type ParentProps,
@ -16,11 +17,15 @@ import {
export type Anchor = Pick<DOMRect, "top" | "left" | "right"> & { e?: number }; export type Anchor = Pick<DOMRect, "top" | "left" | "right"> & { e?: number };
export type MenuProps = ParentProps<{ export type MenuProps = ParentProps<
open?: boolean; {
onClose?: JSX.EventHandlerUnion<HTMLDialogElement, Event>; open?: boolean;
anchor: () => Anchor; onClose?: JSX.EventHandlerUnion<HTMLDialogElement, Event>;
}>; anchor: () => Anchor;
id?: string;
} & JSX.AriaAttributes
>;
function px(n?: number) { function px(n?: number) {
if (n) { if (n) {
@ -74,6 +79,7 @@ export function createManagedMenuState() {
const Menu: Component<MenuProps> = (props) => { const Menu: Component<MenuProps> = (props) => {
let root: HTMLDialogElement; let root: HTMLDialogElement;
const windowSize = useWindowSize(); const windowSize = useWindowSize();
const [, rest] = splitProps(props, ["open", "onClose", "anchor"]);
const [anchorPos, setAnchorPos] = createSignal<{ const [anchorPos, setAnchorPos] = createSignal<{
left?: number; left?: number;
@ -83,15 +89,16 @@ const Menu: Component<MenuProps> = (props) => {
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
createEffect(() => { createEffect(() => {
switch (anchorPos().e) { if (anchorPos().e)
case 1: switch (anchorPos().e) {
case 2: case 1:
case 3: case 2:
case 3: case 3:
return; case 4:
default: return;
console.warn('value %s is invalid for param "e"', anchorPos().e); default:
} console.warn('value %s is invalid for param "e"', anchorPos().e);
}
}); });
} }
@ -202,12 +209,13 @@ const Menu: Component<MenuProps> = (props) => {
top: px(anchorPos().top), top: px(anchorPos().top),
/* FIXME: the content may be overflow */ /* FIXME: the content may be overflow */
}} }}
role="presentation"
tabIndex={-1}
{...rest}
> >
<div <div
style={{ class="container"
background: "var(--tutu-color-surface)", role="presentation"
display: "contents"
}}
> >
<MenuList>{props.children}</MenuList> <MenuList>{props.children}</MenuList>
</div> </div>