From 47f7e1c5a8fecfd109939bbc0c4b7812e4ebf71a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Thune?= Date: Mon, 4 Nov 2024 16:17:07 +0100 Subject: [PATCH] chore: refactor figma plugin (#2275) resolves #2630 --------- Co-authored-by: barsnes Co-authored-by: Michael Marszalek --- packages/cli/src/colors/utils.ts | 21 +- plugins/figma-plugin/src/common/types.ts | 9 - plugins/figma-plugin/src/plugin/plugin.ts | 68 - plugins/figma-plugin/src/ui/App.css | 59 - plugins/figma-plugin/src/ui/app.tsx | 48 - .../src/ui/components/Footer/Footer.tsx | 26 - .../src/ui/components/Toast/Toast.css | 24 - .../src/ui/components/Toast/Toast.tsx | 43 - plugins/figma-plugin/src/ui/index.html | 2 - .../src/ui/pages/PageOne/PageOne.tsx | 136 -- .../src/ui/pages/PageTwo/PageTwo.tsx | 5 - .../src/ui/pages/pageThree/PageThree.tsx | 5 - plugins/figma-plugin/tsconfig.json | 22 - plugins/{figma-plugin => figma}/.gitignore | 0 plugins/{figma-plugin => figma}/README.md | 0 .../assets/img/preview.png | Bin plugins/figma/decalations.d.ts | 0 plugins/{figma-plugin => figma}/manifest.json | 2 +- plugins/{figma-plugin => figma}/package.json | 12 +- plugins/figma/src/common/dummyTheme.ts | 274 +++ plugins/figma/src/common/store.ts | 79 + plugins/figma/src/common/types.ts | 19 + plugins/figma/src/common/utils.ts | 59 + .../figma/src/plugin/figma/getVariables.ts | 16 + plugins/figma/src/plugin/figma/themes.ts | 63 + .../figma/src/plugin/figma/updateVariables.ts | 94 + plugins/figma/src/plugin/plugin.ts | 96 + plugins/figma/src/ui/App.css | 90 + plugins/figma/src/ui/app.tsx | 31 + .../src/ui/components/Card/Card.module.css | 42 + plugins/figma/src/ui/components/Card/Card.tsx | 39 + .../ui/components/Footer/Footer.module.css} | 42 +- .../figma/src/ui/components/Footer/Footer.tsx | 43 + plugins/figma/src/ui/index.html | 5 + .../{figma-plugin => figma}/src/ui/main.tsx | 0 .../figma/src/ui/pages/Theme/Theme.module.css | 46 + plugins/figma/src/ui/pages/Theme/Theme.tsx | 155 ++ .../src/ui/pages/Themes/Themes.module.css | 13 + plugins/figma/src/ui/pages/Themes/Themes.tsx | 45 + plugins/figma/src/ui/theme.css | 1939 +++++++++++++++++ plugins/figma/src/ui/utils/useDsMode.ts | 46 + plugins/figma/src/ui/utils/useStartup.ts | 58 + .../src/ui/vite-env.d.ts | 0 plugins/figma/tsconfig.json | 14 + .../tsconfig.node.json | 0 .../vite.config.plugin.ts | 0 .../{figma-plugin => figma}/vite.config.ui.ts | 3 +- yarn.lock | 513 ++++- 48 files changed, 3825 insertions(+), 481 deletions(-) delete mode 100644 plugins/figma-plugin/src/common/types.ts delete mode 100644 plugins/figma-plugin/src/plugin/plugin.ts delete mode 100644 plugins/figma-plugin/src/ui/App.css delete mode 100644 plugins/figma-plugin/src/ui/app.tsx delete mode 100644 plugins/figma-plugin/src/ui/components/Footer/Footer.tsx delete mode 100644 plugins/figma-plugin/src/ui/components/Toast/Toast.css delete mode 100644 plugins/figma-plugin/src/ui/components/Toast/Toast.tsx delete mode 100644 plugins/figma-plugin/src/ui/index.html delete mode 100644 plugins/figma-plugin/src/ui/pages/PageOne/PageOne.tsx delete mode 100644 plugins/figma-plugin/src/ui/pages/PageTwo/PageTwo.tsx delete mode 100644 plugins/figma-plugin/src/ui/pages/pageThree/PageThree.tsx delete mode 100644 plugins/figma-plugin/tsconfig.json rename plugins/{figma-plugin => figma}/.gitignore (100%) rename plugins/{figma-plugin => figma}/README.md (100%) rename plugins/{figma-plugin => figma}/assets/img/preview.png (100%) create mode 100644 plugins/figma/decalations.d.ts rename plugins/{figma-plugin => figma}/manifest.json (79%) rename plugins/{figma-plugin => figma}/package.json (80%) create mode 100644 plugins/figma/src/common/dummyTheme.ts create mode 100644 plugins/figma/src/common/store.ts create mode 100644 plugins/figma/src/common/types.ts create mode 100644 plugins/figma/src/common/utils.ts create mode 100644 plugins/figma/src/plugin/figma/getVariables.ts create mode 100644 plugins/figma/src/plugin/figma/themes.ts create mode 100644 plugins/figma/src/plugin/figma/updateVariables.ts create mode 100644 plugins/figma/src/plugin/plugin.ts create mode 100644 plugins/figma/src/ui/App.css create mode 100644 plugins/figma/src/ui/app.tsx create mode 100644 plugins/figma/src/ui/components/Card/Card.module.css create mode 100644 plugins/figma/src/ui/components/Card/Card.tsx rename plugins/{figma-plugin/src/ui/components/Footer/Footer.css => figma/src/ui/components/Footer/Footer.module.css} (57%) create mode 100644 plugins/figma/src/ui/components/Footer/Footer.tsx create mode 100644 plugins/figma/src/ui/index.html rename plugins/{figma-plugin => figma}/src/ui/main.tsx (100%) create mode 100644 plugins/figma/src/ui/pages/Theme/Theme.module.css create mode 100644 plugins/figma/src/ui/pages/Theme/Theme.tsx create mode 100644 plugins/figma/src/ui/pages/Themes/Themes.module.css create mode 100644 plugins/figma/src/ui/pages/Themes/Themes.tsx create mode 100644 plugins/figma/src/ui/theme.css create mode 100644 plugins/figma/src/ui/utils/useDsMode.ts create mode 100644 plugins/figma/src/ui/utils/useStartup.ts rename plugins/{figma-plugin => figma}/src/ui/vite-env.d.ts (100%) create mode 100644 plugins/figma/tsconfig.json rename plugins/{figma-plugin => figma}/tsconfig.node.json (100%) rename plugins/{figma-plugin => figma}/vite.config.plugin.ts (100%) rename plugins/{figma-plugin => figma}/vite.config.ui.ts (86%) diff --git a/packages/cli/src/colors/utils.ts b/packages/cli/src/colors/utils.ts index 4727611b2d..090e0560eb 100644 --- a/packages/cli/src/colors/utils.ts +++ b/packages/cli/src/colors/utils.ts @@ -189,18 +189,19 @@ export const HSLToHex = (h: number, s: number, l: number) => { * Converts a HEX color '#xxxxxx' into an array of RGB values '[R, G, B]' * * @param hex A hex color string + * @param type The type of RGB values to return * @returns RGB values in an array */ -export const hexToRgb = (hex: string) => { +export const hexToRgb = (hex: string, type: '255' | '1' = '255') => { const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; hex = hex.replace(shorthandRegex, (m, r: string, g: string, b: string) => r + r + g + g + b + b); const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16), + r: type === '255' ? parseInt(result[1], 16) : parseInt(result[1], 16) / 255, + g: type === '255' ? parseInt(result[2], 16) : parseInt(result[2], 16) / 255, + b: type === '255' ? parseInt(result[3], 16) : parseInt(result[3], 16) / 255, } : null; }; @@ -382,3 +383,15 @@ export const convertToHex = (color?: string): CssColor => { } return chroma(color).hex() as CssColor; }; + +export const rgbToHex = (rgb: { r: number; g: number; b: number }) => { + return ( + '#' + + [rgb.r, rgb.g, rgb.b] + .map((x) => { + const hex = Math.round(x * 255).toString(16); + return hex.length === 1 ? '0' + hex : hex; + }) + .join('') + ); +}; diff --git a/plugins/figma-plugin/src/common/types.ts b/plugins/figma-plugin/src/common/types.ts deleted file mode 100644 index b6bd570141..0000000000 --- a/plugins/figma-plugin/src/common/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type JsonInput = { - theme: { - accent: object; - neutral: object; - brand1: object; - brand2: object; - brand3: object; - }; -}; diff --git a/plugins/figma-plugin/src/plugin/plugin.ts b/plugins/figma-plugin/src/plugin/plugin.ts deleted file mode 100644 index 57add14ccf..0000000000 --- a/plugins/figma-plugin/src/plugin/plugin.ts +++ /dev/null @@ -1,68 +0,0 @@ -figma.showUI(__html__, { width: 590, height: 575 }); - -function hexToRgb(hex: string) { - const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); - return result - ? { - r: parseInt(result[1], 16) / 255, - g: parseInt(result[2], 16) / 255, - b: parseInt(result[3], 16) / 255, - } - : null; -} - -function UpdateColor( - type: string, - obj: object, - modeId: string, - variable: Variable, -) { - const suffix = variable.name.split('/')[2]; - if (variable.name.startsWith(`theme/${type}`)) { - for (const [key, value] of Object.entries(obj)) { - if (key === suffix) { - const rgb = hexToRgb(value.value as string); - if (rgb) { - variable.setValueForMode(modeId, rgb); - } - } - } - } -} - -function getModeIndex(mode: string) { - if (mode === 'light') { - return 0; - } - return 1; -} - -figma.ui.onmessage = (msg: { type: string; text: string; mode: string }) => { - if (msg.type === 'update-variables') { - const obj = JSON.parse(msg.text); - const accent = obj.theme.accent as object; - const neutral = obj.theme.neutral as object; - const brand1 = obj.theme.brand1 as object; - const brand2 = obj.theme.brand2 as object; - const brand3 = obj.theme.brand3 as object; - - figma.variables.getLocalVariableCollectionsAsync().then((collections) => { - for (const collection of collections) { - if (collection.name === 'Mode') { - figma.variables.getLocalVariablesAsync('COLOR').then((variables) => { - const modeId: string = - collection.modes[getModeIndex(msg.mode)].modeId; - - for (const variable of variables) { - UpdateColor('accent', accent, modeId, variable); - UpdateColor('neutral', neutral, modeId, variable); - UpdateColor('brand1', brand1, modeId, variable); - UpdateColor('brand2', brand2, modeId, variable); - UpdateColor('brand3', brand3, modeId, variable); - } - }); - } - } - }); - } -}; diff --git a/plugins/figma-plugin/src/ui/App.css b/plugins/figma-plugin/src/ui/App.css deleted file mode 100644 index 7ef1c96250..0000000000 --- a/plugins/figma-plugin/src/ui/App.css +++ /dev/null @@ -1,59 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap'); - -* { - font-feature-settings: 'cv05' 1; - box-sizing: border-box; -} - -body { - font-family: 'Inter', sans-serif; - margin: 0; -} - -.content { - padding: 6px; -} - -.heading { - margin-bottom: 8px; -} - -.paragraph { - margin-bottom: 20px; - max-width: 98%; -} - -.modes { - margin-bottom: 20px; -} - -.textarea { - margin-bottom: 20px; -} - -.links { - display: flex; - border-bottom: 1px solid #cecece; - padding: 0 16px; -} - -.button { - position: absolute; - bottom: 65px; -} - -.link { - height: 52px; - display: flex; - align-items: center; - justify-content: center; - text-decoration: none; - color: #a0a0a0; - margin-right: 16px; - font-weight: 500; - font-size: 15px; -} - -.active { - color: #272727; -} diff --git a/plugins/figma-plugin/src/ui/app.tsx b/plugins/figma-plugin/src/ui/app.tsx deleted file mode 100644 index 9bd53e4474..0000000000 --- a/plugins/figma-plugin/src/ui/app.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import '@digdir/designsystemet-theme'; -import '@digdir/designsystemet-css'; - -import './App.css'; -import { Route, Routes } from 'react-router-dom'; - -import { Footer } from './components/Footer/Footer'; -import PageOne from './pages/PageOne/PageOne'; -import PageTwo from './pages/PageTwo/PageTwo'; -import PageThree from './pages/pageThree/PageThree'; - -function App() { - return ( -
- {/*
- (isActive ? 'link active' : 'link')} - to='/' - > - Lokale variabler - - - Sync fra repo - - - Oppdater UI Kit - -
*/} - -
- - } /> - } /> - } /> - -
-
-
- ); -} - -export default App; diff --git a/plugins/figma-plugin/src/ui/components/Footer/Footer.tsx b/plugins/figma-plugin/src/ui/components/Footer/Footer.tsx deleted file mode 100644 index 8f3900632e..0000000000 --- a/plugins/figma-plugin/src/ui/components/Footer/Footer.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import './Footer.css'; -import { Tooltip } from '@digdir/designsystemet-react'; -import { ChatElipsisIcon } from '@navikt/aksel-icons'; - -import packageJson from '../../../../package.json'; - -export const Footer = () => { - return ( -
-
-
-
V {packageJson.version}
- - - - - -
-
- ); -}; diff --git a/plugins/figma-plugin/src/ui/components/Toast/Toast.css b/plugins/figma-plugin/src/ui/components/Toast/Toast.css deleted file mode 100644 index ad193052a7..0000000000 --- a/plugins/figma-plugin/src/ui/components/Toast/Toast.css +++ /dev/null @@ -1,24 +0,0 @@ -.toast { - position: fixed; - z-index: 5; - bottom: -20px; - border-radius: 4px; - left: 16px; - right: 16px; - background-color: var(--ds-color-accent-surface-default); - box-shadow: var(--ds-shadow-xs); - height: 58px; - display: flex; - align-items: center; - padding: 0 16px; - gap: 12px; - transition: 0.4s all ease-out; -} - -.toastActive { - bottom: 65px; -} - -.toastClose { - bottom: -20px; -} diff --git a/plugins/figma-plugin/src/ui/components/Toast/Toast.tsx b/plugins/figma-plugin/src/ui/components/Toast/Toast.tsx deleted file mode 100644 index b1e716da25..0000000000 --- a/plugins/figma-plugin/src/ui/components/Toast/Toast.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { useEffect, useState } from 'react'; -import './Toast.css'; -import { Spinner } from '@digdir/designsystemet-react'; -import { CheckmarkIcon } from '@navikt/aksel-icons'; -import cl from 'clsx/lite'; - -export const Toast = () => { - const [success, setSuccess] = useState(false); - const [open, setOpen] = useState(false); - const [close, setClose] = useState(false); - - useEffect(() => { - setTimeout(() => { - setOpen(true); - }, 10); - setTimeout(() => { - setSuccess(true); - }, 6000); - - setTimeout(() => { - setClose(true); - }, 7500); - }, []); - - return ( -
- {success && ( - <> -
- -
{' '} - Oppdatering vellykket! - - )} - {!success && ( - <> - - Oppdaterer variabler... - - )} -
- ); -}; diff --git a/plugins/figma-plugin/src/ui/index.html b/plugins/figma-plugin/src/ui/index.html deleted file mode 100644 index 440f1f2593..0000000000 --- a/plugins/figma-plugin/src/ui/index.html +++ /dev/null @@ -1,2 +0,0 @@ -
- diff --git a/plugins/figma-plugin/src/ui/pages/PageOne/PageOne.tsx b/plugins/figma-plugin/src/ui/pages/PageOne/PageOne.tsx deleted file mode 100644 index 9245f3fdd4..0000000000 --- a/plugins/figma-plugin/src/ui/pages/PageOne/PageOne.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { - Button, - Heading, - Label, - Link, - Paragraph, - Textarea, - ToggleGroup, - ValidationMessage, -} from '@digdir/designsystemet-react'; -import { useState } from 'react'; - -import { Toast } from '@ui/components/Toast/Toast'; - -import type { JsonInput } from '../../../common/types'; - -function PageOne() { - const [jsonText, setJsonText] = useState(''); - const [mode, setMode] = useState('light'); - const [errorText, setErrorText] = useState(''); - const [isLoading, setIsLoading] = useState(false); - - const isJsonValid = (str: string) => { - try { - JSON.parse(str); - } catch (e) { - return false; - } - return true; - }; - - const isJsonCorrect = (str: string) => { - try { - const obj = JSON.parse(str) as JsonInput; - if ( - obj.theme.accent && - obj.theme.neutral && - obj.theme.brand1 && - obj.theme.brand2 && - obj.theme.brand3 - ) { - return true; - } - } catch (e) { - return false; - } - return false; - }; - - const onSubmit = () => { - if (isLoading) { - return; - } - - if (jsonText === '') { - setErrorText('Dette feltet er påkrevd.'); - return; - } - - if (!isJsonValid(jsonText) || !isJsonCorrect(jsonText)) { - setErrorText('Ugyldig JSON, prøv og kopier og lim inn på nytt.'); - setJsonText(''); - return; - } - - setIsLoading(true); - setErrorText(''); - setJsonText(''); - - setTimeout(() => { - parent.postMessage( - { pluginMessage: { type: 'update-variables', text: jsonText, mode } }, - '*', - ); - }, 400); - - setTimeout(() => { - setIsLoading(false); - }, 7900); - }; - return ( -
-
- - Oppdater fargetema - - - - Oppdater{' '} - - Designsystemet - Core UI Kit - {' '} - community filen med ditt eget fargetema. Gå til{' '} - - theme.designsystemet.no - {' '} - og lag temaet ditt, velg light- eller dark mode og lim inn JSON koden - i feltet under. - - - setMode(e)} - > - Light Mode - Dark Mode - {/* Contrast */} - - -