Skip to content

Commit cf806db

Browse files
committed
wip: save
1 parent 8c1fc4d commit cf806db

File tree

6 files changed

+191
-168
lines changed

6 files changed

+191
-168
lines changed

packages/runtime-dom/src/apiCustomElement.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,6 @@ export abstract class VueElementBase<
285285
}
286286
}
287287

288-
get _isVapor(): boolean {
289-
return `__vapor` in this._def
290-
}
291-
292288
connectedCallback(): void {
293289
// avoid resolving component if it's not connected
294290
if (!this.isConnected) return
@@ -533,7 +529,7 @@ export abstract class VueElementBase<
533529
* @internal
534530
*/
535531
protected _getProp(key: string): any {
536-
return this._isVapor ? this._props[key]() : this._props[key]
532+
return this._props[key]
537533
}
538534

539535
/**
@@ -549,7 +545,7 @@ export abstract class VueElementBase<
549545
if (val === REMOVAL) {
550546
delete this._props[key]
551547
} else {
552-
this._props[key] = this._isVapor ? () => val : val
548+
this._props[key] = val
553549
// support set key on ceVNode
554550
if (key === 'key' && this._app && this._app._ceVNode) {
555551
this._app._ceVNode!.key = val

packages/runtime-vapor/__tests__/customElement.spec.ts

Lines changed: 163 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('defineVaporCustomElement', () => {
7171
})
7272

7373
test('should work w/ manual instantiation', () => {
74-
const e = new E({ msg: () => 'inline' })
74+
const e = new E({ msg: 'inline' })
7575
// should lazy init
7676
expect(e._instance).toBe(null)
7777
// should initialize on connect
@@ -162,7 +162,7 @@ describe('defineVaporCustomElement', () => {
162162
})
163163
})
164164

165-
describe.todo('props', () => {
165+
describe('props', () => {
166166
const E = defineVaporCustomElement({
167167
props: {
168168
foo: [String, null],
@@ -295,163 +295,177 @@ describe('defineVaporCustomElement', () => {
295295
expect((el as any).outerHTML).toBe('<my-el-comp foo-bar=""></my-el-comp>')
296296
})
297297

298-
// test('attribute -> prop type casting', async () => {
299-
// const E = defineVaporCustomElement({
300-
// props: {
301-
// fooBar: Number, // test casting of camelCase prop names
302-
// bar: Boolean,
303-
// baz: String,
304-
// },
305-
// render() {
306-
// return [
307-
// this.fooBar,
308-
// typeof this.fooBar,
309-
// this.bar,
310-
// typeof this.bar,
311-
// this.baz,
312-
// typeof this.baz,
313-
// ].join(' ')
314-
// },
315-
// })
316-
// customElements.define('my-el-props-cast', E)
317-
// container.innerHTML = `<my-el-props-cast foo-bar="1" baz="12345"></my-el-props-cast>`
318-
// const e = container.childNodes[0] as VaporElement
319-
// expect(e.shadowRoot!.innerHTML).toBe(
320-
// `1 number false boolean 12345 string`,
321-
// )
298+
test('attribute -> prop type casting', async () => {
299+
const E = defineVaporCustomElement({
300+
props: {
301+
fooBar: Number, // test casting of camelCase prop names
302+
bar: Boolean,
303+
baz: String,
304+
},
305+
setup(props: any) {
306+
const n0 = template(' ')() as any
307+
renderEffect(() => {
308+
const texts = []
309+
texts.push(
310+
toDisplayString(props.fooBar),
311+
toDisplayString(typeof props.fooBar),
312+
toDisplayString(props.bar),
313+
toDisplayString(typeof props.bar),
314+
toDisplayString(props.baz),
315+
toDisplayString(typeof props.baz),
316+
)
317+
setText(n0, texts.join(' '))
318+
})
319+
return n0
320+
},
321+
})
322+
customElements.define('my-el-props-cast', E)
323+
container.innerHTML = `<my-el-props-cast foo-bar="1" baz="12345"></my-el-props-cast>`
324+
const e = container.childNodes[0] as VaporElement
325+
expect(e.shadowRoot!.innerHTML).toBe(
326+
`1 number false boolean 12345 string`,
327+
)
322328

323-
// e.setAttribute('bar', '')
324-
// await nextTick()
325-
// expect(e.shadowRoot!.innerHTML).toBe(`1 number true boolean 12345 string`)
329+
e.setAttribute('bar', '')
330+
await nextTick()
331+
expect(e.shadowRoot!.innerHTML).toBe(`1 number true boolean 12345 string`)
326332

327-
// e.setAttribute('foo-bar', '2e1')
328-
// await nextTick()
329-
// expect(e.shadowRoot!.innerHTML).toBe(
330-
// `20 number true boolean 12345 string`,
331-
// )
333+
e.setAttribute('foo-bar', '2e1')
334+
await nextTick()
335+
expect(e.shadowRoot!.innerHTML).toBe(
336+
`20 number true boolean 12345 string`,
337+
)
332338

333-
// e.setAttribute('baz', '2e1')
334-
// await nextTick()
335-
// expect(e.shadowRoot!.innerHTML).toBe(`20 number true boolean 2e1 string`)
336-
// })
339+
e.setAttribute('baz', '2e1')
340+
await nextTick()
341+
expect(e.shadowRoot!.innerHTML).toBe(`20 number true boolean 2e1 string`)
342+
})
337343

338-
// // #4772
339-
// test('attr casting w/ programmatic creation', () => {
340-
// const E = defineVaporCustomElement({
341-
// props: {
342-
// foo: Number,
343-
// },
344-
// render() {
345-
// return `foo type: ${typeof this.foo}`
346-
// },
347-
// })
348-
// customElements.define('my-element-programmatic', E)
349-
// const el = document.createElement('my-element-programmatic') as any
350-
// el.setAttribute('foo', '123')
351-
// container.appendChild(el)
352-
// expect(el.shadowRoot.innerHTML).toBe(`foo type: number`)
353-
// })
344+
test('attr casting w/ programmatic creation', () => {
345+
const E = defineVaporCustomElement({
346+
props: {
347+
foo: Number,
348+
},
349+
setup(props: any) {
350+
const n0 = template(' ')() as any
351+
renderEffect(() => {
352+
setText(n0, `foo type: ${typeof props.foo}`)
353+
})
354+
return n0
355+
},
356+
})
357+
customElements.define('my-element-programmatic', E)
358+
const el = document.createElement('my-element-programmatic') as any
359+
el.setAttribute('foo', '123')
360+
container.appendChild(el)
361+
expect(el.shadowRoot.innerHTML).toBe(`foo type: number`)
362+
})
354363

355-
// test('handling properties set before upgrading', () => {
356-
// const E = defineVaporCustomElement({
357-
// props: {
358-
// foo: String,
359-
// dataAge: Number,
360-
// },
361-
// setup(props) {
362-
// expect(props.foo).toBe('hello')
363-
// expect(props.dataAge).toBe(5)
364-
// },
365-
// render() {
366-
// return h('div', `foo: ${this.foo}`)
367-
// },
368-
// })
369-
// const el = document.createElement('my-el-upgrade') as any
370-
// el.foo = 'hello'
371-
// el.dataset.age = 5
372-
// el.notProp = 1
373-
// container.appendChild(el)
374-
// customElements.define('my-el-upgrade', E)
375-
// expect(el.shadowRoot.firstChild.innerHTML).toBe(`foo: hello`)
376-
// // should not reflect if not declared as a prop
377-
// expect(el.hasAttribute('not-prop')).toBe(false)
378-
// })
364+
test('handling properties set before upgrading', () => {
365+
const E = defineVaporCustomElement({
366+
props: {
367+
foo: String,
368+
dataAge: Number,
369+
},
370+
setup(props: any) {
371+
expect(props.foo).toBe('hello')
372+
expect(props.dataAge).toBe(5)
379373

380-
// test('handle properties set before connecting', () => {
381-
// const obj = { a: 1 }
382-
// const E = defineVaporCustomElement({
383-
// props: {
384-
// foo: String,
385-
// post: Object,
386-
// },
387-
// setup(props) {
388-
// expect(props.foo).toBe('hello')
389-
// expect(props.post).toBe(obj)
390-
// },
391-
// render() {
392-
// return JSON.stringify(this.post)
393-
// },
394-
// })
395-
// customElements.define('my-el-preconnect', E)
396-
// const el = document.createElement('my-el-preconnect') as any
397-
// el.foo = 'hello'
398-
// el.post = obj
374+
const n0 = template('<div> </div>', true)() as any
375+
const x0 = txt(n0) as any
376+
renderEffect(() => setText(x0, `foo: ${props.foo}`))
377+
return n0
378+
},
379+
})
380+
const el = document.createElement('my-el-upgrade') as any
381+
el.foo = 'hello'
382+
el.dataset.age = 5
383+
el.notProp = 1
384+
container.appendChild(el)
385+
customElements.define('my-el-upgrade', E)
386+
expect(el.shadowRoot.firstChild.innerHTML).toBe(`foo: hello`)
387+
// should not reflect if not declared as a prop
388+
expect(el.hasAttribute('not-prop')).toBe(false)
389+
})
399390

400-
// container.appendChild(el)
401-
// expect(el.shadowRoot.innerHTML).toBe(JSON.stringify(obj))
402-
// })
391+
test('handle properties set before connecting', () => {
392+
const obj = { a: 1 }
393+
const E = defineVaporCustomElement({
394+
props: {
395+
foo: String,
396+
post: Object,
397+
},
398+
setup(props: any) {
399+
expect(props.foo).toBe('hello')
400+
expect(props.post).toBe(obj)
403401

404-
// // https://github.com/vuejs/core/issues/6163
405-
// test('handle components with no props', async () => {
406-
// const E = defineVaporCustomElement({
407-
// render() {
408-
// return h('div', 'foo')
409-
// },
410-
// })
411-
// customElements.define('my-element-noprops', E)
412-
// const el = document.createElement('my-element-noprops')
413-
// container.appendChild(el)
414-
// await nextTick()
415-
// expect(el.shadowRoot!.innerHTML).toMatchInlineSnapshot('"<div>foo</div>"')
416-
// })
402+
const n0 = template(' ', true)() as any
403+
renderEffect(() => setText(n0, JSON.stringify(props.post)))
404+
return n0
405+
},
406+
})
407+
customElements.define('my-el-preconnect', E)
408+
const el = document.createElement('my-el-preconnect') as any
409+
el.foo = 'hello'
410+
el.post = obj
417411

418-
// // #5793
419-
// test('set number value in dom property', () => {
420-
// const E = defineVaporCustomElement({
421-
// props: {
422-
// 'max-age': Number,
423-
// },
424-
// render() {
425-
// // @ts-expect-error
426-
// return `max age: ${this.maxAge}/type: ${typeof this.maxAge}`
427-
// },
428-
// })
429-
// customElements.define('my-element-number-property', E)
430-
// const el = document.createElement('my-element-number-property') as any
431-
// container.appendChild(el)
432-
// el.maxAge = 50
433-
// expect(el.maxAge).toBe(50)
434-
// expect(el.shadowRoot.innerHTML).toBe('max age: 50/type: number')
435-
// })
412+
container.appendChild(el)
413+
expect(el.shadowRoot.innerHTML).toBe(JSON.stringify(obj))
414+
})
436415

437-
// // #9006
438-
// test('should reflect default value', () => {
439-
// const E = defineVaporCustomElement({
440-
// props: {
441-
// value: {
442-
// type: String,
443-
// default: 'hi',
444-
// },
445-
// },
446-
// render() {
447-
// return this.value
448-
// },
449-
// })
450-
// customElements.define('my-el-default-val', E)
451-
// container.innerHTML = `<my-el-default-val></my-el-default-val>`
452-
// const e = container.childNodes[0] as any
453-
// expect(e.value).toBe('hi')
454-
// })
416+
test('handle components with no props', async () => {
417+
const E = defineVaporCustomElement({
418+
setup() {
419+
return template('<div>foo</div>', true)()
420+
},
421+
})
422+
customElements.define('my-element-noprops', E)
423+
const el = document.createElement('my-element-noprops')
424+
container.appendChild(el)
425+
await nextTick()
426+
expect(el.shadowRoot!.innerHTML).toMatchInlineSnapshot('"<div>foo</div>"')
427+
})
428+
429+
test('set number value in dom property', () => {
430+
const E = defineVaporCustomElement({
431+
props: {
432+
'max-age': Number,
433+
},
434+
setup(props: any) {
435+
const n0 = template(' ')() as any
436+
renderEffect(() => {
437+
setText(n0, `max age: ${props.maxAge}/type: ${typeof props.maxAge}`)
438+
})
439+
return n0
440+
},
441+
})
442+
customElements.define('my-element-number-property', E)
443+
const el = document.createElement('my-element-number-property') as any
444+
container.appendChild(el)
445+
el.maxAge = 50
446+
expect(el.maxAge).toBe(50)
447+
expect(el.shadowRoot.innerHTML).toBe('max age: 50/type: number')
448+
})
449+
450+
test('should reflect default value', () => {
451+
const E = defineVaporCustomElement({
452+
props: {
453+
value: {
454+
type: String,
455+
default: 'hi',
456+
},
457+
},
458+
setup(props: any) {
459+
const n0 = template(' ')() as any
460+
renderEffect(() => setText(n0, props.value))
461+
return n0
462+
},
463+
})
464+
customElements.define('my-el-default-val', E)
465+
container.innerHTML = `<my-el-default-val></my-el-default-val>`
466+
const e = container.childNodes[0] as any
467+
expect(e.value).toBe('hi')
468+
})
455469

456470
// // #12214
457471
// test('Boolean prop with default true', async () => {

0 commit comments

Comments
 (0)