Skip to content

Commit

Permalink
save work
Browse files Browse the repository at this point in the history
  • Loading branch information
roginfarrer committed Mar 28, 2021
1 parent 361f692 commit 93151d0
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 109 deletions.
3 changes: 2 additions & 1 deletion examples/styled-components/src/App.tsx
@@ -1,11 +1,12 @@
import React from 'react';
import { ThemeProvider } from 'styled-components';
import { theme } from './theme';
import { Box } from './Box';
import { Box, css } from './Box';

const Button = (props) => {
return (
<Box
css={css({ color: '$red400' })}
color="white"
as="a"
fontFamily="$base"
Expand Down
46 changes: 15 additions & 31 deletions examples/styled-components/src/Box.tsx
@@ -1,10 +1,7 @@
import React, { ReactNode, ElementType, PropsWithChildren } from 'react';
import { ReactNode } from 'react';
import {
createSystem,
color,
PseudoProps,
AllSystemProps,
SystemProp,
border,
space,
layout,
Expand All @@ -15,8 +12,12 @@ import {
grid,
typography,
shouldForwardProp,
CSSObject,
createCss,
PseudoProps,
AllSystemProps,
SystemProp,
Theme,
CSSObject,
} from 'system-props';
import styled, { CSSProp } from 'styled-components';
import * as CSS from 'csstype';
Expand All @@ -40,7 +41,7 @@ interface BoxProps extends BaseProps, PseudoProps<BaseProps> {
css?: CSSProp;
}

const styles = system({
const config = {
...color,
...border,
...background,
Expand All @@ -52,30 +53,13 @@ const styles = system({
...space,
...typography,
...extraProps,
});

const BaseElement = ({
is: Component = 'div',
...props
}: PropsWithChildren<{ is?: ElementType }>) => {
const rest = Object.keys(props).reduce((acc, curr) => {
if (shouldForwardProp(curr)) {
return { ...acc, [curr]: props[curr] };
}
return acc;
}, {});

return <Component {...rest} />;
};

export const Box = ({ cx, ...props }: BoxProps) => {
return (
<BaseElement
css={`
${styles.css(cx)}
${styles}
`}
{...props}
/>
);
};
export const css = createCss(config);

export const Box = styled('div').withConfig({
shouldForwardProp: (prop, defaultValidtorFn) =>
shouldForwardProp(prop) &&
defaultValidtorFn(prop) &&
!Object.keys(extraProps).includes(prop),
})<BoxProps>({ boxSizing: 'border-box' }, system(config));
2 changes: 2 additions & 0 deletions src/__tests__/exports.test.ts
Expand Up @@ -6,7 +6,9 @@ test('package has expected exports', () => {
"background",
"border",
"color",
"createCss",
"createSystem",
"css",
"flexContainer",
"flexItem",
"flexbox",
Expand Down
33 changes: 30 additions & 3 deletions src/core/createCss.ts
@@ -1,7 +1,14 @@
import { get, memoizedGet } from './get';
import { Theme, SystemConfig, PrefixOptions } from '../types';
import {
PropConfigCollection,
Theme,
SystemConfig,
PrefixOptions,
} from '../types';
import { CSSObject } from '../css-prop';
import { merge } from './merge';
import * as CSS from 'csstype';
import { createStyleFunction } from './createStyleFunction';

type CSSFunctionArgs<T extends PrefixOptions> =
| CSSObject<T>
Expand All @@ -12,9 +19,29 @@ export type CSSFunction<T extends PrefixOptions> = (
) => (theme: Theme) => CSSObject<T> | undefined;

export const createCss = (
config: { [x: string]: SystemConfig },
tokenPrefix: 'all' | 'prefix' | 'noprefix'
propConfig: PropConfigCollection,
options: { tokenPrefix: PrefixOptions } = { tokenPrefix: 'prefix' }
) => {
const { tokenPrefix } = options;
const config: { [x: string]: SystemConfig } = {};

Object.keys(propConfig).forEach((key) => {
const conf = propConfig[key];
if (conf === true) {
// shortcut definition
config[key] = createStyleFunction({
property: key as keyof CSS.Properties,
scale: key,
tokenPrefix,
});
return;
}
if (typeof conf === 'function') {
return;
}
config[key] = createStyleFunction({ ...conf, tokenPrefix });
});

const css: CSSFunction<typeof tokenPrefix> = (args) => ({ theme }) => {
if (typeof args === 'undefined') {
return;
Expand Down
8 changes: 1 addition & 7 deletions src/core/createSystem.ts
Expand Up @@ -8,21 +8,17 @@ import {
Props,
SomeObject,
Cache,
PrefixDefault,
PrefixOptions,
} from '../types';
import { sort } from './sort';
import { merge } from './merge';
import { pseudoSelectors as defaultPseudos } from '../pseudos';
import * as CSS from 'csstype';
import { createCss, CSSFunction } from './createCss';

export interface Parser<TokenPrefix extends PrefixOptions = PrefixDefault> {
export interface Parser {
(...args: any[]): any;
config: { [key: string]: SystemConfig };
propNames: string[];
cache: Cache;
css?: CSSFunction<TokenPrefix>;
}

const createMediaQuery = (n: string) => `@media screen and (min-width: ${n})`;
Expand Down Expand Up @@ -188,8 +184,6 @@ export const createSystem = ({
config[key] = createStyleFunction({ ...conf, tokenPrefix });
});
const parser = createParser(config, pseudoSelectors, strict);
const cssFunction = createCss(config, tokenPrefix);
parser.css = cssFunction;
return parser;
};

Expand Down
1 change: 1 addition & 0 deletions src/core/index.ts
@@ -1,2 +1,3 @@
export { get } from './get';
export { createSystem } from './createSystem';
export { createCss } from './createCss';
105 changes: 105 additions & 0 deletions src/core/tests/css.test.ts
@@ -0,0 +1,105 @@
import { createCss } from '../createCss';
import { space, color } from '../../props';

const breakpoints = [40, 52, 64].map((n) => n + 'em');

test('createCss returns a css parser', () => {
const testCss = createCss({ ...space, ...color });
expect(typeof testCss).toBe('function');
// @ts-ignore
const styles = testCss({
color: 'tomato',
backgroundColor: '$primary',
mx: '$2',
opacity: 1,
':hover': {
opacity: 0.5,
},
$bp1: {
color: 'green',
},
'@media and (min-width: 300px)': {
mx: '$3',
},
})({
theme: {
breakpoints,
mediaQueries: breakpoints.reduce((acc, bp, index) => {
return { ...acc, [`bp${index + 1}`]: `@media and (min-width: ${bp})` };
}, {}),
space: ['0px', '4px', '8px', '16px', '32px'],
colors: {
primary: 'rebeccapurple',
},
},
});
expect(styles).toEqual({
color: 'tomato',
backgroundColor: 'rebeccapurple',
marginLeft: '8px',
marginRight: '8px',
opacity: 1,
':hover': {
opacity: 0.5,
},
'@media and (min-width: 40em)': {
color: 'green',
},
'@media and (min-width: 300px)': {
marginLeft: '16px',
marginRight: '16px',
},
});
});

test('createCss takes option to change token prefix', () => {
const testCss = createCss(
{ ...space, ...color },
{ tokenPrefix: 'noprefix' }
);
expect(typeof testCss).toBe('function');
// @ts-ignore
const styles = testCss({
color: 'tomato',
backgroundColor: 'primary',
mx: 2,
opacity: 1,
':hover': {
opacity: 0.5,
},
bp1: {
color: 'green',
},
'@media and (min-width: 300px)': {
mx: '3',
},
})({
theme: {
breakpoints,
mediaQueries: breakpoints.reduce((acc, bp, index) => {
return { ...acc, [`bp${index + 1}`]: `@media and (min-width: ${bp})` };
}, {}),
space: ['0px', '4px', '8px', '16px', '32px'],
colors: {
primary: 'rebeccapurple',
},
},
});
expect(styles).toEqual({
color: 'tomato',
backgroundColor: 'rebeccapurple',
marginLeft: '8px',
marginRight: '8px',
opacity: 1,
':hover': {
opacity: 0.5,
},
'@media and (min-width: 40em)': {
color: 'green',
},
'@media and (min-width: 300px)': {
marginLeft: '16px',
marginRight: '16px',
},
});
});
66 changes: 0 additions & 66 deletions src/core/tests/system.test.ts
Expand Up @@ -433,69 +433,3 @@ describe('tokenPrefix', () => {
});
});
});

test('parser has a css property that also parses styles', () => {
const system = createSystem();
const parser = system({
color: true,
backgroundColor: {
property: 'backgroundColor',
scale: 'colors',
},
mx: {
scale: 'space',
properties: ['marginLeft', 'marginRight'],
},
size: {
properties: ['height', 'width'],
},
});
expect(typeof parser.css).toBe('function');
// @ts-ignore
const styles = parser.css({
color: 'tomato',
backgroundColor: '$primary',
mx: '$2',
size: '400px',
opacity: 1,
':hover': {
opacity: 0.5,
},
$bp1: {
color: 'green',
},
'@media and (min-width: 300px)': {
mx: '$3',
},
})({
theme: {
breakpoints,
mediaQueries: breakpoints.reduce((acc, bp, index) => {
return { ...acc, [`bp${index + 1}`]: `@media and (min-width: ${bp})` };
}, {}),
space: ['0px', '4px', '8px', '16px', '32px'],
colors: {
primary: 'rebeccapurple',
},
},
});
expect(styles).toEqual({
color: 'tomato',
backgroundColor: 'rebeccapurple',
marginLeft: '8px',
marginRight: '8px',
height: '400px',
width: '400px',
opacity: 1,
':hover': {
opacity: 0.5,
},
'@media and (min-width: 40em)': {
color: 'green',
},
'@media and (min-width: 300px)': {
marginLeft: '16px',
marginRight: '16px',
},
});
});
33 changes: 32 additions & 1 deletion src/index.ts
@@ -1,5 +1,36 @@
export { createSystem } from './core/createSystem';
import {
background,
border,
color,
flexbox,
grid,
layout,
position,
shadow,
space,
transition,
typography,
} from './props';
import { createCss } from './core';

export const css = createCss(
{
...background,
...border,
...color,
...flexbox,
...grid,
...layout,
...position,
...shadow,
...space,
...transition,
...typography,
},
{ tokenPrefix: 'prefix' }
);

export { createSystem, createCss } from './core';
export * from './props';
export * from './pseudos';
export * from './propNames';
Expand Down

0 comments on commit 93151d0

Please sign in to comment.