-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1850 from chanzuckerberg/release-v13.11.0
## [13.11.0](v13.11.0-alpha.0...v13.11.0) (2024-02-20) [Storybook](https://61313967cde49b003ae2a860-xfzakymyle.chromatic.com/) ### Features * **script:** add import from figma script ([#1844](#1844)) ([9ed90e5](9ed90e5)) * **Select:** enable multi-select ([ced70d5](ced70d5)) * **Select:** add handling for long text in select field ([7c79a6e](7c79a6e)) ### Bug Fixes * **PopoverListItem:** adjust size of list item when selected ([0496f56](0496f56)) * **Select:** set trigger type to button to prevent submits ([#1843](#1843)) ([d7ea037](d7ea037))
- Loading branch information
Showing
19 changed files
with
3,641 additions
and
2,939 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
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
672 changes: 336 additions & 336 deletions
672
.yarn/releases/yarn-4.0.2.cjs → .yarn/releases/yarn-4.1.0.cjs
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
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 |
---|---|---|
|
@@ -140,4 +140,114 @@ module.exports = { | |
} | ||
} | ||
}, | ||
/** | ||
* Determine the write path by taking the collection and variable name, and looking it up in | ||
* the existing local theme. If there's a path in the local theme file, we can write there (using lodash/set | ||
* or similar). | ||
* | ||
* @param {object} localTheme JSON file loaded, representing the data for the local theme | ||
* @param {string} collectionName Name of the exported collection | ||
* @param {string} variableName current variable name from figma (e.g., color/text/neutral/default) | ||
* @returns {string|null} representation of the path to write to in the local theme JSON file | ||
*/ | ||
getWritePath: function (localTheme, collectionName, variableName) { | ||
const at = require('lodash/at'); | ||
|
||
const workingPath = | ||
module.exports.getTokenPrefix(collectionName) + | ||
module.exports.tokenNameToPath(variableName); | ||
|
||
const found = at(localTheme, workingPath).filter( | ||
(entries) => typeof entries !== 'undefined', | ||
); | ||
|
||
if (found.length) { | ||
// handle case where we should look for @ in the file, then pluck the value object properly | ||
if (found[0]['@']?.value) { | ||
// update the write path to mark the @ and value | ||
return workingPath + '[email protected]'; | ||
} | ||
|
||
// handle case where it's just value | ||
if (found[0]?.value) { | ||
// update the write path to mark the value | ||
return workingPath + '.value'; | ||
} | ||
} | ||
|
||
// There is no write path based on what's in the local theme so we return null signal it's a missing token | ||
return null; | ||
}, | ||
/** | ||
* Utilities for handling parsing of Figma Theme Data. | ||
* | ||
* These functions are set up to handle, transform, and read data coming from figma API Structure. | ||
* For more information on this API format, refer to: | ||
* - https://help.figma.com/hc/en-us/articles/15339657135383-Guide-to-variables-in-Figma | ||
* - https://www.figma.com/plugin-docs/api/VariableCollection/ | ||
*/ | ||
/** | ||
* Given the value sourced from figma, translate it into a | ||
* style-dictionary format. When encountering an unrecognized type, | ||
* throw an error. | ||
* | ||
* Data Types: | ||
* - Type COLOR: https://www.figma.com/plugin-docs/api/RGB/ | ||
* | ||
* @param {string} type Figma type for the token value (Set:) | ||
* @param {object} figmaResolvedValue | ||
* @returns {string} value using the type | ||
* @throws {TypeError} using `details` on the data read from figma | ||
*/ | ||
parseResolvedValue: function (type, figmaResolvedValue) { | ||
if (type === 'COLOR') { | ||
const r = Math.floor(figmaResolvedValue.r * 255); | ||
const g = Math.floor(figmaResolvedValue.g * 255); | ||
const b = Math.floor(figmaResolvedValue.b * 255); | ||
const a = figmaResolvedValue.a; | ||
if (figmaResolvedValue.a > 0 && figmaResolvedValue.a < 1) { | ||
return `rgba(${r}, ${g}, ${b}, ${a})`; | ||
} else { | ||
// print hex instead | ||
return ( | ||
'#' + | ||
[r, g, b] | ||
.map((x) => x.toString(16)) | ||
.map((x) => (x.length === 1 ? '0' + x : x)) | ||
.join('') | ||
.toUpperCase() | ||
); | ||
} | ||
} else { | ||
throw new TypeError('unknown resolved type: ' + type, { | ||
details: figmaResolvedValue, | ||
}); | ||
} | ||
}, | ||
/** | ||
* Given the "type" of import file (named after the collection name), produce | ||
* a prefix to the token name that corresponds to the prefix used for those | ||
* tokens. | ||
* | ||
* @param {string} collectionName The key to write to | ||
* @returns {string|null} a text prefix for where to write the token value or null when no prefix is found | ||
*/ | ||
getTokenPrefix: function (collectionName) { | ||
switch (collectionName) { | ||
case 'themes': | ||
return 'eds.theme.'; | ||
case 'primitives': | ||
return 'eds.'; | ||
default: | ||
return null; | ||
} | ||
}, | ||
/** | ||
* Conversion of the figma token name (e.g., some/path/to/token) to the equivalent path in a JSON object | ||
* @param {string} figmaTokenName The name from the figma variables panel (slash separated) | ||
* @returns {string} a lodash-compatible string representing the path to the token value in JSON | ||
*/ | ||
tokenNameToPath: function (figmaTokenName) { | ||
return figmaTokenName.replaceAll('/', '.').toLowerCase(); | ||
}, | ||
}; |
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,130 @@ | ||
const utils = require('./_util'); | ||
|
||
describe('utils', function () { | ||
describe('getWritePath', function () { | ||
const exampleTheme = { | ||
eds: { | ||
theme: { | ||
color: { | ||
body: { | ||
background: { | ||
neutral: { | ||
default: { | ||
'@': { | ||
value: '#FFFFFF', | ||
}, | ||
hover: { | ||
value: '#F4F6F8', | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
it('generates a write path for a root-at value', () => { | ||
expect( | ||
utils.getWritePath( | ||
exampleTheme, | ||
'themes', | ||
'color/body/background/neutral/default', | ||
), | ||
).toEqual('[email protected]'); | ||
}); | ||
|
||
it('generates a write path for a non-root-at value', () => { | ||
expect( | ||
utils.getWritePath( | ||
exampleTheme, | ||
'themes', | ||
'color/body/background/neutral/default/hover', | ||
), | ||
).toEqual('eds.theme.color.body.background.neutral.default.hover.value'); | ||
}); | ||
|
||
it('generates a null when the path is not in the local theme', () => { | ||
expect( | ||
utils.getWritePath( | ||
exampleTheme, | ||
'themes', | ||
'color/body/background/neutral/default/focus', | ||
), | ||
).toEqual(null); | ||
}); | ||
}); | ||
|
||
describe('getTokenPath', function () { | ||
it.each([ | ||
['themes', 'eds.theme.'], | ||
['primitives', 'eds.'], | ||
['some-unknown', null], | ||
['', null], | ||
])( | ||
'parses the collection %s to token prefix "%s"', | ||
(collection, expected) => { | ||
expect(utils.getTokenPrefix(collection)).toEqual(expected); | ||
}, | ||
); | ||
}); | ||
|
||
describe('tokenNameToPath', function () { | ||
it('properly converts a token name to a lodash-compatible path', function () { | ||
expect(utils.tokenNameToPath('some/path/to/token')).toEqual( | ||
'some.path.to.token', | ||
); | ||
}); | ||
}); | ||
|
||
describe('parseResolvedValue', function () { | ||
const space500 = { | ||
r: 0.12941177189350128, | ||
g: 0.1568627506494522, | ||
b: 0.4000000059604645, | ||
a: 1, | ||
}; | ||
|
||
const blueprint300 = { | ||
r: 0.027450980618596077, | ||
g: 0.30588236451148987, | ||
b: 0.9098039269447327, | ||
a: 1, | ||
}; | ||
|
||
const neutral800 = { | ||
r: 0.12941177189350128, | ||
g: 0.15294118225574493, | ||
b: 0.1764705926179886, | ||
a: 1, | ||
}; | ||
|
||
const backgroundVeil = { | ||
r: 0.12941177189350128, | ||
g: 0.15294118225574493, | ||
b: 0.1764705926179886, | ||
a: 0.5, | ||
}; | ||
|
||
it.each` | ||
figmaColor | type | expected | ||
${space500} | ${'COLOR'} | ${'#212866'} | ||
${blueprint300} | ${'COLOR'} | ${'#074EE8'} | ||
${neutral800} | ${'COLOR'} | ${'#21272D'} | ||
${backgroundVeil} | ${'COLOR'} | ${'rgba(33, 39, 45, 0.5)'} | ||
`( | ||
'will use type $type to convert $figmaColor to $expected', | ||
({ figmaColor, type, expected }) => { | ||
expect(utils.parseResolvedValue(type, figmaColor)).toEqual(expected); | ||
}, | ||
); | ||
|
||
it('will throw on unrecognized types', () => { | ||
const test = () => { | ||
utils.parseResolvedValue('FLOAT', 0.5); | ||
}; | ||
expect(test).toThrow(TypeError); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.