GithubHelp home page GithubHelp logo

Comments (1)

corymharper avatar corymharper commented on September 22, 2024

Right now I'm leaning towards the best design being to add an option submenu: boolean = false. When enabled two new controls would be added, which are detailed in the issue description for the right arrow and the left arrow, no new work would really need to be done for escape. When submenu was true, instead of returning buttonProps from the hook for the menu button we would return parentProps, which would be shaped like the following:

type ParentProps = {
        onKeyDown: (e: React.KeyboardEvent | React.MouseEvent) => void;
        onClick: (e: React.KeyboardEvent | React.MouseEvent) => void;
        tabIndex: -1;
        ref: React.RefObject<T>;
        role: 'menuitem';
        'aria-haspopup': true;
        'aria-expanded': boolean;
};

Very similar to buttonProps with some small differences. On the users side, it would be expected they'd be using the hook in some fashion similar to this:

div[role='menu'] {
    visibility: hidden;
}

div[role='menu'].visible {
    visibility: visible;
}
// Inner menu
const Submenu = React.forwardRef((props: { 
    parentMenuItem: {
        text: string;
        children: { text: string }[];
    },
    ...props,
}, ref) => {
    const { parentProps, itemProps, isOpen } = useDropdownMenu(props.parentMenuItem.children.length, { submenu: true });
    
    return (
        <React.Fragment>
            <a {...parentProps} ref={ref}>Parent menu item</a>

            <div className={isOpen ? 'visible' : ''} role='menu'>
                {props.parentMenuItem.children.map((child, i) =>
                    <a {...itemProps[i]}>{child.text}</a>
                )}
            </div>
        </React.Fragment>
    );
})


// Outer menu
const DropdownMenu = () => {
    const items = [
        {
            text: 'I am a submenu',
            children: [
                {
                    text: 'I am a child of a submenu'
                }
        }
    ];

    const { buttonProps, itemProps, isOpen } = useDropdownMenu(items.length);

    return (
        <React.Fragment>
            <button {...buttonProps}>Example</button>

            <div className={isOpen ? 'visible' : ''} role='menu'>
                    <Submenu {...itemProps[0]} parentMenuItem={items[0]}  />
            </div>
        </React.Fragment>
    );
}

There's probably some issues with what I've drafted above but that would be the general idea, keep the hook mostly the same, implement the new submenu option and related behavior, then expect developer's to leverage that behavior by encapsulating their submenus into their own components. This leverages all the behavior built into the hook already, and still does a lot of work for developers wanting to build menus with submenus while using our hook.

from react-accessible-dropdown-menu-hook.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.