diff --git a/packages/babel-plugin-htm/README.md b/packages/babel-plugin-htm/README.md
index a2bb474..d0e4359 100644
--- a/packages/babel-plugin-htm/README.md
+++ b/packages/babel-plugin-htm/README.md
@@ -159,6 +159,17 @@ html`
hello ${you}
`
] }
```
+### `noNullProps` _(experimental)_
+
+Setting `noNullProps` to `true` passes empty object literals rather than `null` literals when a tag has no props:
+
+```js
+// input:
+html``
+// output:
+h('div', {})
+```
+
[htm]: https://github.com/developit/htm
[Babel docs]: https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#pragma
diff --git a/packages/babel-plugin-htm/index.mjs b/packages/babel-plugin-htm/index.mjs
index 9e00c37..eb3958e 100644
--- a/packages/babel-plugin-htm/index.mjs
+++ b/packages/babel-plugin-htm/index.mjs
@@ -10,12 +10,14 @@ import { build, treeify } from '../../src/build.mjs';
* @param {boolean} [options.useBuiltIns=false] Use the native Object.assign instead of trying to polyfill it.
* @param {boolean} [options.useNativeSpread=false] Use the native { ...a, ...b } syntax for prop spreads.
* @param {boolean} [options.variableArity=true] If `false`, always passes exactly 3 arguments to the pragma function.
+ * @param {boolean} [options.noNullProps=false] If `true`, passes an empty object instead of null when there are no props.
*/
export default function htmBabelPlugin({ types: t }, options = {}) {
const pragmaString = options.pragma===false ? false : options.pragma || 'h';
const pragma = pragmaString===false ? false : dottedIdentifier(pragmaString);
const useBuiltIns = options.useBuiltIns;
const useNativeSpread = options.useNativeSpread;
+ const noNullProps = options.noNullProps;
const inlineVNodes = options.monomorphic || pragma===false;
const importDeclaration = pragmaImport(options.import || false);
@@ -123,7 +125,7 @@ export default function htmBabelPlugin({ types: t }, options = {}) {
function spreadNode(args, state) {
if (args.length === 0) {
- return t.nullLiteral();
+ return noNullProps ? t.objectExpression([]) : t.nullLiteral();
}
if (args.length > 0 && t.isNode(args[0])) {
args.unshift({});
diff --git a/test/babel.test.mjs b/test/babel.test.mjs
index c7ad833..cd771e8 100644
--- a/test/babel.test.mjs
+++ b/test/babel.test.mjs
@@ -360,6 +360,21 @@ describe('htm/babel', () => {
});
});
+ describe('{noNullProps:true}', () => {
+ test('should use empty objects instead of null props', () => {
+ expect(
+ transform('html``;', {
+ ...options,
+ plugins: [
+ [htmBabelPlugin, {
+ noNullProps: true
+ }]
+ ]
+ }).code
+ ).toBe(`h("div",{});`);
+ });
+ });
+
describe('{import:Object}', () => {
test('should add import', () => {
expect(