-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathsvelte-state-renderer.js
85 lines (66 loc) · 1.94 KB
/
svelte-state-renderer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { tick } from 'svelte'
import UiView from './UiView.svelte'
UiView.from = (target, asr) => {
if (target instanceof HTMLElement) {
// it's a target element
return new UiView({ target, props: { asr } })
} else {
// it's alreay a UiView
target.setAsr(asr)
return target
}
}
const ASR = Symbol('asr')
export default (defaultOptions = {}) => stateRouter => {
const { props: defaultProps } = defaultOptions
const asr = {
makePath: stateRouter.makePath,
stateIsActive: stateRouter.stateIsActive,
}
const render = async context => {
const { element: target, template, content } = context
const props = { ...content, ...defaultProps }
const view = UiView.from(target, asr)
const construct = async (getComponent, props) => {
const { default: Component } = await getComponent()
const component = await view.setComponent(Component, props)
return component
}
let cmp
if (typeof template === `function`) {
cmp = await construct(template, props)
} else {
cmp = await construct(template.component, { ...props, ...template.props })
}
function onRouteChange() {
// FIXME what's this? force refresh? why?
// cmp.$set({ asr })
}
stateRouter.on(`stateChangeEnd`, onRouteChange)
const onDestroy = () =>
stateRouter.removeListener(`stateChangeEnd`, onRouteChange)
cmp[ASR] = { view, onDestroy }
return cmp
}
return {
render,
reset(context, cb) {
// TODO untested
const cmp = context.domApi
const { view, onDestroy } = cmp[ASR]
onDestroy()
const renderContext = Object.assign({ element: view }, context)
render(renderContext, cb)
},
async destroy(cmp) {
const { view, onDestroy } = cmp[ASR]
onDestroy()
view.$destroy()
await tick()
},
async getChildElement(cmp) {
const { [ASR]: {view} } = cmp
return view.getChild()
},
}
}