SideMenu

Designer doc
SideMenu is used to help user navigate quickly and effciently.

Example

Basic Usage
Normally, it should be rendered inside Sidebar.
View code
Types
There are two types of SideMenu: Primary (default) and Secondary. Secondary is usually rendered after the Primary, and by standard it doesn’t have icons and is not collapsible.
In Secondary, we can also have a <SideMenuTitle level={1}> on top.
View code
Variants
SidebarVariants is used for SideMenu variants. Note that you can specify uncollapsedVariant prop to SidebarCollapse to match the background color.
Primary
Secondary
View code
Scrollable and Stick to Bottom
There is a common use case where we have a second SideMenu sticking to the bottom on the same Sidebar. You can provide grow prop to the first SideMenu so that it fills the remaining space and is scrollable when overflow.
View code
Routing library integrations
Coral SideMenu (or as general) is independent from any routing library like react-router-dom. Otherwise, what do you think will happen to @reach/router user?
Instead, SideMenu API is created with easy integrations with those libraries in mind.
React Router DOM
Each item is highlighted when className of "coral-side-menu__item--selected" is added.
This is an alternative to the selected prop. Regarding accessibility, you don’t need to worry about aria-selected because React Router has added aria-current="page" automatically for you.
Below is an example with React Router’s MemoryRouter to sort of mock the URL instead of using the real one. So, don’t include MemoryRouter in your application, just use your normal BrowserRouter.
@reach/router
data-coral-selected attribute can also be used to highlight selected item. For reach-router, this attribute is slightly easier to integrate with than using className.
Similarly, you can ignore <LocationProvider/> part since it’s just for demonstration purposes.
Note that, by standard, SideMenuGroup should be selected when a child is selected while collapsed. To handle this more easily, SideMenuGroup’s selected prop also accepts a function.
Expand state
SideMenuGroup is expanded by default, you can specify expanded or initialExpanded to modify them.
View code
Disabling items
View code

Accessibility

Normally navigation doesn’t need any special role aside from using nav tag. However, SideMenu has tree structured navigation and resembes more like a menu. Aria roles and attributes follow based on WAI-ARIA specification and example.

Relevant components

API Discussion

Section below just throwing some abstract comparisons with Ant Design Menu. You can read it only if you’re interested.
Coral’s SideMenu API takes different step from Ant Design. Ant Design Menu centralised expanded and selected states into the parent, and thus accepted as a list. However, that kind of API doesn’t integrate nicely with some well-known routing libraries like React Router.
It’s true that this makes Ant Design Menu can support both uncontrolled and controlled, while Coral SideMenu supports only controlled but for each item. Despite that, menu is mainly used for navigation, and doesn’t have much use case for centralised uncontrolled selected state. Keep in mind that it’s different from component like Tabs, because Tabs wraps and decides on which panels are shown, whereas Menu or SideMenu don’t.
The main problem is, if you have that kind of Ant Design Menu API which accepts the selected prop from the wrapping component (Menu), but you most probably want to pass it directly to each Menu.Item in real production app. If you forgot to pass selected prop to Menu to control it, it will assume to be uncontrolled and has their own internal selected state - which is not what we want.
Why Coral’s SideMenu integration is so simple is because the API is designed based some grasp of the React Router, but still keeping it independent and flexible (it can even cover Ant Design’s Menu features too). Compared to Ant Design, you basically need to either style from scratch or calculate the selectedKeys again.
In Ant Design, they also missed one great opportunity from their API design is roving tabindex feature. However, they don’t even make it tabbable.

References

API

SideMenu
Prop nameTypeDefaultDescription
asany
Tag or component, but a simple tag (i.e. built-in components, e.g. div, span) is recommended.
collapsedboolean
growboolean
navPropsNavProps
typeSideMenuTypesprimary
variantSidebarVariants
SideMenuGroup
Prop nameTypeDefaultDescription
asany
Tag or component, but a simple tag (i.e. built-in components, e.g. div, span) is recommended.
disabledboolean
Equivalent to button's disabled property.
expandedboolean
iconReactNode
initialExpandedbooleantrue
keyboardClickKeysstring[]
labelReactNode
labelPropsLabelProps
listItemPropsSideMenuGroupListItemProps
Props passed to the top component, containing the menuitem and menu.
Note that rest of props are forwarded to menuitem.
listPropsSideMenuGroupListProps
Props passed to the menu, which wraps the children.
Note that rest of props are forwarded to menuitem.
menuLabelPropsHTMLAttributes<HTMLDivElement> & { as?: any; ref?: Ref<HTMLDivElement>; }
menuPropsOmit<MenuProps, "button"> & { ref?: Ref<HTMLDivElement>; }
onBlurFocusEventHandler<HTMLDivElement>
onClickMouseEventHandler<HTMLDivElement>
onExpandedChange(expanded: boolean) => void
onKeyDownKeyboardEventHandler<HTMLDivElement>
onKeyUpKeyboardEventHandler<HTMLDivElement>
onMouseDownMouseEventHandler<HTMLDivElement>
onMouseLeaveMouseEventHandler<HTMLDivElement>
onMouseUpMouseEventHandler<HTMLDivElement>
onReleaseEventHandler<SyntheticEvent<HTMLDivElement, Event>>
Callback that's triggered after click i.e. mouseup and keyup of enter or space.
onTouchEndTouchEventHandler<HTMLDivElement>
onTouchStartTouchEventHandler<HTMLDivElement>
selectedboolean | (({ childrenVisible }: { childrenVisible: boolean; }) => boolean)
SideMenuGroupItem
Prop nameTypeDefaultDescription
asany
Tag or component, but a simple tag (i.e. built-in components, e.g. div, span) is recommended.
disabledboolean
labelPropsLabelProps
listItemPropsSideMenuGroupItemListItemProps
selectedboolean
SideMenuItem
Prop nameTypeDefaultDescription
asany
Tag or component, but a simple tag (i.e. built-in components, e.g. div, span) is recommended.
disabledboolean
iconReactNode
labelPropsLabelProps
listItemPropsSideMenuItemListItemProps
selectedboolean
tooltipPropsTooltipProps & { ref?: Ref<HTMLDivElement>; }
SideMenuTitle
Prop nameTypeDefaultDescription
asany
Tag or component, but a simple tag (i.e. built-in components, e.g. div, span) is recommended.
dividerboolean
levelTitleLevel2
    Example
    Example
    Basic Usage
    Basic Usage
    Types
    Types
    Variants
    Variants
    Scrollable and Stick to Bottom
    Scrollable and Stick to Bottom
    Routing library integrations
    Routing library integrations
    Expand state
    Expand state
    Disabling items
    Disabling items
    Accessibility
    Accessibility
    Relevant components
    Relevant components
    API Discussion
    API Discussion
    References
    References
    API
    API
    SideMenu
    SideMenu
    SideMenuGroup
    SideMenuGroup
    SideMenuGroupItem
    SideMenuGroupItem
    SideMenuItem
    SideMenuItem
    SideMenuTitle
    SideMenuTitle
Coral is a thoroughly developed design system widely adopted by developers and designers for creating beautiful and user-friendly Sea internal products.

Copyright © 2018-2025 Sea Labs