🎨(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:
@@ -1,3 +1,4 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import * as dotenv from 'dotenv';
|
||||
|
||||
dotenv.config({ path: './.env.test' });
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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%;`);
|
||||
});
|
||||
});
|
||||
79
src/frontend/apps/impress/src/utils/styleBuilder.ts
Normal file
79
src/frontend/apps/impress/src/utils/styleBuilder.ts
Normal 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),
|
||||
};
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user