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 specificTextField
).
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:
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:
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
);
What if we need to use different configurations for a component, depending on where it's used?
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";