Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrospective doc about component structure #1053

Open
mfal opened this issue Dec 9, 2024 · 0 comments
Open

Retrospective doc about component structure #1053

mfal opened this issue Dec 9, 2024 · 0 comments
Labels
documentation Improvements or additions to documentation

Comments

@mfal
Copy link
Member

mfal commented Dec 9, 2024

Flow encourages the nesting of components to build your UI. This is a small doc about why decided to do so. The following code examples are referred to in the explanation.

// Flow
import Button from "@mittwald/flow-react-components/Button";
import { IconNotification } from "@mittwald/flow-react-components/Icons";
import CounterBadge from "@mittwald/flow-react-components/CounterBadge";

<Button aria-label="Notifications: 7">
  <IconNotification />
  <CounterBadge count={7} />
</Button>

vs.

// Not Flow
import Button from "@mittwald/flow-react-components/Button";
import { IconNotification } from "@mittwald/flow-react-components/Icons";

<IconButton label="Benachrichtigung" icon="Notification" counterBadge={7} />

Logical

Component libraries are generally based on nesting components to build up larger components. This is a commonly used, effective pattern that also transports an easy to understand mental model. Because of this we are supporting this model in Flow as well. For example if you put a CounterBadge inside a Button, this CounterBadge is automatically positioned a the top right, as you might would expect it.

Readable

We asked our frontend devs what is more readable at the end:

  1. putting sub-components into props like the icon in the example or
  2. putting the icon as a child into the component

We decided that 2) is more readable, especially with more sub-components.

Reusability

Developers often build their own components to reuse them, or to split up the implementation. For example, if there is already an <UnreadNotificationsCounter />, which loads the count from the API and displays it in a CounterBadge, this component can just used as a child in the Button.

<Button>
  <IconNotification />
  <UnreadNotificationsCounter />
</Button>

Suspense-/ ErrorBoundaries

Only with the "components-approach" it is possible to wrap child components into Loading- or ErrorBoundaries.

<Button>
  <IconNotification />
  <Suspense>
    <UnreadNotificationsCounter />
  </Suspense>
</Button>

Bloated props interface

When components starting to natively support features of other components, their props interface gets bloated. If you look at the counterBadge={7} in the example, one might think "Hey, this is just one prop more, and it is easy to understand!". But what about if the CounterBadge supports more properties, than just the count? Each supported prop must have its counter[counterProp] part in the Button component and potentially other parents.

Bloated overall components vs. all-mighty components

If Flow would offer special components for each use case, it must support an IconButton, CounterBadgeButton and strictly speaking IconCounterBadgeButton. This would potentially result in a lot of components.

And what about supporting everything in the Button itself? This tends to very large all-mighty components that do not have a clear scope and an overloaded implementation.

Children in sub components

Only with the "components-approach" it is possible to use children in sub components.

// Flow
import Button from "@mittwald/flow-react-components/Button";
import { Icon } from "@mittwald/flow-react-components/Icon";
import { IconStar } from "@tabler/icons-react";
import CounterBadge from "@mittwald/flow-react-components/CounterBadge";

<Button aria-label="Notifications: 7">
  <Icon>
    <IconStar />
  </Icon>
  <CounterBadge count={7} />
</Button>

Build your own

If you often use a special combination of components in your UI, you just can build your own components with the props you need.

@mfal mfal added the documentation Improvements or additions to documentation label Dec 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant