From 9e96fae0da3a6b0c3fb6fa5f4dacf0c4bc9bd0c7 Mon Sep 17 00:00:00 2001 From: Daniil Gaponov Date: Sat, 15 Jun 2024 22:39:53 +0300 Subject: [PATCH] feat: base theme export --- .../ColorPickerInput/ColorPickerInput.scss | 12 ++- .../ColorPickerInput/ColorPickerInput.tsx | 1 + .../PrivateColorSelect/PrivateColorSelect.tsx | 37 +-------- .../Theme/ThemeCreator/ThemeCreator.tsx | 6 +- src/components/Theme/utils.ts | 83 ++++++++++++++++++- 5 files changed, 100 insertions(+), 39 deletions(-) diff --git a/src/components/ColorPickerInput/ColorPickerInput.scss b/src/components/ColorPickerInput/ColorPickerInput.scss index a42d8a7ef183..68d19b24298a 100644 --- a/src/components/ColorPickerInput/ColorPickerInput.scss +++ b/src/components/ColorPickerInput/ColorPickerInput.scss @@ -5,6 +5,11 @@ $block: '.#{variables.$ns}color-picker'; #{$block} { --g-border-radius-xl: 8px; flex-grow: 1; + position: relative; + + &__text-input { + z-index: 1; + } &__preview { margin-inline-start: var(--g-spacing-2); @@ -12,11 +17,14 @@ $block: '.#{variables.$ns}color-picker'; } &__input { - width: 100%; - height: 0; + width: 35px; opacity: 0; padding: 0; margin: 0; border: 0; + position: absolute; + bottom: 0; + right: 0; + z-index: 0; } } diff --git a/src/components/ColorPickerInput/ColorPickerInput.tsx b/src/components/ColorPickerInput/ColorPickerInput.tsx index 06d5c36dbe8f..1f458709bbd3 100644 --- a/src/components/ColorPickerInput/ColorPickerInput.tsx +++ b/src/components/ColorPickerInput/ColorPickerInput.tsx @@ -95,6 +95,7 @@ export const ColorPickerInput = ({ return ( = ({ const containerRef = React.useRef(null); const [showPopup, toggleShowPopup] = React.useReducer((prev) => !prev, false); const isCustomValue = !isPrivateColorToken(value); - const isValueDiffersFromDefault = defaultValue && defaultValue !== value; - - const defaultValueToken = React.useMemo(() => { - if (!defaultValue) { - return ''; - } - - const result = parsePrivateColorToken(defaultValue); - if (result) { - return createPrivateColorTitle(result.mainColorToken, result.privateColorCode); - } - - return ''; - }, [defaultValue]); - - const resetToDefault = React.useCallback(() => { - if (defaultValue) { - onChange(defaultValue); - } - }, [onChange, defaultValue]); const switchMode = React.useCallback(() => { if (isCustomValue) { @@ -85,17 +65,6 @@ export const PrivateColorSelect: React.FC = ({ - {isValueDiffersFromDefault && ( - - - - )} } controlProps={{ diff --git a/src/components/Theme/ThemeCreator/ThemeCreator.tsx b/src/components/Theme/ThemeCreator/ThemeCreator.tsx index d0c05ce8e5fd..90127174ccc5 100644 --- a/src/components/Theme/ThemeCreator/ThemeCreator.tsx +++ b/src/components/Theme/ThemeCreator/ThemeCreator.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {ThemeOptions} from '../types'; -import {initThemeWizard} from '../utils'; +import {exportTheme, initThemeWizard} from '../utils'; import {ThemeCreatorContextProvider} from './ThemeCreatorContext'; @@ -16,6 +16,10 @@ export const ThemeCreator: React.FC = ({theme, children}) => updateState(initThemeWizard(theme)); }, [theme]); + React.useEffect(() => { + console.log(exportTheme(state, 'scss')); + }, [state]); + return ( ({ token: createPrivateColorToken(token, privateColorCode), - title: createPrivateColorTitle(token, privateColorCode), + title: createPrivateColorCssVariable(token, privateColorCode), color, })), }, @@ -417,3 +434,65 @@ export function initThemeWizard(inputTheme: ThemeOptions): ThemeWizardState { tokens: Object.keys(paletteTokens), }; } + +type ExportType = 'scss' | 'json'; + +export function exportTheme(themeState: ThemeWizardState, exportType: ExportType = 'scss'): string { + if (exportType === 'json') { + throw new Error('Not implemented'); + } + + const {paletteTokens} = themeState; + + const prepareThemeVariables = (themeVariant: ThemeVariant) => { + let cssVariables = ''; + const privateColors: Record = {}; + + themeState.tokens.forEach((token) => { + // Dont export colors that are equals to default + if (DEFAULT_PALETTE[themeVariant][token] === themeState.palette[themeVariant][token]) { + return; + } + + if (paletteTokens[token]?.privateColors[themeVariant]) { + Object.entries(paletteTokens[token].privateColors[themeVariant]).forEach( + ([privateColorCode, color]) => { + privateColors[createPrivateColorToken(token, privateColorCode)] = color; + cssVariables += `${createPrivateColorCssVariable( + token, + privateColorCode, + )}: ${color};\n`; + }, + ); + cssVariables += '\n'; + } + }); + + cssVariables += '\n'; + + Object.entries(themeState.colors[themeVariant]).forEach( + ([colorName, colorOrPrivateToken]) => { + // Dont export colors that are equals to default + if ( + DEFAULT_THEME.colors[themeVariant][colorName as ColorOption] === + colorOrPrivateToken + ) { + return; + } + + const color = isPrivateColorToken(colorOrPrivateToken) + ? `var(${createPrivateColorCssVariableFromToken(colorOrPrivateToken)})` + : colorOrPrivateToken; + + cssVariables += `${createUtilityColorCssVariable(colorName)}: ${color};\n`; + }, + ); + + return cssVariables; + }; + + let result = ''; + result += '// Light\n' + prepareThemeVariables('light'); + result += '\n// Dark\n' + prepareThemeVariables('dark'); + return result; +}