Skip to content

Commit 4a8d4a0

Browse files
Merge pull request #424 from preactjs/fix-signals-support
Detect and unwrap signal properties
2 parents ec0b614 + a5fc66b commit 4a8d4a0

File tree

6 files changed

+54
-2
lines changed

6 files changed

+54
-2
lines changed

.changeset/mean-dragons-ring.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'preact-render-to-string': patch
3+
---
4+
5+
Fix support for signals, we need to detect and unwrap the signal

package-lock.json

Lines changed: 14 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
"@babel/register": "^7.12.10",
114114
"@changesets/changelog-github": "^0.4.1",
115115
"@changesets/cli": "^2.18.0",
116+
"@preact/signals-core": "^1.11.0",
116117
"baseline-rts": "npm:preact-render-to-string@latest",
117118
"benchmarkjs-pretty": "^2.0.1",
118119
"check-export-map": "^1.3.1",

src/index.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
unsetDirty,
1212
isDirty
1313
} from './lib/util.js';
14+
import { Signal } from '@preact/signals-core';
1415
import { options, h, Fragment } from 'preact';
1516
import {
1617
CHILDREN,
@@ -563,6 +564,7 @@ function _renderToString(
563564

564565
for (let name in props) {
565566
let v = props[name];
567+
v = isSignal(v) ? v.value : v;
566568

567569
if (typeof v == 'function' && name !== 'class' && name !== 'className') {
568570
continue;
@@ -744,3 +746,12 @@ const SELF_CLOSING = new Set([
744746
export default renderToString;
745747
export const render = renderToString;
746748
export const renderToStaticMarkup = renderToString;
749+
750+
function isSignal(x) {
751+
return (
752+
x !== null &&
753+
typeof x === 'object' &&
754+
typeof x.peek === 'function' &&
755+
'value' in x
756+
);
757+
}

test/render.test.jsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ describe('render', () => {
144144
expect(rendered).to.equal(expected);
145145
});
146146

147+
it('should include boolean disabled attribute', () => {
148+
let rendered = render(<input disabled={false} />),
149+
expected = `<input/>`;
150+
151+
expect(rendered).to.equal(expected);
152+
});
153+
147154
it('should support false aria-* attributes', () => {
148155
let rendered = render(<div aria-checked={false} />);
149156
expect(rendered).to.equal(`<div aria-checked="false"></div>`);

test/signals/render.test.jsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import render from '../../src/index.js';
2+
import { signal } from '@preact/signals-core';
3+
import { h } from 'preact';
4+
import { expect, describe, it } from 'vitest';
5+
6+
/** @jsx h */
7+
8+
describe('signals', () => {
9+
it('should render signals', () => {
10+
const disabled = signal(false);
11+
12+
const vdom = <input draggable={false} disabled={disabled} />;
13+
14+
expect(render(vdom)).to.equal('<input draggable="false"/>');
15+
});
16+
});

0 commit comments

Comments
 (0)