diff --git a/packages/core/__tests__/language-server/diagnostic-augmentation.test.ts b/packages/core/__tests__/language-server/diagnostic-augmentation.test.ts index c093023c8..ff20b00bb 100644 --- a/packages/core/__tests__/language-server/diagnostic-augmentation.test.ts +++ b/packages/core/__tests__/language-server/diagnostic-augmentation.test.ts @@ -215,11 +215,11 @@ describe('Language Server: Diagnostic Augmentation', () => { Type '{}' is not assignable to type 'AttrValue'.", "range": { "end": { - "character": 16, + "character": 35, "line": 9, }, "start": { - "character": 9, + "character": 17, "line": 9, }, }, @@ -287,11 +287,11 @@ describe('Language Server: Diagnostic Augmentation', () => { Type '{}' is not assignable to type 'AttrValue'.", "range": { "end": { - "character": 16, + "character": 39, "line": 14, }, "start": { - "character": 9, + "character": 17, "line": 14, }, }, diff --git a/packages/core/__tests__/transform/template-to-typescript.test.ts b/packages/core/__tests__/transform/template-to-typescript.test.ts index 6f0762e9e..f52ea4e0b 100644 --- a/packages/core/__tests__/transform/template-to-typescript.test.ts +++ b/packages/core/__tests__/transform/template-to-typescript.test.ts @@ -756,9 +756,9 @@ describe('Transform: rewriteTemplate', () => { expect(templateBody(template, { globals: [] })).toMatchInlineSnapshot(` "{ const 𝛄 = χ.emitComponent(χ.resolve(Foo)()); - χ.applyAttributes(𝛄.element, { - \\"data-bar\\": χ.resolve(helper)({ param: true , ...χ.NamedArgsMarker }), - }); + χ.applyAttributes(𝛄.element, [ + [\\"data-bar\\", χ.resolve(helper)({ param: true , ...χ.NamedArgsMarker })], + ]); }" `); }); @@ -790,9 +790,9 @@ describe('Transform: rewriteTemplate', () => { expect(templateBody(template)).toMatchInlineSnapshot(` "{ const 𝛄 = χ.emitElement(\\"div\\"); - χ.applyAttributes(𝛄.element, { - \\"data-attr\\": χ.resolveOrReturn(𝚪.args.input)(), - }); + χ.applyAttributes(𝛄.element, [ + [\\"data-attr\\", χ.resolveOrReturn(𝚪.args.input)()], + ]); }" `); }); @@ -803,9 +803,9 @@ describe('Transform: rewriteTemplate', () => { expect(templateBody(template)).toMatchInlineSnapshot(` "{ const 𝛄 = χ.emitElement(\\"div\\"); - χ.applyAttributes(𝛄.element, { - \\"data-attr\\": \`\${χ.resolveOrReturn(𝚪.args.input)()}\`, - }); + χ.applyAttributes(𝛄.element, [ + [\\"data-attr\\", \`\${χ.resolveOrReturn(𝚪.args.input)()}\`], + ]); }" `); }); @@ -957,9 +957,9 @@ describe('Transform: rewriteTemplate', () => { expect(templateBody(template, { globals: [] })).toMatchInlineSnapshot(` "{ const 𝛄 = χ.emitElement(\\"div\\"); - χ.applyAttributes(𝛄.element, { - \\"data-attr\\": χ.resolve(concat)(χ.resolve(foo)(1), χ.resolve(foo)(true)), - }); + χ.applyAttributes(𝛄.element, [ + [\\"data-attr\\", χ.resolve(concat)(χ.resolve(foo)(1), χ.resolve(foo)(true))], + ]); }" `); }); @@ -1058,9 +1058,9 @@ describe('Transform: rewriteTemplate', () => { expect(templateBody(template)).toMatchInlineSnapshot(` "{ const 𝛄 = χ.emitElement(\\"div\\"); - χ.applyAttributes(𝛄.element, { - \\"data-foo\\": χ.resolveOrReturn(𝚪.args.foo)(), - }); + χ.applyAttributes(𝛄.element, [ + [\\"data-foo\\", χ.resolveOrReturn(𝚪.args.foo)()], + ]); }" `); }); @@ -1071,9 +1071,9 @@ describe('Transform: rewriteTemplate', () => { expect(templateBody(template)).toMatchInlineSnapshot(` "{ const 𝛄 = χ.emitElement(\\"div\\"); - χ.applyAttributes(𝛄.element, { - \\"data-foo\\": \`\${χ.resolveOrReturn(𝚪.args.foo)()}\${χ.resolveOrReturn(𝚪.args.bar)()}\`, - }); + χ.applyAttributes(𝛄.element, [ + [\\"data-foo\\", \`\${χ.resolveOrReturn(𝚪.args.foo)()}\${χ.resolveOrReturn(𝚪.args.bar)()}\`], + ]); }" `); }); @@ -1251,9 +1251,9 @@ describe('Transform: rewriteTemplate', () => { const [NS] = 𝛄.blockParams[\\"default\\"]; { const 𝛄 = χ.emitComponent(χ.resolve(NS?.Nested?.Custom)()); - χ.applyAttributes(𝛄.element, { - class: \\"foo\\", - }); + χ.applyAttributes(𝛄.element, [ + [\\"class\\", \\"foo\\"], + ]); } } χ.Globals[\\"Foo\\"]; diff --git a/packages/core/src/transform/diagnostics/augmentation.ts b/packages/core/src/transform/diagnostics/augmentation.ts index 4fc4a7b14..ccb93377f 100644 --- a/packages/core/src/transform/diagnostics/augmentation.ts +++ b/packages/core/src/transform/diagnostics/augmentation.ts @@ -47,7 +47,7 @@ function checkAssignabilityError( if (!parentNode) return; if ( - node.type === 'Identifier' && + node.type === 'MustacheStatement' && parentNode.type === 'AttrNode' && !/^(@|\.)/.test(parentNode.name) ) { diff --git a/packages/core/src/transform/template/template-to-typescript.ts b/packages/core/src/transform/template/template-to-typescript.ts index 5157b4c51..773453524 100644 --- a/packages/core/src/transform/template/template-to-typescript.ts +++ b/packages/core/src/transform/template/template-to-typescript.ts @@ -795,7 +795,7 @@ export function templateToTypescript( if (!attributes.length) return; - emit.text('χ.applyAttributes(𝛄.element, {'); + emit.text('χ.applyAttributes(𝛄.element, ['); emit.newline(); emit.indent(); @@ -805,8 +805,9 @@ export function templateToTypescript( emit.forNode(attr, () => { start = template.indexOf(attr.name, start + 1); - emitHashKey(attr.name, start); - emit.text(': '); + emit.text('['); + emitIdentifierString(attr.name, start); + emit.text(', '); if (attr.value.type === 'MustacheStatement') { emitMustacheStatement(attr.value, 'attr'); @@ -816,13 +817,13 @@ export function templateToTypescript( emit.text(JSON.stringify(attr.value.chars)); } - emit.text(','); + emit.text('],'); emit.newline(); }); } emit.dedent(); - emit.text('});'); + emit.text(']);'); emit.newline(); } diff --git a/packages/template/-private/dsl/emit.d.ts b/packages/template/-private/dsl/emit.d.ts index 4b832bf23..01545a80d 100644 --- a/packages/template/-private/dsl/emit.d.ts +++ b/packages/template/-private/dsl/emit.d.ts @@ -40,7 +40,7 @@ export declare function emitContent(value: ContentValue): void; * * emitElement('div', (𝛄) => { * applySplattributes(𝚪.element, 𝛄.element); - * applyAttributes(𝛄.element, { class: 'hello' }); + * applyAttributes(𝛄.element, [[ 'class': 'hello' ]]); * applyModifier(𝛄.element, resolve(on)({}, 'click', this.clicked)); * }); */ @@ -133,7 +133,7 @@ export declare function applySplattributes< *
* */ -export declare function applyAttributes(element: Element, attrs: Record): void; +export declare function applyAttributes(element: Element, attrs: Array<[string, AttrValue]>): void; /* * Applies a modifier to an element or component. diff --git a/packages/template/__tests__/attributes.test.ts b/packages/template/__tests__/attributes.test.ts index d9664e3a6..60c98edcf 100644 --- a/packages/template/__tests__/attributes.test.ts +++ b/packages/template/__tests__/attributes.test.ts @@ -61,7 +61,7 @@ class MyComponent extends TestComponent<{ Element: HTMLImageElement }> { { const component = emitComponent(resolve(MyComponent)()); applySplattributes(new HTMLImageElement(), component.element); - applyAttributes(component.element, { foo: 'bar' }); + applyAttributes(component.element, [['foo', 'bar']]); } /** @@ -179,21 +179,21 @@ class MyComponent extends TestComponent<{ Element: HTMLImageElement }> { applyAttributes( // @ts-expect-error: Trying to apply attributes to a component with no root element component.element, - { foo: 'bar' } + [ ['foo', 'bar'] ] ); } { - applyAttributes(document.createElement('div'), { - string: 'ok', - safeString: htmlSafe('ok'), - number: 123, - bool: false, - null: null, - undefined: undefined, + applyAttributes(document.createElement('div'), [ + ['string', 'ok'], + ['safeString', htmlSafe('ok')], + ['number', 123], + ['bool', false], + ['null', null], + ['undefined', undefined], // @ts-expect-error: setting a `void` return as an attr makes no sense - nothing: undefined as void, + ['nothing', undefined as void], // @ts-expect-error: DOM nodes aren't valid values - div: document.createElement('div'), - }); + ['div', document.createElement('div')], + ]); }