Improve docs + container props on Grid + Flex
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
@@ -282,21 +282,16 @@ export const BgAutoIncrement = meta.story({
|
||||
render: args => (
|
||||
<Flex direction="column">
|
||||
<div style={{ maxWidth: '600px', marginBottom: '16px' }}>
|
||||
Nested Flex components automatically increment their neutral background
|
||||
level. No explicit bg prop is needed on inner Flex components.
|
||||
Flex is a layout primitive and is transparent to the bg system by
|
||||
default. Only an explicit bg prop establishes a new bg level. Nested
|
||||
Flex components without a bg prop inherit the parent context unchanged.
|
||||
</div>
|
||||
<Flex {...args} bg="neutral-1" direction="column">
|
||||
<div>Neutral 1 (explicit)</div>
|
||||
<Flex {...args} direction="column">
|
||||
<div>Auto (becomes neutral-2)</div>
|
||||
<Flex {...args} direction="column">
|
||||
<div>Auto (becomes neutral-3)</div>
|
||||
<Flex {...args} direction="column">
|
||||
<div>Auto (becomes neutral-4)</div>
|
||||
<Flex {...args} direction="column">
|
||||
<div>Auto (stays neutral-4 - capped)</div>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex {...args} bg="neutral-2" direction="column">
|
||||
<div>Neutral 2 (explicit)</div>
|
||||
<Flex {...args} bg="neutral-3" direction="column">
|
||||
<div>Neutral 3 (explicit, capped)</div>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
@@ -24,8 +24,11 @@ import { BgProvider, useBg } from '../../hooks/useBg';
|
||||
|
||||
/** @public */
|
||||
export const Flex = forwardRef<HTMLDivElement, FlexProps>((props, ref) => {
|
||||
// Resolve the bg this Flex creates for its children
|
||||
const { bg: resolvedBg } = useBg({ mode: 'container', bg: props.bg });
|
||||
// Only establish bg context when an explicit bg prop is provided.
|
||||
// Flex is a layout primitive — it should be transparent to the bg system by default.
|
||||
const { bg: resolvedBg } = useBg(
|
||||
props.bg !== undefined ? { mode: 'container', bg: props.bg } : undefined,
|
||||
);
|
||||
|
||||
const { classNames, dataAttributes, utilityClasses, style, cleanedProps } =
|
||||
useStyles(FlexDefinition, {
|
||||
|
||||
@@ -182,15 +182,16 @@ export const BgAutoIncrement = meta.story({
|
||||
render: args => (
|
||||
<Flex direction="column">
|
||||
<div style={{ maxWidth: '600px', marginBottom: '16px' }}>
|
||||
Nested Grid components automatically increment their neutral background.
|
||||
Each nested Grid.Item inherits and increments from its parent's bg.
|
||||
Grid is a layout primitive and is transparent to the bg system by
|
||||
default. Only an explicit bg prop establishes a new bg level. Nested
|
||||
grids without a bg prop inherit the parent context unchanged.
|
||||
</div>
|
||||
<Grid.Root {...args} bg="neutral-1">
|
||||
<Grid.Item>Neutral 1 (Grid.Root)</Grid.Item>
|
||||
<Grid.Item>
|
||||
<Grid.Root {...args}>
|
||||
<Grid.Item>Nested: Auto (becomes neutral-2)</Grid.Item>
|
||||
<Grid.Item>Nested: Auto (becomes neutral-2)</Grid.Item>
|
||||
<Grid.Root {...args} bg="neutral-2">
|
||||
<Grid.Item>Nested: neutral-2 (explicit)</Grid.Item>
|
||||
<Grid.Item>Nested: neutral-2 (explicit)</Grid.Item>
|
||||
</Grid.Root>
|
||||
</Grid.Item>
|
||||
</Grid.Root>
|
||||
|
||||
@@ -23,8 +23,11 @@ import styles from './Grid.module.css';
|
||||
import { BgProvider, useBg } from '../../hooks/useBg';
|
||||
|
||||
const GridRoot = forwardRef<HTMLDivElement, GridProps>((props, ref) => {
|
||||
// Resolve the bg this Grid creates for its children
|
||||
const { bg: resolvedBg } = useBg({ mode: 'container', bg: props.bg });
|
||||
// Only establish bg context when an explicit bg prop is provided.
|
||||
// Grid is a layout primitive — it should be transparent to the bg system by default.
|
||||
const { bg: resolvedBg } = useBg(
|
||||
props.bg !== undefined ? { mode: 'container', bg: props.bg } : undefined,
|
||||
);
|
||||
|
||||
const { classNames, dataAttributes, utilityClasses, style, cleanedProps } =
|
||||
useStyles(GridDefinition, {
|
||||
@@ -59,8 +62,11 @@ const GridRoot = forwardRef<HTMLDivElement, GridProps>((props, ref) => {
|
||||
});
|
||||
|
||||
const GridItem = forwardRef<HTMLDivElement, GridItemProps>((props, ref) => {
|
||||
// Resolve the bg this GridItem creates for its children
|
||||
const { bg: resolvedBg } = useBg({ mode: 'container', bg: props.bg });
|
||||
// Only establish bg context when an explicit bg prop is provided.
|
||||
// GridItem is a layout slot — it should be transparent to the bg system by default.
|
||||
const { bg: resolvedBg } = useBg(
|
||||
props.bg !== undefined ? { mode: 'container', bg: props.bg } : undefined,
|
||||
);
|
||||
|
||||
const { classNames, dataAttributes, utilityClasses, style, cleanedProps } =
|
||||
useStyles(GridItemDefinition, {
|
||||
|
||||
@@ -21,7 +21,6 @@ import type { ToggleButtonProps } from './types';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
import { ToggleButtonDefinition } from './definition';
|
||||
import styles from './ToggleButton.module.css';
|
||||
import { useBg } from '../../hooks/useBg';
|
||||
|
||||
/** @public */
|
||||
export const ToggleButton = forwardRef(
|
||||
@@ -36,14 +35,11 @@ export const ToggleButton = forwardRef(
|
||||
|
||||
const { children, className, iconStart, iconEnd, ...rest } = cleanedProps;
|
||||
|
||||
const { bg } = useBg({ mode: 'leaf' });
|
||||
|
||||
return (
|
||||
<AriaToggleButton
|
||||
className={clsx(classNames.root, styles[classNames.root], className)}
|
||||
ref={ref}
|
||||
{...dataAttributes}
|
||||
{...(bg ? { 'data-on-bg': bg } : {})}
|
||||
{...rest}
|
||||
>
|
||||
{renderProps => {
|
||||
|
||||
@@ -62,11 +62,9 @@ const BgContext = createVersionedContext<{
|
||||
* Increments a neutral bg level by one, capping at 'neutral-3'.
|
||||
* Intent backgrounds (danger, warning, success) pass through unchanged.
|
||||
*
|
||||
* Only used by container components for auto-increment. The 'neutral-4'
|
||||
* level is reserved for leaf components and is never set on containers.
|
||||
* The 'neutral-4' level is reserved for leaf component CSS and is never
|
||||
* set on containers.
|
||||
*
|
||||
* @param bg - The current bg value
|
||||
* @returns The incremented bg value
|
||||
* @internal
|
||||
*/
|
||||
function incrementNeutralBg(
|
||||
@@ -81,44 +79,29 @@ function incrementNeutralBg(
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the bg value for a container component.
|
||||
* Resolves the bg for a container component.
|
||||
*
|
||||
* - If an explicit bg prop is provided, use that.
|
||||
* - If no bg prop is provided but there is a parent context, auto-increment from parent.
|
||||
* - If no bg prop and no context, return undefined (no bg).
|
||||
* Uses the explicit `bg` prop if provided. Otherwise auto-increments from
|
||||
* the parent context, capping at `neutral-3`. Returns undefined when there
|
||||
* is no prop and no parent context.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function resolveBgForContainer(
|
||||
contextBg: ContainerBg | undefined,
|
||||
function resolveContainerBg(
|
||||
context: BgContextValue,
|
||||
propBg: ContainerBg | undefined,
|
||||
): ContainerBg | undefined {
|
||||
): BgContextValue {
|
||||
// Explicit bg prop takes priority
|
||||
if (propBg !== undefined) {
|
||||
return propBg;
|
||||
return { bg: propBg };
|
||||
}
|
||||
|
||||
// No explicit bg: auto-increment from context if available
|
||||
if (contextBg === undefined) {
|
||||
return undefined;
|
||||
if (context.bg === undefined) {
|
||||
return { bg: undefined };
|
||||
}
|
||||
|
||||
return incrementNeutralBg(contextBg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the bg value for a leaf component.
|
||||
*
|
||||
* Returns the parent context bg unchanged. The leaf component's CSS
|
||||
* handles the visual step-up (e.g. on neutral-1 surface → use neutral-2 tokens).
|
||||
* If no context, returns undefined.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function resolveBgForLeaf(
|
||||
contextBg: ContainerBg | undefined,
|
||||
): ContainerBg | undefined {
|
||||
return contextBg;
|
||||
return { bg: incrementNeutralBg(context.bg) };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,9 +120,6 @@ export const BgProvider = ({ bg, children }: BgProviderProps) => {
|
||||
/**
|
||||
* Hook to access and resolve the current bg context.
|
||||
*
|
||||
* All bg resolution logic lives here — callers only need to specify the mode
|
||||
* and (for containers) the explicit bg prop value.
|
||||
*
|
||||
* - **Container mode** — uses explicit `bg` if provided, otherwise auto-increments
|
||||
* from parent context. Caps at `neutral-3`.
|
||||
* - **Leaf mode** — returns the parent context bg unchanged. No prop needed.
|
||||
@@ -157,15 +137,17 @@ export const useBg = (options?: UseBgOptions): BgContextValue => {
|
||||
return context;
|
||||
}
|
||||
|
||||
// Leaf mode: return the parent context bg unchanged.
|
||||
// The leaf component's CSS handles the visual step-up.
|
||||
if (options.mode === 'leaf') {
|
||||
return context;
|
||||
}
|
||||
|
||||
// Resolve responsive prop value to a scalar for the current breakpoint
|
||||
const resolvedPropBg =
|
||||
const propBg =
|
||||
options.bg !== undefined
|
||||
? resolveResponsiveValue(options.bg, breakpoint)
|
||||
: undefined;
|
||||
|
||||
if (options.mode === 'leaf') {
|
||||
return { bg: resolveBgForLeaf(context.bg) };
|
||||
}
|
||||
|
||||
return { bg: resolveBgForContainer(context.bg, resolvedPropBg) };
|
||||
return resolveContainerBg(context, propBg);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user