diff --git a/plugins/figma/manifest.json b/plugins/figma/manifest.json index b4ce2f54cf..a40bad4fca 100644 --- a/plugins/figma/manifest.json +++ b/plugins/figma/manifest.json @@ -8,5 +8,7 @@ "enableProposedApi": false, "editorType": ["figma"], "documentAccess": "dynamic-page", - "networkAccess": { "allowedDomains": ["https://api.github.com"] } + "networkAccess": { + "allowedDomains": ["https://api.github.com", "https://altinncdn.no"] + } } diff --git a/plugins/figma/package.json b/plugins/figma/package.json index 28310ddbe0..62b10ba9cb 100644 --- a/plugins/figma/package.json +++ b/plugins/figma/package.json @@ -1,7 +1,7 @@ { "name": "figma-plugin", "private": true, - "version": "0.2.0", + "version": "0.3.0", "type": "module", "scripts": { "dev": "run-s watch", diff --git a/plugins/figma/src/plugin/figma/themes.ts b/plugins/figma/src/plugin/figma/themes.ts index 508bbc487a..e2d86ef3e7 100644 --- a/plugins/figma/src/plugin/figma/themes.ts +++ b/plugins/figma/src/plugin/figma/themes.ts @@ -5,13 +5,13 @@ import type { StoreThemes } from '../../common/store'; export const getThemes = async () => { const collections = await figma.variables.getLocalVariableCollectionsAsync(); const modeColModes = collections.find( - (collection) => collection.name === 'Mode', + (collection) => collection.name === 'Color scheme', )?.modes; const themeModes = collections.find( (collection) => collection.name === 'Theme', )?.modes; const modeColId = collections.find( - (collection) => collection.name === 'Mode', + (collection) => collection.name === 'Color scheme', )?.id; const variables = await figma.variables.getLocalVariablesAsync('COLOR'); diff --git a/plugins/figma/src/plugin/figma/updateVariables.ts b/plugins/figma/src/plugin/figma/updateVariables.ts index 24bbd74d5f..2ee9c3abbc 100644 --- a/plugins/figma/src/plugin/figma/updateVariables.ts +++ b/plugins/figma/src/plugin/figma/updateVariables.ts @@ -62,7 +62,7 @@ const updateColors = ( export const updateVariables = async (themes: StoreThemes) => { const collections = await figma.variables.getLocalVariableCollectionsAsync(); - const modeCollection = collections.find((col) => col.name === 'Mode'); + const modeCollection = collections.find((col) => col.name === 'Color scheme'); const themeCollection = collections.find((col) => col.name === 'Theme'); console.log('themes', themes); diff --git a/plugins/figma/src/ui/App.css b/plugins/figma/src/ui/App.css index 0c56231292..2e7597a1f2 100644 --- a/plugins/figma/src/ui/App.css +++ b/plugins/figma/src/ui/App.css @@ -1,5 +1,3 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap'); - * { font-feature-settings: 'cv05' 1; box-sizing: border-box; diff --git a/plugins/figma/src/ui/index.html b/plugins/figma/src/ui/index.html index ec4a1ae568..2268404b64 100644 --- a/plugins/figma/src/ui/index.html +++ b/plugins/figma/src/ui/index.html @@ -1,5 +1,17 @@ -
- + + + + + + + +
+ + + diff --git a/plugins/figma/src/ui/pages/Theme/Theme.tsx b/plugins/figma/src/ui/pages/Theme/Theme.tsx index cc12e8d4e3..51b19fe9e0 100644 --- a/plugins/figma/src/ui/pages/Theme/Theme.tsx +++ b/plugins/figma/src/ui/pages/Theme/Theme.tsx @@ -10,12 +10,11 @@ import { import { useEffect, useId, useState } from 'react'; import { Link as RouterLink, useParams } from 'react-router-dom'; -import { type ColorTheme, useThemeStore } from '../../../common/store'; - import type { CssColor } from '@adobe/leonardo-contrast-colors'; import { getDummyTheme } from '@common/dummyTheme'; +import { colorCliOptions } from '@digdir/designsystemet'; import { generateThemeForColor } from '@digdir/designsystemet/color'; -import { colorCliOptions } from '@digdir/designsystemet/tokens'; +import { type ColorTheme, useThemeStore } from '../../../common/store'; import { themeToFigmaFormat } from '../../../common/utils'; import classes from './Theme.module.css'; @@ -43,56 +42,104 @@ function Theme() { }); const handleClick = () => { - const pattern = new RegExp( - `--${colorCliOptions.main}\s+"accent:(#\w{6})"\s+--${colorCliOptions.neutral}\s+"(#\w{6})"\s+--${colorCliOptions.support}\s+"brand1:(#\w{6})"\s+"brand2:(#\w{6})"\s+"brand3:(#\w{6})"`, - ); - const matches = command.replace(/\\/g, '').match(pattern); + // split input into lines + const lines = command.split('\\\n'); - if (matches) { - const accent = matches[1] as CssColor; - const neutral = matches[2] as CssColor; - const brand1 = matches[3] as CssColor; - const brand2 = matches[4] as CssColor; - const brand3 = matches[5] as CssColor; + // helper regex for extracting color info + const colorRegex = /"([^:]+):(#\w{6})"/g; - console.log( - `Accent: ${accent}, Neutral: ${neutral}, Brand1: ${brand1}, Brand2: ${brand2}, Brand3: ${brand3}`, - ); + const result: { + mainColors: { name: string; hex: CssColor }[]; + neutralColor: CssColor | null; + supportColors: { name: string; hex: CssColor }[]; + } = { + mainColors: [], + neutralColor: null, + supportColors: [], + }; - const newArray = Array.from(themes); - newArray[themeIndex] = { - ...newArray[themeIndex], - colors: { - ...newArray[themeIndex].colors, - accent: themeToFigmaFormat(generateThemeForColor(accent)), - neutral: themeToFigmaFormat(generateThemeForColor(neutral)), - brand1: themeToFigmaFormat(generateThemeForColor(brand1)), - brand2: themeToFigmaFormat(generateThemeForColor(brand2)), - brand3: themeToFigmaFormat(generateThemeForColor(brand3)), - }, - }; - - setThemes(newArray); - setLoading(true); - setCommand(''); - - setTimeout(() => { - parent.postMessage( - { - pluginMessage: { - type: 'updateVariables', - themes: newArray, - }, - }, - '*', - ); - }, 500); - } else { + for (const line of lines) { + if (line.includes(`--${colorCliOptions.main}`)) { + const matches = [...line.matchAll(colorRegex)]; + result.mainColors = matches.map((match) => ({ + name: match[1], + hex: match[2] as CssColor, + })); + } else if (line.includes(`--${colorCliOptions.neutral}`)) { + const match = line.match(/#\w{6}/); + if (match) result.neutralColor = match[0] as CssColor; + } else if (line.includes(`--${colorCliOptions.support}`)) { + const matches = [...line.matchAll(colorRegex)]; + result.supportColors = matches.map((match) => ({ + name: match[1], + hex: match[2] as CssColor, + })); + } + } + + if (!result.mainColors.length || !result.neutralColor) { console.log('No match'); setCodeSnippetError( 'Koden du limte inn er ikke gyldig. Prøv å lim inn på nytt.', ); + return; } + + /* For now we check that we have accent, brand1, brand2, brand3 */ + const accent = result.mainColors.find( + (color) => color.name === 'accent', + )?.hex; + const brand1 = result.supportColors.find( + (color) => color.name === 'brand1', + )?.hex; + const brand2 = result.supportColors.find( + (color) => color.name === 'brand2', + )?.hex; + const brand3 = result.supportColors.find( + (color) => color.name === 'brand3', + )?.hex; + + const neutral = result.neutralColor; + + if (!accent || !brand1 || !brand2 || !brand3) { + setCodeSnippetError( + 'I denne versjonen av pluginen må du ha fargene accent, brand1, brand2 og brand3', + ); + return; + } + + console.log( + `Accent: ${accent}, Neutral: ${neutral}, Brand1: ${brand1}, Brand2: ${brand2}, Brand3: ${brand3}`, + ); + + const newArray = Array.from(themes); + newArray[themeIndex] = { + ...newArray[themeIndex], + colors: { + ...newArray[themeIndex].colors, + accent: themeToFigmaFormat(generateThemeForColor(accent)), + neutral: themeToFigmaFormat(generateThemeForColor(neutral)), + brand1: themeToFigmaFormat(generateThemeForColor(brand1)), + brand2: themeToFigmaFormat(generateThemeForColor(brand2)), + brand3: themeToFigmaFormat(generateThemeForColor(brand3)), + }, + }; + + setThemes(newArray); + setLoading(true); + setCommand(''); + + setTimeout(() => { + parent.postMessage( + { + pluginMessage: { + type: 'updateVariables', + themes: newArray, + }, + }, + '*', + ); + }, 500); }; return (