Skip to content

Commit b491104

Browse files
author
Elson Correia
committed
honnor empty attributes
1 parent 8ffbdc1 commit b491104

File tree

5 files changed

+55
-3
lines changed

5 files changed

+55
-3
lines changed

docs/documentation/templating/html-attributes.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,22 @@ html`
4444
// <input type="checkbox">
4545
```
4646

47+
Setting an attribute value to `false` (as string or boolean) or nil (`undefined` or `null`) will remove the attribute.
48+
49+
```
50+
const disabled = false
51+
const checked = null
52+
53+
html`
54+
<p hidden="false">hidden text</p>
55+
<button disabled="${disabled}">click me</button>
56+
<input type="checkbox" checked="${checked}" />
57+
`.render(document.body)
58+
// <p>hidden text</p>
59+
// <button>click me</button>
60+
// <input type="checkbox">
61+
```
62+
4763
### Value attributes
4864

4965
Markup is aware of value you inject in the template as attribute values and will track and update them accordingly. There is no extra syntax necessary to make this happen.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@beforesemicolon/markup",
3-
"version": "1.13.4",
3+
"version": "1.14.0",
44
"description": "Reactive HTML Templating System",
55
"engines": {
66
"node": ">=18.16.0"

src/helpers/element.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ describe('element', () => {
8888

8989
expect(el).toBeInstanceOf(MyButton)
9090
expect(el.outerHTML).toBe(
91-
'<my-button id="btn" disabled="false"><span>click me</span></my-button>'
91+
'<my-button id="btn"><span>click me</span></my-button>'
9292
)
9393
})
9494

src/html.spec.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,21 @@ describe('html', () => {
713713
expect(document.body.innerHTML).toBe('<button style="background: red;">click me</button>');
714714
})
715715

716+
it('any boolean attr without value', () => {
717+
const [disabled, setDisabled] = state(true)
718+
const btn = html`
719+
<button disabled>click me</button>
720+
<button disabled="">click me</button>
721+
`
722+
723+
btn.render(document.body)
724+
725+
expect(document.body.innerHTML).toBe(
726+
'<button disabled="">click me</button>\n' +
727+
'\t\t\t\t<button disabled="">click me</button>'
728+
)
729+
})
730+
716731
it('any boolean attr', () => {
717732
const [disabled, setDisabled] = state(true)
718733
const btn = html`
@@ -755,6 +770,12 @@ describe('html', () => {
755770
setHidden('')
756771
jest.advanceTimersToNextTimer()
757772

773+
expect(document.body.innerHTML).toBe('<button hidden="">click me</button>')
774+
775+
// @ts-ignore
776+
setHidden(false)
777+
jest.advanceTimersToNextTimer()
778+
758779
expect(document.body.innerHTML).toBe('<button>click me</button>')
759780
})
760781

@@ -893,6 +914,21 @@ describe('html', () => {
893914
expect(inputField.getAttribute('value')).toBe('')
894915
expect(inputField.value).toBe('')
895916
})
917+
918+
it('and not set false boolean or nil attributes', () => {
919+
const disabled = false
920+
const checked = null
921+
922+
html`
923+
<p hidden="false" id="${undefined}">hidden text</p>
924+
<button disabled="${disabled}" type="${null}">click me</button>
925+
<input type="checkbox" checked="${checked}" />
926+
`.render(document.body)
927+
928+
expect(document.body.innerHTML).toBe('<p>hidden text</p>\n' +
929+
'\t\t\t <button>click me</button>\n' +
930+
'\t\t\t <input type="checkbox">')
931+
})
896932
})
897933

898934
it('should handle primitive attribute value', () => {

src/utils/set-element-attribute.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const setElementAttribute = (
1616
if (
1717
value !== undefined &&
1818
value !== null &&
19-
(!booleanAttributes[key] || value)
19+
(!booleanAttributes[key] || !/false/.test(String(value).trim()))
2020
) {
2121
const descriptor =
2222
Object.getOwnPropertyDescriptor(el, key) ??

0 commit comments

Comments
 (0)