Skip to content

Commit

Permalink
feat(theme): Introduce micro spacing for components and named spacing (
Browse files Browse the repository at this point in the history
  • Loading branch information
tchock authored Dec 22, 2024
1 parent fa11c64 commit 0bfa3da
Show file tree
Hide file tree
Showing 37 changed files with 660 additions and 472 deletions.
2 changes: 1 addition & 1 deletion benchmark/button/SimpleThemedButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import styled from '@emotion/styled';
import { PabloThemeProvider } from '../../src/theme';
import { themeVars } from '../../src/theme/themeVars';
import { getSpacing } from '../../src/utils/styleHelpers';
import { getSpacing } from '../../src/styleHelpers';

const color = 'brand';
const SimpleThemedButton = styled.button`
Expand Down
8 changes: 3 additions & 5 deletions src/Box/Box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { color, ColorProps } from './interpolations/color';
import { CssFunctionReturn } from '../types';
import { baseStyle } from '../shared/baseStyle';
import { interpolateCssProp } from '../utils/interpolateCssProp';
import { margin, MarginProps, PaddingProps, padding } from './interpolations/spacing';
import { margin, padding, SpacingProps } from './interpolations/spacing';
import { layout, LayoutProps } from './interpolations/layout';
import { svg, SvgProps } from './interpolations/svg';
import { position, PositionProps } from './interpolations/position';
Expand All @@ -13,8 +13,7 @@ export interface BoxCssProps {
css?: CssFunctionReturn;
}

export type BoxProps = MarginProps &
PaddingProps &
export type BoxProps = SpacingProps &
ColorProps &
LayoutProps &
FlexItemProps &
Expand All @@ -32,8 +31,7 @@ export const Box = styled.div<BoxProps>`
${boxInterpolateFn}
`;

export type LayoutBoxProps = MarginProps &
PaddingProps &
export type LayoutBoxProps = SpacingProps &
FlexItemProps &
LayoutProps &
PositionProps &
Expand Down
8 changes: 4 additions & 4 deletions src/Box/interpolations/position.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test('position', () => {

test('top', () => {
expect(position({ ...props, top: 2 })).toEqual({
top: '16px',
top: '1rem',
});
expect(position({ ...props, top: '100%' })).toEqual({
top: '100%',
Expand All @@ -32,7 +32,7 @@ test('top', () => {

test('right', () => {
expect(position({ ...props, right: 2 })).toEqual({
right: '16px',
right: '1rem',
});
expect(position({ ...props, right: '100%' })).toEqual({
right: '100%',
Expand All @@ -41,7 +41,7 @@ test('right', () => {

test('bottom', () => {
expect(position({ ...props, bottom: 2 })).toEqual({
bottom: '16px',
bottom: '1rem',
});
expect(position({ ...props, bottom: '100%' })).toEqual({
bottom: '100%',
Expand All @@ -50,7 +50,7 @@ test('bottom', () => {

test('left', () => {
expect(position({ ...props, left: 2 })).toEqual({
left: '16px',
left: '1rem',
});
expect(position({ ...props, left: '100%' })).toEqual({
left: '100%',
Expand Down
12 changes: 7 additions & 5 deletions src/Box/interpolations/position.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
identityTransform,
InterpolationTransformFn,
ResponsiveValue,
spacingTransform,
macroSpacingTransform,
system,
} from '../system';

Expand All @@ -17,6 +17,8 @@ export interface PositionProps {
left?: ResponsiveValue<CSS.Property.Left>;
}

const transform = macroSpacingTransform;

export const position = system([
{
properties: ['position'],
Expand All @@ -29,18 +31,18 @@ export const position = system([
},
{
properties: ['top'],
transform: spacingTransform,
transform,
},
{
properties: ['right'],
transform: spacingTransform,
transform,
},
{
properties: ['bottom'],
transform: spacingTransform,
transform,
},
{
properties: ['left'],
transform: spacingTransform,
transform,
},
]);
207 changes: 133 additions & 74 deletions src/Box/interpolations/spacing.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defaultTheme } from '../../theme';
import { PabloThemeableProps } from '../../theme/types';
import { margin, padding } from './spacing';
import { margin, microMargin, microPadding, padding } from './spacing';

let props: PabloThemeableProps = {
theme: defaultTheme,
Expand All @@ -12,93 +12,152 @@ beforeEach(() => {
} as any;
});

test('Margin system', () => {
expect(margin({ m: 10, ...props })).toEqual({
margin: '80px',
describe.each([
['macro margin', margin, 'margin', 0.5, 'm'],
['macro padding', padding, 'padding', 0.5, 'p'],
['micro margin', microMargin, 'margin', 0.25, 'mm'],
['micro padding', microPadding, 'padding', 0.25, 'mp'],
])('%s system', (name, systemFn: any, property, base, shorthand) => {
test(`${name} system`, () => {
expect(systemFn({ [shorthand]: 10, ...props })).toEqual({
[property]: `${10 * base}rem`,
});
});
});

test('Margin system single props', () => {
expect(margin({ mt: 1, mr: 2, mb: 3, ml: 4, ...props })).toEqual({
marginTop: '8px',
marginRight: '16px',
marginBottom: '24px',
marginLeft: '32px',
test(`${name} system single props`, () => {
expect(
systemFn({
[`${shorthand}t`]: 1,
[`${shorthand}r`]: 2,
[`${shorthand}b`]: 3,
[`${shorthand}l`]: 4,
...props,
})
).toEqual({
[`${property}Top`]: `${1 * base}rem`,
[`${property}Right`]: `${2 * base}rem`,
[`${property}Bottom`]: `${3 * base}rem`,
[`${property}Left`]: `${4 * base}rem`,
});
});
});

test('Margin system with x and y props', () => {
expect(margin({ mx: 10, my: 20, ...props })).toEqual({
marginLeft: '80px',
marginRight: '80px',
marginTop: '160px',
marginBottom: '160px',
test(`${name} system with x and y props`, () => {
expect(systemFn({ [`${shorthand}x`]: 10, [`${shorthand}y`]: 20, ...props })).toEqual({
[`${property}Left`]: `${10 * base}rem`,
[`${property}Right`]: `${10 * base}rem`,
[`${property}Top`]: `${20 * base}rem`,
[`${property}Bottom`]: `${20 * base}rem`,
});
});
});

test('Padding system', () => {
expect(padding({ p: 10, ...props })).toEqual({
padding: '80px',
});
});
test('named spacing', () => {
const namedSpacings = [
['xxxs', 0.25],
['xxs', 0.5],
['xs', 0.75],
['sm', 1],
['md', 1.5],
['lg', 2],
['xl', 3],
['xxl', 4],
['xxxl', 6],
] as const;

test('Padding system single props', () => {
expect(padding({ pt: 1, pr: 2, pb: 3, pl: 4, ...props })).toEqual({
paddingTop: '8px',
paddingRight: '16px',
paddingBottom: '24px',
paddingLeft: '32px',
namedSpacings.forEach(([name, multiplier]) => {
expect(systemFn({ [`${shorthand}`]: name, ...props })).toEqual({
[property]: `${multiplier * base}rem`,
});
expect(systemFn({ [`${shorthand}t`]: name, ...props })).toEqual({
[`${property}Top`]: `${multiplier * base}rem`,
});
expect(systemFn({ [`${shorthand}r`]: name, ...props })).toEqual({
[`${property}Right`]: `${multiplier * base}rem`,
});
expect(systemFn({ [`${shorthand}b`]: name, ...props })).toEqual({
[`${property}Bottom`]: `${multiplier * base}rem`,
});
expect(systemFn({ [`${shorthand}l`]: name, ...props })).toEqual({
[`${property}Left`]: `${multiplier * base}rem`,
});
expect(systemFn({ [`${shorthand}x`]: name, ...props })).toEqual({
[`${property}Left`]: `${multiplier * base}rem`,
[`${property}Right`]: `${multiplier * base}rem`,
});
expect(systemFn({ [`${shorthand}y`]: name, ...props })).toEqual({
[`${property}Top`]: `${multiplier * base}rem`,
[`${property}Bottom`]: `${multiplier * base}rem`,
});
});
});
});

test('Padding system with x and y props', () => {
expect(padding({ px: 10, py: 20, ...props })).toEqual({
paddingLeft: '80px',
paddingRight: '80px',
paddingTop: '160px',
paddingBottom: '160px',
test(`styled interpolation functions for ${name}`, () => {
expect(systemFn.all(10)(props)).toEqual({
[property]: `${10 * base}rem`,
});
expect(systemFn.top(1)(props)).toEqual({
[`${property}Top`]: `${1 * base}rem`,
});
expect(systemFn.x(10)(props)).toEqual({
[`${property}Left`]: `${10 * base}rem`,
[`${property}Right`]: `${10 * base}rem`,
});
expect(systemFn.y(10)(props)).toEqual({
[`${property}Top`]: `${10 * base}rem`,
[`${property}Bottom`]: `${10 * base}rem`,
});
});
});

test('Padding system with gap', () => {
expect(padding({ gap: 10, ...props })).toEqual({
gap: '80px 80px',
test.each([
['macro', 0.5, padding],
['micro', 0.25, microPadding],
])('%s gap spacing', (_, base, systemFn: typeof padding) => {
expect(systemFn({ gap: 10, ...props })).toEqual({
gap: `${10 * base}rem ${10 * base}rem`,
});
expect(padding({ gap: [[10, 1]], ...props })).toEqual({
gap: '80px 8px',
expect(systemFn({ gap: [[10, 1]], ...props })).toEqual({
gap: `${10 * base}rem ${1 * base}rem`,
});
expect(systemFn.gap(10)(props)).toEqual({
gap: `${10 * base}rem ${10 * base}rem`,
});
});

test('styled interpolation functions', () => {
expect(margin.all(10)(props)).toEqual({
margin: '80px',
});
expect(margin.top(1)(props)).toEqual({
marginTop: '8px',
});
expect(margin.x(10)(props)).toEqual({
marginLeft: '80px',
marginRight: '80px',
});
expect(margin.y(10)(props)).toEqual({
marginTop: '80px',
marginBottom: '80px',
});
expect(padding.all(10)(props)).toEqual({
padding: '80px',
});
expect(padding.top(1)(props)).toEqual({
paddingTop: '8px',
});
expect(padding.x(10)(props)).toEqual({
paddingLeft: '80px',
paddingRight: '80px',
});
expect(padding.y(10)(props)).toEqual({
paddingTop: '80px',
paddingBottom: '80px',
});
expect(padding.gap(10)(props)).toEqual({
gap: '80px 80px',
});
test('getSpacing', () => {
expect(margin.get('xxxs')(props)).toEqual('0.125rem');
expect(margin.get('xxs')(props)).toEqual('0.25rem');
expect(margin.get('xs')(props)).toEqual('0.375rem');
expect(margin.get('sm')(props)).toEqual('0.5rem');
expect(margin.get('md')(props)).toEqual('0.75rem');
expect(margin.get('lg')(props)).toEqual('1rem');
expect(margin.get('xl')(props)).toEqual('1.5rem');
expect(margin.get('xxl')(props)).toEqual('2rem');
expect(margin.get('xxxl')(props)).toEqual('3rem');
expect(padding.get('xxxs')(props)).toEqual('0.125rem');
expect(padding.get('xxs')(props)).toEqual('0.25rem');
expect(padding.get('xs')(props)).toEqual('0.375rem');
expect(padding.get('sm')(props)).toEqual('0.5rem');
expect(padding.get('md')(props)).toEqual('0.75rem');
expect(padding.get('lg')(props)).toEqual('1rem');
expect(padding.get('xl')(props)).toEqual('1.5rem');
expect(padding.get('xxl')(props)).toEqual('2rem');
expect(padding.get('xxxl')(props)).toEqual('3rem');
expect(microMargin.get('xxxs')(props)).toEqual('0.0625rem');
expect(microMargin.get('xxs')(props)).toEqual('0.125rem');
expect(microMargin.get('xs')(props)).toEqual('0.1875rem');
expect(microMargin.get('sm')(props)).toEqual('0.25rem');
expect(microMargin.get('md')(props)).toEqual('0.375rem');
expect(microMargin.get('lg')(props)).toEqual('0.5rem');
expect(microMargin.get('xl')(props)).toEqual('0.75rem');
expect(microMargin.get('xxl')(props)).toEqual('1rem');
expect(microMargin.get('xxxl')(props)).toEqual('1.5rem');
expect(microPadding.get('xxxs')(props)).toEqual('0.0625rem');
expect(microPadding.get('xxs')(props)).toEqual('0.125rem');
expect(microPadding.get('xs')(props)).toEqual('0.1875rem');
expect(microPadding.get('sm')(props)).toEqual('0.25rem');
expect(microPadding.get('md')(props)).toEqual('0.375rem');
expect(microPadding.get('lg')(props)).toEqual('0.5rem');
expect(microPadding.get('xl')(props)).toEqual('0.75rem');
expect(microPadding.get('xxl')(props)).toEqual('1rem');
expect(microPadding.get('xxxl')(props)).toEqual('1.5rem');
});
Loading

0 comments on commit 0bfa3da

Please sign in to comment.