New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@teleporthq/teleport-plugin-react-styled-components

Package Overview
Dependencies
Maintainers
5
Versions
136
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@teleporthq/teleport-plugin-react-styled-components - npm Package Compare versions

Comparing version

to
0.17.0

__tests__/component-scoped.ts

31

__tests__/index.ts
import { component, elementNode } from '@teleporthq/teleport-uidl-builders'
import {
ComponentStructure,
ChunkDefinition,
ChunkType,
FileType,
} from '@teleporthq/teleport-types'
import { ComponentStructure } from '@teleporthq/teleport-types'
import { createReactStyledComponentsPlugin } from '../src/index'
import { createElementWithStyle } from './mocks'
import { createComponentChunk, createElementWithStyle } from './mocks'
describe('Testing the functionality for StyledComponents', () => {
const plugin = createReactStyledComponentsPlugin()
const componentChunk: ChunkDefinition = {
name: 'jsx-component',
meta: {
nodesLookup: {
container: {
openingElement: {
name: {
name: '',
},
},
},
},
dynamicRefPrefix: {
prop: 'props.',
},
},
type: ChunkType.AST,
fileType: FileType.JS,
linkAfter: ['import-local'],
content: {},
}
const componentChunk = createComponentChunk()

@@ -35,0 +10,0 @@ it('Should not add styled as dependency', async () => {

import { staticNode, elementNode } from '@teleporthq/teleport-uidl-builders'
import { ChunkDefinition, ChunkType, FileType } from '@teleporthq/teleport-types'

@@ -18,1 +19,27 @@ export const createElementWithStyle = () => {

}
export const createComponentChunk = () => {
const componentChunk: ChunkDefinition = {
name: 'jsx-component',
meta: {
nodesLookup: {
container: {
openingElement: {
attributes: [],
name: {
name: '',
},
},
},
},
dynamicRefPrefix: {
prop: 'props',
},
},
type: ChunkType.AST,
fileType: FileType.JS,
linkAfter: ['import-local'],
content: {},
}
return componentChunk
}

@@ -1,32 +0,8 @@

import {
ChunkDefinition,
ChunkType,
FileType,
ComponentStructure,
} from '@teleporthq/teleport-types'
import { ComponentStructure, UIDLStyleSetDefinition } from '@teleporthq/teleport-types'
import { createReactStyledComponentsPlugin } from '../src'
import { component, elementNode, staticNode } from '@teleporthq/teleport-uidl-builders'
import { createComponentChunk } from './mocks'
describe('Referenced Styles on Node', () => {
const componentChunk: ChunkDefinition = {
name: 'jsx-component',
meta: {
nodesLookup: {
container: {
openingElement: {
name: {
name: '',
},
},
},
},
dynamicRefPrefix: {
prop: 'props.',
},
},
type: ChunkType.AST,
fileType: FileType.JS,
linkAfter: ['import-local'],
content: {},
}
const componentChunk = createComponentChunk()
const uidl = component('MyComponent', elementNode('container', null, [], null, null, null, null))

@@ -38,3 +14,2 @@

'5ed659b1732f9b804f7b6381': {
id: '5ed659b1732f9b804f7b6381',
type: 'style-map',

@@ -50,3 +25,2 @@ content: {

'5ed659b1732f9b804f7b6382': {
id: '5ed659b1732f9b804f7b6382',
type: 'style-map',

@@ -71,15 +45,15 @@ content: {

const result = await plugin(structure)
const { chunks, dependencies } = result
const { chunks, dependencies } = await plugin(structure)
const containerChunk = chunks.find((chunk) => chunk.name === 'Container')
expect(chunks[1].name).toBe('Container')
expect(chunks[1].content.declarations[0].init.quasi.quasis[0].value.raw).toContain(
'display: block'
)
expect(chunks[1].content.declarations[0].init.quasi.quasis[0].value.raw).toContain(
'display: none'
)
expect(chunks[1].content.declarations[0].init.quasi.quasis[0].value.raw).toContain(
'@media(max-width: 991px)'
)
expect(containerChunk).toBeDefined()
expect(containerChunk.content.type).toBe('VariableDeclaration')
const declerationArguments = containerChunk.content.declarations[0].init.arguments
expect(declerationArguments.length).toBe(1)
expect(declerationArguments[0].name).not.toBe('projectStyleVariants')
expect(declerationArguments[0].properties.length).toBe(2)
expect(declerationArguments[0].properties[0].key.value).toBe('@media(max-width: 991px)')
expect(declerationArguments[0].properties[1].key.value).toBe('&:hover')
expect(Object.keys(dependencies).length).toBe(1)

@@ -92,3 +66,2 @@ })

'5ed659b1732f9b804f7b6381': {
id: '5ed659b1732f9b804f7b6381',
type: 'style-map',

@@ -104,3 +77,2 @@ content: {

'5ed659b1732f9b804f7b6382': {
id: '5ed659b1732f9b804f7b6382',
type: 'style-map',

@@ -116,7 +88,6 @@ content: {

'5ed659b1732f9b804f7b6384': {
id: '5ed659b1732f9b804f7b6384',
type: 'style-map',
content: {
mapType: 'project-referenced',
referenceId: '5ecfa1233b8e50f60ea2b64d',
referenceId: 'primaryButton',
},

@@ -134,6 +105,4 @@ },

const styleSetDefinitions = {
'5ecfa1233b8e50f60ea2b64d': {
id: '5ecfa1233b8e50f60ea2b64d',
name: 'primaryButton',
const styleSetDefinitions: Record<string, UIDLStyleSetDefinition> = {
primaryButton: {
type: 'reusable-project-style-map',

@@ -153,20 +122,18 @@ content: {

const result = await plugin(structure)
const { chunks, dependencies } = result
const { chunks, dependencies } = await plugin(structure)
const containerChunk = chunks.find((chunk) => chunk.name === 'Container')
expect(chunks[1].name).toBe('Container')
expect(chunks[1].content.declarations[0].init.quasi.quasis[0].value.raw).toContain(
'display: block'
)
expect(chunks[1].content.declarations[0].init.quasi.quasis[0].value.raw).toContain(
'display: none'
)
expect(chunks[1].content.declarations[0].init.quasi.quasis[0].value.raw).toContain(
'@media(max-width: 991px)'
)
expect(chunks[1].content.declarations[0].init.quasi.quasis[0].value.raw).toContain(
'${PrimaryButton'
)
expect(containerChunk).toBeDefined()
expect(containerChunk.content.type).toBe('VariableDeclaration')
const declerationArguments = containerChunk.content.declarations[0].init.arguments
expect(declerationArguments.length).toBe(2)
expect(declerationArguments[0].name).toBe('projectStyleVariants')
expect(declerationArguments[1].properties.length).toBe(2)
expect(declerationArguments[1].properties[0].key.value).toBe('@media(max-width: 991px)')
expect(declerationArguments[1].properties[1].key.value).toBe('&:hover')
expect(Object.keys(dependencies).length).toBe(2)
})
})
import {
ChunkDefinition,
ChunkType,
FileType,
ComponentStructure,

@@ -11,25 +8,6 @@ UIDLDesignTokens,

import { component, elementNode, staticNode } from '@teleporthq/teleport-uidl-builders'
import { createComponentChunk } from './mocks'
describe('Style Sheet from styled components', () => {
const componentChunk: ChunkDefinition = {
name: 'jsx-component',
meta: {
nodesLookup: {
container: {
openingElement: {
name: {
name: '',
},
},
},
},
dynamicRefPrefix: {
prop: 'props.',
},
},
type: ChunkType.AST,
fileType: FileType.JS,
linkAfter: ['import-local'],
content: {},
}
const componentChunk = createComponentChunk()

@@ -61,5 +39,3 @@ it('Generates a style sheet from the give JSON of styleSet', async () => {

const styleSetDefinitions: Record<string, UIDLStyleSetDefinition> = {
'5ecfa1233b8e50f60ea2b64d': {
id: '5ecfa1233b8e50f60ea2b64d',
name: 'primaryButton',
primaryButton: {
type: 'reusable-project-style-map',

@@ -71,5 +47,3 @@ content: {

},
'5ecfa1233b8e50f60ea2b64b': {
id: '5ecfa1233b8e50f60ea2b64b',
name: 'secondaryButton',
secondaryButton: {
type: 'reusable-project-style-map',

@@ -81,5 +55,3 @@ content: {

},
'5ecfa1233b8e50f60ea2b64c': {
id: '5ecfa1233b8e50f60ea2b64c',
name: 'conditionalButton',
conditionalButton: {
type: 'reusable-project-style-map',

@@ -121,4 +93,4 @@ conditions: [

expect(styleChunks.length).toBe(3)
expect(dependencies.css.path).toBe('styled-components')
expect(styleChunks.length).toBe(1)
expect(dependencies.variant.path).toBe('styled-system')
})

@@ -136,5 +108,3 @@

structure.uidl.styleSetDefinitions = {
'5ecfa1233b8e50f60ea2b64d': {
id: '5ecfa1233b8e50f60ea2b64d',
name: 'primaryButton',
primaryButton: {
type: 'reusable-project-style-map',

@@ -146,5 +116,3 @@ content: {

},
'5ecfa1233b8e50f60ea2b64b': {
id: '5ecfa1233b8e50f60ea2b64b',
name: 'secondaryButton',
secondaryButton: {
type: 'reusable-project-style-map',

@@ -160,8 +128,12 @@ content: {

const { chunks, dependencies } = result
const styleChunks = chunks.filter((chunk) => chunk.name === 'style')
const styleChunk = chunks.find((chunk) => chunk.name === 'index')
const declaration = styleChunk.content.declaration.declarations[0]
expect(styleChunks.length).toBe(0)
expect(dependencies.css.path).toBe('styled-components')
expect(styleChunk).toBeDefined()
expect(dependencies.variant.path).toBe('styled-system')
expect(result.uidl.outputOptions.fileName).toBe('index')
expect(declaration.id.name).toBe('projectStyleVariants')
expect(declaration.init.arguments[0].properties[0].value.value).toBe('projVariant')
expect(declaration.init.arguments[0].properties[1].value.properties.length).toBe(2)
})
})

@@ -8,2 +8,3 @@ import { ComponentPluginFactory, ComponentPlugin } from '@teleporthq/teleport-types';

illegalComponentNames?: string[];
classAttributeName?: string;
}

@@ -10,0 +11,0 @@ export declare const createReactStyledComponentsPlugin: ComponentPluginFactory<StyledComponentsConfig>;

@@ -1,193 +0,449 @@

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
return __assign.apply(this, arguments);
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
// packages/teleport-plugin-react-styled-components/src/index.ts
__markAsModule(exports);
__export(exports, {
createReactStyledComponentsPlugin: () => createReactStyledComponentsPlugin,
createStyleSheetPlugin: () => createStyleSheetPlugin,
default: () => src_default
});
var types3 = __toModule(require("@babel/types"));
var import_teleport_types3 = __toModule(require("@teleporthq/teleport-types"));
var import_teleport_shared3 = __toModule(require("@teleporthq/teleport-shared"));
var import_teleport_plugin_common = __toModule(require("@teleporthq/teleport-plugin-common"));
// packages/teleport-plugin-react-styled-components/src/utils.ts
var types = __toModule(require("@babel/types"));
var import_teleport_shared = __toModule(require("@teleporthq/teleport-shared"));
var import_teleport_types = __toModule(require("@teleporthq/teleport-types"));
var generateStyledComponent = (params) => {
const {
name,
elementType,
styles,
propsReferred,
componentStyleReferences,
projectStyleReferences
} = params;
let styleExpressions = styles;
const expressionArguments = [];
if (propsReferred.size > 0) {
styleExpressions = types.arrowFunctionExpression([types.identifier("props")], styles);
}
if (projectStyleReferences.size > 0) {
expressionArguments.push(...Array.from(projectStyleReferences).map((ref) => types.identifier(ref)));
}
if (styles && styles.properties.length > 0) {
expressionArguments.push(styleExpressions);
}
if (componentStyleReferences.size > 0) {
expressionArguments.push(...Array.from(componentStyleReferences).map((ref) => types.identifier(ref)));
}
return types.variableDeclaration("const", [
types.variableDeclarator(types.identifier(name), types.callExpression(types.callExpression(types.identifier("styled"), [types.stringLiteral(elementType)]), expressionArguments))
]);
};
var removeUnusedDependencies = (dependencies, jsxNodesLookup) => {
Object.keys(dependencies).forEach((depKey) => {
const dependency = dependencies[depKey];
if (dependency.type === "library" && dependency.path === "react-native") {
const dependencyIsStillNeeded = Object.keys(jsxNodesLookup).some((elementKey) => {
const jsxNode = jsxNodesLookup[elementKey];
return jsxNode.openingElement.name.name === depKey;
});
if (!dependencyIsStillNeeded) {
delete dependencies[depKey];
}
}
});
};
var generateStyledComponentStyles = (params) => {
const {
styles,
tokensReferred,
propsReferred,
propsPrefix = "props",
tokensPrefix = "TOKENS"
} = params;
const properties = Object.keys(styles).reduce((acc, styleId) => {
const style = styles[styleId];
const styleKey = types.stringLiteral(import_teleport_shared.StringUtils.camelCaseToDashCase(styleId));
if (style.type === "static") {
const styleContent = typeof style.content === "string" ? types.stringLiteral(style.content) : types.numericLiteral(Number(style.content));
acc.push(types.objectProperty(styleKey, styleContent));
}
if (style.type === "dynamic" && style.content.referenceType === "state") {
throw new import_teleport_types.PluginStyledComponent(`Error running transformDynamicStyles in reactStyledComponentsPlugin.
Unsupported styleValue.content.referenceType value ${style.content.referenceType}`);
}
if (style.type === "dynamic" && style.content.referenceType === "prop") {
const isNestedProp = style.content.id.includes(".");
acc.push(types.objectProperty(styleKey, types.memberExpression(types.identifier(propsPrefix), isNestedProp ? types.identifier(style.content.id) : types.identifier(`'${style.content.id}'`), !isNestedProp)));
propsReferred == null ? void 0 : propsReferred.add(style.content.id);
}
if (style.type === "dynamic" && style.content.referenceType === "token") {
const usedToken = import_teleport_shared.StringUtils.capitalize(import_teleport_shared.StringUtils.dashCaseToCamelCase(style.content.id));
acc.push(types.objectProperty(styleKey, types.memberExpression(types.identifier(tokensPrefix), types.identifier(usedToken))));
tokensReferred == null ? void 0 : tokensReferred.add(usedToken);
}
return acc;
}, []);
return types.objectExpression(properties);
};
var generateVariantsfromStyleSet = (styleSets, variantPropPrefix, variantPropKey, tokensReferred) => {
const variantExpressions = types.objectExpression(Object.keys(styleSets).reduce((acc, styleId) => {
const style = styleSets[styleId];
const { content = {}, conditions = [] } = style;
const property = types.objectProperty(types.stringLiteral(styleId), generateStyledComponentStyles(__spreadValues({
styles: content
}, tokensReferred && { tokensReferred })));
conditions.forEach((cond) => {
const mediaProperty = types.objectProperty(cond.type === "screen-size" ? types.stringLiteral(`@media(max-width: ${cond.meta.maxWidth}px)`) : types.stringLiteral(`&:${cond.meta.state}`), generateStyledComponentStyles(__spreadValues({
styles: cond.content
}, tokensReferred && { tokensReferred })));
if (property.value.type === "ObjectExpression") {
property.value.properties.push(mediaProperty);
}
});
acc.push(property);
return acc;
}, []));
return types.variableDeclaration("const", [
types.variableDeclarator(types.identifier(variantPropPrefix), types.callExpression(types.identifier("variant"), [
types.objectExpression([
types.objectProperty(types.identifier("prop"), types.stringLiteral(variantPropKey)),
types.objectProperty(types.identifier("variants"), variantExpressions)
])
]))
]);
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
// packages/teleport-plugin-react-styled-components/src/style-sheet.ts
var types2 = __toModule(require("@babel/types"));
var import_teleport_types2 = __toModule(require("@teleporthq/teleport-types"));
var import_teleport_shared2 = __toModule(require("@teleporthq/teleport-shared"));
// packages/teleport-plugin-react-styled-components/src/constants.ts
var VARIANT_DEPENDENCY = {
type: "package",
path: "styled-system",
version: "^5.1.5",
meta: {
namedImport: true
}
};
var componentVariantPropPrefix = "componentStyleVariants";
var componentVariantPropKey = "compVariant";
var projectVariantPropPrefix = "projectStyleVariants";
var projectVariantPropKey = "projVariant";
// packages/teleport-plugin-react-styled-components/src/style-sheet.ts
var createStyleSheetPlugin = (config) => {
const { fileName = "style" } = config || {};
const styleSheetPlugin = (structure) => __async(void 0, null, function* () {
const { uidl, chunks, dependencies } = structure;
const { styleSetDefinitions = {}, designLanguage: { tokens = {} } = {} } = uidl;
if (Object.keys(styleSetDefinitions).length === 0 && Object.keys(tokens).length === 0) {
return structure;
}
const tokensMap = Object.keys(tokens || {}).reduce((acc, key) => {
const style = tokens[key];
const name = import_teleport_shared2.StringUtils.capitalize(import_teleport_shared2.StringUtils.dashCaseToCamelCase(key));
acc[name] = style.content;
return acc;
}, {});
if (Object.keys(styleSetDefinitions).length > 0) {
const variants = generateVariantsfromStyleSet(styleSetDefinitions, projectVariantPropPrefix, projectVariantPropKey);
chunks.push({
name: fileName,
type: import_teleport_types2.ChunkType.AST,
content: types2.exportNamedDeclaration(variants),
fileType: import_teleport_types2.FileType.JS,
linkAfter: ["tokens-chunk"]
});
dependencies.variant = VARIANT_DEPENDENCY;
}
if (Object.keys(tokensMap).length > 0) {
chunks.push({
name: "tokens-chunk",
type: import_teleport_types2.ChunkType.AST,
fileType: import_teleport_types2.FileType.JS,
content: types2.exportNamedDeclaration(types2.variableDeclaration("const", [
types2.variableDeclarator(types2.identifier("TOKENS"), types2.objectExpression(Object.keys(tokensMap).reduce((acc, token) => {
const value = typeof tokensMap[token] === "number" ? types2.numericLiteral(Number(tokensMap[token])) : types2.stringLiteral(String(tokensMap[token]));
acc.push(types2.objectProperty(types2.identifier(token), value));
return acc;
}, [])))
])),
linkAfter: ["import-local"]
});
}
uidl.outputOptions = uidl.outputOptions || {};
uidl.outputOptions.fileName = fileName;
return structure;
});
return styleSheetPlugin;
};
Object.defineProperty(exports, "__esModule", { value: true });
var teleport_types_1 = require("@teleporthq/teleport-types");
var teleport_shared_1 = require("@teleporthq/teleport-shared");
var teleport_plugin_common_1 = require("@teleporthq/teleport-plugin-common");
var utils_1 = require("./utils");
var style_sheet_1 = require("./style-sheet");
exports.createStyleSheetPlugin = style_sheet_1.createStyleSheetPlugin;
exports.createReactStyledComponentsPlugin = function (config) {
var _a = config || {}, _b = _a.componentChunkName, componentChunkName = _b === void 0 ? 'jsx-component' : _b, _c = _a.importChunkName, importChunkName = _c === void 0 ? 'import-local' : _c, _d = _a.componentLibrary, componentLibrary = _d === void 0 ? 'react' : _d, _e = _a.illegalComponentNames, illegalComponentNames = _e === void 0 ? [] : _e;
var reactStyledComponentsPlugin = function (structure) { return __awaiter(void 0, void 0, void 0, function () {
var uidl, chunks, dependencies, options, node, name, projectStyleSet, componentChunk, jsxNodesLookup, propsPrefix, jssStyleMap, tokensReferred;
return __generator(this, function (_a) {
uidl = structure.uidl, chunks = structure.chunks, dependencies = structure.dependencies, options = structure.options;
node = uidl.node, name = uidl.name;
projectStyleSet = options.projectStyleSet;
componentChunk = chunks.find(function (chunk) { return chunk.name === componentChunkName; });
if (!componentChunk) {
return [2 /*return*/, structure];
}
jsxNodesLookup = componentChunk.meta.nodesLookup;
propsPrefix = componentChunk.meta.dynamicRefPrefix.prop;
jssStyleMap = {};
tokensReferred = [];
teleport_shared_1.UIDLUtils.traverseElements(node, function (element) {
var _a;
var style = element.style;
var key = element.key, elementType = element.elementType, referencedStyles = element.referencedStyles;
if (!style && !referencedStyles) {
return;
// packages/teleport-plugin-react-styled-components/src/index.ts
var createReactStyledComponentsPlugin = (config) => {
const {
componentChunkName = "jsx-component",
importChunkName = "import-local",
componentLibrary = "react",
illegalComponentNames = [],
classAttributeName = "className"
} = config || {};
const reactStyledComponentsPlugin = (structure) => __async(void 0, null, function* () {
const { uidl, chunks, dependencies, options } = structure;
const { node, name, styleSetDefinitions: componentStyleSheet = {} } = uidl;
const { projectStyleSet } = options;
const componentChunk = chunks.find((chunk) => chunk.name === componentChunkName);
if (!componentChunk) {
return structure;
}
const jsxNodesLookup = componentChunk.meta.nodesLookup;
const propsPrefix = componentChunk.meta.dynamicRefPrefix.prop;
const cssMap = {};
const tokensReferred = new Set();
if (Object.keys(componentStyleSheet).length > 0) {
const variants = generateVariantsfromStyleSet(componentStyleSheet, componentVariantPropPrefix, componentVariantPropKey, tokensReferred);
chunks.push({
name: "variant",
type: import_teleport_types3.ChunkType.AST,
content: variants,
fileType: import_teleport_types3.FileType.JS,
linkAfter: ["jsx-component"]
});
dependencies.variant = VARIANT_DEPENDENCY;
}
import_teleport_shared3.UIDLUtils.traverseElements(node, (element) => {
var _a;
const { style = {} } = element;
const { key, elementType, referencedStyles = {} } = element;
const propsReferred = new Set();
const componentStyleReferences = new Set();
const projectStyleReferences = new Set();
const staticClasses = new Set();
if (Object.keys(style).length === 0 && Object.keys(referencedStyles).length === 0) {
return;
}
const root = jsxNodesLookup[key];
let className = import_teleport_shared3.StringUtils.dashCaseToUpperCamelCase(key);
if (style && Object.keys(style).length > 0) {
if (illegalComponentNames.includes(className) || import_teleport_shared3.StringUtils.dashCaseToUpperCamelCase(key) === name || Object.keys(dependencies).includes(className)) {
className = `Styled${className}`;
}
if (componentLibrary === "reactnative") {
if (referencedStyles && Object.keys(referencedStyles).length > 0) {
Object.keys(referencedStyles).forEach((styleId) => {
const styleRef = referencedStyles[styleId];
if (styleRef.content.mapType === "inlined") {
referencedStyles[styleId] = __spreadProps(__spreadValues({}, referencedStyles[styleId]), {
content: __spreadProps(__spreadValues({}, referencedStyles[styleId].content), {
styles: styleRef.content.styles
})
});
}
});
}
}
cssMap[className] = generateStyledComponentStyles({
styles: style,
propsReferred,
tokensReferred,
propsPrefix,
tokensPrefix: "TOKENS"
});
}
if (referencedStyles && ((_a = Object.keys(referencedStyles)) == null ? void 0 : _a.length) > 0) {
Object.values(referencedStyles).forEach((styleRef) => {
var _a2;
switch ((_a2 = styleRef.content) == null ? void 0 : _a2.mapType) {
case "inlined": {
const { conditions } = styleRef.content;
const [condition] = conditions;
if (condition.conditionType === "screen-size") {
const nodeStyle = cssMap[className];
const mediaStyles = types3.objectProperty(types3.stringLiteral(`@media(max-width: ${condition.maxWidth}px)`), generateStyledComponentStyles({
styles: styleRef.content.styles,
propsReferred,
tokensReferred,
propsPrefix,
tokensPrefix: "TOKENS"
}));
if ((nodeStyle == null ? void 0 : nodeStyle.type) === "ObjectExpression") {
nodeStyle.properties.push(mediaStyles);
} else {
cssMap[className] = import_teleport_plugin_common.ASTUtils.wrapObjectPropertiesWithExpression([mediaStyles]);
}
var root = jsxNodesLookup[key];
var className = teleport_shared_1.StringUtils.dashCaseToUpperCamelCase(key);
var projectReferencedClassNames = [];
var timesProsReferred = utils_1.countPropReferences(style, 0);
timesProsReferred = utils_1.countPropRefernecesFromReferencedStyles(referencedStyles, timesProsReferred);
if (style && Object.keys(style).length > 0) {
/* Styled components might create an element that
clashes with native element (Text, View, Image, etc.) */
if (illegalComponentNames.includes(className) ||
teleport_shared_1.StringUtils.dashCaseToUpperCamelCase(key) === name ||
Object.keys(dependencies).includes(className)) {
className = "Styled" + className;
}
if (componentLibrary === 'reactnative') {
if (referencedStyles && Object.keys(referencedStyles).length > 0) {
Object.values(referencedStyles).forEach(function (styleRef) {
if (styleRef.content.mapType === 'inlined') {
referencedStyles[styleRef.id] = __assign(__assign({}, referencedStyles[styleRef.id]), { content: __assign(__assign({}, referencedStyles[styleRef.id].content), {
// @ts-ignore
styles: styleRef.content.styles }) });
}
});
}
}
jssStyleMap[className] = utils_1.generatePropReferencesSyntax(style, timesProsReferred, tokensReferred, root, propsPrefix);
}
if (condition.conditionType === "element-state") {
const nodeStyle = cssMap[className];
const mediaStyles = types3.objectProperty(types3.stringLiteral(`&:${condition.content}`), generateStyledComponentStyles({
styles: styleRef.content.styles,
propsReferred,
tokensReferred,
propsPrefix,
tokensPrefix: "TOKENS"
}));
if ((nodeStyle == null ? void 0 : nodeStyle.type) === "ObjectExpression") {
nodeStyle.properties.push(mediaStyles);
} else {
cssMap[className] = import_teleport_plugin_common.ASTUtils.wrapObjectPropertiesWithExpression([mediaStyles]);
}
if (referencedStyles && ((_a = Object.keys(referencedStyles)) === null || _a === void 0 ? void 0 : _a.length) > 0) {
Object.values(referencedStyles).forEach(function (styleRef) {
var _a, _b;
var _c, _d, _e;
switch ((_c = styleRef.content) === null || _c === void 0 ? void 0 : _c.mapType) {
case 'inlined': {
var conditions = styleRef.content.conditions;
var condition = conditions[0];
if (((_d = styleRef.content) === null || _d === void 0 ? void 0 : _d.styles) && Object.keys(styleRef.content.styles).length === 0) {
return;
}
if (condition.conditionType === 'screen-size') {
jssStyleMap[className] = __assign(__assign({}, jssStyleMap[className]), (_a = {}, _a["@media(max-width: " + condition.maxWidth + "px)"] = utils_1.generatePropReferencesSyntax(styleRef.content.styles, timesProsReferred, tokensReferred, root, propsPrefix), _a));
}
if (condition.conditionType === 'element-state') {
jssStyleMap[className] = __assign(__assign({}, jssStyleMap[className]), (_b = {}, _b["&:" + condition.content] = utils_1.generatePropReferencesSyntax(styleRef.content.styles, timesProsReferred, tokensReferred, root, propsPrefix), _b));
}
return;
}
case 'project-referenced': {
if (!projectStyleSet) {
throw new Error("Project Style Sheet is missing, but the node is referring to it " + element);
}
var content = styleRef.content;
if (content.referenceId && !((_e = content) === null || _e === void 0 ? void 0 : _e.conditions)) {
var referedStyle = projectStyleSet.styleSetDefinitions[content.referenceId];
if (!referedStyle) {
throw new Error("Style that is being used for reference is missing - " + content.referenceId);
}
var styleName = teleport_shared_1.StringUtils.dashCaseToUpperCamelCase(referedStyle.name);
projectReferencedClassNames.push(styleName);
dependencies[styleName] = {
type: 'local',
path: projectStyleSet.path + "/" + projectStyleSet.fileName,
meta: {
namedImport: true,
},
};
}
return;
}
default: {
throw new Error("\n We support only inlined and project-referenced styles as of now, received " + styleRef.content + "\n ");
}
}
});
}
return;
}
case "component-referenced": {
if (componentStyleReferences.size > 0) {
throw new import_teleport_types3.PluginStyledComponent(`Styled Component can have only one reference per node.
i.e either a direct static reference from component style sheet or from props. Got both. ${JSON.stringify(Array.from(componentStyleReferences), null, 2)}`);
}
if (styleRef.content.content.type === "static") {
staticClasses.add(types3.identifier(`'${styleRef.content.content.content}'`));
}
if (styleRef.content.content.type === "dynamic" && styleRef.content.content.content.referenceType === "comp") {
componentStyleReferences.add(componentVariantPropPrefix);
import_teleport_plugin_common.ASTUtils.addAttributeToJSXTag(root, componentVariantPropKey, styleRef.content.content.content.id);
}
if (styleRef.content.content.type === "dynamic" && styleRef.content.content.content.referenceType === "prop") {
componentStyleReferences.add(componentVariantPropPrefix);
import_teleport_plugin_common.ASTUtils.addDynamicAttributeToJSXTag(root, componentVariantPropKey, `${propsPrefix}.${styleRef.content.content.content.id}`);
}
return;
}
case "project-referenced": {
if (!projectStyleSet) {
throw new Error(`Project Style Sheet is missing, but the node is referring to it ${element}`);
}
const { content } = styleRef;
const referedStyle = projectStyleSet.styleSetDefinitions[content.referenceId];
if (!referedStyle) {
throw new Error(`Style that is being used for reference is missing - ${content.referenceId}`);
}
dependencies[projectVariantPropPrefix] = {
type: "local",
path: `${projectStyleSet.path}/${projectStyleSet.fileName}`,
meta: {
namedImport: true
}
if (timesProsReferred > 1) {
teleport_plugin_common_1.ASTUtils.addSpreadAttributeToJSXTag(root, propsPrefix);
}
teleport_plugin_common_1.ASTUtils.renameJSXTag(root, className);
var code = {
type: teleport_types_1.ChunkType.AST,
fileType: teleport_types_1.FileType.JS,
name: className,
linkAfter: [importChunkName],
content: utils_1.generateStyledComponent(className, elementType, jssStyleMap[className], projectReferencedClassNames),
};
chunks.push(code);
});
if (Object.keys(jssStyleMap).length === 0) {
return [2 /*return*/, structure];
};
projectStyleReferences.add(projectVariantPropPrefix);
import_teleport_plugin_common.ASTUtils.addAttributeToJSXTag(root, projectVariantPropKey, content.referenceId);
return;
}
if (tokensReferred.length > 0) {
dependencies.TOKENS = {
type: 'local',
path: projectStyleSet.path + "/" + projectStyleSet.fileName,
meta: {
namedImport: true,
},
};
default: {
throw new Error(`
We support only inlined and project-referenced styles as of now, received ${JSON.stringify(styleRef.content, null, 2)}
`);
}
dependencies.styled = {
type: 'package',
path: componentLibrary === 'react' ? 'styled-components' : 'styled-components/native',
version: '4.2.0',
};
/* React Native elements are imported from styled-components/native,
so direct dependency to `react-native` is removed */
if (componentLibrary === 'reactnative') {
utils_1.removeUnusedDependencies(dependencies, jsxNodesLookup);
}
return [2 /*return*/, structure];
}
});
}); };
return reactStyledComponentsPlugin;
}
if (propsReferred.size > 0) {
import_teleport_plugin_common.ASTUtils.addSpreadAttributeToJSXTag(root, propsPrefix);
}
if (staticClasses.size > 0) {
import_teleport_plugin_common.ASTUtils.addMultipleDynamicAttributesToJSXTag(root, classAttributeName, Array.from(staticClasses));
}
import_teleport_plugin_common.ASTUtils.renameJSXTag(root, className);
const code = {
type: import_teleport_types3.ChunkType.AST,
fileType: import_teleport_types3.FileType.JS,
name: className,
linkAfter: [importChunkName],
content: generateStyledComponent({
name: className,
styles: cssMap[className],
elementType,
propsReferred,
componentStyleReferences,
projectStyleReferences
})
};
chunks.push(code);
});
if (Object.keys(cssMap).length === 0) {
return structure;
}
if (tokensReferred.size > 0) {
dependencies.TOKENS = {
type: "local",
path: `${projectStyleSet.path}/${projectStyleSet.fileName}`,
meta: {
namedImport: true
}
};
}
dependencies.styled = {
type: "package",
path: componentLibrary === "react" ? "styled-components" : "styled-components/native",
version: "^5.3.0"
};
if (componentLibrary === "reactnative") {
removeUnusedDependencies(dependencies, jsxNodesLookup);
}
return structure;
});
return reactStyledComponentsPlugin;
};
exports.default = exports.createReactStyledComponentsPlugin();
//# sourceMappingURL=index.js.map
var src_default = createReactStyledComponentsPlugin();
import { ComponentPluginFactory } from '@teleporthq/teleport-types';
interface StyleSheetPlugin {
fileName?: string;
componentLibrary?: string;
}
export declare const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin>;
export {};

@@ -1,9 +0,19 @@

import * as t from '@babel/types';
import { UIDLStyleValue, UIDLDependency } from '@teleporthq/teleport-types';
export declare const generateStyledComponent: (name: string, type: string, styles: Record<string, unknown>, projectReferencedStyles?: string[]) => t.VariableDeclaration;
export declare const generateCSSInterpolate: (name: string, styles: Record<string, unknown>) => t.VariableDeclaration;
export declare const generateExportablCSSInterpolate: (name: string, styles: Record<string, unknown>) => t.ExportNamedDeclaration;
export declare const countPropReferences: (style: Record<string, UIDLStyleValue>, timesReferred: number) => number;
export declare const countPropRefernecesFromReferencedStyles: (styles: Record<string, import("@teleporthq/teleport-types").UIDLElementNodeReferenceStyles>, timesReferred: number) => number;
export declare const removeUnusedDependencies: (dependencies: Record<string, UIDLDependency>, jsxNodesLookup: Record<string, t.JSXElement>) => void;
export declare const generatePropReferencesSyntax: (style: Record<string, UIDLStyleValue>, timesPropsReferred?: number, tokensReferred?: string[], root?: t.JSXElement, propsPrefix?: unknown) => Record<string, any>;
import * as types from '@babel/types';
import { UIDLStyleValue, UIDLDependency, UIDLStyleSetDefinition } from '@teleporthq/teleport-types';
export declare const generateStyledComponent: (params: {
name: string;
elementType: string;
styles: types.ObjectExpression;
propsReferred: Set<string>;
componentStyleReferences: Set<string>;
projectStyleReferences: Set<string>;
}) => types.VariableDeclaration;
export declare const removeUnusedDependencies: (dependencies: Record<string, UIDLDependency>, jsxNodesLookup: Record<string, types.JSXElement>) => void;
export declare const generateStyledComponentStyles: (params: {
styles: Record<string, UIDLStyleValue>;
propsReferred?: Set<string>;
tokensReferred?: Set<string>;
propsPrefix?: string;
tokensPrefix?: string;
}) => types.ObjectExpression;
export declare const generateVariantsfromStyleSet: (styleSets: Record<string, UIDLStyleSetDefinition>, variantPropPrefix: string, variantPropKey: string, tokensReferred?: Set<string>) => types.VariableDeclaration;

@@ -1,154 +0,461 @@

import { ChunkType, FileType, } from '@teleporthq/teleport-types';
import { UIDLUtils, StringUtils } from '@teleporthq/teleport-shared';
import { ASTUtils } from '@teleporthq/teleport-plugin-common';
import { generateStyledComponent, countPropReferences, removeUnusedDependencies, generatePropReferencesSyntax, countPropRefernecesFromReferencedStyles, } from './utils';
import { createStyleSheetPlugin } from './style-sheet';
export const createReactStyledComponentsPlugin = (config) => {
const { componentChunkName = 'jsx-component', importChunkName = 'import-local', componentLibrary = 'react', illegalComponentNames = [], } = config || {};
const reactStyledComponentsPlugin = async (structure) => {
const { uidl, chunks, dependencies, options } = structure;
const { node, name } = uidl;
const { projectStyleSet } = options;
const componentChunk = chunks.find((chunk) => chunk.name === componentChunkName);
if (!componentChunk) {
return structure;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// packages/teleport-plugin-react-styled-components/src/index.ts
import {
identifier as identifier3,
objectProperty as objectProperty3,
stringLiteral as stringLiteral3
} from "@babel/types";
import {
ChunkType as ChunkType2,
FileType as FileType2,
PluginStyledComponent as PluginStyledComponent2
} from "@teleporthq/teleport-types";
import { UIDLUtils, StringUtils as StringUtils3 } from "@teleporthq/teleport-shared";
import { ASTUtils } from "@teleporthq/teleport-plugin-common";
// packages/teleport-plugin-react-styled-components/src/utils.ts
import {
arrowFunctionExpression,
callExpression,
identifier,
memberExpression,
numericLiteral,
objectExpression,
objectProperty,
stringLiteral,
variableDeclaration,
variableDeclarator
} from "@babel/types";
import { StringUtils } from "@teleporthq/teleport-shared";
import {
PluginStyledComponent
} from "@teleporthq/teleport-types";
var generateStyledComponent = (params) => {
const {
name,
elementType,
styles,
propsReferred,
componentStyleReferences,
projectStyleReferences
} = params;
let styleExpressions = styles;
const expressionArguments = [];
if (propsReferred.size > 0) {
styleExpressions = arrowFunctionExpression([identifier("props")], styles);
}
if (projectStyleReferences.size > 0) {
expressionArguments.push(...Array.from(projectStyleReferences).map((ref) => identifier(ref)));
}
if (styles && styles.properties.length > 0) {
expressionArguments.push(styleExpressions);
}
if (componentStyleReferences.size > 0) {
expressionArguments.push(...Array.from(componentStyleReferences).map((ref) => identifier(ref)));
}
return variableDeclaration("const", [
variableDeclarator(identifier(name), callExpression(callExpression(identifier("styled"), [stringLiteral(elementType)]), expressionArguments))
]);
};
var removeUnusedDependencies = (dependencies, jsxNodesLookup) => {
Object.keys(dependencies).forEach((depKey) => {
const dependency = dependencies[depKey];
if (dependency.type === "library" && dependency.path === "react-native") {
const dependencyIsStillNeeded = Object.keys(jsxNodesLookup).some((elementKey) => {
const jsxNode = jsxNodesLookup[elementKey];
return jsxNode.openingElement.name.name === depKey;
});
if (!dependencyIsStillNeeded) {
delete dependencies[depKey];
}
}
});
};
var generateStyledComponentStyles = (params) => {
const {
styles,
tokensReferred,
propsReferred,
propsPrefix = "props",
tokensPrefix = "TOKENS"
} = params;
const properties = Object.keys(styles).reduce((acc, styleId) => {
const style = styles[styleId];
const styleKey = stringLiteral(StringUtils.camelCaseToDashCase(styleId));
if (style.type === "static") {
const styleContent = typeof style.content === "string" ? stringLiteral(style.content) : numericLiteral(Number(style.content));
acc.push(objectProperty(styleKey, styleContent));
}
if (style.type === "dynamic" && style.content.referenceType === "state") {
throw new PluginStyledComponent(`Error running transformDynamicStyles in reactStyledComponentsPlugin.
Unsupported styleValue.content.referenceType value ${style.content.referenceType}`);
}
if (style.type === "dynamic" && style.content.referenceType === "prop") {
const isNestedProp = style.content.id.includes(".");
acc.push(objectProperty(styleKey, memberExpression(identifier(propsPrefix), isNestedProp ? identifier(style.content.id) : identifier(`'${style.content.id}'`), !isNestedProp)));
propsReferred == null ? void 0 : propsReferred.add(style.content.id);
}
if (style.type === "dynamic" && style.content.referenceType === "token") {
const usedToken = StringUtils.capitalize(StringUtils.dashCaseToCamelCase(style.content.id));
acc.push(objectProperty(styleKey, memberExpression(identifier(tokensPrefix), identifier(usedToken))));
tokensReferred == null ? void 0 : tokensReferred.add(usedToken);
}
return acc;
}, []);
return objectExpression(properties);
};
var generateVariantsfromStyleSet = (styleSets, variantPropPrefix, variantPropKey, tokensReferred) => {
const variantExpressions = objectExpression(Object.keys(styleSets).reduce((acc, styleId) => {
const style = styleSets[styleId];
const { content = {}, conditions = [] } = style;
const property = objectProperty(stringLiteral(styleId), generateStyledComponentStyles(__spreadValues({
styles: content
}, tokensReferred && { tokensReferred })));
conditions.forEach((cond) => {
const mediaProperty = objectProperty(cond.type === "screen-size" ? stringLiteral(`@media(max-width: ${cond.meta.maxWidth}px)`) : stringLiteral(`&:${cond.meta.state}`), generateStyledComponentStyles(__spreadValues({
styles: cond.content
}, tokensReferred && { tokensReferred })));
if (property.value.type === "ObjectExpression") {
property.value.properties.push(mediaProperty);
}
});
acc.push(property);
return acc;
}, []));
return variableDeclaration("const", [
variableDeclarator(identifier(variantPropPrefix), callExpression(identifier("variant"), [
objectExpression([
objectProperty(identifier("prop"), stringLiteral(variantPropKey)),
objectProperty(identifier("variants"), variantExpressions)
])
]))
]);
};
// packages/teleport-plugin-react-styled-components/src/style-sheet.ts
import {
exportNamedDeclaration,
identifier as identifier2,
numericLiteral as numericLiteral2,
objectExpression as objectExpression2,
objectProperty as objectProperty2,
stringLiteral as stringLiteral2,
variableDeclaration as variableDeclaration2,
variableDeclarator as variableDeclarator2
} from "@babel/types";
import {
ChunkType,
FileType
} from "@teleporthq/teleport-types";
import { StringUtils as StringUtils2 } from "@teleporthq/teleport-shared";
// packages/teleport-plugin-react-styled-components/src/constants.ts
var VARIANT_DEPENDENCY = {
type: "package",
path: "styled-system",
version: "^5.1.5",
meta: {
namedImport: true
}
};
var componentVariantPropPrefix = "componentStyleVariants";
var componentVariantPropKey = "compVariant";
var projectVariantPropPrefix = "projectStyleVariants";
var projectVariantPropKey = "projVariant";
// packages/teleport-plugin-react-styled-components/src/style-sheet.ts
var createStyleSheetPlugin = (config) => {
const { fileName = "style" } = config || {};
const styleSheetPlugin = (structure) => __async(void 0, null, function* () {
const { uidl, chunks, dependencies } = structure;
const { styleSetDefinitions = {}, designLanguage: { tokens = {} } = {} } = uidl;
if (Object.keys(styleSetDefinitions).length === 0 && Object.keys(tokens).length === 0) {
return structure;
}
const tokensMap = Object.keys(tokens || {}).reduce((acc, key) => {
const style = tokens[key];
const name = StringUtils2.capitalize(StringUtils2.dashCaseToCamelCase(key));
acc[name] = style.content;
return acc;
}, {});
if (Object.keys(styleSetDefinitions).length > 0) {
const variants = generateVariantsfromStyleSet(styleSetDefinitions, projectVariantPropPrefix, projectVariantPropKey);
chunks.push({
name: fileName,
type: ChunkType.AST,
content: exportNamedDeclaration(variants),
fileType: FileType.JS,
linkAfter: ["tokens-chunk"]
});
dependencies.variant = VARIANT_DEPENDENCY;
}
if (Object.keys(tokensMap).length > 0) {
chunks.push({
name: "tokens-chunk",
type: ChunkType.AST,
fileType: FileType.JS,
content: exportNamedDeclaration(variableDeclaration2("const", [
variableDeclarator2(identifier2("TOKENS"), objectExpression2(Object.keys(tokensMap).reduce((acc, token) => {
const value = typeof tokensMap[token] === "number" ? numericLiteral2(Number(tokensMap[token])) : stringLiteral2(String(tokensMap[token]));
acc.push(objectProperty2(identifier2(token), value));
return acc;
}, [])))
])),
linkAfter: ["import-local"]
});
}
uidl.outputOptions = uidl.outputOptions || {};
uidl.outputOptions.fileName = fileName;
return structure;
});
return styleSheetPlugin;
};
// packages/teleport-plugin-react-styled-components/src/index.ts
var createReactStyledComponentsPlugin = (config) => {
const {
componentChunkName = "jsx-component",
importChunkName = "import-local",
componentLibrary = "react",
illegalComponentNames = [],
classAttributeName = "className"
} = config || {};
const reactStyledComponentsPlugin = (structure) => __async(void 0, null, function* () {
const { uidl, chunks, dependencies, options } = structure;
const { node, name, styleSetDefinitions: componentStyleSheet = {} } = uidl;
const { projectStyleSet } = options;
const componentChunk = chunks.find((chunk) => chunk.name === componentChunkName);
if (!componentChunk) {
return structure;
}
const jsxNodesLookup = componentChunk.meta.nodesLookup;
const propsPrefix = componentChunk.meta.dynamicRefPrefix.prop;
const cssMap = {};
const tokensReferred = new Set();
if (Object.keys(componentStyleSheet).length > 0) {
const variants = generateVariantsfromStyleSet(componentStyleSheet, componentVariantPropPrefix, componentVariantPropKey, tokensReferred);
chunks.push({
name: "variant",
type: ChunkType2.AST,
content: variants,
fileType: FileType2.JS,
linkAfter: ["jsx-component"]
});
dependencies.variant = VARIANT_DEPENDENCY;
}
UIDLUtils.traverseElements(node, (element) => {
var _a;
const { style = {} } = element;
const { key, elementType, referencedStyles = {} } = element;
const propsReferred = new Set();
const componentStyleReferences = new Set();
const projectStyleReferences = new Set();
const staticClasses = new Set();
if (Object.keys(style).length === 0 && Object.keys(referencedStyles).length === 0) {
return;
}
const root = jsxNodesLookup[key];
let className = StringUtils3.dashCaseToUpperCamelCase(key);
if (style && Object.keys(style).length > 0) {
if (illegalComponentNames.includes(className) || StringUtils3.dashCaseToUpperCamelCase(key) === name || Object.keys(dependencies).includes(className)) {
className = `Styled${className}`;
}
const jsxNodesLookup = componentChunk.meta.nodesLookup;
// @ts-ignore
const propsPrefix = componentChunk.meta.dynamicRefPrefix.prop;
const jssStyleMap = {};
const tokensReferred = [];
UIDLUtils.traverseElements(node, (element) => {
var _a;
const { style } = element;
const { key, elementType, referencedStyles } = element;
if (!style && !referencedStyles) {
return;
}
const root = jsxNodesLookup[key];
let className = StringUtils.dashCaseToUpperCamelCase(key);
const projectReferencedClassNames = [];
let timesProsReferred = countPropReferences(style, 0);
timesProsReferred = countPropRefernecesFromReferencedStyles(referencedStyles, timesProsReferred);
if (style && Object.keys(style).length > 0) {
/* Styled components might create an element that
clashes with native element (Text, View, Image, etc.) */
if (illegalComponentNames.includes(className) ||
StringUtils.dashCaseToUpperCamelCase(key) === name ||
Object.keys(dependencies).includes(className)) {
className = `Styled${className}`;
if (componentLibrary === "reactnative") {
if (referencedStyles && Object.keys(referencedStyles).length > 0) {
Object.keys(referencedStyles).forEach((styleId) => {
const styleRef = referencedStyles[styleId];
if (styleRef.content.mapType === "inlined") {
referencedStyles[styleId] = __spreadProps(__spreadValues({}, referencedStyles[styleId]), {
content: __spreadProps(__spreadValues({}, referencedStyles[styleId].content), {
styles: styleRef.content.styles
})
});
}
});
}
}
cssMap[className] = generateStyledComponentStyles({
styles: style,
propsReferred,
tokensReferred,
propsPrefix,
tokensPrefix: "TOKENS"
});
}
if (referencedStyles && ((_a = Object.keys(referencedStyles)) == null ? void 0 : _a.length) > 0) {
Object.values(referencedStyles).forEach((styleRef) => {
var _a2;
switch ((_a2 = styleRef.content) == null ? void 0 : _a2.mapType) {
case "inlined": {
const { conditions } = styleRef.content;
const [condition] = conditions;
if (condition.conditionType === "screen-size") {
const nodeStyle = cssMap[className];
const mediaStyles = objectProperty3(stringLiteral3(`@media(max-width: ${condition.maxWidth}px)`), generateStyledComponentStyles({
styles: styleRef.content.styles,
propsReferred,
tokensReferred,
propsPrefix,
tokensPrefix: "TOKENS"
}));
if ((nodeStyle == null ? void 0 : nodeStyle.type) === "ObjectExpression") {
nodeStyle.properties.push(mediaStyles);
} else {
cssMap[className] = ASTUtils.wrapObjectPropertiesWithExpression([mediaStyles]);
}
if (componentLibrary === 'reactnative') {
if (referencedStyles && Object.keys(referencedStyles).length > 0) {
Object.values(referencedStyles).forEach((styleRef) => {
if (styleRef.content.mapType === 'inlined') {
referencedStyles[styleRef.id] = {
...referencedStyles[styleRef.id],
content: {
...referencedStyles[styleRef.id].content,
// @ts-ignore
styles: styleRef.content.styles,
},
};
}
});
}
}
if (condition.conditionType === "element-state") {
const nodeStyle = cssMap[className];
const mediaStyles = objectProperty3(stringLiteral3(`&:${condition.content}`), generateStyledComponentStyles({
styles: styleRef.content.styles,
propsReferred,
tokensReferred,
propsPrefix,
tokensPrefix: "TOKENS"
}));
if ((nodeStyle == null ? void 0 : nodeStyle.type) === "ObjectExpression") {
nodeStyle.properties.push(mediaStyles);
} else {
cssMap[className] = ASTUtils.wrapObjectPropertiesWithExpression([mediaStyles]);
}
jssStyleMap[className] = generatePropReferencesSyntax(style, timesProsReferred, tokensReferred, root, propsPrefix);
}
return;
}
if (referencedStyles && ((_a = Object.keys(referencedStyles)) === null || _a === void 0 ? void 0 : _a.length) > 0) {
Object.values(referencedStyles).forEach((styleRef) => {
var _a, _b, _c;
switch ((_a = styleRef.content) === null || _a === void 0 ? void 0 : _a.mapType) {
case 'inlined': {
const { conditions } = styleRef.content;
const [condition] = conditions;
if (((_b = styleRef.content) === null || _b === void 0 ? void 0 : _b.styles) && Object.keys(styleRef.content.styles).length === 0) {
return;
}
if (condition.conditionType === 'screen-size') {
jssStyleMap[className] = {
...jssStyleMap[className],
[`@media(max-width: ${condition.maxWidth}px)`]: generatePropReferencesSyntax(styleRef.content.styles, timesProsReferred, tokensReferred, root, propsPrefix),
};
}
if (condition.conditionType === 'element-state') {
jssStyleMap[className] = {
...jssStyleMap[className],
[`&:${condition.content}`]: generatePropReferencesSyntax(styleRef.content.styles, timesProsReferred, tokensReferred, root, propsPrefix),
};
}
return;
}
case 'project-referenced': {
if (!projectStyleSet) {
throw new Error(`Project Style Sheet is missing, but the node is referring to it ${element}`);
}
const { content } = styleRef;
if (content.referenceId && !((_c = content) === null || _c === void 0 ? void 0 : _c.conditions)) {
const referedStyle = projectStyleSet.styleSetDefinitions[content.referenceId];
if (!referedStyle) {
throw new Error(`Style that is being used for reference is missing - ${content.referenceId}`);
}
const styleName = StringUtils.dashCaseToUpperCamelCase(referedStyle.name);
projectReferencedClassNames.push(styleName);
dependencies[styleName] = {
type: 'local',
path: `${projectStyleSet.path}/${projectStyleSet.fileName}`,
meta: {
namedImport: true,
},
};
}
return;
}
default: {
throw new Error(`
We support only inlined and project-referenced styles as of now, received ${styleRef.content}
`);
}
}
});
case "component-referenced": {
if (componentStyleReferences.size > 0) {
throw new PluginStyledComponent2(`Styled Component can have only one reference per node.
i.e either a direct static reference from component style sheet or from props. Got both. ${JSON.stringify(Array.from(componentStyleReferences), null, 2)}`);
}
if (styleRef.content.content.type === "static") {
staticClasses.add(identifier3(`'${styleRef.content.content.content}'`));
}
if (styleRef.content.content.type === "dynamic" && styleRef.content.content.content.referenceType === "comp") {
componentStyleReferences.add(componentVariantPropPrefix);
ASTUtils.addAttributeToJSXTag(root, componentVariantPropKey, styleRef.content.content.content.id);
}
if (styleRef.content.content.type === "dynamic" && styleRef.content.content.content.referenceType === "prop") {
componentStyleReferences.add(componentVariantPropPrefix);
ASTUtils.addDynamicAttributeToJSXTag(root, componentVariantPropKey, `${propsPrefix}.${styleRef.content.content.content.id}`);
}
return;
}
if (timesProsReferred > 1) {
ASTUtils.addSpreadAttributeToJSXTag(root, propsPrefix);
case "project-referenced": {
if (!projectStyleSet) {
throw new Error(`Project Style Sheet is missing, but the node is referring to it ${element}`);
}
const { content } = styleRef;
const referedStyle = projectStyleSet.styleSetDefinitions[content.referenceId];
if (!referedStyle) {
throw new Error(`Style that is being used for reference is missing - ${content.referenceId}`);
}
dependencies[projectVariantPropPrefix] = {
type: "local",
path: `${projectStyleSet.path}/${projectStyleSet.fileName}`,
meta: {
namedImport: true
}
};
projectStyleReferences.add(projectVariantPropPrefix);
ASTUtils.addAttributeToJSXTag(root, projectVariantPropKey, content.referenceId);
return;
}
ASTUtils.renameJSXTag(root, className);
const code = {
type: ChunkType.AST,
fileType: FileType.JS,
name: className,
linkAfter: [importChunkName],
content: generateStyledComponent(className, elementType, jssStyleMap[className], projectReferencedClassNames),
};
chunks.push(code);
default: {
throw new Error(`
We support only inlined and project-referenced styles as of now, received ${JSON.stringify(styleRef.content, null, 2)}
`);
}
}
});
if (Object.keys(jssStyleMap).length === 0) {
return structure;
}
if (propsReferred.size > 0) {
ASTUtils.addSpreadAttributeToJSXTag(root, propsPrefix);
}
if (staticClasses.size > 0) {
ASTUtils.addMultipleDynamicAttributesToJSXTag(root, classAttributeName, Array.from(staticClasses));
}
ASTUtils.renameJSXTag(root, className);
const code = {
type: ChunkType2.AST,
fileType: FileType2.JS,
name: className,
linkAfter: [importChunkName],
content: generateStyledComponent({
name: className,
styles: cssMap[className],
elementType,
propsReferred,
componentStyleReferences,
projectStyleReferences
})
};
chunks.push(code);
});
if (Object.keys(cssMap).length === 0) {
return structure;
}
if (tokensReferred.size > 0) {
dependencies.TOKENS = {
type: "local",
path: `${projectStyleSet.path}/${projectStyleSet.fileName}`,
meta: {
namedImport: true
}
if (tokensReferred.length > 0) {
dependencies.TOKENS = {
type: 'local',
path: `${projectStyleSet.path}/${projectStyleSet.fileName}`,
meta: {
namedImport: true,
},
};
}
dependencies.styled = {
type: 'package',
path: componentLibrary === 'react' ? 'styled-components' : 'styled-components/native',
version: '4.2.0',
};
/* React Native elements are imported from styled-components/native,
so direct dependency to `react-native` is removed */
if (componentLibrary === 'reactnative') {
removeUnusedDependencies(dependencies, jsxNodesLookup);
}
return structure;
};
}
dependencies.styled = {
type: "package",
path: componentLibrary === "react" ? "styled-components" : "styled-components/native",
version: "^5.3.0"
};
return reactStyledComponentsPlugin;
if (componentLibrary === "reactnative") {
removeUnusedDependencies(dependencies, jsxNodesLookup);
}
return structure;
});
return reactStyledComponentsPlugin;
};
export { createStyleSheetPlugin };
export default createReactStyledComponentsPlugin();
//# sourceMappingURL=index.js.map
var src_default = createReactStyledComponentsPlugin();
export {
createReactStyledComponentsPlugin,
createStyleSheetPlugin,
src_default as default
};
{
"name": "@teleporthq/teleport-plugin-react-styled-components",
"version": "0.16.3",
"version": "0.17.0",
"description": "A plugin for injecting the styles through styled-components inside React components",

@@ -11,2 +11,7 @@ "author": "teleportHQ",

"module": "dist/esm/index.js",
"exports": {
"module": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"import": "./dist/esm/index.js"
},
"sideEffects": false,

@@ -25,13 +30,11 @@ "repository": {

"clean": "rimraf dist",
"build": "npm run build:cjs & npm run build:esm",
"build:cjs": "tsc -p tsconfig-cjs.json",
"build:esm": "tsc -p tsconfig-esm.json"
"types": "tsc -p tsconfig.json"
},
"dependencies": {
"@babel/types": "^7.5.5",
"@teleporthq/teleport-plugin-common": "^0.16.3",
"@teleporthq/teleport-shared": "^0.16.3",
"@teleporthq/teleport-types": "^0.16.3"
"@teleporthq/teleport-plugin-common": "^0.17.0",
"@teleporthq/teleport-shared": "^0.17.0",
"@teleporthq/teleport-types": "^0.17.0"
},
"gitHead": "7e373501206d293ea7ac0494b563ee5f6a2fccb2"
"gitHead": "959317a18068b52ffd8b912e41d123f70d97e7bc"
}

@@ -7,2 +7,3 @@ import * as types from '@babel/types'

FileType,
PluginStyledComponent,
} from '@teleporthq/teleport-types'

@@ -13,8 +14,14 @@ import { UIDLUtils, StringUtils } from '@teleporthq/teleport-shared'

generateStyledComponent,
countPropReferences,
removeUnusedDependencies,
generatePropReferencesSyntax,
countPropRefernecesFromReferencedStyles,
generateVariantsfromStyleSet,
generateStyledComponentStyles,
} from './utils'
import { createStyleSheetPlugin } from './style-sheet'
import {
componentVariantPropKey,
componentVariantPropPrefix,
projectVariantPropKey,
projectVariantPropPrefix,
VARIANT_DEPENDENCY,
} from './constants'

@@ -26,2 +33,3 @@ interface StyledComponentsConfig {

illegalComponentNames?: string[]
classAttributeName?: string
}

@@ -37,2 +45,3 @@

illegalComponentNames = [],
classAttributeName = 'className',
} = config || {}

@@ -42,3 +51,3 @@

const { uidl, chunks, dependencies, options } = structure
const { node, name } = uidl
const { node, name, styleSetDefinitions: componentStyleSheet = {} } = uidl
const { projectStyleSet } = options

@@ -51,12 +60,32 @@ const componentChunk = chunks.find((chunk) => chunk.name === componentChunkName)

const jsxNodesLookup = componentChunk.meta.nodesLookup as Record<string, types.JSXElement>
// @ts-ignore
const propsPrefix = componentChunk.meta.dynamicRefPrefix.prop
const jssStyleMap: Record<string, unknown> = {}
const tokensReferred: string[] = []
const propsPrefix = componentChunk.meta.dynamicRefPrefix.prop as string
const cssMap: Record<string, types.ObjectExpression> = {}
const tokensReferred: Set<string> = new Set()
if (Object.keys(componentStyleSheet).length > 0) {
const variants = generateVariantsfromStyleSet(
componentStyleSheet,
componentVariantPropPrefix,
componentVariantPropKey,
tokensReferred
)
chunks.push({
name: 'variant',
type: ChunkType.AST,
content: variants,
fileType: FileType.JS,
linkAfter: ['jsx-component'],
})
dependencies.variant = VARIANT_DEPENDENCY
}
UIDLUtils.traverseElements(node, (element) => {
const { style } = element
const { key, elementType, referencedStyles } = element
const { style = {} } = element
const { key, elementType, referencedStyles = {} } = element
const propsReferred: Set<string> = new Set()
const componentStyleReferences: Set<string> = new Set()
const projectStyleReferences: Set<string> = new Set()
const staticClasses: Set<types.Identifier> = new Set()
if (!style && !referencedStyles) {
if (Object.keys(style).length === 0 && Object.keys(referencedStyles).length === 0) {
return

@@ -67,14 +96,6 @@ }

let className = StringUtils.dashCaseToUpperCamelCase(key)
const projectReferencedClassNames: string[] = []
let timesProsReferred = countPropReferences(style, 0)
timesProsReferred = countPropRefernecesFromReferencedStyles(
referencedStyles,
timesProsReferred
)
if (style && Object.keys(style).length > 0) {
/* Styled components might create an element that
clashes with native element (Text, View, Image, etc.) */
clashes with native element (Text, View, Image, etc.) */
if (

@@ -90,8 +111,9 @@ illegalComponentNames.includes(className) ||

if (referencedStyles && Object.keys(referencedStyles).length > 0) {
Object.values(referencedStyles).forEach((styleRef) => {
Object.keys(referencedStyles).forEach((styleId) => {
const styleRef = referencedStyles[styleId]
if (styleRef.content.mapType === 'inlined') {
referencedStyles[styleRef.id] = {
...referencedStyles[styleRef.id],
referencedStyles[styleId] = {
...referencedStyles[styleId],
content: {
...referencedStyles[styleRef.id].content,
...referencedStyles[styleId].content,
// @ts-ignore

@@ -105,9 +127,9 @@ styles: styleRef.content.styles,

}
jssStyleMap[className] = generatePropReferencesSyntax(
style,
timesProsReferred,
cssMap[className] = generateStyledComponentStyles({
styles: style,
propsReferred,
tokensReferred,
root,
propsPrefix
)
propsPrefix,
tokensPrefix: 'TOKENS',
})
}

@@ -122,16 +144,18 @@

if (styleRef.content?.styles && Object.keys(styleRef.content.styles).length === 0) {
return
}
if (condition.conditionType === 'screen-size') {
jssStyleMap[className] = {
...(jssStyleMap[className] as Record<string, string>),
[`@media(max-width: ${condition.maxWidth}px)`]: generatePropReferencesSyntax(
styleRef.content.styles,
timesProsReferred,
const nodeStyle = cssMap[className]
const mediaStyles = types.objectProperty(
types.stringLiteral(`@media(max-width: ${condition.maxWidth}px)`),
generateStyledComponentStyles({
styles: styleRef.content.styles,
propsReferred,
tokensReferred,
root,
propsPrefix
),
propsPrefix,
tokensPrefix: 'TOKENS',
})
)
if (nodeStyle?.type === 'ObjectExpression') {
nodeStyle.properties.push(mediaStyles)
} else {
cssMap[className] = ASTUtils.wrapObjectPropertiesWithExpression([mediaStyles])
}

@@ -141,11 +165,17 @@ }

if (condition.conditionType === 'element-state') {
jssStyleMap[className] = {
...(jssStyleMap[className] as Record<string, string>),
[`&:${condition.content}`]: generatePropReferencesSyntax(
styleRef.content.styles,
timesProsReferred,
const nodeStyle = cssMap[className]
const mediaStyles = types.objectProperty(
types.stringLiteral(`&:${condition.content}`),
generateStyledComponentStyles({
styles: styleRef.content.styles,
propsReferred,
tokensReferred,
root,
propsPrefix
),
propsPrefix,
tokensPrefix: 'TOKENS',
})
)
if (nodeStyle?.type === 'ObjectExpression') {
nodeStyle.properties.push(mediaStyles)
} else {
cssMap[className] = ASTUtils.wrapObjectPropertiesWithExpression([mediaStyles])
}

@@ -156,2 +186,44 @@ }

}
case 'component-referenced': {
if (componentStyleReferences.size > 0) {
throw new PluginStyledComponent(`Styled Component can have only one reference per node.
i.e either a direct static reference from component style sheet or from props. Got both. ${JSON.stringify(
Array.from(componentStyleReferences),
null,
2
)}`)
}
if (styleRef.content.content.type === 'static') {
staticClasses.add(types.identifier(`'${styleRef.content.content.content}'`))
}
if (
styleRef.content.content.type === 'dynamic' &&
styleRef.content.content.content.referenceType === 'comp'
) {
componentStyleReferences.add(componentVariantPropPrefix)
ASTUtils.addAttributeToJSXTag(
root,
componentVariantPropKey,
styleRef.content.content.content.id
)
}
if (
styleRef.content.content.type === 'dynamic' &&
styleRef.content.content.content.referenceType === 'prop'
) {
componentStyleReferences.add(componentVariantPropPrefix)
ASTUtils.addDynamicAttributeToJSXTag(
root,
componentVariantPropKey,
`${propsPrefix}.${styleRef.content.content.content.id}`
)
}
return
}
case 'project-referenced': {

@@ -164,20 +236,18 @@ if (!projectStyleSet) {

const { content } = styleRef
if (content.referenceId && !content?.conditions) {
const referedStyle = projectStyleSet.styleSetDefinitions[content.referenceId]
if (!referedStyle) {
throw new Error(
`Style that is being used for reference is missing - ${content.referenceId}`
)
}
const styleName = StringUtils.dashCaseToUpperCamelCase(referedStyle.name)
projectReferencedClassNames.push(styleName)
dependencies[styleName] = {
type: 'local',
path: `${projectStyleSet.path}/${projectStyleSet.fileName}`,
meta: {
namedImport: true,
},
}
const referedStyle = projectStyleSet.styleSetDefinitions[content.referenceId]
if (!referedStyle) {
throw new Error(
`Style that is being used for reference is missing - ${content.referenceId}`
)
}
dependencies[projectVariantPropPrefix] = {
type: 'local',
path: `${projectStyleSet.path}/${projectStyleSet.fileName}`,
meta: {
namedImport: true,
},
}
projectStyleReferences.add(projectVariantPropPrefix)
ASTUtils.addAttributeToJSXTag(root, projectVariantPropKey, content.referenceId)
return

@@ -187,4 +257,8 @@ }

throw new Error(`
We support only inlined and project-referenced styles as of now, received ${styleRef.content}
`)
We support only inlined and project-referenced styles as of now, received ${JSON.stringify(
styleRef.content,
null,
2
)}
`)
}

@@ -195,6 +269,14 @@ }

if (timesProsReferred > 1) {
if (propsReferred.size > 0) {
ASTUtils.addSpreadAttributeToJSXTag(root, propsPrefix)
}
if (staticClasses.size > 0) {
ASTUtils.addMultipleDynamicAttributesToJSXTag(
root,
classAttributeName,
Array.from(staticClasses)
)
}
ASTUtils.renameJSXTag(root, className)

@@ -207,8 +289,10 @@

linkAfter: [importChunkName],
content: generateStyledComponent(
className,
content: generateStyledComponent({
name: className,
styles: cssMap[className],
elementType,
jssStyleMap[className] as Record<string, unknown>,
projectReferencedClassNames
),
propsReferred,
componentStyleReferences,
projectStyleReferences,
}),
}

@@ -218,7 +302,7 @@ chunks.push(code)

if (Object.keys(jssStyleMap).length === 0) {
if (Object.keys(cssMap).length === 0) {
return structure
}
if (tokensReferred.length > 0) {
if (tokensReferred.size > 0) {
dependencies.TOKENS = {

@@ -236,3 +320,3 @@ type: 'local',

path: componentLibrary === 'react' ? 'styled-components' : 'styled-components/native',
version: '4.2.0',
version: '^5.3.0',
}

@@ -239,0 +323,0 @@

@@ -1,2 +0,2 @@

import * as t from '@babel/types'
import * as types from '@babel/types'
import {

@@ -8,12 +8,12 @@ ComponentPlugin,

} from '@teleporthq/teleport-types'
import { generateExportablCSSInterpolate, generatePropReferencesSyntax } from './utils'
import { generateVariantsfromStyleSet } from './utils'
import { StringUtils } from '@teleporthq/teleport-shared'
import { projectVariantPropKey, projectVariantPropPrefix, VARIANT_DEPENDENCY } from './constants'
interface StyleSheetPlugin {
fileName?: string
componentLibrary?: string
}
export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> = (config) => {
const { fileName = 'style', componentLibrary = 'react' } = config || {}
const { fileName = 'style' } = config || {}

@@ -23,7 +23,3 @@ const styleSheetPlugin: ComponentPlugin = async (structure) => {

const { styleSetDefinitions = {}, designLanguage: { tokens = {} } = {} } = uidl
if (
(!styleSetDefinitions && !tokens) ||
(Object.keys(styleSetDefinitions).length === 0 && Object.keys(tokens).length === 0)
) {
if (Object.keys(styleSetDefinitions).length === 0 && Object.keys(tokens).length === 0) {
return structure

@@ -42,58 +38,18 @@ }

Object.values(styleSetDefinitions).forEach((style) => {
const { name, content, conditions = [] } = style
const className = StringUtils.dashCaseToUpperCamelCase(name)
let styles = {}
styles = {
...styles,
...generatePropReferencesSyntax(content),
}
if (conditions.length > 0) {
conditions.forEach((styleRef) => {
if (Object.keys(styleRef.content).length === 0) {
return
}
if (styleRef.type === 'screen-size') {
styles = {
...styles,
...{
[`@media(max-width: ${styleRef.meta.maxWidth}px)`]: generatePropReferencesSyntax(
styleRef.content
),
},
}
}
if (styleRef.type === 'element-state') {
styles = {
...styles,
...{
[`&:${styleRef.meta.state}`]: generatePropReferencesSyntax(styleRef.content),
},
}
}
})
}
if (Object.keys(styleSetDefinitions).length > 0) {
const variants = generateVariantsfromStyleSet(
styleSetDefinitions,
projectVariantPropPrefix,
projectVariantPropKey
)
chunks.push({
name: fileName,
type: ChunkType.AST,
content: types.exportNamedDeclaration(variants),
fileType: FileType.JS,
content: generateExportablCSSInterpolate(className, styles),
linkAfter: ['tokens-chunk'],
})
dependencies.variant = VARIANT_DEPENDENCY
}
dependencies.css = {
type: 'package',
path: componentLibrary === 'react' ? 'styled-components' : 'styled-components/native',
version: '4.2.0',
meta: {
namedImport: true,
},
}
})
if (Object.keys(tokensMap).length > 0) {

@@ -104,13 +60,13 @@ chunks.push({

fileType: FileType.JS,
content: t.exportNamedDeclaration(
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier('TOKENS'),
t.objectExpression(
Object.keys(tokensMap).reduce((acc: t.ObjectProperty[], token) => {
content: types.exportNamedDeclaration(
types.variableDeclaration('const', [
types.variableDeclarator(
types.identifier('TOKENS'),
types.objectExpression(
Object.keys(tokensMap).reduce((acc: types.ObjectProperty[], token) => {
const value =
typeof tokensMap[token] === 'number'
? t.numericLiteral(Number(tokensMap[token]))
: t.stringLiteral(String(tokensMap[token]))
acc.push(t.objectProperty(t.identifier(token), value))
? types.numericLiteral(Number(tokensMap[token]))
: types.stringLiteral(String(tokensMap[token]))
acc.push(types.objectProperty(types.identifier(token), value))
return acc

@@ -117,0 +73,0 @@ }, [])

@@ -1,83 +0,60 @@

import * as t from '@babel/types'
import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
import { ASTUtils } from '@teleporthq/teleport-plugin-common'
import { UIDLStyleValue, UIDLDependency, UIDLReferencedStyles } from '@teleporthq/teleport-types'
import * as types from '@babel/types'
import { StringUtils } from '@teleporthq/teleport-shared'
import {
UIDLStyleValue,
UIDLDependency,
UIDLStyleSetDefinition,
PluginStyledComponent,
} from '@teleporthq/teleport-types'
export const generateStyledComponent = (
name: string,
type: string,
styles: Record<string, unknown>,
projectReferencedStyles?: string[]
) => {
return t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(name),
t.taggedTemplateExpression(
t.memberExpression(t.identifier('styled'), t.identifier(type)),
projectReferencedStyles?.length > 0
? ASTUtils.stringAsTemplateLiteral(
`${projectReferencedStyles.map((item) => `\$\{${item}\};`)} ${mapStyles(styles)}`
)
: ASTUtils.stringAsTemplateLiteral(mapStyles(styles))
)
),
])
}
export const generateStyledComponent = (params: {
name: string
elementType: string
styles: types.ObjectExpression
propsReferred: Set<string>
componentStyleReferences: Set<string>
projectStyleReferences: Set<string>
}) => {
const {
name,
elementType,
styles,
propsReferred,
componentStyleReferences,
projectStyleReferences,
} = params
let styleExpressions: types.ObjectExpression | types.ArrowFunctionExpression = styles
const expressionArguments: Array<
types.ObjectExpression | types.ArrowFunctionExpression | types.Identifier
> = []
export const generateCSSInterpolate = (name: string, styles: Record<string, unknown>) => {
return t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(name),
t.taggedTemplateExpression(
t.identifier('css'),
ASTUtils.stringAsTemplateLiteral(mapStyles(styles))
)
),
])
}
if (propsReferred.size > 0) {
styleExpressions = types.arrowFunctionExpression([types.identifier('props')], styles)
}
export const generateExportablCSSInterpolate = (name: string, styles: Record<string, unknown>) => {
return t.exportNamedDeclaration(generateCSSInterpolate(name, styles))
}
if (projectStyleReferences.size > 0) {
expressionArguments.push(
...Array.from(projectStyleReferences).map((ref) => types.identifier(ref))
)
}
const mapStyles = (styles: Record<string, unknown>): string => {
return Object.keys(styles || {}).reduce((acc: string, item) => {
const value = styles[item]
acc =
typeof value === 'string' || typeof value === 'number'
? `${acc} ${StringUtils.camelCaseToDashCase(item)}: ${value}; \n`
: `${acc} ${item} {\n ${mapStyles(value as Record<string, unknown>)}};`
return acc
}, ``)
}
if (styles && styles.properties.length > 0) {
expressionArguments.push(styleExpressions)
}
export const countPropReferences = (
style: Record<string, UIDLStyleValue>,
timesReferred: number
) => {
if (style && Object.keys(style).length > 0) {
Object.keys(style).map((item) => {
const styleAttr = style[item]
if (styleAttr.type === 'dynamic' && styleAttr.content.referenceType === 'prop') {
timesReferred++
}
})
return timesReferred
if (componentStyleReferences.size > 0) {
expressionArguments.push(
...Array.from(componentStyleReferences).map((ref) => types.identifier(ref))
)
}
return timesReferred
}
export const countPropRefernecesFromReferencedStyles = (
styles: UIDLReferencedStyles,
timesReferred: number
) => {
let propsCount = 0
if (styles && Object.keys(styles).length > 0) {
Object.values(styles).forEach((styleRef) => {
if (styleRef.content.mapType === 'inlined') {
propsCount = countPropReferences(styleRef.content.styles, 0)
}
})
}
return timesReferred + propsCount
return types.variableDeclaration('const', [
types.variableDeclarator(
types.identifier(name),
types.callExpression(
types.callExpression(types.identifier('styled'), [types.stringLiteral(elementType)]),
expressionArguments
)
),
])
}

@@ -87,3 +64,3 @@

dependencies: Record<string, UIDLDependency>,
jsxNodesLookup: Record<string, t.JSXElement>
jsxNodesLookup: Record<string, types.JSXElement>
) => {

@@ -95,3 +72,3 @@ Object.keys(dependencies).forEach((depKey) => {

const jsxNode = jsxNodesLookup[elementKey]
return (jsxNode.openingElement.name as t.JSXIdentifier).name === depKey
return (jsxNode.openingElement.name as types.JSXIdentifier).name === depKey
})

@@ -106,35 +83,121 @@

export const generatePropReferencesSyntax = (
style: Record<string, UIDLStyleValue>,
timesPropsReferred?: number,
tokensReferred?: string[],
root?: t.JSXElement,
propsPrefix?: unknown
) => {
return UIDLUtils.transformDynamicStyles(style, (styleValue, attribute) => {
switch (styleValue.content.referenceType) {
case 'prop': {
const dashCaseAttribute = StringUtils.dashCaseToCamelCase(attribute)
if (timesPropsReferred && timesPropsReferred === 1 && root && propsPrefix) {
ASTUtils.addDynamicAttributeToJSXTag(
root,
dashCaseAttribute,
styleValue.content.id,
propsPrefix as string
export const generateStyledComponentStyles = (params: {
styles: Record<string, UIDLStyleValue>
propsReferred?: Set<string>
tokensReferred?: Set<string>
propsPrefix?: string
tokensPrefix?: string
}): types.ObjectExpression => {
const {
styles,
tokensReferred,
propsReferred,
propsPrefix = 'props',
tokensPrefix = 'TOKENS',
} = params
const properties: types.ObjectProperty[] = Object.keys(styles).reduce(
(acc: types.ObjectProperty[], styleId) => {
const style = styles[styleId]
const styleKey = types.stringLiteral(StringUtils.camelCaseToDashCase(styleId))
if (style.type === 'static') {
const styleContent =
typeof style.content === 'string'
? types.stringLiteral(style.content)
: types.numericLiteral(Number(style.content))
acc.push(types.objectProperty(styleKey, styleContent))
}
if (style.type === 'dynamic' && style.content.referenceType === 'state') {
throw new PluginStyledComponent(`Error running transformDynamicStyles in reactStyledComponentsPlugin.
Unsupported styleValue.content.referenceType value ${style.content.referenceType}`)
}
if (style.type === 'dynamic' && style.content.referenceType === 'prop') {
const isNestedProp = style.content.id.includes('.')
acc.push(
types.objectProperty(
styleKey,
types.memberExpression(
types.identifier(propsPrefix),
isNestedProp
? types.identifier(style.content.id)
: types.identifier(`'${style.content.id}'`),
!isNestedProp
)
)
return `\$\{props => props.${dashCaseAttribute}\}`
}
return `\$\{props => props.${styleValue.content.id}\}`
)
propsReferred?.add(style.content.id)
}
case 'token':
const token = StringUtils.capitalize(StringUtils.dashCaseToCamelCase(styleValue.content.id))
tokensReferred?.push(token)
return `\$\{TOKENS.${token}\}`
default:
throw new Error(
`Error running transformDynamicStyles in reactStyledComponentsPlugin.
Unsupported styleValue.content.referenceType value ${styleValue.content.referenceType}`
if (style.type === 'dynamic' && style.content.referenceType === 'token') {
const usedToken = StringUtils.capitalize(StringUtils.dashCaseToCamelCase(style.content.id))
acc.push(
types.objectProperty(
styleKey,
types.memberExpression(types.identifier(tokensPrefix), types.identifier(usedToken))
)
)
}
})
tokensReferred?.add(usedToken)
}
return acc
},
[]
)
return types.objectExpression(properties)
}
export const generateVariantsfromStyleSet = (
styleSets: Record<string, UIDLStyleSetDefinition>,
variantPropPrefix: string,
variantPropKey: string,
tokensReferred?: Set<string>
) => {
const variantExpressions = types.objectExpression(
Object.keys(styleSets).reduce((acc: types.ObjectProperty[], styleId) => {
const style = styleSets[styleId]
const { content = {}, conditions = [] } = style
const property = types.objectProperty(
types.stringLiteral(styleId),
generateStyledComponentStyles({
styles: content,
...(tokensReferred && { tokensReferred }),
})
)
conditions.forEach((cond) => {
const mediaProperty = types.objectProperty(
cond.type === 'screen-size'
? types.stringLiteral(`@media(max-width: ${cond.meta.maxWidth}px)`)
: types.stringLiteral(`&:${cond.meta.state}`),
generateStyledComponentStyles({
styles: cond.content,
...(tokensReferred && { tokensReferred }),
})
)
if (property.value.type === 'ObjectExpression') {
property.value.properties.push(mediaProperty)
}
})
acc.push(property)
return acc
}, [])
)
return types.variableDeclaration('const', [
types.variableDeclarator(
types.identifier(variantPropPrefix),
types.callExpression(types.identifier('variant'), [
types.objectExpression([
types.objectProperty(types.identifier('prop'), types.stringLiteral(variantPropKey)),
types.objectProperty(types.identifier('variants'), variantExpressions),
]),
])
),
])
}