Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 73 additions & 4 deletions src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ function rgba2hex(orig: any) {
alpha = ((rgb && rgb[4]) || '').trim();
let hex = rgb
? (rgb[1] | (1 << 8)).toString(16).slice(1) +
(rgb[2] | (1 << 8)).toString(16).slice(1) +
(rgb[3] | (1 << 8)).toString(16).slice(1)
(rgb[2] | (1 << 8)).toString(16).slice(1) +
(rgb[3] | (1 << 8)).toString(16).slice(1)
: orig;

if (alpha !== '') {
Expand Down Expand Up @@ -54,6 +54,24 @@ function rgbaObjectToCSSHexaString(obj: {
** =================
*/

/*
** Converts a rgba object to a Dart hexa string
*/
function rgbaObjectToDartHexaString(obj: {
r: number;
g: number;
b: number;
a: number;
}): string {
const { r, g, b, a } = obj;
const rgbaString = rgba2hex(
`rgba(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(
b * 255
)}, ${a})`
);
return `Color(0x${rgbaString.substring(7)}${rgbaString.substring(1, 7)})`;
}

/*
** Converts a rgba JavaScript object to a Compose hexa string
*/
Expand Down Expand Up @@ -163,6 +181,27 @@ function generatesCSSValueString(variable: Variable): string {
}
}

/*
** Generates a Dart key string
*/
function generatesDartKeyString(variable: Variable): string {
const camelCaseVariableName = variable.name
.toLowerCase()
.replace(/-(\w)/g, (_, letter) => letter.toUpperCase());

const parts = camelCaseVariableName.split('/');
let transformedString = '';

for (let i = 0; i < parts.length; i++) {
const part = parts[i].trim();
const capitalizedPart =
(i > 0 ? part.charAt(0).toUpperCase() : part.charAt(0)) + part.slice(1);
transformedString += capitalizedPart;
}

return transformedString;
}

/*
** Generates a Compose key string
*/
Expand All @@ -179,6 +218,22 @@ function generatesComposeKeyString(variable: Variable): string {
return transformedString;
}

/*
** Generates a Dart value string
*/
function generatesDartValueString(variable: Variable): string {
const value: any =
variable.valuesByMode[Object.keys(variable.valuesByMode)[0]];
if (value.type === 'VARIABLE_ALIAS') {
const alias = <Variable>figmaVariables.find((obj) => obj.id === value.id);
return `Variables.${generatesDartKeyString(alias)}`;
} else if (variable.resolvedType === 'COLOR') {
return rgbaObjectToDartHexaString(value);
} else {
return value;
}
}

/*
** Generates a Compose value string
*/
Expand Down Expand Up @@ -241,6 +296,7 @@ figma.showUI(__html__);
/* Prepare variables for code generation */
let cssFile = ':root {\n';
let jsFile = '';
let dartFile = 'class Variables {\n';
let composeFile = 'object Variables {\n';
let swiftuiFile = 'struct Constants {\n';

Expand Down Expand Up @@ -269,6 +325,16 @@ filteredFigmaVariables
});
cssFile += '}';

/* Iterates through variables to generate Dart variables */
filteredFigmaVariables
.map((variable) => {
return ` static const ${generatesDartKeyString(variable)} = ${generatesDartValueString(variable)};`;
})
.forEach((variable) => {
dartFile += variable + '\n';
});
dartFile += '}';

/* Iterates through variables to generate Compose variables */
filteredFigmaVariables
.map(
Expand All @@ -282,7 +348,7 @@ filteredFigmaVariables
});
composeFile += '}';

/* Iterates through variables to generate Compose variables */
/* Iterates through variables to generate Swift UI variables */
filteredFigmaVariables
.map(
(variable) =>
Expand All @@ -296,7 +362,7 @@ filteredFigmaVariables
swiftuiFile += '}';

/* Sends to the UI the code generation */
figma.ui.postMessage({ cssFile, jsFile, composeFile, swiftuiFile });
figma.ui.postMessage({ cssFile, jsFile, dartFile, composeFile, swiftuiFile });

/* Catches event when code copied to clipboard and notify the user */
figma.ui.onmessage = (message) => {
Expand All @@ -306,6 +372,9 @@ figma.ui.onmessage = (message) => {
if (message.type === 'code-copied-js') {
figma.notify('JavaScript variables successfully copied to clipboard');
}
if (message.type === 'code-copied-dart') {
figma.notify('Dart variables successfully copied to clipboard');
}
if (message.type === 'code-copied-compose') {
figma.notify('Compose variables successfully copied to clipboard');
}
Expand Down
37 changes: 37 additions & 0 deletions src/ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<script>
let cssCode;
let jsCode;
let dartCode;
let composeCode;
let swiftuiCode;

Expand All @@ -96,6 +97,17 @@
document.getElementById('js-file').innerHTML = code;
});

shiki
.getHighlighter({
theme: 'nord',
langs: ['dart'],
})
.then((highlighter) => {
dartCode = event.data.pluginMessage.dartFile;
const code = highlighter.codeToHtml(dartCode, { lang: 'dart' });
document.getElementById('dart-file').innerHTML = code;
});

shiki
.getHighlighter({
theme: 'nord',
Expand Down Expand Up @@ -131,6 +143,9 @@
case 'css-file':
code = cssCode;
break;
case 'dart-file':
code = dartCode;
break;
case 'compose-file':
code = composeCode;
break;
Expand Down Expand Up @@ -219,6 +234,28 @@ <h2>JavaScript variables</h2>
<code id="js-file"></code>
</pre>

<div class="box-space-between">
<div class="box-flex-center">
<svg xmlns="http://www.w3.org/2000/svg" width="16" viewBox="0 0 64 64">
<path
fill="#F05138"
d="M59.387 16.45a82.463 82.463 0 0 0-.027-1.792c-.035-1.301-.112-2.614-.343-3.9-.234-1.307-.618-2.523-1.222-3.71a12.464 12.464 0 0 0-5.453-5.452C51.156.992 49.941.609 48.635.374c-1.288-.232-2.6-.308-3.902-.343a85.714 85.714 0 0 0-1.792-.027C42.23 0 41.52 0 40.813 0H18.578c-.71 0-1.419 0-2.128.004-.597.004-1.195.01-1.792.027-.325.009-.651.02-.978.036-.978.047-1.959.133-2.924.307-.98.176-1.908.436-2.811.81A12.503 12.503 0 0 0 3.89 3.89a12.46 12.46 0 0 0-2.294 3.158C.992 8.235.61 9.45.374 10.758c-.231 1.286-.308 2.599-.343 3.9a85.767 85.767 0 0 0-.027 1.792C-.001 17.16 0 17.869 0 18.578v22.235c0 .71 0 1.418.004 2.128.004.597.01 1.194.027 1.791.035 1.302.112 2.615.343 3.901.235 1.307.618 2.523 1.222 3.71a12.457 12.457 0 0 0 5.453 5.453c1.186.603 2.401.986 3.707 1.22 1.287.232 2.6.31 3.902.344.597.016 1.195.023 1.793.027.709.005 1.417.004 2.127.004h22.235c.709 0 1.418 0 2.128-.004.597-.004 1.194-.011 1.792-.027 1.302-.035 2.614-.112 3.902-.343 1.306-.235 2.521-.618 3.707-1.222a12.461 12.461 0 0 0 5.453-5.452c.604-1.187.987-2.403 1.222-3.71.231-1.286.308-2.6.343-3.9.016-.598.023-1.194.027-1.792.004-.71.004-1.419.004-2.129V18.578c0-.71 0-1.419-.004-2.128z"
/>
<path
fill="#FFF"
d="m47.06 36.66-.004-.004c.066-.224.134-.446.191-.675 2.465-9.821-3.55-21.432-13.731-27.546 4.461 6.048 6.434 13.374 4.681 19.78-.156.571-.344 1.12-.552 1.653-.225-.148-.51-.316-.89-.527 0 0-10.127-6.252-21.103-17.312-.288-.29 5.852 8.777 12.822 16.14-3.284-1.843-12.434-8.5-18.227-13.802.712 1.187 1.558 2.33 2.489 3.43C17.573 23.932 23.882 31.5 31.44 37.314c-5.31 3.25-12.814 3.502-20.285.003a30.646 30.646 0 0 1-5.193-3.098c3.162 5.058 8.033 9.423 13.96 11.97 7.07 3.039 14.1 2.833 19.336.05l-.004.007c.024-.016.055-.032.08-.047.214-.116.428-.234.636-.358 2.516-1.306 7.485-2.63 10.152 2.559.654 1.27 2.041-5.46-3.061-11.74z"
/>
</svg>
<h2>Dart variables</h2>
</div>
<button onclick="copyCodeToClipboard(('dart-file'))">
Copy to Clipboard
</button>
</div>
<pre>
<code id="dart-file"></code>
</pre>

<div class="box-space-between">
<div class="box-flex-center">
<svg
Expand Down