Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "AUI: Refactored Swatch to Color",
"packageName": "@adaptive-web/adaptive-ui",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "AUI: Refactored Swatch to Color",
"packageName": "@adaptive-web/adaptive-web-components",
"email": "[email protected]",
"dependentChangeType": "patch"
}
183 changes: 101 additions & 82 deletions packages/adaptive-ui-designer-figma-plugin/src/figma/node.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { type Color, modeLrgb, modeRgb, parse, type Rgb, useMode, wcagLuminance } from "culori/fn";
import { Shadow, StyleProperty } from "@adaptive-web/adaptive-ui";
import { type Color as CuloriColor, modeLrgb, modeRgb, parse, type Rgb, useMode, wcagLuminance } from "culori/fn";
import { Color, Shadow, StyleProperty } from "@adaptive-web/adaptive-ui";
import { AppliedStyleModules, AppliedStyleValues, Controller, focusIndicatorNodeName, PluginNode, PluginNodeData, State, StatesState, STYLE_REMOVE } from "@adaptive-web/adaptive-ui-designer-core";
import { FIGMA_SHARED_DATA_NAMESPACE } from "@adaptive-web/adaptive-ui-designer-figma";
import { colorToRgba, variantBooleanHelper } from "./utility.js";
import { colorToRgba, roundToDecimals, variantBooleanHelper } from "./utility.js";

const rgb = useMode(modeRgb);
// For luminance
Expand Down Expand Up @@ -119,7 +119,7 @@ export class FigmaPluginNode extends PluginNode {
public id: string;
public type: string;
public name: string;
public fillColor: Color | null = null;
public fillColor: CuloriColor | null = null;
public states?: StatesState;
private _node: BaseNode;
private _state?: State;
Expand Down Expand Up @@ -760,7 +760,7 @@ export class FigmaPluginNode extends PluginNode {
return await FigmaPluginNode.get(parent, false);
}

private getFillColor(): Color | null {
private getFillColor(): CuloriColor | null {
// console.log("FigmaPluginNode.getFillColor", this.debugInfo);
if ((this._node as GeometryMixin).fills) {
const fills = (this._node as GeometryMixin).fills;
Expand All @@ -783,7 +783,7 @@ export class FigmaPluginNode extends PluginNode {
return null;
}

public async getEffectiveFillColor(): Promise<Color | null> {
public async getEffectiveFillColor(): Promise<CuloriColor | null> {
if (this.fillColor) {
return this.fillColor;
}
Expand Down Expand Up @@ -849,90 +849,109 @@ export class FigmaPluginNode extends PluginNode {
}
}

private paintColor(target: StyleProperty, value: string): void {
private paintColor(target: StyleProperty, value: unknown): void {
let paint: Paint | null = null;

if (value !== STYLE_REMOVE) {
if (value.startsWith("linear-gradient")) {
const linearMatch = /linear-gradient\((?<params>.+)\)/;
const matches = value.match(linearMatch);
if (matches && matches.groups) {
const array = matches.groups.params.split(",").map(p => p.trim());

let degrees: number = 90;
if (array[0].endsWith("deg")) {
const angle = array.shift()?.replace("deg", "") || "90";
degrees = Number.parseFloat(angle);
}
const radians: number = degrees * (Math.PI / 180);

const paramMatch = /(?<color>#[\w\d]+)( (?<pos>.+))?/;
const stops = array.map((p, index, array) => {
const paramMatches = p.match(paramMatch);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const color = rgb(parse(paramMatches?.groups?.color || "FF00FF")!);
let position: number = 0;
if (paramMatches?.groups && paramMatches?.groups?.pos) {
if (paramMatches.groups.pos.endsWith("%")) {
position = Number.parseFloat(paramMatches.groups.pos) / 100;
} else if (paramMatches.groups.pos.startsWith("calc(100% - ")) {
const px = Number.parseFloat(
paramMatches.groups.pos
.replace("calc(100% - ", "")
.replace("px)", "")
);
const size = degrees === 90 || degrees === 270
? (this._node as LayoutMixin).height
: (this._node as LayoutMixin).width;
position = (size - px) / size;
}
} else if (index === array.length - 1) {
position = 1;
if (typeof value === "string") {
if (value.startsWith("linear-gradient")) {
const linearMatch = /linear-gradient\((?<params>.+)\)/;
const matches = value.match(linearMatch);
if (matches && matches.groups) {
const array = matches.groups.params.split(",").map(p => p.trim());

let degrees: number = 90;
if (array[0].endsWith("deg")) {
const angle = array.shift()?.replace("deg", "") || "90";
degrees = Number.parseFloat(angle);
}
const stop: ColorStop = {
position,
color: {
r: color.r,
g: color.g,
b: color.b,
a: color.alpha || 1,
},
const radians: number = degrees * (Math.PI / 180);

const paramMatch = /(?<color>#[\w\d]+)( (?<pos>.+))?/;
const stops = array.map((p, index, array) => {
const paramMatches = p.match(paramMatch);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const color = rgb(parse(paramMatches?.groups?.color || "FF00FF")!);
let position: number = 0;
if (paramMatches?.groups && paramMatches?.groups?.pos) {
if (paramMatches.groups.pos.endsWith("%")) {
position = Number.parseFloat(paramMatches.groups.pos) / 100;
} else if (paramMatches.groups.pos.startsWith("calc(100% - ")) {
const px = Number.parseFloat(
paramMatches.groups.pos
.replace("calc(100% - ", "")
.replace("px)", "")
);
const size = degrees === 90 || degrees === 270
? (this._node as LayoutMixin).height
: (this._node as LayoutMixin).width;
position = (size - px) / size;
}
} else if (index === array.length - 1) {
position = 1;
}
const stop: ColorStop = {
position,
color: {
r: color.r,
g: color.g,
b: color.b,
a: color.alpha || 1,
},
};
return stop;
});

const gradientPaint: GradientPaint = {
type: "GRADIENT_LINEAR",
gradientStops: stops,
gradientTransform: [
[Math.cos(radians), Math.sin(radians), 0],
[Math.sin(radians) * -1, Math.cos(radians), 1],
],
};
return stop;
});

const gradientPaint: GradientPaint = {
type: "GRADIENT_LINEAR",
gradientStops: stops,
gradientTransform: [
[Math.cos(radians), Math.sin(radians), 0],
[Math.sin(radians) * -1, Math.cos(radians), 1],
],
paint = gradientPaint;
}
} else {
// Assume it's solid
const color = parse(value);
if (!color) {
throw new Error(
`The value "${value}" could not be parsed`
);
}

const rgbColor = rgb(color);
const solidPaint: SolidPaint = {
type: "SOLID",
visible: true,
opacity: rgbColor.alpha,
blendMode: "NORMAL",
color: {
r: rgbColor.r,
g: rgbColor.g,
b: rgbColor.b,
},
};
paint = gradientPaint;
paint = solidPaint;
}
} else {
// Assume it's solid
const color = parse(value);
if (!color) {
throw new Error(
`The value "${value}" could not be parsed`
);
} else if (value && typeof value === "object") {
if (Object.keys(value).includes("color")) {
const color = value as Color;
// console.log(" Color", color);
const solidPaint: SolidPaint = {
type: "SOLID",
visible: true,
opacity: color.color.alpha,
blendMode: "NORMAL",
color: {
r: roundToDecimals((color.color as Rgb).r, 6),
g: roundToDecimals((color.color as Rgb).g, 6),
b: roundToDecimals((color.color as Rgb).b, 6),
},
};
paint = solidPaint;
}

const rgbColor = rgb(color);
const solidPaint: SolidPaint = {
type: "SOLID",
visible: true,
opacity: rgbColor.alpha,
blendMode: "NORMAL",
color: {
r: rgbColor.r,
g: rgbColor.g,
b: rgbColor.b,
},
};
paint = solidPaint;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ export const colorToRgba = (color: Rgb): RGBA => {
a: color.alpha || 1,
};
}

export const roundToDecimals = (num: number, dec: number): number => {
return parseFloat(num.toFixed(dec));
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { customElement, FASTElement, html } from "@microsoft/fast-element";
import { DesignToken, StaticDesignTokenValue } from "@microsoft/fast-foundation";
import { Swatch } from "@adaptive-web/adaptive-ui";
import { Color } from "@adaptive-web/adaptive-ui";
import { fillColor } from "@adaptive-web/adaptive-ui/reference";
import { DesignTokenValue, PluginUINodeData } from "@adaptive-web/adaptive-ui-designer-core";
import { UIController } from "./ui-controller.js";
Expand Down Expand Up @@ -55,7 +55,13 @@ export class ElementsController {
try {
if (value) {
// TODO figure out a better way to handle storage data types
const color = Swatch.parse((value as unknown) as string);

let color: Color | null = null;
if (value instanceof Color) {
color = value;
} else {
color = Color.parse((value as unknown) as string);
}
if (color) {
// TODO fix this logic
// console.log(" setting DesignToken value (color)", token.name, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { calc } from '@csstools/css-calc';
import { observable } from "@microsoft/fast-element";
import { DesignToken } from "@microsoft/fast-foundation";
import { Color } from "@adaptive-web/adaptive-ui";
import { formatHex8 } from 'culori';
import { DesignTokenValue, PluginUINodeData } from "@adaptive-web/adaptive-ui-designer-core";
import { UIController } from "./ui-controller.js";
import { ElementsController } from "./ui-controller-elements.js";
Expand Down Expand Up @@ -110,7 +109,7 @@ export class DesignTokenController {
// TODO figure out a better way to handle storage data types
// Reconcile with similar block in evaluateEffectiveAppliedDesignToken
if (value instanceof Color) {
return formatHex8(value.color);
return value.toString();
} else if (typeof value === "string") {
if (value.startsWith("calc")) {
return calc(value);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { calc } from '@csstools/css-calc';
import { FASTElement, observable } from "@microsoft/fast-element";
import { CSSDesignToken, DesignToken, type ValuesOf } from "@microsoft/fast-foundation";
import { Color, InteractiveState, InteractiveTokenGroup, StyleProperty, Styles, Swatch } from "@adaptive-web/adaptive-ui";
import { Color, InteractiveState, InteractiveTokenGroup, StyleProperty, Styles } from "@adaptive-web/adaptive-ui";
import { fillColor } from "@adaptive-web/adaptive-ui/reference";
import { formatHex8 } from 'culori';
import {
Expand Down Expand Up @@ -382,7 +382,7 @@ export class UIController {
if (colorHex) {
const parentElement = this._elements.getElementForNode(node).parentElement as FASTElement;
// console.log(" setting fill color token on parent element", colorHex, parentElement.id, parentElement.title);
this._elements.setDesignTokenForElement(parentElement, fillColor, Swatch.parse(colorHex));
this._elements.setDesignTokenForElement(parentElement, fillColor, Color.parse(colorHex));
}

const allApplied = this.collectEffectiveAppliedStyles(node);
Expand Down Expand Up @@ -413,8 +413,8 @@ export class UIController {
let value: any = valueOriginal;
// let valueDebug: any;
if (valueOriginal instanceof Color) {
const swatch = valueOriginal;
value = formatHex8(swatch.color);
const color = valueOriginal;
value = formatHex8(color.color);
// valueDebug = swatch.toColorString();
} else if (typeof valueOriginal === "string") {
if (valueOriginal.startsWith("calc")) {
Expand All @@ -423,7 +423,7 @@ export class UIController {
value = ret;
}
}
const fillColorValue = (this._elements.getDesignTokenValue(node, fillColor) as Swatch).toColorString();
// const fillColorValue = (this._elements.getDesignTokenValue(node, fillColor) as Color).toColorString();
// console.log(" evaluateEffectiveAppliedDesignToken", target, " : ", token.name, " -> ", value, valueDebug, `(from ${info.source})`, "fillColor", fillColorValue);

const applied = new AppliedStyleValue(value);
Expand Down
6 changes: 3 additions & 3 deletions packages/adaptive-ui-explorer/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
Color,
Palette,
Swatch,
} from "@adaptive-web/adaptive-ui";
import {
accentBaseColor,
Expand Down Expand Up @@ -289,7 +289,7 @@ export class App extends FASTElement {
});
}

private layerTokens: Array<[DesignToken<Swatch>, string]> = [
private layerTokens: Array<[DesignToken<Color>, string]> = [
[layerFillFixedPlus1, "+1"],
[layerFillFixedBase, "Base"],
[layerFillFixedMinus1, "-1"],
Expand All @@ -303,7 +303,7 @@ export class App extends FASTElement {
layerFillBaseLuminance.setValueFor(ds, luminance);

return this.layerTokens
.map((conf: [DesignToken<Swatch>, string]): SwatchInfo => {
.map((conf: [DesignToken<Color>, string]): SwatchInfo => {
const color = conf[0].getValueFor(ds).toColorString();
return {
index: this.neutralColors.indexOf(color),
Expand Down
8 changes: 4 additions & 4 deletions packages/adaptive-ui-explorer/src/components/color-block.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Swatch } from "@adaptive-web/adaptive-ui";
import { Color } from "@adaptive-web/adaptive-ui";
import {
accentFillDiscernibleControlStyles,
accentFillIdealControlStyles,
Expand Down Expand Up @@ -261,9 +261,9 @@ export class ColorBlock extends FASTElement {

private updateColor(): void {
if (this.color && this.$fastController.isConnected) {
const swatch =Swatch.parse(this.color)
if (swatch) {
fillColor.setValueFor(this, swatch);
const color = Color.parse(this.color)
if (color) {
fillColor.setValueFor(this, color);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Swatch } from '@adaptive-web/adaptive-ui';
import { Color } from '@adaptive-web/adaptive-ui';
import {
fillColor,
layerFillBaseLuminance,
Expand Down Expand Up @@ -61,7 +61,7 @@ export class LayerBackground extends FASTElement {
}

if (this.backgroundLayerRecipe !== undefined) {
let swatch: Swatch | null = null;
let swatch: Color | null = null;
switch (this.backgroundLayerRecipe) {
case "-1":
swatch = layerFillFixedMinus1.getValueFor(this);
Expand Down
Loading
Loading