From 354b6550fd45b438368bd315b965a0332e68a464 Mon Sep 17 00:00:00 2001 From: Viktoria Dragun Date: Fri, 14 Jun 2024 01:02:12 +0300 Subject: [PATCH] refactor: colors generator --- .../src/FigmaThemeColorsGenerator.ts | 137 +++++++++++++---- .../theme-colors-generator/src/Interfaces.ts | 38 +++-- .../src/getters/get-button-states.ts | 120 --------------- .../src/getters/get-input-states.ts | 140 ------------------ .../src/getters/index.ts | 2 - theme/theme/src/FigmaTheme.ts | 12 +- 6 files changed, 130 insertions(+), 319 deletions(-) delete mode 100644 theme/theme-colors-generator/src/getters/get-button-states.ts delete mode 100644 theme/theme-colors-generator/src/getters/get-input-states.ts delete mode 100644 theme/theme-colors-generator/src/getters/index.ts diff --git a/theme/theme-colors-generator/src/FigmaThemeColorsGenerator.ts b/theme/theme-colors-generator/src/FigmaThemeColorsGenerator.ts index cbb2fdd..65db901 100644 --- a/theme/theme-colors-generator/src/FigmaThemeColorsGenerator.ts +++ b/theme/theme-colors-generator/src/FigmaThemeColorsGenerator.ts @@ -5,13 +5,14 @@ import { FigmaThemeGenerator } from '@atls/figma-theme-generator-common' import { FigmaThemeGeneratorResult } from '@atls/figma-theme-generator-common' import { clearStringOfSpecialChars } from '@atls/figma-utils' import { isColor } from '@atls/figma-utils' +import { toColorOpacityString } from '@atls/figma-utils' import { toAverage } from '@atls/figma-utils' import { toColorName } from '@atls/figma-utils' import { toColorString } from '@atls/figma-utils' import { walk } from '@atls/figma-utils' -import { getButtonStates } from './getters' -import { getInputStates } from './getters' +import { ButtonState } from './Interfaces' +import { InputState } from './Interfaces' export class FigmaThemeColorsGenerator extends FigmaThemeGenerator { readonly name = 'colors' @@ -24,20 +25,106 @@ export class FigmaThemeColorsGenerator extends FigmaThemeGenerator { return camelCase(clearStringOfSpecialChars(str), { pascalCase: false }) } - getColor(obj) { - if (obj.type === 'TEXT') return toColorString(obj.fills[0]?.color) - if (obj.type === 'INSTANCE') + getColor(obj): string { + if (obj?.type === 'TEXT') { + return toColorString(obj.fills[0]?.color) + } + if (obj?.type === 'INSTANCE') { return obj.children[0].fills[0]?.color ? toColorString(obj.children[0].fills[0].color) : 'rgba(0, 0, 0, 0.00)' - + } return '' } - getColors(nodes) { + getColors(nodes): any { const colors = {} + const buttonNames: string[] = [] + const buttonStates: ButtonState[] = [] + const inputStates: InputState[] = [] + const inputNames: string[] = [] walk(nodes, (node) => { + const { name } = node + + if (name?.match(this.buttonFrameId)) { + const names = node.children.map((buttonName) => buttonName.name) + + const buttons = node.children.map((item) => { + const obj = { + name: item.name, + default: item.children[0], + hover: item.children[1], + pressed: item.children[2] !== undefined ? item.children[2] : item.children[0], + disabled: item.children[3] !== undefined ? item.children[3] : item.children[0], + } + + const getStateColors = (state) => ({ + background: state?.backgroundColor + ? toColorString(state.backgroundColor) + : 'rgba(0, 0, 0, 0.00)', + font: this.getColor(state?.children?.find((child) => child?.type === 'TEXT')), + border: state?.strokes[0]?.color + ? toColorOpacityString(state.strokes[0].color, state.strokes[0]?.opacity) + : 'rgba(0, 0, 0, 0.00)', + }) + + return { + default: getStateColors(obj.default), + hover: getStateColors(obj.hover), + pressed: getStateColors(obj.pressed), + disabled: getStateColors(obj.disabled), + } + }) + + buttonStates.push(...buttons) + names.forEach((buttonName: string) => { + if (buttonName) { + buttonNames.push(this.formatString(buttonName)) + } + }) + } + + if (name?.match(this.inputFrameId)) { + const names = node.children.map((inputName) => inputName.name) + + const inputs = node.children.map((item) => { + const obj = { + name: item.name, + default: item.children[0], + active: item.children[1], + error: item.children[2], + focus: item.children[3], + disabled: item.children[4] !== undefined ? item.children[4] : item.children[0], + } + + const getStateColors = (state) => ({ + background: state?.backgroundColor + ? toColorString(state.backgroundColor) + : 'rgba(0, 0, 0, 0.00)', + font: this.getColor(state?.children?.find((child) => child?.type === 'TEXT')), + border: state?.strokes[0]?.color + ? toColorOpacityString(state.strokes[0].color, state.strokes[0]?.opacity) + : 'rgba(0, 0, 0, 0.00)', + }) + + return { + default: getStateColors(obj.default), + active: getStateColors(obj.active), + error: getStateColors(obj.error), + focus: getStateColors(obj.focus), + disabled: getStateColors(obj.disabled), + } + }) + + inputStates.push(...inputs) + names.forEach((inputName: string) => { + if (inputName) { + inputNames.push(this.formatString(inputName)) + } + }) + } + if (node.color && isColor(node.color)) { const color = toColorString(node.color) if (!colors[color]) { @@ -46,7 +133,7 @@ export class FigmaThemeColorsGenerator extends FigmaThemeGenerator { } }) - return Object.keys(colors) + const colorsResult = Object.keys(colors) .sort((a, b) => toAverage(colors[b]) - toAverage(colors[a])) .reduce( (result, color) => ({ @@ -55,24 +142,6 @@ export class FigmaThemeColorsGenerator extends FigmaThemeGenerator { }), {} ) - } - - generate(file: FileResponse): FigmaThemeGeneratorResult { - const colorsResult = this.getColors(file.document.children) - - const { buttonNames, buttonStates } = getButtonStates( - file.document.children, - this.buttonFrameId, - this.getColor.bind(this), - this.formatString.bind(this) - ) - - const { inputNames, inputStates } = getInputStates( - file.document.children, - this.inputFrameId, - this.getColor.bind(this), - this.formatString.bind(this) - ) const buttonColorsResult = buttonNames.reduce( (result, name, index) => ({ @@ -90,15 +159,23 @@ export class FigmaThemeColorsGenerator extends FigmaThemeGenerator { {} ) - const result = { + return { ...colorsResult, - ...(Object.keys(buttonColorsResult).length ? { button: buttonColorsResult } : {}), - ...(Object.keys(inputColorsResult).length ? { input: inputColorsResult } : {}), + ...(Object.keys(buttonColorsResult).length + ? { + button: { ...buttonColorsResult }, + } + : {}), + ...(Object.keys(inputColorsResult).length ? { input: { ...inputColorsResult } } : {}), } + } + + generate(file: FileResponse): FigmaThemeGeneratorResult { + const values = this.getColors(file.document.children) return { name: this.name, - content: this.exportValuesTemplate('colors', result), + content: this.exportValuesTemplate('colors', values), } } } diff --git a/theme/theme-colors-generator/src/Interfaces.ts b/theme/theme-colors-generator/src/Interfaces.ts index 6f49ee9..acceb3b 100644 --- a/theme/theme-colors-generator/src/Interfaces.ts +++ b/theme/theme-colors-generator/src/Interfaces.ts @@ -1,22 +1,20 @@ export interface ButtonState { - default: { - background: string - font: string - border: string - } - hover: { - background: string - font: string - border: string - } - pressed: { - background: string - font: string - border: string - } - disabled: { - background: string - font: string - border: string - } + default: StateColors + hover: StateColors + pressed: StateColors + disabled: StateColors +} + +export interface InputState { + default: StateColors + active: StateColors + error: StateColors + focus: StateColors + disabled: StateColors +} + +export interface StateColors { + background: string + font: string + border: string } diff --git a/theme/theme-colors-generator/src/getters/get-button-states.ts b/theme/theme-colors-generator/src/getters/get-button-states.ts deleted file mode 100644 index e33ed2e..0000000 --- a/theme/theme-colors-generator/src/getters/get-button-states.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { toColorOpacityString } from '@atls/figma-utils' -import { toColorString } from '@atls/figma-utils' - -interface ButtonState { - default: StateColors - hover: StateColors - pressed: StateColors - disabled: StateColors -} - -interface StateColors { - background: string - font: string - border: string -} - -export function getButtonStates( - nodes, - frameId: string, - getColor: (obj: any) => string, - formatString: (str: string) => string -) { - const buttonStates: ButtonState[] = [] - const buttonNames: string[] = [] - - nodes.forEach((node) => { - const { name } = node - if (name?.match(frameId)) { - const names = node.children.map((buttonName) => buttonName.name) - - const buttons = node.children - .map((item) => { - const obj = { - name: item.name, - default: item.children[0], - hover: item.children[1], - pressed: item.children[2] !== undefined ? item.children[2] : item.children[0], - disabled: item.children[3] !== undefined ? item.children[3] : item.children[0], - } - - const fontDefault = obj.default.children.find((child) => child.type === 'TEXT') - const fontColorDefault = fontDefault ? getColor(fontDefault) : 'rgba(0, 0, 0, 0.00)' - - const backgroundColorDefault = toColorString(obj.default.backgroundColor) - const borderColorDefault = - obj.default.strokes[0]?.color !== undefined - ? toColorOpacityString(obj.default.strokes[0].color, obj.default.strokes[0]?.opacity) - : 'rgba(0, 0, 0, 0.00)' - - const fontHover = obj.hover?.children?.find((child) => child.type === 'TEXT') - const fontColorHover = fontHover ? getColor(fontHover) : 'rgba(0, 0, 0, 0.00)' - - const backgroundColorHover = obj.hover?.backgroundColor - ? toColorString(obj.hover.backgroundColor) - : 'rgba(0, 0, 0, 0.00)' - const borderColorHover = - obj.hover.strokes[0]?.color !== undefined - ? toColorOpacityString(obj.hover.strokes[0].color, obj.hover.strokes[0]?.opacity) - : 'rgba(0, 0, 0, 0.00)' - - const fontPressed = obj.pressed?.children?.find((child) => child.type === 'TEXT') - const fontColorPressed = fontPressed ? getColor(fontPressed) : 'rgba(0, 0, 0, 0.00)' - - const backgroundColorPressed = toColorString(obj.pressed.backgroundColor) - const borderColorPressed = - obj.pressed.strokes[0]?.color !== undefined - ? toColorOpacityString(obj.pressed.strokes[0].color, obj.pressed.strokes[0]?.opacity) - : 'rgba(0, 0, 0, 0.00)' - - const fontDisabled = obj.disabled?.children?.find((child) => child.type === 'TEXT') - const fontColorDisabled = fontDisabled ? getColor(fontDisabled) : 'rgba(0, 0, 0, 0.00)' - - const backgroundColorDisabled = toColorString(obj.disabled.backgroundColor) - const borderColorDisabled = - obj.disabled.strokes[0]?.color !== undefined - ? toColorOpacityString( - obj.disabled.strokes[0].color, - obj.disabled.strokes[0]?.opacity - ) - : 'rgba(0, 0, 0, 0.00)' - - return { - default: { - background: backgroundColorDefault, - font: fontColorDefault, - border: borderColorDefault, - }, - hover: { - background: backgroundColorHover, - font: fontColorHover, - border: borderColorHover, - }, - pressed: { - background: backgroundColorPressed, - font: fontColorPressed, - border: borderColorPressed, - }, - disabled: { - background: backgroundColorDisabled, - font: fontColorDisabled, - border: borderColorDisabled, - }, - } - }) - .flat() - .filter((item) => item !== undefined) - - buttonStates.push(...buttons) - - names.forEach((buttonName: string) => { - if (buttonName !== undefined) { - const trimItem = formatString(buttonName) - buttonNames.push(trimItem) - } - }) - } - }) - - return { buttonNames, buttonStates } -} diff --git a/theme/theme-colors-generator/src/getters/get-input-states.ts b/theme/theme-colors-generator/src/getters/get-input-states.ts deleted file mode 100644 index f250777..0000000 --- a/theme/theme-colors-generator/src/getters/get-input-states.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { toColorOpacityString } from '@atls/figma-utils' -import { toColorString } from '@atls/figma-utils' - -interface InputState { - default: StateColors - active: StateColors - error: StateColors - focus: StateColors - disabled: StateColors -} - -interface StateColors { - background: string - font: string - border: string -} - -export function getInputStates( - nodes, - frameId: string, - getColor: (obj: any) => string, - formatString: (str: string) => string -) { - const inputStates: InputState[] = [] - const inputNames: string[] = [] - - nodes.forEach((node) => { - const { name } = node - if (name?.match(frameId)) { - const names = node.children.map((inputName) => inputName.name) - - const inputs = node.children - .map((item) => { - const obj = { - name: item.name, - default: item.children[0], - active: item.children[1], - error: item.children[2], - focus: item.children[3], - disabled: item.children[4] !== undefined ? item.children[4] : item.children[0], - } - - const fontDefault = obj.default.children.find((child) => child.type === 'TEXT') - const fontColorDefault = fontDefault ? getColor(fontDefault) : 'rgba(0, 0, 0, 0.00)' - - const backgroundColorDefault = toColorString(obj.default.backgroundColor) - const borderColorDefault = - obj.default.strokes[0]?.color !== undefined - ? toColorOpacityString(obj.default.strokes[0].color, obj.default.strokes[0]?.opacity) - : 'rgba(0, 0, 0, 0.00)' - - const fontActive = obj.active?.children?.find((child) => child.type === 'TEXT') - const fontColorActive = fontActive ? getColor(fontActive) : 'rgba(0, 0, 0, 0.00)' - - const backgroundColorActive = obj.active?.backgroundColor - ? toColorString(obj.active.backgroundColor) - : 'rgba(0, 0, 0, 0.00)' - const borderColorActive = - obj.active.strokes[0]?.color !== undefined - ? toColorOpacityString(obj.active.strokes[0].color, obj.active.strokes[0]?.opacity) - : 'rgba(0, 0, 0, 0.00)' - - const fontError = obj.error?.children?.find((child) => child.type === 'TEXT') - const fontColorError = fontError ? getColor(fontError) : 'rgba(0, 0, 0, 0.00)' - - const backgroundColorError = obj.error?.backgroundColor - ? toColorString(obj.error.backgroundColor) - : 'rgba(0, 0, 0, 0.00)' - const borderColorError = - obj.error?.strokes[0]?.color !== undefined - ? toColorOpacityString(obj.error.strokes[0].color, obj.error.strokes[0]?.opacity) - : 'rgba(0, 0, 0, 0.00)' - - const fontFocus = obj.focus?.children?.find((child) => child.type === 'TEXT') - const fontColorFocus = fontFocus ? getColor(fontFocus) : 'rgba(0, 0, 0, 0.00)' - - const backgroundColorFocus = obj.focus?.backgroundColor - ? toColorString(obj.focus.backgroundColor) - : 'rgba(0, 0, 0, 0.00)' - const borderColorFocus = - obj.focus?.strokes[0]?.color !== undefined - ? toColorOpacityString(obj.focus.strokes[0].color, obj.focus.strokes[0]?.opacity) - : 'rgba(0, 0, 0, 0.00)' - - const fontDisabled = obj.disabled?.children?.find((child) => child.type === 'TEXT') - const fontColorDisabled = fontDisabled ? getColor(fontDisabled) : 'rgba(0, 0, 0, 0.00)' - - const backgroundColorDisabled = toColorString(obj.disabled.backgroundColor) - const borderColorDisabled = - obj.disabled.strokes[0]?.color !== undefined - ? toColorOpacityString( - obj.disabled.strokes[0].color, - obj.disabled.strokes[0]?.opacity - ) - : 'rgba(0, 0, 0, 0.00)' - - return { - default: { - background: backgroundColorDefault, - font: fontColorDefault, - border: borderColorDefault, - }, - active: { - background: backgroundColorActive, - font: fontColorActive, - border: borderColorActive, - }, - error: { - background: backgroundColorError, - font: fontColorError, - border: borderColorError, - }, - focus: { - background: backgroundColorFocus, - font: fontColorFocus, - border: borderColorFocus, - }, - disabled: { - background: backgroundColorDisabled, - font: fontColorDisabled, - border: borderColorDisabled, - }, - } - }) - .flat() - .filter((item) => item !== undefined) - - inputStates.push(...inputs) - - names.forEach((inputName: string) => { - if (inputName !== undefined) { - const trimItem = formatString(inputName) - inputNames.push(trimItem) - } - }) - } - }) - - return { inputNames, inputStates } -} diff --git a/theme/theme-colors-generator/src/getters/index.ts b/theme/theme-colors-generator/src/getters/index.ts deleted file mode 100644 index 700e18a..0000000 --- a/theme/theme-colors-generator/src/getters/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './get-input-states' -export * from './get-button-states' diff --git a/theme/theme/src/FigmaTheme.ts b/theme/theme/src/FigmaTheme.ts index dd9bebe..4956e9a 100644 --- a/theme/theme/src/FigmaTheme.ts +++ b/theme/theme/src/FigmaTheme.ts @@ -84,13 +84,11 @@ export class FigmaTheme { }, } - await Promise.all( - fileData.document.children.map(async () => { - generators.forEach(async (Generator) => { - const instance = new Generator() - const result = await Promise.resolve(instance.generate(fileData)) - await this.write(result) - }) + return Promise.all( + generators.map(async (Generator) => { + const instance = new Generator() + const result = await Promise.resolve(instance.generate(fileData)) + await this.write(result) }) ) }