This repository has been archived by the owner on Jul 28, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Айнур
committed
Aug 6, 2021
1 parent
51b27b4
commit 0386c41
Showing
9 changed files
with
341 additions
and
148 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
type VaritationsMap = Record<string, readonly unknown[]>; | ||
|
||
export function createCombinations(obj: VaritationsMap) { | ||
const fieldNames = Object.keys(obj); | ||
|
||
if (fieldNames.length === 0) return [{}]; | ||
|
||
function _combinations<Combination extends string[]>( | ||
[key, ...restKeys]: Combination, | ||
combinations: Record<string, unknown[]>, | ||
): Record<string, unknown>[] { | ||
const possibleValues = obj[key]; | ||
|
||
if (!Array.isArray(possibleValues) || possibleValues.length === 0) { | ||
throw new Error(`Please provide a non-empty array of possible values for prop ${key}`); | ||
} | ||
|
||
const variation = possibleValues.map((fieldValue) => ({ | ||
...combinations, | ||
[key]: fieldValue, | ||
})); | ||
|
||
if (restKeys.length === 0) { | ||
return variation; | ||
} | ||
|
||
return flatMap(variation, (newAcc) => _combinations(restKeys, newAcc)); | ||
} | ||
|
||
return _combinations(fieldNames, {}); | ||
} | ||
|
||
function flatMap<T>(arr: Array<T>, fn: (value: T, index: number, array: Array<T>) => Array<T>) { | ||
return arr.map(fn).reduce((a, b) => a.concat(b)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export function groupByKey<Variants extends Record<string, unknown>, Key extends keyof Variants>( | ||
arr: Variants[], | ||
key: Key, | ||
keyMapper?: (fn: Variants[Key]) => string, | ||
) { | ||
return arr.reduce<Record<string, Variants[]>>((all, current) => { | ||
const valueAsKey = keyMapper ? keyMapper(current[key]) : `${current[key]}`; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
if (all[valueAsKey] === undefined) { | ||
all[valueAsKey] = []; | ||
} | ||
all[valueAsKey].push(current); | ||
return all; | ||
}, {}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import React from 'react'; | ||
import styled from 'styled-components'; | ||
import { Global } from 'dev/global'; | ||
import { Grid, Heading } from 'ui'; | ||
|
||
import { createCombinations } from './common/combination'; | ||
import { groupByKey } from './common/group-by-key'; | ||
|
||
export const priorities = ['default', 'primary', 'secondary', 'white', 'danger', 'success']; | ||
|
||
interface ThemeProps { | ||
weight: string; | ||
priority: string; | ||
disabled: boolean; | ||
} | ||
|
||
interface PriorityWeightMapProps { | ||
weights: ('fill' | 'outline' | 'goast' | 'transparent')[]; | ||
render: (props: ThemeProps) => React.ReactElement; | ||
} | ||
|
||
export const PriorityWeightMap = ({ weights, render }: PriorityWeightMapProps) => { | ||
const allCombinations = createCombinations({ | ||
weight: weights, | ||
priority: priorities, | ||
disabled: [true, false], | ||
}); | ||
|
||
if (Object.keys(allCombinations).length === 0) return null; | ||
|
||
return ( | ||
<Wrapper> | ||
{Object.entries(groupByKey(allCombinations, 'priority')).map( | ||
([priority, combinations], index) => { | ||
return ( | ||
// eslint-disable-next-line react/no-array-index-key | ||
<PriorityGroup key={index}> | ||
<Header>{priority}</Header> | ||
<GridTemplate columns={weights.length + 1}> | ||
<div /> {/* plug to make empty space at top left corner */} | ||
{weights.map((weight, index) => ( | ||
<Centered key={index}> | ||
<b>{weight}</b> | ||
</Centered> | ||
))} | ||
{Object.entries( | ||
groupByKey(combinations, 'disabled', (key) => (key ? 'normal' : 'disable')), | ||
).map(([state, variations], index) => { | ||
return ( | ||
<React.Fragment key={index}> | ||
<Centered> | ||
<b>{state}</b> | ||
</Centered> | ||
{variations.map((variation, index) => { | ||
const { disabled, ...props } = variation as ThemeProps; | ||
|
||
return ( | ||
<VariantCell key={index}> | ||
{render({ ...props, disabled: state === 'disable' })} | ||
</VariantCell> | ||
); | ||
})} | ||
</React.Fragment> | ||
); | ||
})} | ||
</GridTemplate> | ||
</PriorityGroup> | ||
); | ||
}, | ||
)} | ||
</Wrapper> | ||
); | ||
}; | ||
|
||
const Wrapper = styled(Global)` | ||
display: flex; | ||
flex-direction: row; | ||
overflow-y: auto; | ||
`; | ||
|
||
const PriorityGroup = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
padding: 20px; | ||
`; | ||
|
||
const VariantCell = styled.div` | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
min-width: 100px; | ||
padding: 20px; | ||
`; | ||
|
||
const Header = styled(Heading)` | ||
padding-bottom: 15px; | ||
padding-left: 5px; | ||
`; | ||
|
||
const GridTemplate = styled(Grid)` | ||
gap: 10px; | ||
color: #c4c4c4; | ||
white-space: pre-line; | ||
`; | ||
|
||
const Centered = styled.div` | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.