Skip to main content

Configuration

In addition to the design tokens, covering aspects related to the common design system "foundations", each component exposes an interface to configure its specific features and behaviors.

Bento has been conceived as a design system builder, meaning that it allows a certain degree of flexibility in defining how your components should look like and behave (to adapt them to different scenarios), while remaining strict when it comes to using them in your application once configured.

Props vs Configuration?

We want Bento components to be customizable for each project, but we want them to be strict when using them in the application.

For instance, we want to customize the border radius of TextField for the project, but we don't want to allow this to be set whenever we're using TextField.

So Bento is designed following this strategy:

  • The configuration is everything we want to customize for a project, and never think about again (e.g. the border radius of TextField).
  • Props are instead things we want to configure when we're using the component (e.g. the placeholder of a specific TextField).

Bento comes with a default configuration, but you can override it (partially or entirely) by passing a configuration object to BentoProvider.

Let's say, for example, our designers decided all the actions (e.g. the buttons at the end of a form) should be left-aligned, with the primary action on the left.

We can configure this by setting buttonsAlignment and primaryPosition for the Actions component:

my-project/design-system/src/index.tsx
import { createBentoProvider } from "@buildo/bento-design-system";

export const BentoProvider = createBentoProvider({
actions: {
buttonsAlignment: "left",
primaryPosition: "left",
},
});

export { Actions, Modal /*...*/ } from "@buildo/bento-design-system";

This way, not only the Actions component will always respect the configuration we passed (without the need to specify the behavior every time we use it via props), but also any other component using Actions internally (like Modal) will follow the same configuration.

If you need multiple variants of a component, you can use the withBentoConfig utility. For example, suppose you want two types of Chip, one pill-shaped and one square-shaped:

my-project/design-system/src/index.tsx
import { Chip } from "@buildo/bento-design-system";

export const { Chip: SquaredChip } = withBentoConfig(
{
chip: { radius: 0 },
},
Chip
);

export const { Chip: PillChip } = withBentoConfig(
{
chip: { radius: "circledX" },
},
Chip
);
Details

What if we need to use different configurations for a component, depending on where it's used? Let's say the left-aligned configuration for Actions from the previous example should affect all the usages in the app except for the modals.

Again, we can use withBentoConfig to get different sets of components:

// both Actions and Form exported from here will use the left-aligned Actions
import { Actions, ActionsConfig, Form, PartialBentoConfig } from "@buildo/bento-design-system";

const leftAlignedActionsConfig: PartialBentoConfig = {
actions: {
buttonsAlignment: "left",
primaryPosition: "left",
},
};

// The exported Actions will be left-aligned
export const Actions = withBentoConfig(leftAlignedActionsConfig, Actions);

// The exported Form will use left-aligned Actions
export const Form = withBentoConfig(leftAlignedActionsConfig, Form);

// Modal, instead, will use the default Actions component as configured by BentoProvider
export { Modal } from "@buildo/bento-design-system";