From b4cf180392666580ac39306b13e47c2e715c33da Mon Sep 17 00:00:00 2001 From: Tatiana Cherednichenko Date: Wed, 19 May 2021 18:30:11 +0300 Subject: [PATCH] feat: generate map of states --- package.json | 1 + src/lib/map-generation.tsx | 189 +++++++++++++++++++++++ src/ui/atoms/button-icon/state-props.tsx | 44 ++++++ src/ui/atoms/button-icon/state.mdx | 9 ++ src/ui/atoms/button-icon/usage.mdx | 4 + src/ui/atoms/button/state-props.tsx | 75 +++++++++ src/ui/atoms/button/state.mdx | 9 ++ src/ui/atoms/button/usage.mdx | 4 + src/ui/atoms/chip/state-props.tsx | 49 ++++++ src/ui/atoms/chip/state.mdx | 9 ++ src/ui/atoms/chip/usage.mdx | 4 + src/ui/atoms/input/state-props.tsx | 59 +++++++ src/ui/atoms/input/state.mdx | 9 ++ src/ui/atoms/input/usage.mdx | 4 + yarn.lock | 45 +++++- 15 files changed, 510 insertions(+), 4 deletions(-) create mode 100644 src/lib/map-generation.tsx create mode 100644 src/ui/atoms/button-icon/state-props.tsx create mode 100644 src/ui/atoms/button-icon/state.mdx create mode 100644 src/ui/atoms/button/state-props.tsx create mode 100644 src/ui/atoms/button/state.mdx create mode 100644 src/ui/atoms/chip/state-props.tsx create mode 100644 src/ui/atoms/chip/state.mdx create mode 100644 src/ui/atoms/input/state-props.tsx create mode 100644 src/ui/atoms/input/state.mdx diff --git a/package.json b/package.json index 0b8415a9..ff9203a8 100755 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/lib/map-generation.tsx b/src/lib/map-generation.tsx new file mode 100644 index 00000000..70c72829 --- /dev/null +++ b/src/lib/map-generation.tsx @@ -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 }; + y: { [key: string]: Array }; + otherProps: { [key: string]: Array }; + 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 }, + props: { [key: string]: Array }, +) => { + 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 }, + y: { [key: string]: Array }, + props: { [key: string]: Array }, +) => { + let tree = [{ ...x, ...y }]; + for (const key in props) { + const values: Array = 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 = ({ x, y, otherProps, component }) => { + const Component = component; + const allVariants = generateMap({ ...x, ...y }, otherProps); + + return ( +
+ {allVariants?.map((variant, i) => ( + +
{variant[0][0].variants}
+ + +
+ {variant[0].map((prop, propKey) => ( +
{showHead(prop)}
+ ))} + {variant.map((props, j) => ( + <> + + {props[0].sizes} + + {props.map((prop, propKey) => ( + + ))} + + ))} + + + + ))} +
+ ); +}; + +export const showHead = (props: { [key: string]: Array }) => { + 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, SizesProps>; diff --git a/src/ui/atoms/button-icon/state-props.tsx b/src/ui/atoms/button-icon/state-props.tsx new file mode 100644 index 00000000..4ab3ce5a --- /dev/null +++ b/src/ui/atoms/button-icon/state-props.tsx @@ -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; +} + +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 ( + + } + onClick={() => console.info('ButtonIcon clicked')} + variant={variants} + disabled={disabled} + filled={filled} + /> + + ); +}; + +export const GenerateButtonIconMap = () => ( + +); diff --git a/src/ui/atoms/button-icon/state.mdx b/src/ui/atoms/button-icon/state.mdx new file mode 100644 index 00000000..e1013c07 --- /dev/null +++ b/src/ui/atoms/button-icon/state.mdx @@ -0,0 +1,9 @@ +--- +name: button-icon-map +category: map +package: woly +--- + +import {GenerateButtonIconMap } from './state-props' + + diff --git a/src/ui/atoms/button-icon/usage.mdx b/src/ui/atoms/button-icon/usage.mdx index 0b1bd503..0a773a4c 100644 --- a/src/ui/atoms/button-icon/usage.mdx +++ b/src/ui/atoms/button-icon/usage.mdx @@ -140,6 +140,10 @@ Secondary and error variant should be used to focus user attention. /> +### Map of ButtonIcon + +See map + ### Props | Name | Type | Default | Description | diff --git a/src/ui/atoms/button/state-props.tsx b/src/ui/atoms/button/state-props.tsx new file mode 100644 index 00000000..be61560c --- /dev/null +++ b/src/ui/atoms/button/state-props.tsx @@ -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; +} + +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 ( + +