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 25, 2021
1 parent 034a6f6 commit b4cf180
Show file tree
Hide file tree
Showing 15 changed files with 510 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
189 changes: 189 additions & 0 deletions src/lib/map-generation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/* eslint-disable @typescript-eslint/prefer-for-of */
/* 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';

interface GenerateMapProps {
x: { [key: string]: Array<unknown> };
y: { [key: string]: Array<unknown> };
otherProps: { [key: string]: Array<unknown> };
component: React.FC<{ prop: unknown }>;
}

interface SizesProps {
size: 'N' | 'XS' | 'S' | 'M' | 'L' | 'XL' | 'H';
}

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

const deepCopy = (obj: unknown) => JSON.parse(JSON.stringify(obj));

export const generateMap = (
main: { [key: string]: Array<unknown> },
props: { [key: string]: Array<unknown> },
) => {
const result = [];

const keys = Object.keys(main);

if (keys.length < 2) return;

for (let i = 0; i < main[keys[0]].length; i++) {
const x = { [keys[0]]: main[keys[0]][i] };
const yArr = [];
for (let j = 0; j < main[keys[1]].length; j++) {
const y = { [keys[1]]: main[keys[1]][j] };
const map = generatePropsMap(x, y, props);
yArr.push(map);
}
result.push(yArr);
}
return result;
};

const generatePropsMap = (
x: { [key: string]: Array<unknown> },
y: { [key: string]: Array<unknown> },
props: { [key: string]: Array<unknown> },
) => {
let tree = [{ ...x, ...y }];
for (const key in props) {
const values: Array<unknown> = props[key];
const buffer: Array<{ [x: string]: unknown[] }> = [];

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

tree = buffer;
}

return tree;
};

export const GenerateMap: React.FC<GenerateMapProps> = ({ x, y, otherProps, component }) => {
const Component = component;
const allVariants = generateMap({ ...x, ...y }, otherProps);

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

export const showHead = (props: { [key: string]: Array<unknown> }) => {
let head = ' ';
const { variants, sizes, ...otherProps } = props;
const keys = Object.keys(otherProps);
keys.forEach((key) => {
const value = otherProps[key];
if (value) {
head += key + '\n';
}
});
return head;
};

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>;
44 changes: 44 additions & 0 deletions src/ui/atoms/button-icon/state-props.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as React from 'react';
import { ButtonIcon } from 'ui';
import { IconSearch } from 'static/icons';

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

interface VariantProps {
variants: Array<string>;
}

interface SizesProps {
sizes: Array<'N' | 'XS' | 'S' | 'M' | 'L' | 'XL' | 'H'>;
}

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

export const variants: VariantProps = { variants: ['primary', 'secondary', 'danger'] };
export const sizes: SizesProps = { sizes: ['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
75 changes: 75 additions & 0 deletions src/ui/atoms/button/state-props.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import * as React from 'react';
import { IconSearch } from 'static/icons';

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

interface SizesProps {
sizes: Array<'N' | 'XS' | 'S' | 'M' | 'L' | 'XL' | 'H'>;
}

interface VariantProps {
variants: Array<string>;
}

interface OtherProps {
disabled: boolean[];
icon: boolean[];
outlined: boolean[];
}

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

export const variants: VariantProps = { variants: ['primary', 'secondary'] };
export const sizes: SizesProps = { sizes: ['N', 'XS', 'S', 'M', 'L', 'XL', 'H'] };

export const otherProps: OtherProps = {
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: ['primary'] }}
y={sizes}
/>
<GenerateMap
component={ComponentButton}
otherProps={otherProps}
x={{ variants: ['secondary'] }}
y={sizes}
/>
<GenerateMap
component={ComponentButton}
otherProps={otherProps}
x={{ variants: ['danger'] }}
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 b4cf180

Please sign in to comment.