emdgroup-liquid / liquid

UI component library for the Liquid Design System of Merck KGaA, Darmstadt, Germany
https://liquid.emd.design/liquid/
Other
73 stars 11 forks source link

Demonstrate usage with React Router #461

Closed zemirco closed 1 year ago

zemirco commented 1 year ago

React Router is more or less the default router in the React ecosystem. When building applications a developer usually faces two challenges:

  1. How do I highlight the current route in the main navigation?
  2. How do I build the breadcrumb dynamically?

Since those two questions regularly come up it would be nice a have them solved centrally, maybe as part of the documentation. I've seen that the ld-sidenav component even features multiple levels. In your docs you have

- Mathematical foundations
  - Coding theory
  - Game theory
  - Discrete Mathematics
  - Graph theory
  - Mathematical logic
  - Number theory
- Algorithms and data structures
- ... 

I would image that the corresponding URLs would look very similar, e.g.

/foundations
/foundations/coding-theory
/founcations/game-theory
/foundations/discrete-mathematics
/foundations/graph-theory
...

When I go directly to the URL /foundations/discrete-mathematics I would expect the navigation item "Discrete Mathematics" to be highlighted. The second level of the navigation is visible and I should see the back button to go to the first level.

image

How would I do that? That would be great to have in the documentation.

A similar feature request is more directed at the ld-breadcrumbs component. Let's say I have an application that is similar to GitHub, i.e. organizations, users, repos, {settings, security, insights, etc.}. The URL would be something like this

/organizations/:orgId/users/:userId/repos/:repoId/settings

How would I dynamically build the breadcrumb so that it shows something like

Organizations > Merck KGaA > Users > Mirco > Repositories > mycode > Settings

Thank you very much! You're doing great.

borisdiakur commented 1 year ago

Hi @zemirco πŸ‘‹ Thank you for this issue πŸ™

How do I highlight the current route in the main navigation?

One of our sandbox apps covers this exact use case of the ld-sidenav component: The nav items are highlighted based on the current route. Although the sandbox app is using Solid.js, usage with React and react-router should be pretty similar. Here are the relevant places in the code:

I fully understand that looking at a Solid based example signifies an additional context switch for a React developer and with regard to #459 we may need additional documentation and maybe a port of the Solid based sandbox app.

How would I dynamically build the breadcrumb so that it shows something like

This is also related to #459 I think. It looks like we need some React specific examples in our docs. But in general, to answer your question, something like this should work:

<LdBreadcrumbs>
  {crumbs.map(crumb => (
    <LdCrumb href={crumb.path}>{crumb.title}</LdCrumb>
  ))}
</LdBreadcrumbs>

I'll keep this issue open for now, though we may close it in favor of #459 in the future.

zemirco commented 1 year ago

Thank you for linking to the example. It's great but it took me some time to realize I don't really need an account 😊 I had to read through the source code. Maybe you could make it a bit clearer and explain that there is no communication with any backend and also the user is simply stored in localStorage. However it already has the responsive side navigation that requested in #460 πŸŽ‰ Awesome πŸ₯³

I think the breadcrumbs are a bit more complicated than your example. You could have a URL like

/organizations/merck-kgaa/users/654987/repos/922a1ba9-1e3a-4312-9381-f55f51986016/settings

It's not enough to simply take the URL, clean it, split and build the breadcrumb

Organizations > Merck KGaA > Users > 654987 > Repositories > 922a1ba9-1e3a-4312-9381-f55f51986016 > Settings

There is some data fechting involved and usually we'd like to replace UUIDs and unique identifiers with real names and descriptions, e.g

654987 -> Mirco 922a1ba9-1e3a-4312-9381-f55f51986016 -> mycode

In the end the breadcrumb should look more like this.

Organizations > Merck KGaA > Users > Mirco > Repositories > mycode > Settings

In addition the last crumb is usually not a link and not clickable compared to all previous crumbs that must be links. So there is also some logic involved. That's why it would be nice to see a working example with the latest React Router v6.

borisdiakur commented 1 year ago

There is some data fechting involved and usually we'd like to replace UUIDs and unique identifiers with real names and descriptions, e.g 654987 -> Mirco 922a1ba9-1e3a-4312-9381-f55f51986016 -> mycode

I understand that in some cases, data needs to be transformed (i18n would be a typical use case). However, the breadcrumb is "stupid" by design. In other words: it's not the breadcrumb's responsibility to transform and prepare data. This is business logic that should happen beforehand. So in your React app, you could have a useEffect hook which updates a crumbs list which is then fed to the breadcrumb component.

In addition the last crumb is usually not a link and not clickable compared to all previous crumbs that must be links. So there is also some logic involved.

Yes, this is a responsibility of the breadcrumb component and our component does deactivate the last link automatically, so you don't have to do anything here.

That said, we'll double check anyway if it makes sense to have more advanced examples for the breadcrumb component in a React context with the latest React router for sure.

zemirco commented 1 year ago

Good point!

i18n is indeed important when you're building the breadcrumb. You're also right when you say that most of the components are "dumb" and it's right to keep them this way.

Maybe we can solve this issue within a demo project where we compose all of your components into a single complex application that goes beyond the dumb components and shows how to integrate them with the "smart" parts and the business logic.

Now that I think about it ... one common requirement is also authentication and authorization. Many of our apps use OpenID Connect and JWT. Basically how can we sign in a user, how can we protect routes, how can we access user information and the token across our app, how can we logout a user, etc. It sounds very basic but it's a fundamental part of any application and it would be great to solve this centrally having a demo project. At the same time it is easy to get wrong. So we should provide strong examples and give them to the teams.

toastedtoast commented 1 year ago

Hey @zemirco, you are right and we are perfectly aligned with the need for these examples and guides. We are currently discussing internally how to organize this kind of content as much of is not fundamentally connected to liquid oxygen as a component library.

Anyways, as the overall goal of Liquid Design is to improve and unify the user experience of digital products @ Merck we want to come up with these guides and starter-kits as soon as possible.

Do you have any insights or recommendations what you and / or our users would help most to have an easy start with liquid oxygen? Are the sandboxes helpful? Or should we think about more sophisticated step by step guides for various project setups? We consider creating a blog / series of how-tos. If so, which frameworks would you expect (e.g. CRA, vite, Nexjs, ...)?

We are very grateful for your feedback! Thanks!

zemirco commented 1 year ago

Hey @toastedtoast ,

good questions!

I believe many teams simply use https://create-react-app.dev/.

The sandboxes are super great. They could need some more documentation though πŸ˜… I tried the solid tailwind example (https://stackblitz.com/github/emdgroup-liquid/liquid-sandbox-solid-tailwind?file=README.md) the other day and stopped immediately when I saw the user login πŸ˜ͺ. Add some information how the login works either to the Readme, or to the login screen or to your docs https://liquid.merck.design/liquid/guides/sandbox-applications/. Once you've taken the hurdle of the login the application is super great and has many things we also need in our own apps πŸŽ‰. Unfortunately I believe many people haven' t seen this example yet. The data visualisation (https://liquid.merck.design/liquid/data-visualization/getting-started/) has a real login and that's why I believed the sandbox login is also real.

image

Other open source projects provide integration examples in their docs, e.g. React Query integration with React Router and vice versa https://reactrouter.com/en/main/guides/data-libs https://tanstack.com/query/latest/docs/react/examples/react/react-router

To really accelerate application development and ensure we build high quality products it would be great to have a very robust foundation project having things built-in like

This would certainly go beyond "dumb" components and providing the UI framework, but since every team needs this it would really help us. Otherwise teams always start from scratch and have to reinvent to wheel.

You could provide such an example using a dedicated git repo, IaC via AWS CloudFormation / cdk and AWS Cognito for user management.

borisdiakur commented 1 year ago

Just a quick note about CRA. Since our team uses Tailwind CSS a lot, we currently do not recommend using CRA. From the Tailwind CSS docs:

Create React App does not support custom PostCSS configurations and is incompatible with many important tools in the PostCSS ecosystem, like postcss-import.

We highly recommend using Vite, Parcel, Next.js, or Remix instead of Create React App. They provide an equivalent or better developer experience but with more flexibility, giving you more control over how Tailwind and PostCSS are configured.

Therefore we have just recently updated our React sandbox app to use Vite instead.

toastedtoast commented 1 year ago

We added a recipe for using react router with LdSidenav and LdBreadcrumbs. See #554. Framework recipes are currently added to the getting started section but will move to a separate Cookbook section later on.

zemirco commented 1 year ago

Thank you very much! It's great πŸ‘