mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-21 17:37:01 +01:00
Adding Box
component in TS to component-library (#19363)
* Adding TS version of Box to component-library * Updates to types and comments
This commit is contained in:
parent
fa70aec286
commit
35ae06d824
368
ui/components/component-library/box/README.mdx
Normal file
368
ui/components/component-library/box/README.mdx
Normal file
@ -0,0 +1,368 @@
|
||||
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';
|
||||
|
||||
import { Box } from './box';
|
||||
|
||||
# Box
|
||||
|
||||
The `Box` is a utility component that accepts many helper props to make styling easier.
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--box-default-story" />
|
||||
</Canvas>
|
||||
|
||||
## Props
|
||||
|
||||
<ArgsTable of={Box} />
|
||||
|
||||
## Usage
|
||||
|
||||
The following describes the props and example usage for this component.
|
||||
|
||||
### Margin
|
||||
|
||||
The margin props `margin`, `marginTop`, `marginRight`, `marginBottom`, `marginLeft`, `marginInline`, `marginInlineStart`, and `marginInlineEnd` can be used to set the margins of the `Box` component. All of the margin props accept [responsive props](#responsive-props) in the form of array props
|
||||
|
||||
Accepted props are: `0, 1, 2, 4, 6, 8, 9, 10, 12, 'auto` or array of these values
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--margin" />
|
||||
</Canvas>
|
||||
|
||||
```jsx
|
||||
<Box margin={4} />
|
||||
<Box marginTop={4} />
|
||||
<Box marginRight={4} />
|
||||
<Box marginBottom={4} />
|
||||
<Box marginLeft={'auto'} />
|
||||
<Box marginInline={4} />
|
||||
<Box marginInlineStart={4} />
|
||||
<Box marginInlineEnd={4} />
|
||||
|
||||
// Responsive props
|
||||
<Box margin={[4, 8]} />
|
||||
<Box marginTop={[4, 8]} />
|
||||
<Box marginRight={[4, 8]} />
|
||||
<Box marginBottom={[4, 8]} />
|
||||
<Box marginLeft={['auto', 8]} />
|
||||
<Box marginInline={['auto', 8]} />
|
||||
<Box marginInlineStart={['auto', 8]} />
|
||||
<Box marginInlineEnd={['auto', 8]} />
|
||||
```
|
||||
|
||||
### Padding
|
||||
|
||||
The padding props work very similarly to margin. The padding props `padding`, `paddingTop`, `paddingRight`, `paddingBottom`, `paddingLeft`, `paddingInline`, `paddingInlineStart`, and `paddingInlineEnd` can be used to set the paddings of the `Box` component. All of the padding props accept [responsive props](#responsive-props) in the form of array props
|
||||
|
||||
Accepted props are: `0, 1, 2, 4, 6, 8, 9, 10, 12` or array of these values
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--padding" />
|
||||
</Canvas>
|
||||
|
||||
```jsx
|
||||
<Box padding={4} />
|
||||
<Box paddingTop={4} />
|
||||
<Box paddingRight={4} />
|
||||
<Box paddingBottom={4} />
|
||||
<Box paddingLeft={4} />
|
||||
|
||||
// Responsive props
|
||||
<Box padding={[4, 8]} />
|
||||
<Box paddingTop={[4, 8]} />
|
||||
<Box paddingRight={[4, 8]} />
|
||||
<Box paddingBottom={[4, 8]} />
|
||||
<Box paddingLeft={[4, 8]} />
|
||||
```
|
||||
|
||||
### Display
|
||||
|
||||
The `display` prop can be used to set the display of the `Box` component. All of the display props accept [responsive props](#responsive-props) in the form of array props.
|
||||
|
||||
Accepted props imported from the design system `Display` const are:
|
||||
|
||||
- `Display.Block`
|
||||
- `Display.Flex`
|
||||
- `Display.Grid`
|
||||
- `Display.InlineBlock`
|
||||
- `Display.InlineFlex`
|
||||
- `Display.InlineGrid`
|
||||
- `Display.Inline`
|
||||
- `Display.ListItem`
|
||||
- `Display.None`
|
||||
|
||||
or array of these values.
|
||||
|
||||
```jsx
|
||||
import { Display } from '../../../helpers/constants/design-system';
|
||||
import Box from '../ui/box';
|
||||
|
||||
<Box display={Display.Block} />
|
||||
<Box display={Display.Flex} />
|
||||
<Box display={Display.Grid} />
|
||||
<Box display={Display.InlineBlock} />
|
||||
<Box display={Display.InlineFlex} />
|
||||
<Box display={Display.Inline} />
|
||||
<Box display={Display.None} />
|
||||
```
|
||||
|
||||
### Color
|
||||
|
||||
The `color` prop can be used to set the color of the content in Box component. The `color` prop accepts [responsive props](#responsive-props) in the form of array props. Defaults to `Color.textDefault`.
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--color-story" />
|
||||
</Canvas>
|
||||
|
||||
Example of importing `TextColor` object with `Box` component
|
||||
|
||||
```jsx
|
||||
import { TextColor } from '../../../helpers/constants/design-system';
|
||||
import Box from '../ui/box';
|
||||
|
||||
<Box color={TextColor.textDefault}>Text goes here</Box>;
|
||||
```
|
||||
|
||||
### Background Color
|
||||
|
||||
Use the `backgroundColor` prop along with the `Color` or `BackgroundColor` object from `ui/helpers/constants/design-system.js` to change background color. The `backgroundColor` prop accepts [responsive props](#responsive-props) in the form of array props.
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--background-color-story" />
|
||||
</Canvas>
|
||||
|
||||
Example of importing `BackgroundColor` object with `Box` component
|
||||
|
||||
```jsx
|
||||
import {
|
||||
BackgroundColor,
|
||||
TextColor,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import Box from '../ui/box';
|
||||
|
||||
<Box backgroundColor={BackgroundColor.backgroundDefault}>
|
||||
<Typography color={TextColor.textDefault}>
|
||||
BackgroundColor.backgroundDefault
|
||||
</Typography>
|
||||
</Box>;
|
||||
```
|
||||
|
||||
### Border Color
|
||||
|
||||
Use the `borderColor` prop along with the `Color` or `BorderColor` object from `ui/helpers/constants/design-system.js` to change border color. The `borderColor` prop accepts [responsive props](#responsive-props) in the form of array props.
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--border-color-story" />
|
||||
</Canvas>
|
||||
|
||||
Example of importing `BorderColor` object with `Box` component
|
||||
|
||||
```jsx
|
||||
import {
|
||||
BackgroundColor,
|
||||
BorderColor,
|
||||
TextColor,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import Box from '../ui/box';
|
||||
|
||||
<Box
|
||||
backgroundColor={BackgroundColor.backgroundDefault}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
>
|
||||
<Typography color={TextColor.textDefault}>
|
||||
BorderColor.borderDefault
|
||||
</Typography>
|
||||
</Box>;
|
||||
```
|
||||
|
||||
### Border Radius
|
||||
|
||||
Use the `borderRadius` prop along with the `BorderRadius` object from `ui/helpers/constants/design-system.js` to change border radius. The `borderRadius` prop accepts [responsive props](#responsive-props) in the form of array props.
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--border-radius-story" />
|
||||
</Canvas>
|
||||
|
||||
Example of importing `BorderRadius` object with `Box` component
|
||||
|
||||
```jsx
|
||||
import { BorderRadius } from '../../../helpers/constants/design-system';
|
||||
import Box from '../ui/box';
|
||||
|
||||
<Box borderRadius={BorderRadius.none}>BorderRadius.none 0px</Box>
|
||||
<Box borderRadius={BorderRadius.XS}>BorderRadius.XS 2px</Box>
|
||||
<Box borderRadius={BorderRadius.SM}>BorderRadius.SM 4px</Box>
|
||||
<Box borderRadius={BorderRadius.MD}>BorderRadius.MD 6px</Box>
|
||||
<Box borderRadius={BorderRadius.LG}>BorderRadius.LG 8px</Box>
|
||||
<Box borderRadius={BorderRadius.XL}>BorderRadius.XL 12px</Box>
|
||||
<Box borderRadius={BorderRadius.pill}>BorderRadius.pill 9999px</Box>
|
||||
<Box borderRadius={BorderRadius.full}>BorderRadius.full 50%</Box>
|
||||
```
|
||||
|
||||
### Responsive Props
|
||||
|
||||
The box component provides a responsive props api in the form of array props. Array props are inspired by [styled-systems array props](https://styled-system.com/guides/array-props). The responsive props follow a mobile first methodology with the first item in the array applying the style to the base level size e.g. `0px` and up. The second item overwrites the first items styles at the next breakpoint.
|
||||
|
||||
- All Box props accept the responsive props format
|
||||
- To skip a breakpoint use `null` as the skipped item's value e.g. `<Box display={['display', null, ;flex']} />`
|
||||
|
||||
```
|
||||
// the responsive props
|
||||
<Box display={['block', 'flex']} />
|
||||
|
||||
// is equivalent to the css
|
||||
.box {
|
||||
display: block;
|
||||
|
||||
@media screen and (max-width: $breakpoint-sm) {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--responsive-props" />
|
||||
</Canvas>
|
||||
|
||||
```jsx
|
||||
import {
|
||||
BorderColor,
|
||||
BackgroundColor,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import Box from '../ui/box';
|
||||
|
||||
<Box
|
||||
padding={[2, 4]}
|
||||
gap={[2, 4]}
|
||||
display={['flex']}
|
||||
flexDirection={['column', 'row']}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
>
|
||||
<Box
|
||||
padding={[4, 8]}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
responsive
|
||||
</Box>
|
||||
<Box
|
||||
padding={[4, 8]}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
props
|
||||
</Box>
|
||||
<Box
|
||||
padding={[4, 8]}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
example
|
||||
</Box>
|
||||
</Box>;
|
||||
```
|
||||
|
||||
### As
|
||||
|
||||
The polymorphic `as` prop allows you to change the root HTML element of the Box component. Defaults to `'div'`
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--as" />
|
||||
</Canvas>
|
||||
|
||||
```jsx
|
||||
import Box from '../../ui/box';
|
||||
|
||||
<Box>div(default)</Box>
|
||||
<Box as="ul">ul</Box>
|
||||
<Box as="li">li</Box>
|
||||
<Box as="button">button</Box>
|
||||
<Box as="header">header</Box>
|
||||
```
|
||||
|
||||
### Width
|
||||
|
||||
Use the `width` prop to pass a singular `BlockSize` or for a responsive width pass an array up to 4 `BlockSize`
|
||||
|
||||
Responsive widths go from smallest to largest screen sizes
|
||||
|
||||
Example: [BlockSize.Half, BlockSize.ThreeFourths, BlockSize.OneFifth, BlockSize.ThreeSixths]
|
||||
|
||||
- BlockSize.Half is the default width for `base screen size (0px)` and up
|
||||
- BlockSize.ThreeFourths is the width for `small screen size (576px) ` and up
|
||||
- BlockSize.OneFifth is the width for `medium screen size (768px)` and up
|
||||
- BlockSize.ThreeSixths is the width for `large screen size (1280px)` and up
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-box--width" />
|
||||
</Canvas>
|
||||
|
||||
```jsx
|
||||
import {
|
||||
BlockSize,
|
||||
Display,
|
||||
FlexWrap,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import Box from '../../ui/box';
|
||||
|
||||
<>
|
||||
<p>Static widths</p>
|
||||
|
||||
<Box display={Display.Flex}>
|
||||
<Box width={BlockSize.Full}>BlockSize.Full</Box>
|
||||
<Box width={BlockSize.Half}>BlockSize.Half</Box>
|
||||
<Box width={BlockSize.Half}>BlockSize.Half</Box>
|
||||
<Box width={BlockSize.OneThird}>BlockSize.OneThird</Box>
|
||||
<Box width={BlockSize.OneThird}>BlockSize.OneThird</Box>
|
||||
<Box width={BlockSize.OneThird}>BlockSize.OneThird</Box>
|
||||
<Box width={BlockSize.OneFourth}>BlockSize.OneFourth</Box>
|
||||
<Box width={BlockSize.OneFourth}>BlockSize.OneFourth</Box>
|
||||
<Box width={BlockSize.OneFourth}>BlockSize.OneFourth</Box>
|
||||
<Box width={BlockSize.OneFourth}>BlockSize.OneFourth</Box>
|
||||
</Box>
|
||||
|
||||
<p>Responsive widths</p>
|
||||
|
||||
<Box display={Display.Flex} flexWrap={FlexWrap.Wrap}>
|
||||
<Box
|
||||
width={[
|
||||
BlockSize.Full,
|
||||
BlockSize.Half,
|
||||
BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
]}
|
||||
>
|
||||
BlockSize.Full, BlockSize.Half, BlockSize.OneThird, BlockSize.OneFourth,
|
||||
</Box>
|
||||
<Box
|
||||
width={[
|
||||
BlockSize.Full,
|
||||
BlockSize.Half,
|
||||
BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
]}
|
||||
>
|
||||
BlockSize.Full, BlockSize.Half, BlockSize.OneThird, BlockSize.OneFourth,
|
||||
</Box>
|
||||
<Box
|
||||
width={[
|
||||
BlockSize.Full,
|
||||
BlockSize.Half,
|
||||
BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
]}
|
||||
>
|
||||
BlockSize.Full, BlockSize.Half, BlockSize.OneThird, BlockSize.OneFourth,
|
||||
</Box>
|
||||
<Box
|
||||
width={[
|
||||
BlockSize.Full,
|
||||
BlockSize.Half,
|
||||
BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
]}
|
||||
>
|
||||
BlockSize.Full, BlockSize.Half, BlockSize.OneThird, BlockSize.OneFourth,
|
||||
</Box>
|
||||
</Box>
|
||||
</>;
|
||||
```
|
402
ui/components/component-library/box/box.scss
Normal file
402
ui/components/component-library/box/box.scss
Normal file
@ -0,0 +1,402 @@
|
||||
@use "sass:list";
|
||||
@use "sass:map";
|
||||
@use "design-system";
|
||||
@use "utilities";
|
||||
|
||||
$attributes: padding, margin, gap;
|
||||
$extraProperties: auto;
|
||||
$attributesToApplyExtraProperties: margin;
|
||||
|
||||
.mm-box {
|
||||
// Padding, Margin, and Gap
|
||||
@each $attribute in $attributes {
|
||||
@each $size in design-system.$sizes-numeric {
|
||||
&--#{$attribute}-#{$size} {
|
||||
#{$attribute}: utilities.get-spacing($size);
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $size in design-system.$sizes-numeric {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:#{$attribute}-#{$size} {
|
||||
#{$attribute}: utilities.get-spacing($size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $size in design-system.$sizes-numeric {
|
||||
@each $direction in design-system.$directions {
|
||||
&--#{$attribute}-#{$direction}-#{$size} {
|
||||
#{$attribute}-#{$direction}: utilities.get-spacing($size);
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $direction in design-system.$directions {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:#{$attribute}-#{$direction}-#{$size} {
|
||||
#{$attribute}-#{$direction}: utilities.get-spacing($size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@if list.index($attributesToApplyExtraProperties, $attribute) {
|
||||
@each $property in $extraProperties {
|
||||
&--#{$attribute}-#{$property} {
|
||||
#{$attribute}: $property;
|
||||
}
|
||||
}
|
||||
|
||||
@each $property in $extraProperties {
|
||||
@each $direction in design-system.$directions {
|
||||
&--#{$attribute}-#{$direction}-#{$property} {
|
||||
#{$attribute}-#{$direction}: $property;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $property in $extraProperties {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:#{$attribute}-#{$property} {
|
||||
#{$attribute}: $property;
|
||||
}
|
||||
}
|
||||
|
||||
@each $direction in design-system.$directions {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:#{$attribute}-#{$direction}-#{$property} {
|
||||
#{$attribute}-#{$direction}: $property;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Borders
|
||||
@each $size in design-system.$sizes-numeric {
|
||||
&--border-width-#{$size} {
|
||||
border-width: #{$size}px;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $size in design-system.$sizes-numeric {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:border-width-#{$size} {
|
||||
border-width: #{$size}px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// border-color
|
||||
@each $variant, $color in design-system.$color-map {
|
||||
&--border-color-#{$variant} {
|
||||
border-color: var($color);
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $variant, $color in design-system.$color-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:border-color-#{$variant} {
|
||||
border-color: var($color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// border-style
|
||||
@each $border-style in design-system.$border-style {
|
||||
&--border-style-#{$border-style} {
|
||||
border-style: $border-style;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $border-style in design-system.$border-style {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:border-style-#{$border-style} {
|
||||
border-style: $border-style;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// border-radius
|
||||
@each $radius, $value in design-system.$border-radius {
|
||||
&--rounded-#{$radius} {
|
||||
border-radius: $value;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $radius, $value in design-system.$border-radius {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:rounded-#{$radius} {
|
||||
border-radius: $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display and Flex/Grid alignment
|
||||
@each $display in design-system.$display {
|
||||
&--display-#{$display} {
|
||||
display: $display;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $display in design-system.$display {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:display-#{$display} {
|
||||
display: $display;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $alignment in design-system.$align-items {
|
||||
&--align-items-#{$alignment} {
|
||||
align-items: $alignment;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $alignment in design-system.$align-items {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:align-items-#{$alignment} {
|
||||
align-items: $alignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $justification in design-system.$justify-content {
|
||||
&--justify-content-#{$justification} {
|
||||
justify-content: $justification;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $justification in design-system.$justify-content {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:justify-content-#{$justification} {
|
||||
justify-content: $justification;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $direction in design-system.$flex-direction {
|
||||
&--flex-direction-#{$direction} {
|
||||
flex-direction: $direction;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $direction in design-system.$flex-direction {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:flex-direction-#{$direction} {
|
||||
flex-direction: $direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $wrap in design-system.$flex-wrap {
|
||||
&--flex-wrap-#{$wrap} {
|
||||
flex-wrap: $wrap;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $wrap in design-system.$flex-wrap {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:flex-wrap-#{$wrap} {
|
||||
flex-wrap: $wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Width and Height
|
||||
&--width-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
&--height-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@each $fraction, $value in design-system.$fractions {
|
||||
&--width-#{$fraction} {
|
||||
width: $value;
|
||||
}
|
||||
|
||||
&--height-#{$fraction} {
|
||||
height: $value;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $fraction, $value in design-system.$fractions {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:width-#{$fraction} {
|
||||
width: $value;
|
||||
}
|
||||
&--#{$breakpoint}\:height-#{$fraction} {
|
||||
height: $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:width-full {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:height-full {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--height-screen {
|
||||
height: 100vh;
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:height-screen {
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--width-screen {
|
||||
width: 100vw;
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:width-screen {
|
||||
width: 100vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--height-max {
|
||||
height: max-content;
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:height-max {
|
||||
height: max-content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--width-max {
|
||||
width: max-content;
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:height-max {
|
||||
height: max-content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--height-min {
|
||||
height: min-content;
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:height-min {
|
||||
height: min-content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--width-min {
|
||||
width: min-content;
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:width-min {
|
||||
width: min-content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// text
|
||||
@each $alignment in design-system.$text-align {
|
||||
&--text-align-#{$alignment} {
|
||||
text-align: $alignment;
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $alignment in design-system.$text-align {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:text-align-#{$alignment} {
|
||||
text-align: $alignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// background
|
||||
@each $variant, $color in design-system.$color-map {
|
||||
&--background-color-#{$variant} {
|
||||
background-color: var($color);
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $variant, $color in design-system.$color-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\:background-color-#{$variant} {
|
||||
background-color: var($color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// color
|
||||
@each $variant, $color in design-system.$color-map {
|
||||
&--color-#{$variant} {
|
||||
color: var($color);
|
||||
}
|
||||
}
|
||||
// breakpoint classes
|
||||
@each $breakpoint, $min-width in $screen-sizes-map {
|
||||
@each $variant, $color in design-system.$color-map {
|
||||
@media screen and (min-width: $min-width) {
|
||||
&--#{$breakpoint}\color-#{$variant} {
|
||||
color: var($color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
956
ui/components/component-library/box/box.stories.tsx
Normal file
956
ui/components/component-library/box/box.stories.tsx
Normal file
@ -0,0 +1,956 @@
|
||||
import React from 'react';
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
|
||||
import {
|
||||
BlockSize,
|
||||
BorderStyle,
|
||||
BorderRadius,
|
||||
TextColor,
|
||||
BorderColor,
|
||||
BackgroundColor,
|
||||
Display,
|
||||
AlignItems,
|
||||
JustifyContent,
|
||||
TextAlign,
|
||||
FlexDirection,
|
||||
FlexWrap,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
|
||||
import { Text } from '..';
|
||||
|
||||
import { Box } from './box';
|
||||
|
||||
import README from './README.mdx';
|
||||
|
||||
const sizeControlOptions = [
|
||||
undefined,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
];
|
||||
const marginSizeControlOptions = [...sizeControlOptions, 'auto'];
|
||||
|
||||
export default {
|
||||
title: 'Components/ComponentLibrary/Box',
|
||||
component: Box,
|
||||
parameters: {
|
||||
docs: {
|
||||
page: README,
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
children: {
|
||||
table: { category: 'children' },
|
||||
},
|
||||
display: {
|
||||
options: Object.values(Display),
|
||||
control: 'select',
|
||||
table: { category: 'display' },
|
||||
},
|
||||
width: {
|
||||
options: Object.values(BlockSize),
|
||||
control: 'multi-select',
|
||||
table: { category: 'display' },
|
||||
},
|
||||
height: {
|
||||
options: Object.values(BlockSize),
|
||||
control: 'select',
|
||||
table: { category: 'display' },
|
||||
},
|
||||
gap: {
|
||||
control: 'select',
|
||||
options: sizeControlOptions,
|
||||
table: { category: 'display' },
|
||||
},
|
||||
backgroundColor: {
|
||||
options: Object.values(BackgroundColor),
|
||||
control: 'select',
|
||||
table: {
|
||||
category: 'background',
|
||||
},
|
||||
},
|
||||
color: {
|
||||
options: Object.values(TextColor),
|
||||
control: 'select',
|
||||
table: { category: 'color' },
|
||||
},
|
||||
borderStyle: {
|
||||
options: Object.values(BorderStyle),
|
||||
control: 'select',
|
||||
table: { category: 'border' },
|
||||
},
|
||||
borderWidth: {
|
||||
options: sizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'border' },
|
||||
},
|
||||
borderColor: {
|
||||
options: Object.values(BorderColor),
|
||||
control: 'select',
|
||||
table: { category: 'border' },
|
||||
},
|
||||
borderRadius: {
|
||||
options: Object.values(BorderRadius),
|
||||
control: 'select',
|
||||
table: { category: 'border' },
|
||||
},
|
||||
flexWrap: {
|
||||
options: Object.values(FlexWrap),
|
||||
control: 'select',
|
||||
table: { category: 'display' },
|
||||
},
|
||||
flexDirection: {
|
||||
options: Object.values(FlexDirection),
|
||||
control: 'select',
|
||||
table: { category: 'display' },
|
||||
},
|
||||
justifyContent: {
|
||||
options: Object.values(JustifyContent),
|
||||
control: 'select',
|
||||
table: { category: 'display' },
|
||||
},
|
||||
alignItems: {
|
||||
options: Object.values(AlignItems),
|
||||
control: 'select',
|
||||
table: { category: 'display' },
|
||||
},
|
||||
textAlign: {
|
||||
options: Object.values(TextAlign),
|
||||
control: 'select',
|
||||
table: { category: 'text' },
|
||||
},
|
||||
margin: {
|
||||
options: marginSizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'margin' },
|
||||
},
|
||||
marginTop: {
|
||||
options: marginSizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'margin' },
|
||||
},
|
||||
marginRight: {
|
||||
options: marginSizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'margin' },
|
||||
},
|
||||
marginBottom: {
|
||||
options: marginSizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'margin' },
|
||||
},
|
||||
marginLeft: {
|
||||
options: marginSizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'margin' },
|
||||
},
|
||||
marginInline: {
|
||||
options: marginSizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'margin' },
|
||||
},
|
||||
marginInlineStart: {
|
||||
options: marginSizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'margin' },
|
||||
},
|
||||
marginInlineEnd: {
|
||||
options: marginSizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'margin' },
|
||||
},
|
||||
padding: {
|
||||
options: sizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'padding' },
|
||||
},
|
||||
paddingTop: {
|
||||
options: sizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'padding' },
|
||||
},
|
||||
paddingRight: {
|
||||
options: sizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'padding' },
|
||||
},
|
||||
paddingBottom: {
|
||||
options: sizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'padding' },
|
||||
},
|
||||
paddingLeft: {
|
||||
options: sizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'padding' },
|
||||
},
|
||||
paddingInline: {
|
||||
options: sizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'padding' },
|
||||
},
|
||||
paddingInlineStart: {
|
||||
options: sizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'padding' },
|
||||
},
|
||||
paddingInlineEnd: {
|
||||
options: sizeControlOptions,
|
||||
control: 'select',
|
||||
table: { category: 'padding' },
|
||||
},
|
||||
as: {
|
||||
control: 'select',
|
||||
options: ['div', 'ul', 'li', 'span', 'a', 'button'],
|
||||
table: { category: 'as (root html element)' },
|
||||
},
|
||||
},
|
||||
} as Meta<typeof Box>;
|
||||
|
||||
export const BoxDefaultStory: StoryFn<typeof Box> = (args) => <Box {...args} />;
|
||||
|
||||
BoxDefaultStory.args = {
|
||||
children: 'Box component',
|
||||
display: Display.Flex,
|
||||
justifyContent: JustifyContent.center,
|
||||
alignItems: AlignItems.center,
|
||||
width: BlockSize.Half,
|
||||
height: BlockSize.Half,
|
||||
borderColor: BorderColor.borderDefault,
|
||||
padding: 4,
|
||||
};
|
||||
|
||||
BoxDefaultStory.storyName = 'Default';
|
||||
|
||||
export const Margin: StoryFn<typeof Box> = (args) => {
|
||||
return (
|
||||
<Box borderColor={BorderColor.borderMuted}>
|
||||
<Box
|
||||
{...args}
|
||||
margin={2}
|
||||
padding={4}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
Static margin
|
||||
</Box>
|
||||
<Box
|
||||
{...args}
|
||||
margin={[2, 4, 8, 12]}
|
||||
padding={[4]}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
Responsive margin changes based on breakpoint
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export const Padding: StoryFn<typeof Box> = (args) => {
|
||||
return (
|
||||
<Box borderColor={BorderColor.borderMuted}>
|
||||
<Box
|
||||
{...args}
|
||||
padding={4}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
Static padding
|
||||
</Box>
|
||||
<Box
|
||||
{...args}
|
||||
padding={[4, 8, 12]}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
Responsive padding changes based on breakpoint
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export const ColorStory: StoryFn<typeof Box> = (args) => {
|
||||
return (
|
||||
<>
|
||||
<Box {...args} padding={3} color={TextColor.textDefault}>
|
||||
TextColor.textDefault
|
||||
</Box>
|
||||
<Box {...args} padding={3} color={TextColor.textAlternative}>
|
||||
TextColor.textAlternative
|
||||
</Box>
|
||||
<Box {...args} padding={3} color={TextColor.textMuted}>
|
||||
TextColor.textMuted
|
||||
</Box>
|
||||
<Box {...args} padding={3} color={TextColor.primaryDefault}>
|
||||
TextColor.primaryDefault
|
||||
</Box>
|
||||
<Box
|
||||
{...args}
|
||||
padding={3}
|
||||
color={TextColor.primaryInverse}
|
||||
backgroundColor={BackgroundColor.primaryDefault}
|
||||
>
|
||||
TextColor.primaryInverse
|
||||
</Box>
|
||||
<Box {...args} padding={3} color={TextColor.errorDefault}>
|
||||
TextColor.errorDefault
|
||||
</Box>
|
||||
<Box
|
||||
{...args}
|
||||
padding={3}
|
||||
color={TextColor.errorInverse}
|
||||
backgroundColor={BackgroundColor.errorDefault}
|
||||
>
|
||||
TextColor.errorInverse
|
||||
</Box>
|
||||
<Box {...args} padding={3} color={TextColor.successDefault}>
|
||||
TextColor.successDefault
|
||||
</Box>
|
||||
<Box
|
||||
{...args}
|
||||
padding={3}
|
||||
color={TextColor.successInverse}
|
||||
backgroundColor={BackgroundColor.successDefault}
|
||||
>
|
||||
TextColor.successInverse
|
||||
</Box>
|
||||
<Box {...args} padding={3} color={TextColor.warningDefault}>
|
||||
TextColor.warningDefault
|
||||
</Box>
|
||||
<Box
|
||||
{...args}
|
||||
padding={3}
|
||||
color={TextColor.warningInverse}
|
||||
backgroundColor={BackgroundColor.warningDefault}
|
||||
>
|
||||
TextColor.warningInverse
|
||||
</Box>
|
||||
<Box {...args} padding={3} color={TextColor.infoDefault}>
|
||||
TextColor.infoDefault
|
||||
</Box>
|
||||
<Box
|
||||
{...args}
|
||||
padding={3}
|
||||
color={TextColor.infoInverse}
|
||||
backgroundColor={BackgroundColor.infoDefault}
|
||||
>
|
||||
TextColor.infoInverse
|
||||
</Box>
|
||||
<Box {...args} padding={3} color={TextColor.inherit}>
|
||||
TextColor.inherit
|
||||
</Box>
|
||||
<Box
|
||||
{...args}
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.sepolia}
|
||||
color={TextColor.sepoliaInverse}
|
||||
>
|
||||
TextColor.sepoliaInverse
|
||||
</Box>
|
||||
<Box
|
||||
{...args}
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.goerli}
|
||||
color={TextColor.goerliInverse}
|
||||
>
|
||||
TextColor.goerliInverse
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
ColorStory.storyName = 'Color';
|
||||
|
||||
export const BackgroundColorStory = () => {
|
||||
return (
|
||||
<>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.backgroundDefault}>
|
||||
<Text color={TextColor.textDefault}>
|
||||
BackgroundColor.backgroundDefault
|
||||
</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.backgroundAlternative}>
|
||||
<Text color={TextColor.textDefault}>
|
||||
BackgroundColor.backgroundAlternative
|
||||
</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.overlayDefault}>
|
||||
<Text color={TextColor.overlayInverse}>
|
||||
BackgroundColor.overlayDefault
|
||||
</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.primaryDefault}>
|
||||
<Text color={TextColor.primaryInverse}>
|
||||
BackgroundColor.primaryDefault
|
||||
</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.primaryMuted}>
|
||||
<Text color={TextColor.textDefault}>BackgroundColor.primaryMuted</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.errorDefault}>
|
||||
<Text color={TextColor.errorInverse}>BackgroundColor.errorDefault</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.errorMuted}>
|
||||
<Text color={TextColor.textDefault}>BackgroundColor.errorMuted</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.successDefault}>
|
||||
<Text color={TextColor.successInverse}>
|
||||
BackgroundColor.successDefault
|
||||
</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.successMuted}>
|
||||
<Text color={TextColor.textDefault}>BackgroundColor.successMuted</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.warningDefault}>
|
||||
<Text color={TextColor.warningInverse}>
|
||||
BackgroundColor.warningDefault
|
||||
</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.warningMuted}>
|
||||
<Text color={TextColor.textDefault}>BackgroundColor.warningMuted</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.sepolia}>
|
||||
<Text color={TextColor.sepoliaInverse}>BackgroundColor.sepolia</Text>
|
||||
</Box>
|
||||
<Box padding={3} backgroundColor={BackgroundColor.goerli}>
|
||||
<Text color={TextColor.goerliInverse}>BackgroundColor.goerli</Text>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
BackgroundColorStory.storyName = 'BackgroundColor';
|
||||
|
||||
export const BorderColorStory = () => {
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundDefault}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
borderWidth={2}
|
||||
marginBottom={1}
|
||||
>
|
||||
<Text color={TextColor.textDefault}>BorderColor.borderDefault</Text>
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundDefault}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={2}
|
||||
marginBottom={1}
|
||||
>
|
||||
<Text color={TextColor.textDefault}>BorderColor.borderMuted</Text>
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
borderColor={BorderColor.primaryDefault}
|
||||
borderWidth={2}
|
||||
marginBottom={1}
|
||||
backgroundColor={BackgroundColor.primaryMuted}
|
||||
>
|
||||
<Text color={TextColor.textDefault}>BorderColor.primaryDefault</Text>
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.errorMuted}
|
||||
borderColor={BorderColor.errorDefault}
|
||||
borderWidth={2}
|
||||
marginBottom={1}
|
||||
>
|
||||
<Text color={TextColor.textDefault}>BorderColor.errorDefault</Text>
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.successMuted}
|
||||
borderColor={BorderColor.successDefault}
|
||||
borderWidth={2}
|
||||
marginBottom={1}
|
||||
>
|
||||
<Text color={TextColor.textDefault}>BorderColor.successDefault</Text>
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.warningMuted}
|
||||
borderColor={BorderColor.warningDefault}
|
||||
borderWidth={2}
|
||||
>
|
||||
<Text color={TextColor.textDefault}>BorderColor.warningDefault</Text>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
BorderColorStory.storyName = 'BorderColor';
|
||||
|
||||
export const BorderRadiusStory = () => {
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
display={Display.Grid}
|
||||
style={{ gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))' }}
|
||||
gap={4}
|
||||
>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
borderWidth={2}
|
||||
borderRadius={BorderRadius.none}
|
||||
>
|
||||
BorderRadius.NONE 0px
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
borderWidth={2}
|
||||
borderRadius={BorderRadius.XS}
|
||||
>
|
||||
BorderRadius.XS 2px
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
borderWidth={2}
|
||||
borderRadius={BorderRadius.SM}
|
||||
>
|
||||
BorderRadius.SM 4px
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
borderWidth={2}
|
||||
borderRadius={BorderRadius.MD}
|
||||
>
|
||||
BorderRadius.MD 6px
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
borderWidth={2}
|
||||
borderRadius={BorderRadius.LG}
|
||||
>
|
||||
BorderRadius.LG 8px
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
borderWidth={2}
|
||||
borderRadius={BorderRadius.XL}
|
||||
>
|
||||
BorderRadius.XL 12px
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
borderWidth={2}
|
||||
borderRadius={BorderRadius.pill}
|
||||
>
|
||||
BorderRadius.pill 9999px
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
padding={3}
|
||||
backgroundColor={BackgroundColor.backgroundAlternative}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
borderWidth={2}
|
||||
borderRadius={BorderRadius.full}
|
||||
margin={4}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
style={{ height: '250px', width: '250px' }}
|
||||
>
|
||||
BorderRadius.full 50%
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
BorderRadiusStory.storyName = 'BorderRadius';
|
||||
|
||||
export const ResponsiveProps = () => {
|
||||
return (
|
||||
<>
|
||||
<Text marginBottom={4}>
|
||||
Responsive props example. Stacks vertically on small screens and aligns
|
||||
horizontally on large screens. Padding is also adjusted between small
|
||||
and large screens
|
||||
</Text>
|
||||
<Box
|
||||
marginTop="auto"
|
||||
marginBottom={[0]}
|
||||
padding={[2, 4]}
|
||||
gap={[2, 4]}
|
||||
display={[Display.Flex, null, null, Display.None]}
|
||||
flexDirection={[
|
||||
FlexDirection.Column,
|
||||
FlexDirection.Column,
|
||||
FlexDirection.Row,
|
||||
]}
|
||||
borderColor={BorderColor.borderDefault}
|
||||
>
|
||||
<Box
|
||||
padding={[4, 8]}
|
||||
backgroundColor={[
|
||||
BackgroundColor.backgroundAlternative,
|
||||
BackgroundColor.primaryMuted,
|
||||
]}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
responsive
|
||||
</Box>
|
||||
<Box
|
||||
padding={[4, 8]}
|
||||
backgroundColor={[
|
||||
BackgroundColor.backgroundAlternative,
|
||||
BackgroundColor.primaryMuted,
|
||||
]}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
props
|
||||
</Box>
|
||||
<Box
|
||||
padding={[4, 8]}
|
||||
backgroundColor={[
|
||||
BackgroundColor.backgroundAlternative,
|
||||
BackgroundColor.primaryMuted,
|
||||
]}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
example
|
||||
</Box>
|
||||
<Box
|
||||
padding={[4, 8]}
|
||||
borderRadius={[
|
||||
BorderRadius.XS,
|
||||
BorderRadius.SM,
|
||||
BorderRadius.MD,
|
||||
BorderRadius.LG,
|
||||
]}
|
||||
backgroundColor={[
|
||||
BackgroundColor.backgroundAlternative,
|
||||
BackgroundColor.primaryMuted,
|
||||
]}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
Responsive Border Radius 1
|
||||
</Box>
|
||||
<Box
|
||||
padding={[4, 8]}
|
||||
borderRadius={[
|
||||
BorderRadius.XL,
|
||||
BorderRadius.pill,
|
||||
BorderRadius.none,
|
||||
BorderRadius.full,
|
||||
]}
|
||||
backgroundColor={[
|
||||
BackgroundColor.backgroundAlternative,
|
||||
BackgroundColor.primaryMuted,
|
||||
]}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
>
|
||||
Responsive Border Radius 2
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const As: StoryFn<typeof Box> = (args) => {
|
||||
return (
|
||||
<>
|
||||
<Text marginBottom={4}>
|
||||
You can change the root element of the Box component using the as prop.
|
||||
Inspect the below elements to see the underlying HTML elements
|
||||
</Text>
|
||||
<Box {...args}>div(default)</Box>
|
||||
<Box as="button" disabled>
|
||||
Box as 'button' tag
|
||||
</Box>
|
||||
<br />
|
||||
<Box as="button" disabled>
|
||||
Box as 'button' tag and disabled
|
||||
</Box>
|
||||
<br />
|
||||
<Box as="a" href="https://metamask.io">
|
||||
Box as 'a' tag with href
|
||||
</Box>
|
||||
<br />
|
||||
<Box as="p" href="https://metamask.io" data-testid="hello">
|
||||
Box as 'p' tag with href and data-testid
|
||||
</Box>
|
||||
<br />
|
||||
<Box as="p" disabled>
|
||||
Box as 'p' tag and disabled
|
||||
</Box>
|
||||
<br />
|
||||
<Box>Box as 'span' tag (default)</Box>
|
||||
<br />
|
||||
<Box as="p">Box as 'p' tag</Box>
|
||||
<br />
|
||||
<Box as="li">Box as 'li' tag</Box>
|
||||
<br />
|
||||
<Box as="h1">Box as 'h1' tag</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const Width: StoryFn<typeof Box> = () => {
|
||||
const getColumns = (): JSX.Element[] => {
|
||||
const content: JSX.Element[] = [];
|
||||
for (let i = 0; i < 12; i++) {
|
||||
content.push(
|
||||
<Box
|
||||
key={i}
|
||||
backgroundColor={
|
||||
i % 2 === 0
|
||||
? BackgroundColor.errorMuted
|
||||
: BackgroundColor.warningMuted
|
||||
}
|
||||
width={BlockSize.OneTwelfth}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
<b>Static widths</b>
|
||||
</p>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
style={{
|
||||
height: '100vh',
|
||||
position: 'relative',
|
||||
}}
|
||||
marginBottom={6}
|
||||
>
|
||||
{getColumns()}
|
||||
|
||||
<Box
|
||||
width={BlockSize.Full}
|
||||
display={Display.Flex}
|
||||
flexWrap={FlexWrap.Wrap}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
marginBottom={6}
|
||||
width={BlockSize.Full}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.Full
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
marginBottom={6}
|
||||
width={BlockSize.Half}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.Half
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
marginBottom={6}
|
||||
width={BlockSize.Half}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.Half
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
marginBottom={6}
|
||||
width={BlockSize.OneThird}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.OneThird
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
marginBottom={6}
|
||||
width={BlockSize.OneThird}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.OneThird
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
marginBottom={6}
|
||||
width={BlockSize.OneThird}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.OneThird
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
width={BlockSize.OneFourth}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.OneFourth
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
width={BlockSize.OneFourth}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.OneFourth
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
width={BlockSize.OneFourth}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.OneFourth
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
width={BlockSize.OneFourth}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.OneFourth
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
<p>
|
||||
<b>Responsive widths</b>
|
||||
</p>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
style={{ height: '100vh', position: 'relative', textAlign: 'center' }}
|
||||
>
|
||||
{getColumns()}
|
||||
|
||||
<Box
|
||||
width={BlockSize.Full}
|
||||
display={Display.Flex}
|
||||
flexWrap={FlexWrap.Wrap}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
width={[
|
||||
BlockSize.Full,
|
||||
BlockSize.Half,
|
||||
BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
]}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.Full, BlockSize.Half, BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
width={[
|
||||
BlockSize.Full,
|
||||
BlockSize.Half,
|
||||
BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
]}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.Full, BlockSize.Half, BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
width={[
|
||||
BlockSize.Full,
|
||||
BlockSize.Half,
|
||||
BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
]}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.Full, BlockSize.Half, BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
</Box>
|
||||
<Box
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderWidth={6}
|
||||
width={[
|
||||
BlockSize.Full,
|
||||
BlockSize.Half,
|
||||
BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
]}
|
||||
display={Display.Flex}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
>
|
||||
BlockSize.Full, BlockSize.Half, BlockSize.OneThird,
|
||||
BlockSize.OneFourth,
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
2044
ui/components/component-library/box/box.test.tsx
Normal file
2044
ui/components/component-library/box/box.test.tsx
Normal file
File diff suppressed because it is too large
Load Diff
234
ui/components/component-library/box/box.tsx
Normal file
234
ui/components/component-library/box/box.tsx
Normal file
@ -0,0 +1,234 @@
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { memoize } from 'lodash';
|
||||
|
||||
import { BREAKPOINTS } from '../../../helpers/constants/design-system';
|
||||
|
||||
import type {
|
||||
BoxComponent,
|
||||
BoxProps,
|
||||
PolymorphicRef,
|
||||
StyleDeclarationType,
|
||||
StylePropValueType,
|
||||
ClassNamesObject,
|
||||
} from './box.types';
|
||||
|
||||
const BASE_CLASS_NAME = 'mm-box';
|
||||
|
||||
function isValidSize(
|
||||
styleProp: StyleDeclarationType,
|
||||
value: StylePropValueType,
|
||||
) {
|
||||
// Only margin types allow 'auto'
|
||||
return (
|
||||
typeof value === 'number' ||
|
||||
((styleProp === 'margin' ||
|
||||
styleProp === 'margin-top' ||
|
||||
styleProp === 'margin-right' ||
|
||||
styleProp === 'margin-bottom' ||
|
||||
styleProp === 'margin-left' ||
|
||||
styleProp === 'margin-inline' ||
|
||||
styleProp === 'margin-inline-start' ||
|
||||
styleProp === 'margin-inline-end') &&
|
||||
value === 'auto')
|
||||
);
|
||||
}
|
||||
|
||||
function isValidString(type: StyleDeclarationType, value: StylePropValueType) {
|
||||
return typeof type === 'string' && typeof value === 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate classnames
|
||||
* Generates classnames for different utility styles
|
||||
* Also accepts responsive props in the form of an array
|
||||
* Maps responsive props to mobile first breakpoints
|
||||
*
|
||||
* @param {string} styleDeclaration - The style declaration type "margin", "margin-top", "padding", "display" etc
|
||||
* @param {array || number || string} value - prop value being passed in array props are responsive props
|
||||
* @param {*} validatorFn - The validation function for each type of value
|
||||
* @returns
|
||||
*/
|
||||
|
||||
const generateClassNames = memoize(
|
||||
(
|
||||
styleDeclaration: StyleDeclarationType,
|
||||
value: StylePropValueType,
|
||||
validatorFn: typeof isValidString | typeof isValidSize,
|
||||
) => {
|
||||
// if value does not exist return empty object for classnames library
|
||||
// Accepts 0 as a valid value
|
||||
if (!value && typeof value !== 'number') {
|
||||
return {};
|
||||
}
|
||||
const classNamesObject: ClassNamesObject = {};
|
||||
// if value is an array with single item e.g. marginTop={[1]}
|
||||
const singleArrayItemProp =
|
||||
Array.isArray(value) && value.length === 1 ? value[0] : undefined;
|
||||
// if value single value e.g. marginTop={1}
|
||||
const singleValueProp =
|
||||
(!Array.isArray(value) && typeof value === 'string') ||
|
||||
typeof value === 'number'
|
||||
? value
|
||||
: undefined;
|
||||
// single digit equals single value or single array item
|
||||
let singleValue;
|
||||
if (singleValueProp || singleValueProp === 0) {
|
||||
singleValue = singleValueProp;
|
||||
}
|
||||
if (singleArrayItemProp || singleArrayItemProp === 0) {
|
||||
singleValue = singleArrayItemProp;
|
||||
}
|
||||
// 0 is an acceptable value but is falsy in js
|
||||
if (singleValue || singleValue === 0) {
|
||||
// add base style without any breakpoint prefixes to classObject
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${styleDeclaration}-${singleValue}`
|
||||
] = validatorFn(styleDeclaration, singleValue);
|
||||
} else if (Array.isArray(value)) {
|
||||
// If array with more than one item
|
||||
switch (value.length) {
|
||||
case 4:
|
||||
// add base/sm/md/lg
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${styleDeclaration}-${value[0]}`
|
||||
] = validatorFn(styleDeclaration, value[0]);
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${BREAKPOINTS[1]}:${styleDeclaration}-${value[1]}`
|
||||
] = validatorFn(styleDeclaration, value[1]);
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${BREAKPOINTS[2]}:${styleDeclaration}-${value[2]}`
|
||||
] = validatorFn(styleDeclaration, value[2]);
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${BREAKPOINTS[3]}:${styleDeclaration}-${value[3]}`
|
||||
] = validatorFn(styleDeclaration, value[3]);
|
||||
break;
|
||||
case 3:
|
||||
// add base/sm/md
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${styleDeclaration}-${value[0]}`
|
||||
] = validatorFn(styleDeclaration, value[0]);
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${BREAKPOINTS[1]}:${styleDeclaration}-${value[1]}`
|
||||
] = validatorFn(styleDeclaration, value[1]);
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${BREAKPOINTS[2]}:${styleDeclaration}-${value[2]}`
|
||||
] = validatorFn(styleDeclaration, value[2]);
|
||||
break;
|
||||
case 2:
|
||||
// add base/sm
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${styleDeclaration}-${value[0]}`
|
||||
] = validatorFn(styleDeclaration, value[0]);
|
||||
classNamesObject[
|
||||
`${BASE_CLASS_NAME}--${BREAKPOINTS[1]}:${styleDeclaration}-${value[1]}`
|
||||
] = validatorFn(styleDeclaration, value[1]);
|
||||
break;
|
||||
default:
|
||||
console.log(`Invalid array prop length: ${value.length}`);
|
||||
}
|
||||
}
|
||||
return classNamesObject;
|
||||
},
|
||||
(styleDeclaration, value) => [styleDeclaration, value],
|
||||
);
|
||||
|
||||
export const Box: BoxComponent = React.forwardRef(
|
||||
<C extends React.ElementType = 'div'>(
|
||||
{
|
||||
as,
|
||||
padding,
|
||||
paddingTop,
|
||||
paddingRight,
|
||||
paddingBottom,
|
||||
paddingLeft,
|
||||
paddingInline,
|
||||
paddingInlineStart,
|
||||
paddingInlineEnd,
|
||||
margin,
|
||||
marginTop,
|
||||
marginRight,
|
||||
marginBottom,
|
||||
marginLeft,
|
||||
marginInline,
|
||||
marginInlineStart,
|
||||
marginInlineEnd,
|
||||
borderColor,
|
||||
borderWidth,
|
||||
borderRadius,
|
||||
borderStyle,
|
||||
alignItems,
|
||||
justifyContent,
|
||||
textAlign,
|
||||
flexDirection,
|
||||
flexWrap,
|
||||
gap,
|
||||
display,
|
||||
width,
|
||||
height,
|
||||
children,
|
||||
className = '',
|
||||
backgroundColor,
|
||||
color,
|
||||
...props
|
||||
}: BoxProps<C>,
|
||||
ref?: PolymorphicRef<C>,
|
||||
) => {
|
||||
const Component = as || 'div';
|
||||
const boxClassName = classnames(
|
||||
BASE_CLASS_NAME,
|
||||
className,
|
||||
// Margin
|
||||
generateClassNames('margin', margin, isValidSize),
|
||||
generateClassNames('margin-top', marginTop, isValidSize),
|
||||
generateClassNames('margin-right', marginRight, isValidSize),
|
||||
generateClassNames('margin-bottom', marginBottom, isValidSize),
|
||||
generateClassNames('margin-left', marginLeft, isValidSize),
|
||||
generateClassNames('margin-inline', marginInline, isValidSize),
|
||||
generateClassNames('margin-inline-start', marginInlineStart, isValidSize),
|
||||
generateClassNames('margin-inline-end', marginInlineEnd, isValidSize),
|
||||
// Padding
|
||||
generateClassNames('padding', padding, isValidSize),
|
||||
generateClassNames('padding-top', paddingTop, isValidSize),
|
||||
generateClassNames('padding-right', paddingRight, isValidSize),
|
||||
generateClassNames('padding-bottom', paddingBottom, isValidSize),
|
||||
generateClassNames('padding-left', paddingLeft, isValidSize),
|
||||
generateClassNames('padding-inline', paddingInline, isValidSize),
|
||||
generateClassNames(
|
||||
'padding-inline-start',
|
||||
paddingInlineStart,
|
||||
isValidSize,
|
||||
),
|
||||
generateClassNames('padding-inline-end', paddingInlineEnd, isValidSize),
|
||||
generateClassNames('display', display, isValidString),
|
||||
generateClassNames('gap', gap, isValidSize),
|
||||
generateClassNames('flex-direction', flexDirection, isValidString),
|
||||
generateClassNames('flex-wrap', flexWrap, isValidString),
|
||||
generateClassNames('justify-content', justifyContent, isValidString),
|
||||
generateClassNames('align-items', alignItems, isValidString),
|
||||
generateClassNames('text-align', textAlign, isValidString),
|
||||
generateClassNames('width', width, isValidString),
|
||||
generateClassNames('height', height, isValidString),
|
||||
generateClassNames('color', color, isValidString),
|
||||
generateClassNames('background-color', backgroundColor, isValidString),
|
||||
generateClassNames('rounded', borderRadius, isValidString),
|
||||
generateClassNames('border-style', borderStyle, isValidString),
|
||||
generateClassNames('border-color', borderColor, isValidString),
|
||||
generateClassNames('border-width', borderWidth, isValidSize),
|
||||
{
|
||||
// Auto applied classes
|
||||
// ---Borders---
|
||||
// if borderWidth or borderColor is supplied w/o style, default to solid
|
||||
'box--border-style-solid':
|
||||
!borderStyle && (Boolean(borderWidth) || Boolean(borderColor)),
|
||||
// if borderColor supplied w/o width, default to 1
|
||||
'box--border-width-1': !borderWidth && Boolean(borderColor),
|
||||
},
|
||||
);
|
||||
return (
|
||||
<Component className={boxClassName} ref={ref} {...props}>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
},
|
||||
);
|
433
ui/components/component-library/box/box.types.ts
Normal file
433
ui/components/component-library/box/box.types.ts
Normal file
@ -0,0 +1,433 @@
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
AlignItems,
|
||||
BackgroundColor,
|
||||
BlockSize,
|
||||
BorderColor,
|
||||
BorderRadius,
|
||||
BorderStyle,
|
||||
Color,
|
||||
Display,
|
||||
FlexDirection,
|
||||
FlexWrap,
|
||||
IconColor,
|
||||
JustifyContent,
|
||||
TextAlign,
|
||||
TextColor,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
|
||||
export type StyleDeclarationType =
|
||||
| 'margin'
|
||||
| 'margin-top'
|
||||
| 'margin-right'
|
||||
| 'margin-bottom'
|
||||
| 'margin-left'
|
||||
| 'margin-inline'
|
||||
| 'margin-inline-start'
|
||||
| 'margin-inline-end'
|
||||
| 'padding'
|
||||
| 'padding-top'
|
||||
| 'padding-right'
|
||||
| 'padding-bottom'
|
||||
| 'padding-left'
|
||||
| 'padding-inline'
|
||||
| 'padding-inline-start'
|
||||
| 'padding-inline-end'
|
||||
| 'display'
|
||||
| 'gap'
|
||||
| 'flex-direction'
|
||||
| 'flex-wrap'
|
||||
| 'justify-content'
|
||||
| 'align-items'
|
||||
| 'text-align'
|
||||
| 'width'
|
||||
| 'height'
|
||||
| 'color'
|
||||
| 'background-color'
|
||||
| 'rounded'
|
||||
| 'border-style'
|
||||
| 'border-color'
|
||||
| 'border-width';
|
||||
|
||||
export type StylePropValueType =
|
||||
| AlignItems
|
||||
| AlignItemsArray
|
||||
| BackgroundColor
|
||||
| BackgroundColorArray
|
||||
| BlockSize
|
||||
| BlockSizeArray
|
||||
| BorderColor
|
||||
| BorderColorArray
|
||||
| BorderRadius
|
||||
| BorderRadiusArray
|
||||
| BorderStyle
|
||||
| BorderStyleArray
|
||||
| Color
|
||||
| Display
|
||||
| DisplayArray
|
||||
| FlexDirection
|
||||
| FlexDirectionArray
|
||||
| FlexWrap
|
||||
| FlexWrapArray
|
||||
| IconColor
|
||||
| JustifyContent
|
||||
| JustifyContentArray
|
||||
| SizeNumberAndAuto
|
||||
| SizeNumberAndAutoArray
|
||||
| TextAlign
|
||||
| TextAlignArray
|
||||
| TextColor
|
||||
| TextColorArray
|
||||
| IconColor
|
||||
| IconColorArray
|
||||
| undefined;
|
||||
|
||||
export interface ClassNamesObject {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export type FlexDirectionArray = [
|
||||
FlexDirection,
|
||||
FlexDirection?,
|
||||
FlexDirection?,
|
||||
FlexDirection?,
|
||||
];
|
||||
export type FlexWrapArray = [FlexWrap, FlexWrap?, FlexWrap?, FlexWrap?];
|
||||
export type TextAlignArray = [TextAlign, TextAlign?, TextAlign?, TextAlign?];
|
||||
export type DisplayArray = [Display, Display?, Display?, Display?];
|
||||
export type BlockSizeArray = [BlockSize, BlockSize?, BlockSize?, BlockSize?];
|
||||
|
||||
export type SizeNumber =
|
||||
| 0
|
||||
| 1
|
||||
| 2
|
||||
| 3
|
||||
| 4
|
||||
| 5
|
||||
| 6
|
||||
| 7
|
||||
| 8
|
||||
| 9
|
||||
| 10
|
||||
| 11
|
||||
| 12
|
||||
| null;
|
||||
|
||||
export type SizeNumberArray = [
|
||||
SizeNumber,
|
||||
SizeNumber?,
|
||||
SizeNumber?,
|
||||
SizeNumber?,
|
||||
];
|
||||
|
||||
export type SizeNumberAndAuto = SizeNumber | 'auto';
|
||||
|
||||
export type SizeNumberAndAutoArray = [
|
||||
SizeNumberAndAuto,
|
||||
SizeNumberAndAuto?,
|
||||
SizeNumberAndAuto?,
|
||||
SizeNumberAndAuto?,
|
||||
];
|
||||
|
||||
export type BorderColorArray = [
|
||||
BorderColor,
|
||||
BorderColor?,
|
||||
BorderColor?,
|
||||
BorderColor?,
|
||||
];
|
||||
|
||||
export type BorderRadiusArray = [
|
||||
BorderRadius,
|
||||
BorderRadius?,
|
||||
BorderRadius?,
|
||||
BorderRadius?,
|
||||
];
|
||||
|
||||
export type BorderStyleArray = [
|
||||
BorderStyle,
|
||||
BorderStyle?,
|
||||
BorderStyle?,
|
||||
BorderStyle?,
|
||||
];
|
||||
|
||||
export type AlignItemsArray = [
|
||||
AlignItems,
|
||||
AlignItems?,
|
||||
AlignItems?,
|
||||
AlignItems?,
|
||||
];
|
||||
|
||||
export type JustifyContentArray = [
|
||||
JustifyContent,
|
||||
JustifyContent?,
|
||||
JustifyContent?,
|
||||
JustifyContent?,
|
||||
];
|
||||
|
||||
export type BackgroundColorArray = [
|
||||
BackgroundColor,
|
||||
BackgroundColor?,
|
||||
BackgroundColor?,
|
||||
BackgroundColor?,
|
||||
];
|
||||
|
||||
export type TextColorArray = [TextColor, TextColor?, TextColor?, TextColor?];
|
||||
|
||||
export type IconColorArray = [IconColor, IconColor?, IconColor?, IconColor?];
|
||||
|
||||
/**
|
||||
* Polymorphic props based on Ohans Emmanuel's article below
|
||||
* https://blog.logrocket.com/build-strongly-typed-polymorphic-components-react-typescript/#ensuring-as-prop-only-receives-valid-html-element-strings
|
||||
*/
|
||||
|
||||
/**
|
||||
* Uses generic type C to create polymorphic ref type
|
||||
*/
|
||||
export type PolymorphicRef<C extends React.ElementType> =
|
||||
React.ComponentPropsWithRef<C>['ref'];
|
||||
|
||||
/**
|
||||
* Uses generic type C to define the type for the polymorphic "as" prop
|
||||
* "as" can be used to override the default HTML element
|
||||
*/
|
||||
type AsProp<C extends React.ElementType> = {
|
||||
/**
|
||||
* An override of the default HTML tag.
|
||||
* Can also be a React component.
|
||||
*/
|
||||
as?: C;
|
||||
};
|
||||
|
||||
/**
|
||||
* Omits the as prop and props from component definition
|
||||
*/
|
||||
type PropsToOmit<C extends React.ElementType, P> = keyof (AsProp<C> & P);
|
||||
|
||||
/**
|
||||
* Accepts 2 generic types: C which represents the as prop and the component props - Props
|
||||
*/
|
||||
type PolymorphicComponentProp<
|
||||
C extends React.ElementType,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
Props = {},
|
||||
> = React.PropsWithChildren<Props & AsProp<C>> &
|
||||
Omit<React.ComponentPropsWithoutRef<C>, PropsToOmit<C, Props>>;
|
||||
|
||||
export type PolymorphicComponentPropWithRef<
|
||||
C extends React.ElementType,
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
Props = {},
|
||||
> = PolymorphicComponentProp<C, Props> & { ref?: PolymorphicRef<C> };
|
||||
|
||||
/**
|
||||
* Includes all style utility props. This should be used to extend the props of a component.
|
||||
*/
|
||||
export interface StyleUtilityProps {
|
||||
/**
|
||||
* The flex direction of the Box component.
|
||||
* Use the FlexDirection enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
flexDirection?: FlexDirection | FlexDirectionArray;
|
||||
/**
|
||||
* The flex wrap of the Box component.
|
||||
* Use the FlexWrap enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
flexWrap?: FlexWrap | FlexWrapArray;
|
||||
/**
|
||||
* The gap between the Box component's children.
|
||||
* Use 1-12 for a gap of 4px-48px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
gap?: SizeNumber | SizeNumberArray | undefined;
|
||||
/**
|
||||
* The margin of the Box component.
|
||||
* Use 1-12 for 4px-48px or 'auto'.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
margin?: SizeNumberAndAuto | SizeNumberAndAutoArray;
|
||||
/**
|
||||
* The margin-top of the Box component.
|
||||
* Use 1-12 for 4px-48px or 'auto'.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
marginTop?: SizeNumberAndAuto | SizeNumberAndAutoArray;
|
||||
/**
|
||||
* The margin-bottom of the Box component.
|
||||
* Use 1-12 for 4px-48px or 'auto'.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
marginBottom?: SizeNumberAndAuto | SizeNumberAndAutoArray;
|
||||
/**
|
||||
* The margin-right of the Box component.
|
||||
* Use 1-12 for 4px-48px or 'auto'.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
marginRight?: SizeNumberAndAuto | SizeNumberAndAutoArray;
|
||||
/**
|
||||
* The margin-left of the Box component.
|
||||
* Use 1-12 for 4px-48px or 'auto'.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
marginLeft?: SizeNumberAndAuto | SizeNumberAndAutoArray;
|
||||
/**
|
||||
* The margin-inline of the Box component.
|
||||
* Use 1-12 for 4px-48px or 'auto'.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
marginInline?: SizeNumberAndAuto | SizeNumberAndAutoArray;
|
||||
/**
|
||||
* The margin-inline-start of the Box component.
|
||||
* Use 1-12 for 4px-48px or 'auto'.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
marginInlineStart?: SizeNumberAndAuto | SizeNumberAndAutoArray;
|
||||
/**
|
||||
* The margin-inline-end of the Box component.
|
||||
* Use 1-12 for 4px-48px or 'auto'.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
marginInlineEnd?: SizeNumberAndAuto | SizeNumberAndAutoArray;
|
||||
/**
|
||||
* The padding of the Box component.
|
||||
* Use 1-12 for 4px-48px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
padding?: SizeNumber | SizeNumberArray;
|
||||
/**
|
||||
* The padding-top of the Box component.
|
||||
* Use 1-12 for 4px-48px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
paddingTop?: SizeNumber | SizeNumberArray;
|
||||
/**
|
||||
* The padding-bottom of the Box component.
|
||||
* Use 1-12 for 4px-48px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
paddingBottom?: SizeNumber | SizeNumberArray;
|
||||
/**
|
||||
* The padding-right of the Box component.
|
||||
* Use 1-12 for 4px-48px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
paddingRight?: SizeNumber | SizeNumberArray;
|
||||
/**
|
||||
* The padding-left of the Box component.
|
||||
* Use 1-12 for 4px-48px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
paddingLeft?: SizeNumber | SizeNumberArray;
|
||||
/**
|
||||
* The padding-inline of the Box component.
|
||||
* Use 1-12 for 4px-48px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
paddingInline?: SizeNumber | SizeNumberArray;
|
||||
/**
|
||||
* The padding-inline-start of the Box component.
|
||||
* Use 1-12 for 4px-48px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
paddingInlineStart?: SizeNumber | SizeNumberArray;
|
||||
/**
|
||||
* The padding-inline-end of the Box component.
|
||||
* Use 1-12 for 4px-48px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
paddingInlineEnd?: SizeNumber | SizeNumberArray;
|
||||
/**
|
||||
* The border-color of the Box component.
|
||||
* Use BorderColor enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
borderColor?: BorderColor | BorderColorArray;
|
||||
/**
|
||||
* The border-width of the Box component.
|
||||
* Use 1-12 for 1px-12px.
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
borderWidth?: SizeNumber | SizeNumberArray;
|
||||
/**
|
||||
* The border-radius of the Box component.
|
||||
* Use BorderRadius enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
borderRadius?: BorderRadius | BorderRadiusArray;
|
||||
/**
|
||||
* The border-style of the Box component.
|
||||
* Use BorderStyle enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
borderStyle?: BorderStyle | BorderStyleArray;
|
||||
/**
|
||||
* The align-items of the Box component.
|
||||
* Use AlignItems enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
alignItems?: AlignItems | AlignItemsArray;
|
||||
/**
|
||||
* The justify-content of the Box component.
|
||||
* Use JustifyContent enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
justifyContent?: JustifyContent | JustifyContentArray;
|
||||
/**
|
||||
* The text-align of the Box component.
|
||||
* Use TextAlign enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
textAlign?: TextAlign | TextAlignArray;
|
||||
/**
|
||||
* The display of the Box component.
|
||||
* Use Display enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
display?: Display | DisplayArray;
|
||||
/**
|
||||
* The width of the Box component.
|
||||
* Use BlockSize enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
width?: BlockSize | BlockSizeArray;
|
||||
/**
|
||||
* The height of the Box component.
|
||||
* Use BlockSize enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
height?: BlockSize | BlockSizeArray;
|
||||
/**
|
||||
* The background-color of the Box component.
|
||||
* Use BackgroundColor enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
backgroundColor?: BackgroundColor | BackgroundColorArray;
|
||||
/**
|
||||
* The text-color of the Box component.
|
||||
* Use TextColor enum from '../../../helpers/constants/design-system';
|
||||
* Accepts responsive props in the form of an array.
|
||||
*/
|
||||
color?: TextColor | TextColorArray | IconColor | IconColorArray;
|
||||
}
|
||||
/**
|
||||
* Box component props.
|
||||
*/
|
||||
interface Props extends StyleUtilityProps {
|
||||
/**
|
||||
* The content of the Box component.
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
/**
|
||||
* Additional className to apply to the Box component.
|
||||
*/
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export type BoxProps<C extends React.ElementType> =
|
||||
PolymorphicComponentPropWithRef<C, Props>;
|
||||
|
||||
export type BoxComponent = <C extends React.ElementType = 'span'>(
|
||||
props: BoxProps<C>,
|
||||
) => React.ReactElement | null;
|
8
ui/components/component-library/box/index.ts
Normal file
8
ui/components/component-library/box/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export { Box } from './box';
|
||||
export type {
|
||||
PolymorphicRef,
|
||||
PolymorphicComponentPropWithRef,
|
||||
StyleUtilityProps,
|
||||
BoxProps,
|
||||
BoxComponent,
|
||||
} from './box.types';
|
@ -5,6 +5,7 @@
|
||||
* unintended overrides.
|
||||
**/
|
||||
// Atoms
|
||||
@import 'box/box';
|
||||
@import 'text/text';
|
||||
@import 'icon/icon';
|
||||
@import 'label/label';
|
||||
|
@ -8,12 +8,13 @@ export { AvatarFavicon, AVATAR_FAVICON_SIZES } from './avatar-favicon';
|
||||
export { AvatarIcon, AVATAR_ICON_SIZES } from './avatar-icon';
|
||||
export { AvatarNetwork, AVATAR_NETWORK_SIZES } from './avatar-network';
|
||||
export { AvatarToken } from './avatar-token';
|
||||
export { AvatarBase } from './avatar-base';
|
||||
export {
|
||||
BadgeWrapper,
|
||||
BadgeWrapperPosition,
|
||||
BadgeWrapperAnchorElementShape,
|
||||
} from './badge-wrapper';
|
||||
export { AvatarBase } from './avatar-base';
|
||||
export { Box } from './box';
|
||||
export { Button, BUTTON_VARIANT, BUTTON_SIZES } from './button';
|
||||
export { ButtonBase, BUTTON_BASE_SIZES } from './button-base';
|
||||
export { ButtonIcon, ButtonIconSize } from './button-icon';
|
||||
|
Loading…
Reference in New Issue
Block a user