diff --git a/src/index.js b/src/index.js
index 5e1663d..5cc220e 100644
--- a/src/index.js
+++ b/src/index.js
@@ -13,7 +13,7 @@ const compile = (templateParts, ...values) => {
Array.from({ length: values.length }, (_, i) => 'arg' + i),
];
const gen = new GeneratorFunction(...args, src);
- return (...values) => gen({ escape }, ...values);
+ return (...values) => gen({ escape, attributesFragment }, ...values);
};
const buildSource = (templateParts, ...values) => {
@@ -29,11 +29,21 @@ const buildSource = (templateParts, ...values) => {
return src + `;yield arg${i}; yield \`${tplPart}\``;
}
+ if (typeof value === 'object') {
+ return src + `+utils.attributesFragment(arg${i}) + \`${tplPart}\``;
+ }
+
return src + `+utils.escape(String(arg${i})) + \`${tplPart}\``;
}, `yield \`${first}\``) + ';'
);
};
+const attributesFragment = (value) =>
+ Object.entries(value)
+ .filter(([_, value]) => value !== false)
+ .map(([attr, value]) => `${attr}="${escape(value)}"`)
+ .join(' ');
+
const isAsync = (value) =>
value?.then !== undefined || value?.[Symbol.asyncIterator];
diff --git a/test/objects.js b/test/objects.js
new file mode 100644
index 0000000..5232f24
--- /dev/null
+++ b/test/objects.js
@@ -0,0 +1,28 @@
+import { test } from 'zora';
+import { renderAsString, html } from '../src/index.js';
+
+test('object pairs result into html attributes', async ({ eq }) => {
+ const htmlString = await renderAsString(
+ html``,
+ );
+ eq(htmlString, ``);
+});
+
+test('attribute values are escaped', async ({ eq }) => {
+ const htmlString = await renderAsString(
+ // prettier-ignore
+ html``,
+ );
+ eq(
+ htmlString,
+ ``,
+ );
+});
+
+test('attributes whose value is false are ignored', async ({ eq }) => {
+ const htmlString = await renderAsString(
+ // prettier-ignore
+ html``,
+ );
+ eq(htmlString, ``);
+});