🎨(app-desk) add margin and padding to Box

Add margin and padding system to Box component.
It proposes the autocompletion.
It is bind with the Cunninghams spacing system.
This commit is contained in:
Anthony LC
2024-05-02 17:05:22 +02:00
committed by Anthony LC
parent 0c2d097d8d
commit d8e7f29072
4 changed files with 145 additions and 4 deletions

View File

@@ -1,3 +1,4 @@
import '@testing-library/jest-dom';
import * as dotenv from 'dotenv';
dotenv.config({ path: './.env.test' });

View File

@@ -2,6 +2,12 @@ import { ComponentPropsWithRef, ReactHTML } from 'react';
import styled from 'styled-components';
import { CSSProperties } from 'styled-components/dist/types';
import {
MarginPadding,
stylesMargin,
stylesPadding,
} from '@/utils/styleBuilder';
import { hideEffect, showEffect } from './Effect';
export interface BoxProps {
@@ -18,11 +24,13 @@ export interface BoxProps {
$height?: CSSProperties['height'];
$justify?: CSSProperties['justifyContent'];
$overflow?: CSSProperties['overflow'];
$margin?: MarginPadding;
$maxWidth?: CSSProperties['maxWidth'];
$minWidth?: CSSProperties['minWidth'];
$padding?: MarginPadding;
$position?: CSSProperties['position'];
$radius?: CSSProperties['borderRadius'];
$width?: CSSProperties['width'];
$maxWidth?: CSSProperties['maxWidth'];
$minWidth?: CSSProperties['minWidth'];
}
export type BoxType = ComponentPropsWithRef<typeof Box>;
@@ -39,12 +47,14 @@ export const Box = styled('div')<BoxProps>`
${({ $gap }) => $gap && `gap: ${$gap};`}
${({ $height }) => $height && `height: ${$height};`}
${({ $justify }) => $justify && `justify-content: ${$justify};`}
${({ $margin }) => $margin && stylesMargin($margin)}
${({ $maxWidth }) => $maxWidth && `max-width: ${$maxWidth};`}
${({ $minWidth }) => $minWidth && `min-width: ${$minWidth};`}
${({ $overflow }) => $overflow && `overflow: ${$overflow};`}
${({ $padding }) => $padding && stylesPadding($padding)}
${({ $position }) => $position && `position: ${$position};`}
${({ $radius }) => $radius && `border-radius: ${$radius};`}
${({ $width }) => $width && `width: ${$width};`}
${({ $maxWidth }) => $maxWidth && `max-width: ${$maxWidth};`}
${({ $minWidth }) => $minWidth && `min-width: ${$minWidth};`}
${({ $css }) => $css && `${$css};`}
${({ $effect }) => {
let effect;

View File

@@ -0,0 +1,51 @@
import { render, screen } from '@testing-library/react';
import { Box } from '../Box';
describe('<Box />', () => {
it('has the padding from prop', () => {
const { unmount } = render(<Box $padding="10px">My Box</Box>);
expect(screen.getByText('My Box')).toHaveStyle('padding: 10px');
unmount();
render(
<Box $padding={{ horizontal: 'xl', all: 'large', bottom: 'tiny' }}>
My Box
</Box>,
);
expect(screen.getByText('My Box')).toHaveStyle(`
padding-left: 4rem;
padding-right: 4rem;
padding-top: 3rem;
padding-bottom: 0.5rem;`);
});
it('has the margin from prop', () => {
const { unmount } = render(<Box $margin="10px">My Box</Box>);
expect(screen.getByText('My Box')).toHaveStyle('margin: 10px');
unmount();
render(
<Box
$margin={{
horizontal: 'auto',
vertical: 'big',
bottom: 'full',
all: 'xtiny',
}}
>
My Box
</Box>,
);
expect(screen.getByText('My Box')).toHaveStyle(`
margin-left: auto;
margin-right: auto;
margin-top: 1.625rem;
margin-bottom: 100%;`);
});
});

View File

@@ -0,0 +1,79 @@
import { tokens } from '@/cunningham/cunningham-tokens';
/* eslint-disable @typescript-eslint/no-unused-vars */
const {
'0': _0,
st,
t,
s,
b,
bx,
l,
...spacingsLight
} = tokens.themes.default.theme.spacings;
/* eslint-enable @typescript-eslint/no-unused-vars */
const spacings = {
xtiny: tokens.themes.default.theme.spacings['st'],
tiny: tokens.themes.default.theme.spacings['t'],
small: tokens.themes.default.theme.spacings['s'],
big: tokens.themes.default.theme.spacings['b'],
xbig: tokens.themes.default.theme.spacings['bx'],
large: tokens.themes.default.theme.spacings['l'],
...spacingsLight,
};
type SpacingsKey = keyof typeof spacings;
// eslint-disable-next-line @typescript-eslint/ban-types
export type Spacings = SpacingsKey | (string & {});
export const spacingValue = (value?: Spacings) =>
value && value in spacings ? spacings[value as SpacingsKey] : value;
export type MarginPadding =
| Spacings
| {
vertical?: Spacings;
horizontal?: Spacings;
top?: Spacings;
bottom?: Spacings;
left?: Spacings;
right?: Spacings;
all?: Spacings;
};
export const stylesPadding = (pad: MarginPadding) => {
if (typeof pad === 'object') {
return {
'padding-top': spacingValue(pad.top || pad.vertical || pad.all),
'padding-bottom': spacingValue(pad.bottom || pad.vertical || pad.all),
'padding-left': spacingValue(pad.left || pad.horizontal || pad.all),
'padding-right': spacingValue(pad.right || pad.horizontal || pad.all),
};
} else {
return {
padding: spacingValue(pad),
};
}
};
export const stylesMargin = (margin: MarginPadding) => {
if (typeof margin === 'object') {
return {
'margin-top': spacingValue(margin.top || margin.vertical || margin.all),
'margin-bottom': spacingValue(
margin.bottom || margin.vertical || margin.all,
),
'margin-left': spacingValue(
margin.left || margin.horizontal || margin.all,
),
'margin-right': spacingValue(
margin.right || margin.horizontal || margin.all,
),
};
} else {
return {
margin: spacingValue(margin),
};
}
};