-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: Adds compiler for turning Figma nodes into Stylesheets (#200)
* adding package for figma non-plugin integrations * migrate designer core to adaptive-ui-designer-core package * Update adaptive-uifigma-designer imports to source from adaptive-ui-designer-core * Add REST node parsing to adaptive-ui-designer-figma * rename plugin directory * Add CLI to compile stylesheets * Add JSON compiler to adaptive-ui and add readme * refactor spinalCase to kebabCase * remove company references * fixing declaration path and schema url * Update packages/adaptive-ui-designer-figma-plugin/src/core/code-gen.ts * fixing typescript build * Change files * adds CI process to build all packages before running tests --------- Co-authored-by: nicholasrice <nicholasrice@users.noreply.github.com>
- Loading branch information
1 parent
d413592
commit ab3d387
Showing
77 changed files
with
4,625 additions
and
1,679 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
change/@adaptive-web-adaptive-ui-9435dadf-6d12-4915-9466-dd24533274aa.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "minor", | ||
"comment": "Adds stylesheet generation from JSON anatomy", | ||
"packageName": "@adaptive-web/adaptive-ui", | ||
"email": "nicholasrice@users.noreply.github.com", | ||
"dependentChangeType": "patch" | ||
} |
7 changes: 7 additions & 0 deletions
7
change/@adaptive-web-adaptive-ui-designer-core-7c2a3ded-5385-4952-897c-53aa895bfaca.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "minor", | ||
"comment": "Initial package creation", | ||
"packageName": "@adaptive-web/adaptive-ui-designer-core", | ||
"email": "nicholasrice@users.noreply.github.com", | ||
"dependentChangeType": "patch" | ||
} |
7 changes: 7 additions & 0 deletions
7
change/@adaptive-web-adaptive-ui-designer-figma-2970b0fd-66c9-45a2-bbe8-a7ea479f0a96.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "minor", | ||
"comment": "Initial package creation", | ||
"packageName": "@adaptive-web/adaptive-ui-designer-figma", | ||
"email": "nicholasrice@users.noreply.github.com", | ||
"dependentChangeType": "patch" | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "@adaptive-web/adaptive-ui-designer-core", | ||
"version": "0.0.0", | ||
"description": "Core infrastructure for the Adaptive UI Designer", | ||
"main": "dist/esm/index.js", | ||
"exports": { | ||
".": { | ||
"types": "./dist/dts/index.d.ts", | ||
"default": "./dist/esm/index.js" | ||
} | ||
}, | ||
"type": "module", | ||
"scripts": { | ||
"build": "tsc", | ||
"watch": "tsc --watch" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/adaptive-web-community/adaptive-web-components.git" | ||
}, | ||
"author": { | ||
"name": "Adaptive Web Community", | ||
"url": "https://github.com/adaptive-web-community" | ||
}, | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/adaptive-web-community/adaptive-web-components/issues" | ||
}, | ||
"homepage": "https://github.com/adaptive-web-community/adaptive-web-components#readme", | ||
"dependencies": { | ||
"@adaptive-web/adaptive-ui": "^0.3.0", | ||
"@microsoft/fast-foundation": "^3.0.0-alpha.31" | ||
}, | ||
"devDependencies": { | ||
"typescript": "^5.4.5" | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export { Controller, PluginUIState, STYLE_REMOVE } from "./controller.js"; | ||
export { | ||
PluginMessage, | ||
PluginNodeData, | ||
AppliedStyleModules, | ||
AppliedStyleValues, | ||
PluginUINodeData, | ||
AdditionalDataKeys, | ||
DesignTokenValue, | ||
AppliedDesignToken, | ||
AppliedStyleValue, | ||
AdditionalData, | ||
AppliedDesignTokens, | ||
DesignTokenValues | ||
} from "./model.js"; | ||
export { mapReplacer, mapReviver, deserializeMap } from "./serialization.js"; | ||
export { State, StatesState, PluginNode, focusIndicatorNodeName, } from "./node.js"; | ||
export { DesignTokenDefinition, DesignTokenRegistry, FormControlId } from "./registry/design-token-registry.js"; | ||
export { nameToTitle, registerAppliableTokens, registerTokens } from "./registry/recipes.js"; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"extends": "../../tsconfig.json", | ||
"compilerOptions": { | ||
"baseUrl": ".", | ||
"importHelpers": true, | ||
"lib": ["DOM", "ES2020"], | ||
"skipLibCheck": true, | ||
"declarationDir": "dist/dts", | ||
"outDir": "dist/esm", | ||
"rootDir": "src" | ||
}, | ||
} |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
packages/adaptive-ui-designer-figma-plugin/src/core/code-gen.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* eslint-disable max-len */ | ||
import { camelCase, kebabCase } from "change-case"; | ||
import { StyleNameMapping } from "@adaptive-web/adaptive-ui/reference"; | ||
import { Anatomy, BooleanCondition, Condition, StringCondition, StyleRule } from "@adaptive-web/adaptive-ui-designer-figma"; | ||
|
||
function makeClassName(value: string) { | ||
return `.${kebabCase(value)}`; | ||
} | ||
|
||
/** | ||
* Code generation capabilities related to component anatomy and styling. | ||
* | ||
* @remarks | ||
* The functionality here is split into two parts to facilitate reuse and customization: | ||
* - Design tool node parsing into a component anatomy definition | ||
* - Generating AUI code based on the anatomy definition (functions named "generate" or "gen") | ||
* | ||
* The common flow for all output is: | ||
* ``` ts | ||
* const codeGen = new CodeGen(); | ||
* const anatomyOutput = codeGen.generateAnatomyCode(anatomy); | ||
* const stylesOutput = codeGen.generateStylesCode(anatomy); | ||
* ``` | ||
*/ | ||
export class CodeGen { | ||
/** | ||
* Generates anatomy code for the provided anatomy definition. | ||
* | ||
* @param anatomy - The provided anatomy definition | ||
* @returns The generated anatomy code | ||
*/ | ||
public generateAnatomyCode(anatomy: Anatomy): string { | ||
const conditionsSet = new Array(...anatomy.conditions.entries()) | ||
.reduce((accumulated: Set<string>, current: [string, Condition]): Set<string> => { | ||
if (current[1] instanceof BooleanCondition) { | ||
accumulated.add(current[0]); | ||
} else if (current[1] instanceof StringCondition) { | ||
current[1].values.forEach(value => { | ||
const currentValue = `${current[0]}${value}`; | ||
accumulated.add(currentValue); | ||
}); | ||
} | ||
|
||
return accumulated; | ||
}, new Set()); | ||
const conditionsOut = this.#genTypeCode(anatomy.name, "Conditions", conditionsSet); | ||
const partsOut = this.#genTypeCode(anatomy.name, "Parts", anatomy.parts); | ||
|
||
// TODO other states (json serialize?) | ||
const interactivity = anatomy.interactivity ? `\n interactivity: {\n interactive: "${anatomy.interactivity.interactive}",\n disabled: "${anatomy.interactivity.disabled}",\n },` : ""; | ||
const conditionsValues = new Array(...conditionsSet).map(property => `\n ${camelCase(property)}: "${makeClassName(property)}",`).join(""); | ||
const partsValues = new Array(...anatomy.parts).map(property => `\n ${camelCase(property)}: "${makeClassName(property)}",`).join(""); | ||
|
||
const anatomyOut = | ||
`export const ${anatomy.name}Anatomy: ComponentAnatomy<${anatomy.name}Conditions, ${anatomy.name}Parts> = {${interactivity} | ||
conditions: {${conditionsValues} | ||
}, | ||
parts: {${partsValues} | ||
}, | ||
}; | ||
`; | ||
// TODO: | ||
// focus: Focus.contextFocused(), | ||
|
||
const output = `${conditionsOut}\n${partsOut}\n${anatomyOut}\n`; | ||
return output; | ||
} | ||
|
||
#genTypeCode(componentName: string, type: "Parts" | "Conditions", properties: Set<string>): string { | ||
// const partsString = parts.map(part => ` ${camelCase(part)}: "${kebabCase(part)}"`).join("\n"); | ||
// const code = `export const ${componentName}Parts = {\n${partsString}\n};`; | ||
const propertiesString = new Array(...properties).map(property => ` ${camelCase(property)}: string;`).join("\n"); | ||
return `export type ${componentName}${type} = {\n${propertiesString}\n};\n`; | ||
} | ||
|
||
/** | ||
* Generates styling code for the provided anatomy definition. | ||
* | ||
* @param anatomy - The provided anatomy definition | ||
* @returns The generated style code | ||
*/ | ||
public generateStylesCode(anatomy: Anatomy): string { | ||
const imported = new Array(...anatomy.styleRules).reduce<Array<string>>((accumulated, current) => { | ||
current.styles.forEach(style => { | ||
const varName = StyleNameMapping[style as keyof typeof StyleNameMapping]; | ||
accumulated.push(varName); | ||
}); | ||
current.tokens.forEach(token => { | ||
const varName = this.tokenIDMap(token.tokenID); | ||
accumulated.push(varName); | ||
}); | ||
return accumulated; | ||
}, new Array<string>()); | ||
const importBase = `import { StyleRules } from "@adaptive-web/adaptive-ui";\n`; | ||
const refImports = [...imported].sort().join(", "); | ||
const importRef = `import { ${refImports} } from "@adaptive-web/adaptive-ui/reference";\n`; | ||
const importAnatomy = `import { ${anatomy.name}Anatomy } from "./${kebabCase(anatomy.name)}.template.js";\n` | ||
const styleRules = new Array(...anatomy.styleRules).map(styleRule => this.#genStyleRuleCode(anatomy.name, styleRule)).join("\n"); | ||
const genStyleRules = `\nexport const styleRules: StyleRules = [\n${styleRules}\n];\n`; | ||
|
||
const output = `${importBase}${importRef}${importAnatomy}${genStyleRules}`; | ||
return output; | ||
} | ||
|
||
#genStyleRuleCode(componentName: string, styleRule: StyleRule): string { | ||
let targetOut = ""; | ||
const contextCondition = styleRule.contextCondition ? ` contextCondition: ${componentName}Anatomy.conditions.${camelCase(styleRule.contextCondition)},\n` : ""; | ||
const part = styleRule.part ? ` part: ${componentName}Anatomy.parts.${camelCase(styleRule.part)},\n` : ""; | ||
if (contextCondition || part) { | ||
targetOut = ` target: {\n${part}${contextCondition} },\n`; | ||
} | ||
|
||
let stylesOut = ""; | ||
if (styleRule.styles.size > 0) { | ||
stylesOut = ` styles: [\n ${new Array(...styleRule.styles).map(style => StyleNameMapping[style as keyof typeof StyleNameMapping] || style).join(",\n ")},\n ],\n`; | ||
} | ||
|
||
let propertiesOut = ""; | ||
if (styleRule.tokens.size > 0) { | ||
// TODO Need to map tokens better | ||
const tokens = new Array(...styleRule.tokens).map(token => `${token.target}: ${this.tokenIDMap(token.tokenID)}`); | ||
propertiesOut = ` properties: {\n ${tokens.join(",\n ")},\n },\n`; | ||
} | ||
|
||
return ` {\n${targetOut}${stylesOut}${propertiesOut} },`; | ||
} | ||
|
||
private tokenIDMap(tokenID: string): string { | ||
let adjustedID = tokenID; | ||
|
||
// TODO: Clean up naming and grouping | ||
const densityGroups = ["control", "item-container", "layer"]; | ||
if (tokenID.startsWith("density_")) { | ||
for (let i = 0; i < densityGroups.length; i++) { | ||
const group = densityGroups[i]; | ||
const testGroup = `density_${group}-`; | ||
const adjustedGroup = `density-${group}_`; | ||
if (tokenID.startsWith(testGroup)) { | ||
adjustedID = tokenID.replace(testGroup, adjustedGroup); | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
const pieces = adjustedID.split("_"); | ||
return pieces.map(piece => camelCase(piece)).join("."); | ||
} | ||
} |
6 changes: 3 additions & 3 deletions
6
...ui-figma-designer/src/figma/controller.ts → ...gner-figma-plugin/src/figma/controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
...ptive-ui-figma-designer/src/figma/main.ts → ...i-designer-figma-plugin/src/figma/main.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
...ptive-ui-figma-designer/src/figma/node.ts → ...i-designer-figma-plugin/src/figma/node.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
Oops, something went wrong.