vaadin / hilla

Build better business applications, faster. No more juggling REST endpoints or deciphering GraphQL queries. Hilla seamlessly connects Spring Boot and React to accelerate application development.
https://hilla.dev
Apache License 2.0
864 stars 58 forks source link

Allow defining custom menu metadata #2564

Open Legioth opened 1 week ago

Legioth commented 1 week ago

Describe your motivation

Custom menu building logic would benefit from a way of defining custom metadata in the menu configuration. As an example, you might want to manually define a hierarchy or provide an additional row of text that should be shown separately from the view title.

Describe the solution you'd like

The initial FS router design suggested that unknown properties from export const config would just be passed through as-is so that they could be used in various parts of the system (not only for generating the menu). This does currently not seem to work as it was defined in the design.

After further consideration, I think it might be better to designate a specific property for this purpose since that makes the type definitions less unruly and removes concerns for backwards compatibility if we introduce new properties in ViewConfig. There would thus be a detail?: unknown property in ViewConfig and a corresponding property in MenuItem. createMenuItems could have a type parameter for asserting the detail type.

I could then do something like this in my view:

export const config: ViewConfig = { 
  title: 'Foo',
  detail: { description: 'Bar'} as MyViewDetails
 };

And render the menu like this:

{createMenuItems<MyViewDetails>().map(({ to, title, icon, detail}) => (
  <SideNavItem path={to} key={to}>
    {icon ? <Icon src={icon} slot="prefix"></Icon> : <></>}
    {title}<span>{detail.description}</span>
  </SideNavItem>
))}

Describe alternatives you've considered

The icon string can be abused to pass arbitrary data as long as you properly extract values out of the value when rendering the menu item.

Additional context

No response