UNPKG

@figma/code-connect

Version:

A tool for connecting your design system components in code with your design system in Figma

219 lines 7.15 kB
"use strict"; /* istanbul ignore file */ // This file needs to be ignored from code coverage, as Istanbul adds extra calls // to `cov_*` functions which are used to track coverage, but these functions // can't be resolved when executing the templates from the unit tests inside // `new Function()` Object.defineProperty(exports, "__esModule", { value: true }); exports._fcc_array = _fcc_array; exports._fcc_jsxElement = _fcc_jsxElement; exports._fcc_function = _fcc_function; exports._fcc_identifier = _fcc_identifier; exports._fcc_object = _fcc_object; exports._fcc_templateString = _fcc_templateString; exports._fcc_reactComponent = _fcc_reactComponent; exports.getParsedTemplateHelpersString = getParsedTemplateHelpersString; function _fcc_array($value) { return { $value, $type: 'array', }; } function _fcc_jsxElement($value) { return { $value, $type: 'jsx-element', }; } function _fcc_function($value) { return { $value, $type: 'function', }; } function _fcc_identifier($value) { return { $value, $type: 'identifier', }; } function _fcc_object($value) { return { $value, $type: 'object', ...$value, }; } function _fcc_templateString($value) { return { $value, $type: 'template-string', }; } function _fcc_reactComponent($value) { return { $value, $type: 'react-component', }; } function isReactComponentArray(prop) { return (Array.isArray(prop) && prop.every((item) => item.type === 'INSTANCE' || item.type === 'CODE' || item.type === 'ERROR')); } // Render a prop value passed to an object literal based on its type. // for example: <Button sx={{ key: value }} /> function _fcc_renderPropValue(prop) { if (isReactComponentArray(prop)) { return prop; } if (prop === undefined) { return 'undefined'; } // Replace any newlines or quotes in the string with escaped versions if (typeof prop === 'string') { const str = `"${prop.replaceAll('\n', '\\n').replaceAll('"', '\\"')}"`; if (str === '') { return 'undefined'; } else { return str; } } if (typeof prop === 'boolean' || typeof prop === 'number') { return prop; } if (prop.$type === 'function' || prop.$type === 'identifier' || prop.$type === 'jsx-element' || prop.$type === 'react-component') { return prop.$value; } if (prop.$type === 'array') { return `[${prop.$value.map((el) => _fcc_renderPropValue(el))}]`; } if (prop.$type === 'object') { return `{${Object.keys(prop.$value) .map((key) => ` ${key}: ${_fcc_renderPropValue(prop.$value[key])} `) .join(',')}}`; } if (prop.$type === 'template-string') { return `\`${prop.$value}\``; } return 'undefined'; } // Render a React prop correctly, based on its type function _fcc_renderReactProp(name, prop) { // If the value is an array, then it's an array of objects representing React // children (either of type INSTANCE for pills, or CODE for inline code). The // template string handler in the template API handles extracting the instance // objects in a way the UI can handle. if (isReactComponentArray(prop)) { if (prop.length > 1) { // If the array has multiple children, render them wrapped in braces and a // fragment. // // We recursively call `figma.tsx` on the value as it itself is an array of // CODE/INSTANCE sections, so we need to run it through the template string // function otherwise this would just output `[object Object]` for the value. // The template string handler function handles flattening nested arrays. return figma.tsx ` ${name}={<>${prop}</>}`; } else { // Render a single child wrapped in braces, see above for why we use `figma.tsx` return figma.tsx ` ${name}={${prop}}`; } } // Render either the prop name or nothing for a boolean, we don't want to // render `prop={true/false}` if (typeof prop === 'boolean') { return prop ? ` ${name}` : ''; } // Replace any newlines or quotes in the string with escaped versions if (typeof prop === 'string') { const str = prop.replaceAll('\n', '\\n').replaceAll('"', '\\"'); if (str === '') { return ''; } return ` ${name}="${str}"`; } if (typeof prop === 'number') { return ` ${name}={${prop}}`; } if (prop === undefined) { return ''; } if (prop.$type === 'function' || prop.$type === 'identifier' || prop.$type === 'jsx-element' || prop.$type === 'react-component') { return ` ${name}={${prop.$value}}`; } if (prop.$type === 'array' || prop.$type === 'object') { return ` ${name}={${_fcc_renderPropValue(prop)}}`; } if (prop.$type === 'template-string') { return ` ${name}={\`${prop.$value}\`}`; } return ''; } // Renders React children correctly, based on their type function _fcc_renderReactChildren(prop) { if (isReactComponentArray(prop)) { return prop; } if (typeof prop === 'string' || typeof prop === 'number' || typeof prop === 'boolean') { return prop; } if (prop === undefined) { return ''; } if (prop.$type === 'template-string') { // If the value is a template string, wrap in braces return figma.tsx `{\`${prop.$value}\`}`; } // If the value is a JSX element, return it directly if (prop.$type === 'jsx-element') { return prop.$value; } // but for other values, wrap in braces if (prop.$type === 'function' || prop.$type === 'identifier') { return `{${prop.$value}}`; } if (prop.$type === 'array' || prop.$type === 'object') { return `{${_fcc_renderPropValue(prop)}}`; } if (prop.$type === 'react-component') { return `<${prop.$value} />`; } } function _fcc_stringifyObject(obj) { if (Array.isArray(obj)) { return `[${obj.map((element) => `${_fcc_stringifyObject(element)}`).join(',')}]`; } if (typeof obj !== 'object' || obj instanceof Date || obj === null) { return JSON.stringify(obj); } return `{${Object.keys(obj) .map((key) => ` ${key}: ${_fcc_stringifyObject(obj[key])} `) .join(',')}}`; } // Return the helpers as a string which can be injected into the template function getParsedTemplateHelpersString() { return [ _fcc_renderReactProp, _fcc_renderReactChildren, _fcc_jsxElement, _fcc_function, _fcc_identifier, _fcc_object, _fcc_templateString, _fcc_renderPropValue, _fcc_stringifyObject, _fcc_reactComponent, _fcc_array, isReactComponentArray, ] .map((fn) => fn.toString()) .join('\n'); } //# sourceMappingURL=parser_template_helpers.js.map