diff --git a/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts b/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts index baf5b6098..8b954ccb5 100644 --- a/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts +++ b/packages/svelte2tsx/src/htmlxtojsx/nodes/attribute.ts @@ -82,9 +82,10 @@ 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 }); + // Custom CSS property + if (parent.type === 'InlineComponent' && attr.name.startsWith('--') && attr.value !== true) { + str.prependRight(attr.start, '{...__sveltets_cssProp({"'); + buildTemplateString(attr, str, htmlx, '": `', '`})}'); return; } @@ -169,23 +170,30 @@ export function handleAttribute( return; } - // we have multiple attribute values, so we build a string out of them. - // technically the user can do something funky like attr="text "{value} or even attr=text{value} - // so instead of trying to maintain a nice sourcemap with prepends etc, we just overwrite the whole thing + // We have multiple attribute values, so we build a template string out of them. + buildTemplateString(attr, str, htmlx, '={`', '`}'); +} +function buildTemplateString( + attr: Attribute, + str: MagicString, + htmlx: string, + leadingOverride: string, + trailingOverride: string +) { const equals = htmlx.lastIndexOf('=', attr.value[0].start); - str.overwrite(equals, attr.value[0].start, '={`'); + str.overwrite(equals, attr.value[0].start, leadingOverride); - for (const n of attr.value) { + for (const n of attr.value as BaseNode[]) { if (n.type == 'MustacheTag') { str.appendRight(n.start, '$'); } } if (isQuote(htmlx[attr.end - 1])) { - str.overwrite(attr.end - 1, attr.end, '`}'); + str.overwrite(attr.end - 1, attr.end, trailingOverride); } else { - str.appendLeft(attr.end, '`}'); + str.appendLeft(attr.end, trailingOverride); } } diff --git a/packages/svelte2tsx/svelte-shims.d.ts b/packages/svelte2tsx/svelte-shims.d.ts index 379aec9e8..182a1b4e4 100644 --- a/packages/svelte2tsx/svelte-shims.d.ts +++ b/packages/svelte2tsx/svelte-shims.d.ts @@ -105,6 +105,7 @@ declare function __sveltets_ensureAction(actionCall: SvelteActionReturnType): {} declare function __sveltets_ensureTransition(transitionCall: SvelteTransitionReturnType): {}; declare function __sveltets_ensureFunction(expression: (e: Event & { detail?: any }) => unknown ): {}; declare function __sveltets_ensureType(type: AConstructorTypeOf, el: T): {}; +declare function __sveltets_cssProp(prop: Record): {}; declare function __sveltets_ctorOf(type: T): AConstructorTypeOf; declare function __sveltets_instanceOf(type: AConstructorTypeOf): T; declare function __sveltets_allPropsType(): SvelteAllProps 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 be7cc3a59..7259b44d4 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 @@ -<>{() => {/*Ω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'];<> +<>{() => {/*Ω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'];<> {foo} {bar} }} diff --git a/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expected.jsx b/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expected.jsx index 04ffa146b..64bc86141 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expected.jsx +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/expected.jsx @@ -1 +1,7 @@ -<> \ No newline at end of file +<> \ 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 index 9c5957b2e..22f7f271b 100644 --- a/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/input.svelte +++ b/packages/svelte2tsx/test/htmlx2jsx/samples/custom-css-properties/input.svelte @@ -1 +1,7 @@ - + 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 c5fa4e291..a76072aa2 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 @@ -<>{/*Ω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 +<>{/*Ω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/svelte2tsx/samples/custom-css-properties-with-$store/expected.tsx b/packages/svelte2tsx/test/svelte2tsx/samples/custom-css-properties-with-$store/expected.tsx new file mode 100644 index 000000000..c6d3e11fa --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/custom-css-properties-with-$store/expected.tsx @@ -0,0 +1,11 @@ +/// +<>;function render() { +<> +return { props: {}, slots: {}, getters: {}, events: {} }} + +export default class Input__SvelteComponent_ extends createSvelte2TsxComponent(__sveltets_partial(__sveltets_with_any_event(render))) { +} \ No newline at end of file diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/custom-css-properties-with-$store/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/custom-css-properties-with-$store/input.svelte new file mode 100644 index 000000000..c1395f873 --- /dev/null +++ b/packages/svelte2tsx/test/svelte2tsx/samples/custom-css-properties-with-$store/input.svelte @@ -0,0 +1,5 @@ +