Skip to content

Commit

Permalink
feat: useStyles hooks added
Browse files Browse the repository at this point in the history
  • Loading branch information
mauroerta committed May 6, 2021
1 parent 5f659d2 commit fee9d48
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 168 deletions.
161 changes: 31 additions & 130 deletions apps/web-sandbox/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,112 +1,15 @@
import React from 'react';
import styled, { ThemeProvider } from 'styled-components';
import { theme, parsers, Component } from '@morfeo/web';
import { useTheme } from '@morfeo/hooks';
import { useState, useCallback, FC } from 'react';
import { ThemeProvider } from 'styled-components';
import { theme, Component } from '@morfeo/web';
import { useTheme, useStyles } from '@morfeo/hooks';
import { customStyled } from './styled';
import { darkTheme, lightTheme } from './theme';

const lightTheme = {
colors: {
primary: 'white',
secondary: 'black',
danger: 'red',
},
radii: {
m: '10px',
round: '50%',
},
space: {
s: '40px',
m: '100px',
},
sizes: {
s: '10px',
m: '100px',
xl: '200px',
},
borderWidths: {
s: '2px',
},
breakpoints: {
md: '900px',
lg: '1300px',
},
transitions: {
light: 'all 0.5s',
},
components: {
Button: {
style: {
componentTag: 'button',
transition: 'light',
height: 'm',
width: 'm',
bg: {
md: 'danger',
lg: 'primary',
},
color: 'secondary',
borderRadius: 'm',
borderWidth: 's',
borderStyle: 'solid',
borderColor: 'primary',
'&:hover': {
bg: 'secondary',
color: 'primary',
},
},
variants: {
primary: {
bg: 'secondary',
borderColor: 'primary',
color: 'primary',
'&:hover': {
bg: 'primary',
color: 'secondary',
},
},
round: {
borderRadius: 'round',
},
},
},
},
};

const darkTheme = {
colors: {
primary: 'black',
secondary: 'white',
},
};

theme.set(lightTheme as any);

function customStyled(component: Component) {
const { components } = theme.get();
const config = components[component];
const tag = config.style.componentTag || component;

return (props: any = {}) => {
const variant: any = props.variant as any;
const variantTag =
props.variant && config.variants
? config.variants[variant].componentTag
: tag;

const Component = styled<any>(variantTag || (tag as any))(
({ theme: styledTheme, ...style }) => {
return parsers.resolve({
style: { ...(style as any), componentName: component },
});
},
);

return <Component {...props} />;
};
}
theme.set(lightTheme);

const Button = customStyled('Button');

const StyledProvider: React.FC = ({ children }) => {
const StyledProvider: FC = ({ children }) => {
const currentTheme = useTheme();

return <ThemeProvider theme={currentTheme}>{children}</ThemeProvider>;
Expand All @@ -123,52 +26,50 @@ function getStyle(component: Component, variant?: string) {
}

function App() {
const [light, setLight] = React.useState(true);
const [light, setLight] = useState(true);

const onClick = React.useCallback(() => {
theme.set(light ? (darkTheme as any) : (lightTheme as any));
const onClick = useCallback(() => {
theme.set(light ? darkTheme : lightTheme);
setLight(prev => !prev);
}, [light]);

const containerStyle = parsers.resolve({
style: {
const { containerStyle, blockStyle, codeStyle } = useStyles({
containerStyle: {
bg: 'secondary',
width: '100vw' as any,
display: 'flex',
height: '100vh' as any,
alignItems: 'center',
justifyContent: 'space-evenly',
transition: 'light',
},
blockStyle: {
flex: 1,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'space-evenly',
height: '100%' as any,
},
});

const codeStyle = parsers.resolve({
style: { color: 'primary', display: 'block', py: 's' },
codeStyle: {
color: 'primary',
display: 'block',
py: 's',
},
});

return (
<StyledProvider>
<div
style={parsers.resolve({
style: {
bg: 'secondary',
width: '100vw',
display: 'flex',
height: '100vh',
alignItems: 'center',
justifyContent: 'space-evenly',
transition: 'light',
} as any,
})}
>
<div style={containerStyle}>
<div style={containerStyle}>
<div style={blockStyle}>
<Button onClick={onClick}>{light ? `🌙` : `☀️`}</Button>
<pre style={codeStyle}>{getStyle('Button')}</pre>
</div>
<div style={containerStyle}>
<div style={blockStyle}>
<Button variant="primary">Primary variant</Button>
<pre style={codeStyle}>{getStyle('Button', 'primary')}</pre>
</div>
<div style={containerStyle}>
<div style={blockStyle}>
<Button variant="round">Round variant</Button>
<pre style={codeStyle}>{getStyle('Button', 'round')}</pre>
</div>
Expand Down
68 changes: 30 additions & 38 deletions apps/web-sandbox/src/styled.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,30 @@
// import React from 'react';
// import scStyled, { StyledInterface } from 'styled-components';
// import { Component, theme, parsers, Style, Theme } from '@morfeo/web';

// const customStyled = (tag: keyof StyledInterface) => {
// const callback = <P extends Style & { theme: Theme }>({
// theme: styledTheme,
// ...style
// }: P) => scStyled[tag](parsers.resolve({ style }));

// const styledKeys = Object.keys(scStyled) as (keyof StyledInterface)[];

// for (let tag of styledKeys) {
// callback[tag] = callback(tag);
// }

// return callback;
// };

// export function themeComponent(component: Component) {
// const { components } = theme.get();
// const config = components[component];
// const tag = config.style.componentTag || component;

// return (props: Style = {}) => {
// const variant = props.variant;
// const variantTag =
// variant && config.variants ? config.variants[variant].componentTag : tag;

// const Component = customStyled(variantTag || tag) as React.FC<Style>;

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

// export default customStyled;

export const TEST = {};
import React from 'react';
import { theme, parsers, Component, Style, Theme } from '@morfeo/web';
import styled, { StyledComponent } from 'styled-components';

export function customStyled(component: Component) {
const { components } = theme.get();
const config = components[component];
const tag = (config.style.componentTag || component) as
| keyof JSX.IntrinsicElements
| React.ComponentType<any>;

const result = function (props: any) {
const variant = props.variant as any;
const variantTag = (props.variant && config.variants
? config.variants[variant].componentTag
: tag) as keyof JSX.IntrinsicElements | React.ComponentType<any>;

const Component = styled<any>(variantTag || (tag as any))(
({ theme: styledTheme, children, ...style }) => {
return parsers.resolve({
style: { componentName: component, ...(style as Style) },
});
},
) as StyledComponent<keyof JSX.IntrinsicElements, Theme, Style>;

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

return result as StyledComponent<keyof JSX.IntrinsicElements, Theme, Style>;
}
74 changes: 74 additions & 0 deletions apps/web-sandbox/src/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
export const lightTheme = {
colors: {
primary: 'white',
secondary: 'black',
danger: 'red',
},
radii: {
m: '10px',
round: '50%',
},
space: {
s: '40px',
m: '100px',
},
sizes: {
s: '10px',
m: '100px',
xl: '200px',
},
borderWidths: {
s: '2px',
},
breakpoints: {
md: '900px',
lg: '1300px',
},
transitions: {
light: 'all 0.5s',
},
components: {
Button: {
style: {
componentTag: 'button',
transition: 'light',
height: 'm',
width: 'm',
bg: {
md: 'danger',
lg: 'primary',
},
color: 'secondary',
borderRadius: 'm',
borderWidth: 's',
borderStyle: 'solid',
borderColor: 'primary',
'&:hover': {
bg: 'secondary',
color: 'primary',
},
},
variants: {
primary: {
bg: 'secondary',
borderColor: 'primary',
color: 'primary',
'&:hover': {
bg: 'primary',
color: 'secondary',
},
},
round: {
borderRadius: 'round',
},
},
},
},
} as any;

export const darkTheme = {
colors: {
primary: 'black',
secondary: 'white',
},
} as any;
1 change: 1 addition & 0 deletions packages/hooks/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './useTheme';
export * from './useStyles';
17 changes: 17 additions & 0 deletions packages/hooks/src/useStyles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Style, parsers } from '@morfeo/core';

export function useStyles<K extends string>(styles: Record<K, Style>) {
const styleKeys = Object.keys(styles);

return styleKeys.reduce(
(acc, curr) => ({
...acc,
[curr]: parsers.resolve({ style: styles[curr] }),
}),
{},
) as Record<K, any>;
}

export function useStyle(style: Style) {
return parsers.resolve({ style });
}
Loading

0 comments on commit fee9d48

Please sign in to comment.