Skip to content

Commit

Permalink
fix(design): update Shadow and Gradient rendering according to specif…
Browse files Browse the repository at this point in the history
…ications (#1985)

## Proposed change

update Shadow and Gradient rendering according to specifications
cf. https://design-tokens.github.io/community-group/format/
  • Loading branch information
kpanot authored Jul 24, 2024
2 parents d724bf1 + 54bb2b8 commit acc15da
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 52 deletions.
122 changes: 79 additions & 43 deletions packages/@o3r/design/schemas/design-token.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,6 @@
}
}
},

"tokenTypeStrokeStyleValue": {
"oneOf": [
{
Expand Down Expand Up @@ -452,6 +451,33 @@
}
}
},
"tokenTypeShadowValue": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"offsetX": {
"type": "string"
},
"offsetY": {
"type": "string"
},
"blur": {
"type": "string"
},
"spread": {
"type": "string"
}
},
"required": [
"color",
"offsetX",
"offsetY",
"blur",
"spread"
]
},
"tokenTypeShadow": {
"type": "object",
"required": [
Expand All @@ -460,30 +486,16 @@
],
"properties": {
"$value": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"offsetX": {
"type": "string"
},
"offsetY": {
"type": "string"
},
"blur": {
"type": "string"
"oneOf": [
{
"$ref": "#/definitions/tokenTypeShadowValue"
},
"spread": {
"type": "string"
{
"type": "array",
"items": {
"$ref": "#/definitions/tokenTypeShadowValue"
}
}
},
"required": [
"color",
"offsetX",
"offsetY",
"blur",
"spread"
]
},
"$type": {
Expand All @@ -492,6 +504,30 @@
}
}
},
"tokenTypeGradientStop": {
"type": "object",
"properties": {
"color": {
"type": "string"
},
"position": {
"oneOf": [
{
"type": "string"
},
{
"type": "number",
"maximum": 100,
"minimum": 0
}
]
}
},
"required": [
"color",
"position"
]
},
"tokenTypeGradient": {
"type": "object",
"required": [
Expand All @@ -500,27 +536,27 @@
],
"properties": {
"$value": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"color": { "type": "string" },
"position": {
"oneOf": [
{ "type": "string" },
{
"type": "number",
"maximum": 1,
"minimum": 0
}
]
}
"type": "object",
"properties": {
"type": {
"default": "linear",
"type": "string",
"enum": [
"linear",
"radial",
"conic"
]
},
"angle": {
"type": ["string", "number"],
"default": "0deg"
},
"required": [
"color",
"position"
]
"stops": {
"type": "array",
"items": {
"$ref": "#/definitions/tokenTypeGradientStop"
}
}
}
},
"$type": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,26 @@ type DesignTokenTypeShadowValue = {
};

/** Design Token Shadow */
export interface DesignTokenTypeShadow extends DesignTokenBase<DesignTokenTypeShadowValue> {
export interface DesignTokenTypeShadow extends DesignTokenBase<DesignTokenTypeShadowValue | DesignTokenTypeShadowValue[]> {
/** @inheritdoc */
$type: 'shadow';
}

type DesignTokenTypeGradientValue = {
type DesignTokenTypeGradientStop = {
/** Color to the stop of a gradient */
color: string;
/** Position of the stop */
position: string | number;
}[];
};

type DesignTokenTypeGradientValue = {
/** Type of the gradient */
type?: 'linear' | 'radial' | 'conic';
/** Angle to the gradient */
angle?: string | number;
/** List of stops in the gradient */
stops?: DesignTokenTypeGradientStop[];
};

/** Design Token Gradient */
export interface DesignTokenTypeGradient extends DesignTokenBase<DesignTokenTypeGradientValue> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,35 @@ describe('Design Token Parser', () => {
expect(border).toBeDefined();
expect(border.getType()).toBe('border');
});

test('generate correctly the gradient', () => {
const result = parser.parseDesignToken(exampleVariable);
const gradient = result.get('example.test.gradient');

expect(gradient).toBeDefined();
expect(gradient.getType()).toBe('gradient');
expect(gradient.getCssRawValue()).toBe('linear-gradient(180deg, #fff 10px)');
});

describe('generate correctly the shadow', () => {
test('with single parameter', () => {
const result = parser.parseDesignToken(exampleVariable);
const shadow = result.get('example.test.shadow');

expect(shadow).toBeDefined();
expect(shadow.getType()).toBe('shadow');
expect(shadow.getCssRawValue()).toBe('1px 1px 1 1 #000');
});

test('with multiple parameter', () => {
const result = parser.parseDesignToken(exampleVariable);
const shadow = result.get('example.test.shadow-multi');

expect(shadow).toBeDefined();
expect(shadow.getType()).toBe('shadow');
expect(shadow.getCssRawValue()).toBe('1px 1px 1 1 #000, 2px 2px 2 2 #fff');
});
});
});

describe('parseDesignTokenFile', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ const getCssRawValue = (variableSet: DesignTokenVariableSet, {node, getType}: De
$type: node.$type || nodeType
} as typeof node;

// TODO in the following code, `typeof checkNode.$value === 'string' ? checkNode.$value :` is defined to please Jest TS compilation. It should be removed when supported
switch (checkNode.$type) {
case 'color':
case 'number':
Expand All @@ -62,13 +61,23 @@ const getCssRawValue = (variableSet: DesignTokenVariableSet, {node, getType}: De
`${checkNode.$value.width} ${renderCssTypeStrokeStyleValue(checkNode.$value.style)} ${checkNode.$value.color}`;
}
case 'gradient': {
return typeof checkNode.$value === 'string' ? checkNode.$value :
// TODO: add support of different gradient type when design-tokens/community-group#101 is fixed.
`linear-gradient(0deg, ${checkNode.$value.map(({color, position}) => `${color} ${position}`).join(', ')})`;
if (typeof checkNode.$value === 'string') {
return checkNode.$value;
}
const angle = typeof checkNode.$value.angle === 'number' ? checkNode.$value.angle + 'deg' : checkNode.$value.angle;
return `${checkNode.$value.type || 'linear'}-gradient(${angle || '0deg'}, ${checkNode.$value.stops
?.map(({ color, position }) => `${color} ${typeof position === 'number' ? position + '%' : position}`)
.join(', ')})`;
}
case 'shadow': {
return typeof checkNode.$value === 'string' ? checkNode.$value :
`${checkNode.$value.offsetX} ${checkNode.$value.offsetY} ${checkNode.$value.blur} ${checkNode.$value.spread} ${checkNode.$value.color}`;
if (typeof checkNode.$value === 'string') {
return checkNode.$value;
}

const values = Array.isArray(checkNode.$value) ? checkNode.$value : [checkNode.$value];
return values
.map((value) => `${value.offsetX} ${value.offsetY} ${value.blur} ${value.spread} ${value.color}`)
.join(', ');
}
case 'transition': {
return typeof checkNode.$value === 'string' ? checkNode.$value :
Expand All @@ -79,6 +88,7 @@ const getCssRawValue = (variableSet: DesignTokenVariableSet, {node, getType}: De
return typeof checkNode.$value === 'string' ? checkNode.$value :
`${checkNode.$value.fontWeight} ${checkNode.$value.fontFamily} ${checkNode.$value.fontSize} ${checkNode.$value.letterSpacing} ${checkNode.$value.lineHeight}`;
}
// TODO: Add support for Grid type when available in the Design Token Standard
default: {
throw new Error(`Not supported type ${(checkNode as any).$type || 'unknown'} (value: ${(checkNode as any).$value || 'unknown'})`);
}
Expand Down
44 changes: 44 additions & 0 deletions packages/@o3r/design/testing/mocks/design-token-theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,50 @@
"style": "dashed",
"width": "{example.test.width}"
}
},
"gradient": {
"$type": "gradient",
"$value": {
"angle": "180deg",
"type": "linear",
"stops": [
{
"color": "#fff",
"position": "10px"
}
]
}
},
"shadow": {
"$type": "shadow",
"$value": [
{
"blur": "1",
"offsetX": "1px",
"offsetY": "1px",
"color": "#000",
"spread": "1"
}
]
},
"shadow-multi": {
"$type": "shadow",
"$value": [
{
"blur": "1",
"offsetX": "1px",
"offsetY": "1px",
"color": "#000",
"spread": "1"
},
{
"blur": "2",
"offsetX": "2px",
"offsetY": "2px",
"color": "#fff",
"spread": "2"
}
]
}
}
}
Expand Down

0 comments on commit acc15da

Please sign in to comment.