Repository: sveltejs/language-tools
Pull request #963 (2021-04-24 14:41:31)

(fix) Don't break on upcoming custom css properties
Remove --custom-css-propeties during Component attribute transformations. They have no property which they can be checked against and the leading dashes are invalid JSX

Related RFC: https://github.com/sveltejs/rfcs/pull/13


Patch:
diff --git a/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts b/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts
index f2801b27..baf5b609 100644
--- a/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts
+++ b/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts
@@ -82,6 +82,12 @@ export function handleAttribute(
         }
     }
 
+    // Custom property -> remove completely due to JSX incompatibility
+    if (parent.type === 'InlineComponent' && attr.name.startsWith('--')) {
+        str.overwrite(attr.start, attr.end, '', { contentOnly: true });
+        return;
+    }
+
     //we are a bare attribute
     if (attr.value === true) {
         if (
diff --git a/packages/svelte2tsx/src/htmlxtojsx/utils/node-utils.ts b/packages/svelte2tsx/src/htmlxtojsx/utils/node-utils.ts
index bc9303a7..73c29c39 100644
--- a/packages/svelte2tsx/src/htmlxtojsx/utils/node-utils.ts
+++ b/packages/svelte2tsx/src/htmlxtojsx/utils/node-utils.ts
@@ -106,7 +106,7 @@ function getNameValuePairsFromAttributes(
     complexExpression?: true;
 }> {
     return ((node.attributes as Node[]) || [])
-        .filter((attr) => attr.type === 'Attribute')
+        .filter((attr) => attr.type === 'Attribute' && !attr.name.startsWith('--'))
         .map((attr) => {
             const name: string = attr.name;
 


Test patch:
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/expected.jsx
index febcc007..3fc62b48 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/expected.jsx
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/expected.jsx
@@ -1,2 +1,2 @@
-<><Hello __custom-prop="foo"></Hello>
+<><Hello __wtf="foo"></Hello>
 <div __custom-prop="foo"></div></>
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/input.svelte b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/input.svelte
index 69727cc0..cb4299c1 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/input.svelte
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/attribute-invalid-jsx-name/input.svelte
@@ -1,2 +1,2 @@
-<Hello --custom-prop="foo"></Hello>
+<Hello |-wtf="foo"></Hello>
 <div --custom-prop="foo"></div>
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/expected.jsx
index 78ecaf64..be7cc3a5 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/expected.jsx
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/expected.jsx
@@ -1,4 +1,4 @@
-<><Parent bare shorthand={shorthand} text1="val1" text2="val2" text3={`a${a}b${b}`} textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}} >{() => {/*Ωignore_startΩ*/const Ψcomplex={a},Ψa_dashed_complex={a};/*Ωignore_endΩ*/() => { let {foo} = /*Ωignore_startΩ*/new Parent({target: __sveltets_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':"", 'text2':"", 'text3':"", 'textEmpty':"", 'literal':true, 'strLiteral':"", 'complex':Ψcomplex, 'a-dashed-complex':Ψa_dashed_complex}})/*Ωignore_endΩ*/.$$slot_def['default'];<>
+<><Parent bare shorthand={shorthand} text1="val1" text2="val2" text3={`a${a}b${b}`} textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}}  >{() => {/*Ωignore_startΩ*/const Ψcomplex={a},Ψa_dashed_complex={a};/*Ωignore_endΩ*/() => { let {foo} = /*Ωignore_startΩ*/new Parent({target: __sveltets_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':"", 'text2':"", 'text3':"", 'textEmpty':"", 'literal':true, 'strLiteral':"", 'complex':Ψcomplex, 'a-dashed-complex':Ψa_dashed_complex}})/*Ωignore_endΩ*/.$$slot_def['default'];<>
     {() => { let {bar} = /*Ωignore_startΩ*/new Parent({target: __sveltets_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':"", 'text2':"", 'text3':"", 'textEmpty':"", 'literal':true, 'strLiteral':"", 'complex':Ψcomplex, 'a-dashed-complex':Ψa_dashed_complex}})/*Ωignore_endΩ*/.$$slot_def['named'];<><Component  >
         {foo} {bar}
     </Component></>}}
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/input.svelte b/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/input.svelte
index bd71e0b3..6f9570f4 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/input.svelte
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/component-slot-infer-props/input.svelte
@@ -1,4 +1,4 @@
-<Parent bare {shorthand} text1=val1 text2="val2" text3="a{a}b{b}" textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}} let:foo>
+<Parent bare {shorthand} text1=val1 text2="val2" text3="a{a}b{b}" textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}} --custom-cssprop="foo" let:foo>
     <Component slot="named" let:bar>
         {foo} {bar}
     </Component>
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expected.jsx
new file mode 100644
index 00000000..04ffa146
--- /dev/null
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expected.jsx
@@ -0,0 +1,1 @@
+<><Component   betweenprop   /></>
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/input.svelte b/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/input.svelte
new file mode 100644
index 00000000..9c5957b2
--- /dev/null
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/input.svelte
@@ -0,0 +1,1 @@
+<Component --custom-css-property1={'hi'} --custom-css-property2="hi" betweenprop  --custom-css-property3="hi{jo}hi" />
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/expected.jsx
index f66f68b7..c5fa4e29 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/expected.jsx
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/expected.jsx
@@ -1,1 +1,1 @@
-<><Component bare shorthand={shorthand} text1="val1" text2="val2" text3={`a${a}b${b}`} textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}}  />{/*Ωignore_startΩ*/new Component({target: __sveltets_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':"", 'text2':"", 'text3':"", 'textEmpty':"", 'literal':true, 'strLiteral':"", 'complex':{a}, 'a-dashed-complex':{a}}})/*Ωignore_endΩ*/.$on('click', e => e)}</>
\ No newline at end of file
+<><Component bare shorthand={shorthand} text1="val1" text2="val2" text3={`a${a}b${b}`} textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}}   />{/*Ωignore_startΩ*/new Component({target: __sveltets_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':"", 'text2':"", 'text3':"", 'textEmpty':"", 'literal':true, 'strLiteral':"", 'complex':{a}, 'a-dashed-complex':{a}}})/*Ωignore_endΩ*/.$on('click', e => e)}</>
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/input.svelte b/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/input.svelte
index 5ddbd664..0d02bc2c 100644
--- a/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/input.svelte
+++ b/packages/svelte2tsx/test/htmlx2jsx/samples/event-handler-component-infer-props/input.svelte
@@ -1,1 +1,1 @@
-<Component bare {shorthand} text1=val1 text2="val2" text3="a{a}b{b}" textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}} on:click={e => e} />
\ No newline at end of file
+<Component bare {shorthand} text1=val1 text2="val2" text3="a{a}b{b}" textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}} --custom-cssprop="foo" on:click={e => e} />
\ No newline at end of file