Skip to content
This repository has been archived by the owner on Jul 28, 2024. It is now read-only.

Commit

Permalink
feat: generate map of states
Browse files Browse the repository at this point in the history
  • Loading branch information
tatinacher committed May 26, 2021
1 parent 034a6f6 commit 741bf1e
Show file tree
Hide file tree
Showing 15 changed files with 495 additions and 4 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@typescript-eslint/parser": "4.15.0",
"@wessberg/rollup-plugin-ts": "^1.3.8",
"babel-loader": "^8.2.2",
"babel-plugin-extract-react-types": "^0.1.14",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-styled-components": "^1.12.0",
"commitizen": "^4.2.3",
Expand Down
184 changes: 184 additions & 0 deletions src/lib/map-generation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/* eslint-disable no-loop-func */
/* eslint-disable react/no-array-index-key */
import * as React from 'react';
import styled, { StyledComponent } from 'styled-components';
import { Global } from 'lib/global';
import { Grid, Heading } from 'ui';

type SizeProps = 'N' | 'XS' | 'S' | 'M' | 'L' | 'XL' | 'H';

type ComponentValuesType = string | boolean | SizeProps;

interface ComponentProps {
name: string;
values: Array<ComponentValuesType>;
}

interface GenerateMapProps {
otherProps: Record<string, Array<unknown>>;
x: ComponentProps;
y: ComponentProps;
}

interface SizesProps {
size: SizeProps;
}

const map = ({ size }: SizesProps) => ({
'data-size': size,
});

export const GenerateMap: React.FC<
GenerateMapProps & { component: React.FC<{ prop: Record<string, unknown> }> }
> = ({ x, y, otherProps, component }) => {
const Component = component;
const variants = generateMap({ x, y, otherProps });

if (!variants) return null;

return (
<Main>
{variants.map((variant, i) => (
<VariantBlock key={i}>
<Header>{variant.name}</Header>
<GridTemplate columns={variant.columns + 1}>
<AreaVariants>
<div />
{variant.values[0].values.map(({ variants, sizes, ...prop }, headKey) => (
<div key={`head-${headKey}`}>{showHead(prop)}</div>
))}
{variant.values.map((props, j) => (
<>
<SizeBlock size={props.name as SizeProps} key={j}>
<b>{props.name}</b>
</SizeBlock>
{props.values.map((prop, propKey) => (
<Component prop={prop} key={`prop-${propKey}`} />
))}
</>
))}
</AreaVariants>
</GridTemplate>
</VariantBlock>
))}
</Main>
);
};

export const generateMap = ({ x, y, otherProps }: GenerateMapProps) => {
const result = [];

if (x.values.length === 0 || y.values.length === 0) return;

for (const valueX of x.values) {
const yArr = [];
let columns = 0;
for (const valueY of y.values) {
const map = generatePropsMap([{ [x.name]: valueX, [y.name]: valueY }], otherProps);
yArr.push({ name: valueY, values: map });
columns = map.length;
}
result.push({ name: valueX, values: yArr, columns });
}
return result;
};

const generatePropsMap = (
main: Array<Record<string, unknown>>,
otherProps: Record<string, Array<unknown>>,
) => {
let tree = main;

Object.keys(otherProps).forEach((key: string) => {
const values: Array<unknown> = otherProps[key];
const buffer: Array<Record<string, unknown>> = [];

values.forEach((value: unknown) => {
const cloned = deepCopy(tree);
cloned.forEach((item: Record<string, unknown>) => (item[key] = value));
buffer.push(...cloned);
});
tree = buffer;
});

return tree;
};

const deepCopy = (obj: Array<Record<string, unknown>>) => JSON.parse(JSON.stringify(obj));

export const showHead = (props: Record<string, unknown>) =>
Object.keys(props).reduce((acc, key) => acc + (props[key] ? key + '\n' : ''), '');

const VariantBlock = styled.div`
display: flex;
flex-direction: column;
padding: 20px;
`;

const Header = styled(Heading)`
padding-left: 5px;
padding-bottom: 15px;
`;

const GridTemplate = styled(Grid)`
gap: 10px;
`;

const AreaVariants = styled(Grid)`
color: #c4c4c4;
white-space: pre-line;
gap: 10px;
`;

export const Column = styled.div`
display: flex;
flex-direction: column;
& > * {
margin: 5px;
}
`;

export const Row = styled.div`
display: flex;
& > * {
margin: 5px;
}
`;

export const Main = styled(Global)`
display: flex;
white-space: nowrap;
overflow: scroll;
`;

export const SizeBlock = styled.div.attrs(map)`
display: flex;
margin: 5px;
align-items: center;
--woly-font-size: 15px;
&[data-size='N'] {
--woly-component-level: 0;
}
&[data-size='XS'] {
--woly-component-level: 1;
}
&[data-size='S'] {
--woly-component-level: 2;
}
&[data-size='M'] {
--woly-component-level: 3;
}
&[data-size='L'] {
--woly-component-level: 4;
--woly-font-size: 18px;
}
&[data-size='XL'] {
--woly-component-level: 5;
--woly-font-size: 21px;
}
&[data-size='H'] {
--woly-component-level: 6;
--woly-font-size: 21px;
}
` as StyledComponent<'div', Record<string, unknown>, SizesProps>;
48 changes: 48 additions & 0 deletions src/ui/atoms/button-icon/state-props.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as React from 'react';
import { ButtonIcon } from 'ui';
import { IconSearch } from 'static/icons';

import { GenerateMap, SizeBlock } from '../../../lib/map-generation';

interface ComponentProps {
name: string;
values: Array<string | boolean>;
}

interface ButtonIconProps {
disabled: boolean;
filled: boolean;
sizes: 'N' | 'XS' | 'S' | 'M' | 'L' | 'XL' | 'H';
variants: string;
}

export const variants: ComponentProps = {
name: 'variants',
values: ['primary', 'secondary'],
};

export const sizes: ComponentProps = {
name: 'sizes',
values: ['N', 'XS', 'S', 'M', 'L', 'XL', 'H'],
};

export const props = { disabled: [false, true], filled: [false, true] };

export const ComponentButtonIcon = ({ prop }: { prop: ButtonIconProps }) => {
const { variants, disabled, filled, sizes } = prop;
return (
<SizeBlock size={sizes}>
<ButtonIcon
icon={<IconSearch />}
onClick={() => console.info('ButtonIcon clicked')}
variant={variants}
disabled={disabled}
filled={filled}
/>
</SizeBlock>
);
};

export const GenerateButtonIconMap = () => (
<GenerateMap component={ComponentButtonIcon} x={variants} y={sizes} otherProps={props} />
);
9 changes: 9 additions & 0 deletions src/ui/atoms/button-icon/state.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name: button-icon-map
category: map
package: woly
---

import {GenerateButtonIconMap } from './state-props'

<GenerateButtonIconMap />
4 changes: 4 additions & 0 deletions src/ui/atoms/button-icon/usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ Secondary and error variant should be used to focus user attention.
/>
</Playground>

### Map of ButtonIcon

<a href="/package/woly/component/button-icon-map">See map</a>

### Props

| Name | Type | Default | Description |
Expand Down
56 changes: 56 additions & 0 deletions src/ui/atoms/button/state-props.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as React from 'react';
import { IconSearch } from 'static/icons';

import { Button } from '.';
import { GenerateMap, SizeBlock } from '../../../lib/map-generation';

interface ComponentProps {
name: string;
values: Array<string | boolean>;
}

interface ComponentButtonProps {
disabled: boolean;
icon: boolean;
outlined: boolean;
sizes: 'N' | 'XS' | 'S' | 'M' | 'L' | 'XL' | 'H';
variants: string;
}

export const variants: ComponentProps = {
name: 'variants',
values: ['primary', 'secondary'],
};

export const sizes: ComponentProps = {
name: 'sizes',
values: ['N', 'XS', 'S', 'M', 'L', 'XL', 'H'],
};

export const otherProps: Record<string, Array<unknown>> = {
disabled: [false, true],
outlined: [false, true],
icon: [false, true],
};

export const ComponentButton = ({ prop }: { prop: ComponentButtonProps }) => {
const { disabled, icon, outlined, sizes, variants } = prop;
return (
<SizeBlock size={sizes}>
<Button
disabled={disabled}
icon={icon ? <IconSearch /> : null}
onClick={() => console.log('Hi!')}
outlined={outlined}
text="Button"
variant={variants}
/>
</SizeBlock>
);
};

export const GenerateButton = () => (
<>
<GenerateMap component={ComponentButton} otherProps={otherProps} x={variants} y={sizes} />
</>
);
9 changes: 9 additions & 0 deletions src/ui/atoms/button/state.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
name: button-map
category: map
package: woly
---

import {GenerateButton } from './state-props'

<GenerateButton />
4 changes: 4 additions & 0 deletions src/ui/atoms/button/usage.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ Buttons can be placed inside the container. Button width is equal to container s
</block.S>
</Playground>

### Map of Button

<a href="/package/woly/component/button-map">See full map of button</a>

### Props

| Name | Type | Default | Description |
Expand Down
Loading

0 comments on commit 741bf1e

Please sign in to comment.