@bento/box
v0.2.0
Published
Shared context for Bento components
Readme
Box
The @bento/box package provides the shared React context that is used throughout
the Bento component ecosystem. It includes the Box context for managing component
environment and slots, and the Slot component for easily passing slot props to children.
[!DANGER]
The
Boxcontext is not meant to be used directly in your application. It is used internally by the Bento component ecosystem to manage the component environment and slots.
Installation
To install the package, use the following command:
npm install --save @bento/boxSlot Component
The Slot component is a convenience wrapper that simplifies passing slot props to
children via the Box context. This is particularly useful when building coordinator
components that need to distribute props to multiple children through the slot system
and does not introduce children as part of it's composition.
[!DANGER]
You should be using the
slotsprops instead of theSlotcomponent. This component is only meant to be used when composing components that do not introduce their own children as part of it's composition.
Basic Usage
import { Slot } from '@bento/box';
const Example = withSlots('Example', function MyComponent(args) {
const { props } = useProps(args);
const slots = {
trigger: { onClick: handleClick },
content: { role: 'dialog' }
};
return (
<Slot slots={slots}>
{props.children}
</Slot>
);
}How It Works
The Slot component:
- Receives a
slotsprop containing slot assignments - Merges these slots with any existing slots from parent Box context
- Provides the merged context to children via
Box.Provider - Preserves all other Box context properties (env, namespace, override flags)
Children that use the slot prop (via @bento/slots) or useProps hook will
automatically receive the appropriate slot props.
Use Cases
The Slot component is ideal for:
Coordinator Components: Components that manage state and pass handlers to children
const Example = withSlots('Example', function Overlay(args) {
const { props } = useProps(args);
const slots = {
trigger: { onClick: () => props.onOpenChange(true) },
backdrop: { onClick: () => props.onOpenChange(false) },
content: { role: 'dialog', 'aria-modal': true }
};
return <Slot slots={slots}>{props.children}</Slot>;
});Compound Components: Components that need to distribute props across multiple child types
const Example = withSlots('Example', function Tabs(args) {
const { props } = useProps(args);
const slots = {
tab: {
'aria-selected': (tab) => tab === props.activeTab,
onClick: (tab) => props.onChange(tab)
},
panel: {
hidden: (panel) => panel !== props.activeTab
}
};
return <Slot slots={slots}>{props.children}</Slot>;
});Slot Merging Behavior
When multiple Slot components are nested, slots are merged with child values
taking precedence over parent values:
<Slot slots={{ trigger: { value: 'parent' } }}>
<Slot slots={{ trigger: { value: 'child' } }}>
{/* trigger slot will have value: 'child' */}
</Slot>
</Slot>New slots from children are added to existing parent slots:
<Slot slots={{ trigger: { onClick: handler1 } }}>
<Slot slots={{ content: { role: 'dialog' } }}>
{/* Both trigger and content slots are available */}
</Slot>
</Slot>Context
import { Box } from '@bento/box';The Box context is a React context that provides Bento-specific configuration
to child components. It is typically used internally and does not require direct
interaction in most cases.
- slots: An object used by the
@bento/slotsand@bento/use-propspackages. - env: An object used by the
@bento/environmentcomponent.
The Box context is used to pass down the Bento specific configuration down to
the child components. This is done automatically for you, for the majority of
the cases you don't need to interact or use this context directly in your
application.
The above example would output the following:
defaults
The package exposes a defaults function that will return the default assigned
values for the Box context. You can use this if you need to provide your
components with a custom Box.Provider
import { Box, defaults } from '@bento/box';
import { useContext } from 'react';
function MyComponent() {
return (
<Box.Provider value={defaults()}>
<MyChildComponent />
</Box.Provider>
);
};Slots
The Box context contains a slots object which is consumed by the
@bento/slots and @bento/use-props packages. This object
contains the following properties:
Env
The env object contains @bento/environment specific configuration. The
object contains the following properties:
