Skip to content

Commit

Permalink
✨ basic theming
Browse files Browse the repository at this point in the history
  • Loading branch information
danieldelcore committed Oct 7, 2020
1 parent f3bc373 commit 0e51c3d
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 42 deletions.
50 changes: 20 additions & 30 deletions examples/v4-proto.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,17 @@
import { ReactNode, Fragment } from 'react';
import { storiesOf } from '@storybook/react';

import { jsx, css, createTheme, styled } from '@trousers/core';

//@ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const theme = createTheme({
default: 'blue',
primary: 'red',
});
import { jsx, css, styled } from '@trousers/core';

const styles = css('button', {
backgroundColor: 'var(--theme-default)',
backgroundColor: 'var(--default)',
color: 'red',
}).modifier('primary', {
backgroundColor: 'var(--theme-primary)',
color: 'blue',
});
})
.modifier('primary', {
backgroundColor: 'var(--primary)',
color: 'blue',
})
.theme({ default: 'blue', primary: 'red' });

interface ButtonProps {
primary?: boolean;
Expand All @@ -33,20 +28,15 @@ const Button = ({ primary, children }: ButtonProps) => (
const StyledButton = styled.button(styles);
const StyledButtonAlt = styled('button')(styles);

storiesOf('v4', module)
.add('Default', () => (
<Fragment>
<Button>Themed Button!</Button>
<Button primary>Primary Themed Button!</Button>
</Fragment>
))
.add('Styled', () => (
<Fragment>
<StyledButton> Styled, Themed Button!</StyledButton>
<StyledButton primary>Styled, Primary Themed Button!</StyledButton>
<StyledButtonAlt> Styled, Themed Button!</StyledButtonAlt>
<StyledButtonAlt primary>
Styled, Primary Themed Button!
</StyledButtonAlt>
</Fragment>
));
storiesOf('v4', module).add('Default', () => (
<Fragment>
<Button>Themed Button!</Button>
<Button primary>Primary Themed Button!</Button>
<StyledButton> Styled, Themed Button!</StyledButton>
<StyledButton primary>Styled, Primary Themed Button!</StyledButton>
<StyledButtonAlt> Styled, Themed Button!</StyledButtonAlt>
<StyledButtonAlt primary>
Styled, Primary Themed Button!
</StyledButtonAlt>
</Fragment>
));
21 changes: 21 additions & 0 deletions packages/core/src/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@ import { CSSProperties } from 'react';
import { Definition } from './types';
import hash from './hash';

function parseTheme(theme: Record<string, any>) {
return Object.keys(theme).reduce<CSSProperties>((accum, key) => {
// TODO: this can be nested - beware
//@ts-ignore
accum[`--${key}`] = theme[key];
return accum;
}, {});
}

function css(id: string, styles: CSSProperties) {
const elementId = `${id}-${hash(JSON.stringify(styles))}`;
const styleMap: Definition[] = [
{
id,
className: elementId,
type: 'element',
styles,
},
];
Expand All @@ -17,12 +27,23 @@ function css(id: string, styles: CSSProperties) {
modifier: (modifierId: string, modifierStyles: CSSProperties) => {
styleMap.push({
id: modifierId,
type: 'modifier',
className: `${elementId}--${modifierId}-${hash(
JSON.stringify(modifierStyles),
)}`,
styles: modifierStyles,
});

return self;
},
theme: (theme: Record<string, any>) => {
styleMap.push({
id: `theme-${id}`,
type: 'theme',
className: `theme-${id}`,
styles: parseTheme(theme),
});

return self;
},
};
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export { default as css } from './css';
export { default as createTheme } from './theme';
export { default as jsx } from './jsx';
export { default as styled } from './styled';
8 changes: 4 additions & 4 deletions packages/core/src/jsx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const jsx = <
const { css, theme, primary, ...rest } = props;
const definitions = css
._get()
.filter(({ id }, index) => index === 0 || !!(props as any)[id]);
.filter(({ id, type }) => type !== 'modifier' || !!(props as any)[id]);
const classes = definitions
.map(({ className }) => className)
.join(' ')
Expand All @@ -43,14 +43,14 @@ const jsx = <
const styleSheet = sheet(headElement, 'data-trousers');

definitions
.filter(({ className }) => !styleSheet.has(`.${className}`))
.filter(({ className }) => !styleSheet.has(className))
.forEach(({ className, styles }) => {
console.log(styles);

if (!styleSheet.has(className)) {
const styleString = parse(styles);
const prefixedStyles = prefix(`.${className}`, styleString);

console.log('mounting', className);

styleSheet.mount(className, prefixedStyles, false);
}
});
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/sheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const sheet = (targetEl: HTMLElement, attributeId: string) => {
const has = (id: string) => styleMap.has(id);

const mount = (id: string, styles: string, isGlobal?: boolean) => {
// TODO: maybe a map isn't the best thing to use here
styleMap.set(id, '');

try {
Expand Down
7 changes: 0 additions & 7 deletions packages/core/src/theme.ts

This file was deleted.

1 change: 1 addition & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CSSProperties } from 'react';

export interface Definition {
id: string;
type: 'element' | 'modifier' | 'theme';
className: string;
styles: CSSProperties;
}

0 comments on commit 0e51c3d

Please sign in to comment.