Skip to content

Commit a93b5f8

Browse files
author
arnoson
committed
feat: add default prop values to dataset
Comes in handy when using css selectors like `.my-component[data-open=true]`. These required to have the dataset property explicitly set, even if there was a prop default value.
1 parent d2432da commit a93b5f8

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

src/mountComponent.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { createPropsProxy } from './props'
1+
import {
2+
createPropsProxy,
3+
getDefaultProp,
4+
isBuiltInTypeConstructor,
5+
stringifyProp
6+
} from './props'
27
import { getRefs } from './refs'
38
import { getComponent } from './registerComponent'
49
import { SimpleComponentEvent, SimpleElement } from './types'
@@ -24,6 +29,19 @@ export const mountComponent = (el: HTMLElement, isChild = false) => {
2429
? createPropsProxy(el, propsDefinitions)
2530
: el.dataset
2631

32+
// Add missing default prop values to dataset for CSS/query selectors.
33+
if (propsDefinitions) {
34+
for (const [key, definition] of Object.entries(propsDefinitions)) {
35+
if (el.dataset[key] !== undefined) continue
36+
37+
const providesDefault = !isBuiltInTypeConstructor(definition)
38+
if (!providesDefault) continue
39+
40+
const value = getDefaultProp(definition)
41+
el.dataset[key] = stringifyProp(value)
42+
}
43+
}
44+
2745
const { refs, refsAll } = getRefs(el)
2846
const ComponentEvent = CustomEvent as SimpleComponentEvent
2947
const ctx = { el, props, refs, refsAll, ComponentEvent }

src/props.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
const isBuiltInTypeConstructor = (value: any) =>
1+
export const isBuiltInTypeConstructor = (value: any) =>
22
[Number, String, Boolean, Array, Object].includes(value)
33

4-
const parseProp = (value: any, type: string) =>
4+
export const parseProp = (value: any, type: string) =>
55
type === 'string' ? String(value) : JSON.parse(value)
66

7-
const stringifyProp = (value: any) =>
7+
export const stringifyProp = (value: any) =>
88
typeof value === 'string' ? value : JSON.stringify(value)
99

10-
const getDefaultProp = (definition: any) =>
10+
export const getDefaultProp = (definition: any) =>
1111
definition instanceof Function ? definition() : definition
1212

1313
export const createPropsProxy = (

tests/index.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,26 @@ it(`provides default values for props`, () => {
175175
expect(props.obj).toEqual({})
176176
})
177177

178+
it(`adds default values to the dataset`, () => {
179+
document.body.innerHTML = `<div data-simple-component="test" data-provided="provided"></div>`
180+
const el = document.querySelector('div')
181+
182+
const options = {
183+
props: {
184+
missing: 10,
185+
provided: 'default',
186+
ignore: Number
187+
}
188+
}
189+
190+
registerComponent('test', options, () => {})
191+
mountComponents()
192+
193+
expect(el?.dataset.missing).toBe('10')
194+
expect(el?.dataset.provided).toBe('provided')
195+
expect(el?.dataset.ignore).toBe(undefined)
196+
})
197+
178198
it('interferes prop types from default values', () => {
179199
document.body.innerHTML = `
180200
<div

0 commit comments

Comments
 (0)