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