v1.1.0

Box

Installation

Install yarn add @spark-web/box
Source GitHub.com
Bundle unpkg.com

The Box component is our lowest-level primitive. The goal of the Box component is to map props to our tokens so that consumers should be able to use these props for all of their styling needs. Ideally, you shouldn't need to use the className or style prop at all. Internally, all Spark Web components are composed using the Box component.

Box is a polymorphic component (meaning it will render different elements depending on what is provided to the as prop). If no as prop is provided, Box will render a div.

We also spread in consumer props, so any valid HTML attributes are also valid for Box. Due to some clever TypeScript we can even warn you when you use an invalid combination of props.

<Box as="input" href="https://spark.brighte.com.au" />

In the example above, you should see a "red squiggly" under the href element with the following error:

Type '{ as: "input"; href: string; }' is not assignable to type 'IntrinsicAttributes & { as?: "input" | undefined; ref?: Ref<HTMLInputElement> | undefined; } & Omit<Pick<DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof InputHTMLAttributes<...>>, "as"> & { ...; } & UnresponsiveBoxProps & ResponsiveBoxProps'.
Property 'href' does not exist on type 'IntrinsicAttributes & { as?: "input" | undefined; ref?: Ref<HTMLInputElement> | undefined; } & Omit<Pick<DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "key" | keyof InputHTMLAttributes<...>>, "as"> & { ...; } & UnresponsiveBoxProps & ResponsiveBoxProps'. Did you mean 'ref'?

Unfortunately TypeScript errors can be pretty cryptic sometimes 🙃.

Pro tip: copying the error message and pasting it into TypeScript Error Translator can sometimes help make these errors easier to understand.

A minimal CSS reset is also applied to each element rendered with Box. This helps prevent styles from "leaking" out and effecting other elements (which should make it easier to incrementally adopt Spark Web into existing projects). If you provide a non-Spark component to the as prop instead of an element, it is recommended that you also use the asElement prop so the appropriate styles can be applied.

Examples

Responsive styles

Most of Box's props accept a string value (usually corresponding to a token), we also accept an object for responsive styles.

1
2
3

Resize your browser to see the example above change at different breakpoints.

Backgrounds

Box stores the background in a provider. We can use this to work out what colour to use by default for text elements.

surface
positiveLight
infoLight
cautionLight
criticalLight
muted
positive
info
caution
critical

Notice that the Text in the example above doesn't use the tone prop, the colour is worked out using the BackgroundProvider in Box.

Note: this will only work if you use the background prop. If you try to style the background colour in any other way the Text component will not know what colour the background is and so cannot invert its colour to make sure that its contents are readable.

<Box style={{ background: 'midnightblue' }} padding="large">
<Text>Good luck reading this!</Text>
</Box>

Props

PropTypeDescription

alignItems?

ResponsiveProp<"center" | "stretch" | "start" | "end">

Controls the alignment of items on the cross axis.

alignSelf?

ResponsiveProp<"center" | "stretch" | "start" | "end">

Overrides the parent's `align-items` value. Controls the alignment of

item's on the cross axis.

background?

"body" | "input" | "infoLight" | "criticalLight" | "positiveLight" | "cautionLight" | "muted" | "disabled" | "backdrop" | "surface" | "surfaceMuted" | "surfacePressed" | "fieldAccent" | ... 23 more ... | "positiveMuted"

The `background` property sets the background color of an element.

border?

ResponsiveProp<"fieldAccent" | "accent" | "accentMuted" | "neutral" | "primary" | "secondary" | "caution" | "cautionMuted" | "critical" | "criticalMuted" | "info" | "infoMuted" | "positive" | ... 9 more ... | "secondaryActive">

The `border` property sets the color of an element's border.

borderBottom?

ResponsiveProp<"fieldAccent" | "accent" | "accentMuted" | "neutral" | "primary" | "secondary" | "caution" | "cautionMuted" | "critical" | "criticalMuted" | "info" | "infoMuted" | "positive" | ... 9 more ... | "secondaryActive">

The `border` property sets the color of an element's border on the bottom side.

borderLeft?

ResponsiveProp<"fieldAccent" | "accent" | "accentMuted" | "neutral" | "primary" | "secondary" | "caution" | "cautionMuted" | "critical" | "criticalMuted" | "info" | "infoMuted" | "positive" | ... 9 more ... | "secondaryActive">

The `border` property sets the color of an element's border on the left side.

borderRadius?

ResponsiveProp<"small" | "medium" | "large" | "full">

The `borderRadius` property rounds the corners of an element's outer

border edge.

borderRight?

ResponsiveProp<"fieldAccent" | "accent" | "accentMuted" | "neutral" | "primary" | "secondary" | "caution" | "cautionMuted" | "critical" | "criticalMuted" | "info" | "infoMuted" | "positive" | ... 9 more ... | "secondaryActive">

The `border` property sets the color of an element's border on the right side.

borderTop?

ResponsiveProp<"fieldAccent" | "accent" | "accentMuted" | "neutral" | "primary" | "secondary" | "caution" | "cautionMuted" | "critical" | "criticalMuted" | "info" | "infoMuted" | "positive" | ... 9 more ... | "secondaryActive">

The `border` property sets the color of an element's border on the top side.

borderWidth?

ResponsiveProp<"large" | "standard">

The `borderWidth` property sets the width of an element's border.

bottom?

ResponsiveProp<0>: 0 | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", 0>>

The `bottom` property participates in setting the vertical position of a

positioned element. It has no effect on non-positioned elements.

children?

ReactNode: string | number | false | true | {} | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal

Children element to be rendered inside the component.

className?

string

Custom css styles.

cursor?

"default" | "pointer"

The `cursor` property sets the type of mouse cursor, if any, to show when

the mouse pointer is over an element.

data?

DataAttributeMap

Sets data attributes on the component.

display?

ResponsiveProp<"flex" | "none" | "block" | "inline" | "inline-block" | "inline-flex">

Sets whether an element is treated as a block or inline element and the

layout used for its children.

flex?

ResponsiveProp<0 | 1>

The `flex` shorthand property sets how a flex item will grow or shrink to

fit the space available in its flex container.

flexDirection?

ResponsiveProp<"row" | "column" | "rowReverse" | "columnReverse">

Defines the main axis, or how the children are placed.

flexGrow?

ResponsiveProp<0 | 1>

The `flexGrow` property sets the flex grow factor of a flex item main size.

flexShrink?

ResponsiveProp<0 | 1>

The `flexShrink` property sets the flex shrink factor of a flex item. If

the size of all flex items is larger than the flex container, items shrink

to fit according to `flex-shrink`.

flexWrap?

ResponsiveProp<"nowrap" | "wrap">

Allow flex items to flow onto multiple lines.

gap?

ResponsiveProp<"small" | "medium" | "large" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">

The size of the gap between each child element.

height?

ResponsiveSizing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "full" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "full">>

Sets the element's height.

id?

string

An identifier which must be unique in the whole document.

justifyContent?

ResponsiveProp<"center" | "stretch" | "start" | "end" | "spaceBetween">

defines how the browser distributes space between and around content items

along the main-axis.

left?

ResponsiveProp<0>: 0 | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", 0>>

The `left` property participates in specifying the horizontal position of a

positioned element. It has no effect on non-positioned elements.

margin?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `margin` shorthand property sets the margin area on all four sides of

an element at once.

marginBottom?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `marginBottom` property sets the margin area on the bottom side of an

element.

marginLeft?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `marginLeft` property sets the margin area on the left side of an

element.

marginRight?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `marginRight` property sets the margin area on the right side of an

element.

marginTop?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `marginTop` property sets the margin area on the top side of an

element.

marginX?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `marginY` shorthand property sets the margin area on the left and

right of the element.

marginY?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `marginY` shorthand property sets the margin area on the top and

bottom of the element.

minHeight?

0

The `minHeight` property sets the minimum height of an element. It prevents

the used value of the height property from becoming smaller than the value

specified for `minHeight`.

minWidth?

0

The `minWidth` property sets the minimum width of an element. It prevents

the used value of the width property from becoming smaller than the value

specified for `minWidth`.

opacity?

ResponsiveProp<number>: number | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", number>>

Sets the opacity of the element. Opacity is the degree to which content

behind an element is hidden, and is the opposite of transparency.

overflow?

"hidden" | "scroll" | "visible" | "auto"

The `overflow` shorthand property sets the desired behavior for an

element's overflow — i.e. when an element's content is too big to fit in

its block formatting context — in both directions.

padding?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `padding` shorthand property sets the padding area on all four sides

of an element at once.

paddingBottom?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `paddingBottom` property sets the height of the padding area on the

bottom of an element.

paddingLeft?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `paddingLeft` property sets the width of the padding area on the left

of an element.

paddingRight?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `paddingRight` property sets the width of the padding area on the

right of an element.

paddingTop?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `paddingTop` property sets the height of the padding area on the top

of an element.

paddingX?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `paddingX` shorthand property sets the padding area on the left and

right of the element.

paddingY?

ResponsiveSpacing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "xlarge" | "xxlarge">>

The `paddingY` shorthand property sets the padding area on the top and

bottom of the element.

position?

ResponsiveProp<"absolute" | "fixed" | "relative" | "sticky">

The `position` property sets how an element is positioned in a document.

The `top`, `right`, `bottom`, and `left` properties determine the final

location of positioned elements.

right?

ResponsiveProp<0>: 0 | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", 0>>

The `right` property participates in specifying the horizontal position of

a positioned element. It has no effect on non-positioned elements.

shadow?

"small" | "medium" | "large"

The `boxShadow` property adds shadow effects around an element's frame.

top?

ResponsiveProp<0>: 0 | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", 0>>

The `top` property participates in specifying the vertical position of a

positioned element. It has no effect on non-positioned elements.

userSelect?

"none"

The `userSelect` property controls whether the user can select text.

width?

ResponsiveSizing: "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "full" | Partial<Record<"mobile" | "tablet" | "desktop" | "wide", "small" | "medium" | "large" | "none" | "xxsmall" | "xsmall" | "full">>

Sets the element's width.

zIndex?

ResponsiveProp<"sticky" | "dropdownBlanket" | "dropdown" | "modalBlanket" | "modal" | "notification">

The `zIndex` property sets the "z-order" of a positioned element and its

descendants or flex items. Overlapping elements with a larger z-index cover

those with a smaller one.

By default, Box renders a div element. You can customise this via the as prop. Extra props will also be forwarded to the underlying element.

© 2023 Brighte Capital Pty Ltd