-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sdds-insol): Add
Tokens
page in stories
- Loading branch information
1 parent
1fb7a93
commit a9fe2a0
Showing
1 changed file
with
161 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import React from 'react'; | ||
import styled from 'styled-components'; | ||
import type { StoryObj, Meta } from '@storybook/react'; | ||
import { sdds_insol__dark, sdds_insol__light } from '@salutejs/sdds-themes/es/themes'; | ||
|
||
import { InSpacingDecorator } from '../helpers'; | ||
|
||
import { DsplS, H2, TextM } from './Typography'; | ||
|
||
// INFO: Предлагаю большую часть логики, которую можно вынести, перенести в библиотеку plasma-sb-utils | ||
|
||
const meta: Meta = { | ||
title: 'Colors', | ||
decorators: [InSpacingDecorator], | ||
}; | ||
|
||
export default meta; | ||
|
||
const StyledContainer = styled.div``; | ||
|
||
// INFO: этот метод есть в пакете plasma-tokens-utils | ||
const camelize = (source?: string) => source?.replace(/[_-]+(.)/g, (_, p1) => p1.toUpperCase()) || ''; | ||
|
||
const convertTheme = (theme: string) => { | ||
const regex = /--([\w-]+):\s*([^;]+);/g; | ||
const cssTokens = [...theme.matchAll(regex)]; | ||
|
||
return cssTokens.reduce((acc, match) => { | ||
const [_, key, value] = match; | ||
acc[key] = value.trim(); | ||
|
||
return acc; | ||
}, {}); | ||
}; | ||
|
||
const getActualCategory = (name: string) => { | ||
if (name.startsWith('on-dark') || name.startsWith('dark')) { | ||
return 'OnDark'; | ||
} | ||
|
||
if (name.startsWith('on-light') || name.startsWith('light')) { | ||
return 'OnLight'; | ||
} | ||
|
||
if (name.startsWith('inverse')) { | ||
return 'Inverse'; | ||
} | ||
|
||
return 'Default'; | ||
}; | ||
|
||
interface GroupedTokens { | ||
[category: string]: { | ||
[subcategory: string]: { | ||
[token: string]: string; | ||
}; | ||
}; | ||
} | ||
|
||
const getGroupedTokens = (themes: string): GroupedTokens => { | ||
const tokensExclude = ['border-radius', 'shadow', 'plasma-typo', 'brightness', 'hover', 'active']; | ||
|
||
const processedTokens = convertTheme(themes); | ||
|
||
const result = Object.entries(processedTokens).filter( | ||
([name]) => !tokensExclude.find((token) => name.includes(token)), | ||
); | ||
|
||
return result.reduce((acc, [name, value]) => { | ||
const actualCategory = getActualCategory(name); | ||
const actualName = name.replace(/(on-dark|dark|on-light|light|inverse)-/g, ''); | ||
const [subcategory] = actualName.split('-'); | ||
|
||
acc[actualCategory] = { | ||
...acc[actualCategory], | ||
[subcategory]: { | ||
...acc[actualCategory]?.[subcategory], | ||
[camelize(name)]: value, | ||
}, | ||
}; | ||
|
||
return acc; | ||
}, {}); | ||
}; | ||
|
||
const themes: Record<string, GroupedTokens> = { | ||
'sdds-insol:light': getGroupedTokens(sdds_insol__light[0]), | ||
'sdds-insol:dark': getGroupedTokens(sdds_insol__dark[0]), | ||
}; | ||
|
||
export const Default: StoryObj = { | ||
render: (_, context) => { | ||
const groupedTokens = themes[context.globals.theme]; | ||
|
||
return ( | ||
<StyledContainer> | ||
{Object.entries(groupedTokens).map(([category, value]) => ( | ||
<div | ||
style={{ | ||
marginBottom: '10rem', | ||
}} | ||
> | ||
<DsplS>{category}</DsplS> | ||
{Object.entries(value).map(([subcategory, value2]) => ( | ||
<div> | ||
<H2 | ||
style={{ | ||
marginTop: '3rem', | ||
marginBottom: '4.25rem', | ||
}} | ||
> | ||
{subcategory} / | ||
</H2> | ||
{Object.entries(value2).map(([token, value3]) => ( | ||
<TextM | ||
style={{ | ||
display: 'flex', | ||
height: '2.5rem', | ||
alignItems: 'center', | ||
}} | ||
> | ||
<div | ||
style={{ | ||
width: '32rem', | ||
}} | ||
> | ||
{token} | ||
</div> | ||
<div | ||
style={{ | ||
width: '16rem', | ||
}} | ||
> | ||
{/* INFO: для восстановления значения из палитры | ||
есть метод getRestoredColorFromPalette в | ||
plasma-tokens-utils | ||
Так же есть нюанс с его использованием: необходимо передавать | ||
вторым аргументом -1, чтобы вернулось | ||
корректное значение прозрачности, например [general.red.500][0.6] | ||
*/} | ||
{value3.includes('gradient') ? 'Градиент' : value3} | ||
</div> | ||
<div | ||
style={{ | ||
width: '1.25rem', | ||
height: '1.25rem', | ||
borderRadius: '50%', | ||
background: value3, | ||
boxShadow: 'inset 0px 0px 0px 1px rgba(8, 8, 8, 0.12)', | ||
}} | ||
/> | ||
</TextM> | ||
))} | ||
</div> | ||
))} | ||
</div> | ||
))} | ||
</StyledContainer> | ||
); | ||
}, | ||
}; |