diff --git a/__mocks__/Examples.tsx b/__mocks__/Examples.tsx
index 23f05f2..1718ac7 100644
--- a/__mocks__/Examples.tsx
+++ b/__mocks__/Examples.tsx
@@ -20,6 +20,25 @@ export const MockNoInlineWithComponent = () => {
)
}
+export const MockNoInlineWithBackticks = () => {
+ return (
+
+ {() => {
+ const DemoComponent = () => {
+ const more = '456'
+ return `123${more}` + `789`
+ }
+
+ return (
+
+
+
+ )
+ }}
+
+ )
+}
+
export const MockNoInlineWithText = () => {
return (
diff --git a/__tests__/babelPluginReactLive.test.ts b/__tests__/babelPluginReactLive.test.ts
index 15fc432..a76380f 100644
--- a/__tests__/babelPluginReactLive.test.ts
+++ b/__tests__/babelPluginReactLive.test.ts
@@ -16,108 +16,124 @@ const pluginOptions = {
prettierPath,
}
-it('babelPluginReactLive', async () => {
- const babelFileResult = await transformFileAsync(targetFile, {
- code: true,
- presets: [
- [
- '@babel/preset-env',
- {
- modules: false,
- targets: { firefox: '100' },
- },
+describe('transformFileAsync', () => {
+ it('should convert Examples.tsx with all exported examples', async () => {
+ const babelFileResult = await transformFileAsync(targetFile, {
+ code: true,
+ presets: [
+ [
+ '@babel/preset-env',
+ {
+ modules: false,
+ targets: { firefox: '100' },
+ },
+ ],
],
- ],
- plugins: [[babelPluginReactLive, pluginOptions]],
- })
+ plugins: [[babelPluginReactLive, pluginOptions]],
+ })
- const code = removeConsoleNinja(String(babelFileResult?.code))
+ const code = removeConsoleNinja(String(babelFileResult?.code))
- const formattedCode = prettier.format(code, {
- filepath: 'file.tsx',
- semi: false,
- })
+ const formattedCode = prettier.format(code, {
+ filepath: 'file.tsx',
+ semi: false,
+ })
- expect(formattedCode).toMatchInlineSnapshot(`
- "const ComponentBox = ({ children }) => children
- export const MockNoInlineWithComponent = () => {
- return (
- {\`const DemoComponent = () => {
- return <>content>
- }
- render(
-
-
-
- )
- \`}
+ expect(formattedCode).toMatchInlineSnapshot(`
+ "const ComponentBox = ({ children }) => children
+ export const MockNoInlineWithComponent = () => {
+ return (
+ {\`const DemoComponent = () => {
+ return <>content>
+ }
+ render(
+
+
+
)
- }
- export const MockNoInlineWithText = () => {
- return (
- {\`render(<>content>)
- \`}
+ \`}
+ )
+ }
+ export const MockNoInlineWithBackticks = () => {
+ return (
+ {\`const DemoComponent = () => {
+ const more = '456'
+ return \\\`123\\\${more}\\\` + \\\`789\\\`
+ }
+ render(
+
+
+
)
- }
- export const MockOneChilds = () => {
- return (
- {\`content
- \`}
- )
- }
- export const MockManyChilds = () => {
- return (
- {\`
- content 1
- content 2
- content 3
+ \`}
+ )
+ }
+ export const MockNoInlineWithText = () => {
+ return (
+ {\`render(<>content>)
+ \`}
+ )
+ }
+ export const MockOneChilds = () => {
+ return (
+ {\`content
+ \`}
+ )
+ }
+ export const MockManyChilds = () => {
+ return (
+ {\`
+ content 1
+ content 2
+ content 3
- \`}
- )
- }
- export const MockFragment = () => {
- return (
- {\`<>
- content 1
- content 2
- content 3
- >
- \`}
- )
- }
- export const MockText = () => {
- return (
- {\`
- text
- {'text'}
- content
- text
- {'text'}
+ \`}
+ )
+ }
+ export const MockFragment = () => {
+ return (
+ {\`<>
+ content 1
+ content 2
+ content 3
+ >
+ \`}
+ )
+ }
+ export const MockText = () => {
+ return (
+ {\`
+ text
+ {'text'}
+ content
+ text
+ {'text'}
- \`}
- )
- }
- export const MockEvents = () => {
- return (
- {\` {
- // comment
- console.log(e)
- }}
- onOpen={(e) => 'console.log(e)'}
- onFocus={(e) => {
- const cleaned = 'console.log(e)'
- }}
- />
- \`}
- )
- }
- "
- `)
+ \`}
+ )
+ }
+ export const MockEvents = () => {
+ return (
+ {\` {
+ // comment
+ console.log(e)
+ }}
+ onOpen={(e) => 'console.log(e)'}
+ onFocus={(e) => {
+ const cleaned = 'console.log(e)'
+ }}
+ />
+ \`}
+ )
+ }
+ "
+ `)
- expect(formattedCode.match(/noInline/g)).toHaveLength(2)
- expect(formattedCode.match(/\{`/g)).toHaveLength(7)
- expect(formattedCode.match(/`\}/g)).toHaveLength(7)
+ expect(formattedCode.match(/noInline/g)).toHaveLength(3)
+ expect(formattedCode.match(/\{`/g)).toHaveLength(8)
+ expect(formattedCode.match(/`\}/g)).toHaveLength(8)
+ })
})
function removeConsoleNinja(code) {
diff --git a/babelPluginReactLive.js b/babelPluginReactLive.js
index 4ab0069..d0dd4c1 100644
--- a/babelPluginReactLive.js
+++ b/babelPluginReactLive.js
@@ -24,16 +24,21 @@ function babelPluginReactLive(babel, options) {
})
// Prettier adds a leading ;
- // And we also escape `
- code = code.replace(/^;/, '').replace(/`/g, '\\`')
+ code = code.replace(/^;/, '')
+
+ // Also escape backticks (`)
+ code = code.replace(/`/g, '\\`')
// Remove fragments we added in the first place
if (children.length > 1) {
code = code.replace(/^<>|<\/>$|^\s{2}/gm, '')
}
+ const raw = code.replace(/\$\{/g, '\\${')
+ const templateElement = t.templateElement({ raw, cooked: code }, true)
+
return t.jsxExpressionContainer(
- t.templateLiteral([t.templateElement({ raw: code })], [])
+ t.templateLiteral([templateElement], [])
)
}