From 5257d8893a9fbd4d16d15590bd8ecf29049ed806 Mon Sep 17 00:00:00 2001 From: Travis Geis Date: Tue, 26 May 2020 21:08:07 -0700 Subject: [PATCH] Add support for custom tags --- src/_utils.js | 10 +++++----- src/babel.js | 8 +++++++- test/attribute.js | 7 +++++++ ...ration-custom-component-class-rewriting.js | 11 +++++++++++ test/snapshots/attribute.js.md | 14 ++++++++++++++ test/snapshots/attribute.js.snap | Bin 1528 -> 1636 bytes 6 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 test/fixtures/attribute-generation-custom-component-class-rewriting.js diff --git a/src/_utils.js b/src/_utils.js index ea8d1d66..4dcaddf4 100644 --- a/src/_utils.js +++ b/src/_utils.js @@ -21,7 +21,7 @@ const joinSpreads = spreads => spreads.reduce((acc, curr) => or(acc, curr)) export const hashString = str => String(_hashString(str)) -export const addClassName = (path, jsxId) => { +export const addClassName = (path, jsxId, classNameAttribute = 'className') => { const jsxIdWithSpace = concat(jsxId, t.stringLiteral(' ')) const attributes = path.get('attributes') const spreads = [] @@ -35,7 +35,7 @@ export const addClassName = (path, jsxId) => { const properties = node.argument.properties const index = properties.findIndex( - property => property.key.name === 'className' + property => property.key.name === classNameAttribute ) if (~index) { @@ -59,7 +59,7 @@ export const addClassName = (path, jsxId) => { : t.identifier(name) const attrNameDotClassName = t.memberExpression( spreadObj, - t.identifier('className') + t.identifier(classNameAttribute) ) spreads.push( @@ -76,7 +76,7 @@ export const addClassName = (path, jsxId) => { continue } - if (t.isJSXAttribute(attr) && node.name.name === 'className') { + if (t.isJSXAttribute(attr) && node.name.name === classNameAttribute) { className = attributes[i] // found className break the loop break @@ -105,7 +105,7 @@ export const addClassName = (path, jsxId) => { } path.node.attributes.push( - t.jSXAttribute(t.jSXIdentifier('className'), className) + t.jSXAttribute(t.jSXIdentifier(classNameAttribute), className) ) } diff --git a/src/babel.js b/src/babel.js index 8c01155d..aea23751 100644 --- a/src/babel.js +++ b/src/babel.js @@ -19,6 +19,11 @@ import { import { STYLE_COMPONENT } from './_constants' +const getClassNameAttributeNameForElementName = name => { + const isLowerCase = name.charAt(0) === name.charAt(0).toLowerCase() + return isLowerCase && name.includes('-') ? 'class' : 'className' +} + export default function({ types: t }) { const jsxVisitors = { JSXOpeningElement(path, state) { @@ -49,8 +54,9 @@ export default function({ types: t }) { binding.referencePaths.some(r => r === tag) )) ) { + const classNameAttribute = getClassNameAttributeNameForElementName(name) if (state.className) { - addClassName(path, state.className) + addClassName(path, state.className, classNameAttribute) } } diff --git a/test/attribute.js b/test/attribute.js index 441a4322..d9cd23ee 100644 --- a/test/attribute.js +++ b/test/attribute.js @@ -18,6 +18,13 @@ test('rewrites className', async t => { t.snapshot(code) }) +test('rewrites class for custom components', async t => { + const { code } = await transform( + './fixtures/attribute-generation-custom-component-class-rewriting.js' + ) + t.snapshot(code) +}) + test('generate attribute for mixed modes (global, static, dynamic)', async t => { const { code } = await transform('./fixtures/attribute-generation-modes.js') t.snapshot(code) diff --git a/test/fixtures/attribute-generation-custom-component-class-rewriting.js b/test/fixtures/attribute-generation-custom-component-class-rewriting.js new file mode 100644 index 00000000..e3744dcf --- /dev/null +++ b/test/fixtures/attribute-generation-custom-component-class-rewriting.js @@ -0,0 +1,11 @@ +import test from 'ava' + +export default () => { + const Element = 'custom-component' + return ( + + + + + ) +} diff --git a/test/snapshots/attribute.js.md b/test/snapshots/attribute.js.md index 594ec1a8..64dae005 100644 --- a/test/snapshots/attribute.js.md +++ b/test/snapshots/attribute.js.md @@ -108,6 +108,20 @@ Generated by [AVA](https://ava.li). return ;␊ };` +## rewrites class for custom components + +> Snapshot 1 + + `import _JSXStyle from "styled-jsx/style";␊ + import test from "ava";␊ + export default (() => {␊ + const Element = 'custom-component';␊ + return ␊ + ␊ + <_JSXStyle id={"1299692644"}>{"custom-component.jsx-1299692644{color:red;}"}␊ + ;␊ + });` + ## rewrites className > Snapshot 1 diff --git a/test/snapshots/attribute.js.snap b/test/snapshots/attribute.js.snap index 6130091626d9dc65a2fdf35bea7a13d4cdbf3a43..98b05556b33a06d77b90f38b022f8bf7f5230449 100644 GIT binary patch literal 1636 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