lunchboxjs 0.2.1020 → 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/lunchboxjs.es.d.ts +1 -1
  2. package/dist/lunchboxjs.js +6 -5
  3. package/dist/lunchboxjs.min.js +1 -1
  4. package/dist/lunchboxjs.module.js +6 -5
  5. package/dist/lunchboxjs.umd.d.ts +1 -1
  6. package/package.json +37 -82
  7. package/LICENSE.md +0 -7
  8. package/README.md +0 -17
  9. package/src/components/LunchboxEventHandlers.tsx +0 -237
  10. package/src/components/LunchboxWrapper/LunchboxScene.tsx +0 -8
  11. package/src/components/LunchboxWrapper/LunchboxWrapper.tsx +0 -341
  12. package/src/components/LunchboxWrapper/prepCanvas.ts +0 -55
  13. package/src/components/LunchboxWrapper/resizeCanvas.ts +0 -41
  14. package/src/components/autoGeneratedComponents.ts +0 -175
  15. package/src/components/index.ts +0 -31
  16. package/src/core/createNode.ts +0 -71
  17. package/src/core/extend.ts +0 -25
  18. package/src/core/index.ts +0 -7
  19. package/src/core/instantiateThreeObject/index.ts +0 -37
  20. package/src/core/instantiateThreeObject/processProps.ts +0 -40
  21. package/src/core/interaction.ts +0 -55
  22. package/src/core/minidom.ts +0 -256
  23. package/src/core/update.ts +0 -149
  24. package/src/core/updateObjectProp.ts +0 -153
  25. package/src/index.ts +0 -400
  26. package/src/keys.ts +0 -31
  27. package/src/nodeOps/createElement.ts +0 -34
  28. package/src/nodeOps/index.ts +0 -83
  29. package/src/nodeOps/insert.ts +0 -165
  30. package/src/nodeOps/remove.ts +0 -32
  31. package/src/plugins/bridge/BridgeComponent.tsx +0 -60
  32. package/src/plugins/bridge/bridge.ts +0 -9
  33. package/src/types.ts +0 -186
  34. package/src/utils/find.ts +0 -24
  35. package/src/utils/get.ts +0 -18
  36. package/src/utils/index.ts +0 -60
  37. package/src/utils/isNumber.ts +0 -87
  38. package/src/utils/set.ts +0 -14
@@ -1,153 +0,0 @@
1
- import {
2
- get,
3
- isEventKey,
4
- isLunchboxStandardNode,
5
- isNumber,
6
- set,
7
- } from '../utils'
8
- import { addEventListener } from './interaction'
9
- import type { Lunch } from '..'
10
- import type { Ref } from 'vue'
11
-
12
- /** Update a single prop on a given node. */
13
- export function updateObjectProp({
14
- node,
15
- key,
16
- interactables,
17
- value,
18
- }: {
19
- node: Lunch.Node
20
- key: string
21
- interactables: Ref<Lunch.Node[]>
22
- value: any
23
- }) {
24
- // handle and return early if prop is an event
25
- // (event list from react-three-fiber)
26
- if (isEventKey(key)) {
27
- return addEventListener({ node, key, interactables, value })
28
- }
29
-
30
- // update THREE property
31
- // get final key
32
- const camelKey = key.replace(/-/g, '.')
33
- const finalKey = propertyShortcuts[camelKey] || camelKey
34
-
35
- // handle and return early if prop is specific to Vue/Lunchbox
36
- if (
37
- internalLunchboxVueKeys.includes(key) ||
38
- internalLunchboxVueKeys.includes(finalKey)
39
- )
40
- return node
41
-
42
- // everything else should be Three-specific, so let's cancel if this isn't a standard node
43
- if (!isLunchboxStandardNode(node)) return node
44
-
45
- // parse $attached values
46
- if (typeof value === 'string' && value.startsWith('$attached')) {
47
- const attachedName = value.replace('$attached.', '')
48
- value = get(node.attached, attachedName, null)
49
- }
50
-
51
- // save instance
52
- const target = node.instance
53
-
54
- // cancel if no target
55
- if (!target) return node
56
-
57
- // burrow down until we get property to change
58
- let liveProperty: any
59
- for (let i = 0; i < nestedPropertiesToCheck.length && !liveProperty; i++) {
60
- const nestedProperty = nestedPropertiesToCheck[i]
61
- const fullPath = [nestedProperty, finalKey].filter(Boolean).join('.')
62
- liveProperty = liveProperty = get(target, fullPath)
63
- }
64
-
65
- // change property
66
- // first, save as array in case we need to spread it
67
- if (liveProperty && isNumber(value) && liveProperty?.setScalar) {
68
- // if value is a number and the property has a `setScalar` method, use that
69
- liveProperty.setScalar(value)
70
- } else if (liveProperty && liveProperty.set) {
71
- // if property has `set` method, use that (https://github.com/pmndrs/react-three-fiber/blob/master/markdown/api.md#shortcuts)
72
- const nextValueAsArray = Array.isArray(value) ? value : [value]
73
- ;(target as any)[finalKey].set(...nextValueAsArray)
74
- } else if (typeof liveProperty === 'function') {
75
- // some function properties are set rather than called, so let's handle them
76
- if (
77
- finalKey.toLowerCase() === 'onbeforerender' ||
78
- finalKey.toLowerCase() === 'onafterrender'
79
- ) {
80
- ;(target as any)[finalKey] = value
81
- } else {
82
- if (!Array.isArray(value)) {
83
- throw new Error(
84
- 'Arguments on a declarative method must be wrapped in an array.\nWorks:\n<example :methodCall="[256]" />\nDoesn\'t work:\n<example :methodCall="256" />'
85
- )
86
- }
87
- // if property is a function, let's try calling it
88
- liveProperty.bind(node.instance)(...value)
89
- }
90
-
91
- // pass the result to the parent
92
- // const parent = node.parentNode
93
- // if (parent) {
94
- // const parentAsLunchboxNode = parent as Lunchbox.Node
95
- // parentAsLunchboxNode.attached[finalKey] = result
96
- // ; (parentAsLunchboxNode.instance as any)[finalKey] = result
97
- // }
98
- } else if (get(target, finalKey, undefined) !== undefined) {
99
- // blank strings evaluate to `true`
100
- // <mesh castShadow receiveShadow /> will work the same as
101
- // <mesh :castShadow="true" :receiveShadow="true" />
102
- set(target, finalKey, value === '' ? true : value)
103
- } else {
104
- // if you see this error in production, you might need to add `finalKey`
105
- // to `internalLunchboxVueKeys` below
106
- console.log(`No property ${finalKey} found on ${target}`)
107
- }
108
-
109
- // mark that we need to update if needed
110
- const targetTypeRaw =
111
- (target as any)?.texture?.type || (target as any)?.type
112
- if (typeof targetTypeRaw === 'string') {
113
- const targetType = targetTypeRaw.toLowerCase()
114
-
115
- switch (true) {
116
- case targetType.includes('material'):
117
- ;(target as unknown as THREE.Material).needsUpdate = true
118
- break
119
- case targetType.includes('camera') &&
120
- (target as any).updateProjectionMatrix:
121
- ;(
122
- target as unknown as
123
- | THREE.PerspectiveCamera
124
- | THREE.OrthographicCamera
125
- ).updateProjectionMatrix()
126
- break
127
- }
128
- }
129
-
130
- return node
131
- }
132
-
133
- const propertyShortcuts: { [key: string]: string } = {
134
- x: 'position.x',
135
- y: 'position.y',
136
- z: 'position.z',
137
- }
138
-
139
- export const nestedPropertiesToCheck = ['', 'parameters']
140
-
141
- /** props that Lunchbox intercepts and prevents passing to created instances */
142
- const internalLunchboxVueKeys = [
143
- 'args',
144
- 'attach',
145
- 'attachArray',
146
- 'is.default',
147
- 'isDefault',
148
- 'key',
149
- 'onAdded',
150
- // 'onReady',
151
- 'ref',
152
- 'src',
153
- ]
package/src/index.ts DELETED
@@ -1,400 +0,0 @@
1
- import {
2
- computed,
3
- createRenderer,
4
- Component,
5
- ComputedRef,
6
- inject,
7
- watch,
8
- reactive,
9
- Ref,
10
- WatchStopHandle,
11
- toRaw,
12
- } from 'vue'
13
- import { createNodeOps } from './nodeOps'
14
- import { extend, MiniDom } from './core'
15
- import { components } from './components'
16
- import { Lunch } from './types'
17
-
18
- export * from './core'
19
- export * from './types'
20
-
21
- import * as Keys from './keys'
22
- export * from './keys'
23
-
24
- // Utilities
25
- export * from './utils/find'
26
-
27
- /** The current camera as a computed value. */
28
- export const useCamera = <T extends THREE.Camera = THREE.Camera>() =>
29
- inject<ComputedRef<T>>(Keys.appCameraKey)!
30
- /** Run a function using the current camera when it's present. */
31
- export const onCameraReady = <T extends THREE.Camera = THREE.Camera>(
32
- cb: (camera?: T) => void
33
- ) => {
34
- const existing = useCamera<T>()
35
- if (existing.value) {
36
- cb(existing.value)
37
- return
38
- }
39
-
40
- let stopWatch: WatchStopHandle | null = null
41
- stopWatch = watch(useCamera<T>(), (newVal) => {
42
- if (newVal) {
43
- cb(newVal)
44
- stopWatch?.()
45
- }
46
- })
47
- }
48
-
49
- /** The current renderer as a computed value. */
50
- export const useRenderer = <T extends THREE.Renderer = THREE.WebGLRenderer>() =>
51
- inject<ComputedRef<T>>(Keys.appRenderersKey)!
52
- /** Run a function using the current renderer when it's present. */
53
- export const onRendererReady = <T extends THREE.Renderer = THREE.Renderer>(
54
- cb: (renderer?: T) => void
55
- ) => {
56
- const existing = useRenderer<T>()
57
- if (existing.value) {
58
- cb(existing.value)
59
- return
60
- }
61
-
62
- let stopWatch: WatchStopHandle | null = null
63
- stopWatch = watch(
64
- useRenderer<T>(),
65
- (newVal) => {
66
- if (newVal) {
67
- cb(newVal)
68
- stopWatch?.()
69
- }
70
- },
71
- { immediate: true }
72
- )
73
- }
74
-
75
- /** The current scene as a computed value. */
76
- export const useScene = <T extends THREE.Scene = THREE.Scene>() =>
77
- inject<ComputedRef<T>>(Keys.appSceneKey)!
78
- /** Run a function using the current scene when it's present. */
79
- export const onSceneReady = <T extends THREE.Scene = THREE.Scene>(
80
- cb: (scene?: T) => void
81
- ) => {
82
- const existing = useScene<T>()
83
- if (existing.value) {
84
- cb(existing.value)
85
- return
86
- }
87
-
88
- let stopWatch: WatchStopHandle | null = null
89
- stopWatch = watch(
90
- useScene<T>(),
91
- (newVal) => {
92
- if (newVal) {
93
- cb(newVal)
94
- stopWatch?.()
95
- }
96
- },
97
- { immediate: true }
98
- )
99
- }
100
-
101
- // CUSTOM RENDER SUPPORT
102
- // ====================
103
- /** Set a custom render function, overriding the Lunchbox app's default render function.
104
- * Changing this requires the user to manually render their scene.
105
- *
106
- * Invokes immediately - use `useCustomRender().setCustomRender`
107
- * if you need to call somewhere outside of `setup`.
108
- */
109
- export const setCustomRender = (
110
- render: (opts: Lunch.UpdateCallbackProperties) => void
111
- ) => {
112
- useCustomRender()?.setCustomRender?.(render)
113
- }
114
-
115
- /** Clear the active app's custom render function.
116
- *
117
- * Invokes immediately - use `useCustomRender().clearCustomRender`
118
- * if you need to call somewhere outside of `setup`.
119
- */
120
- export const clearCustomRender = () => {
121
- useCustomRender()?.clearCustomRender?.()
122
- }
123
-
124
- /** Provides `setCustomRender` and `clearCustomRender` functions to be called in a non-`setup` context. */
125
- export const useCustomRender = () => {
126
- return {
127
- /** Set a custom render function, overriding the Lunchbox app's default render function.
128
- * Changing this requires the user to manually render their scene. */
129
- setCustomRender: inject<Lunch.CustomRenderFunctionSetter>(
130
- Keys.setCustomRenderKey
131
- ),
132
- /** Clear the active app's custom render function. */
133
- clearCustomRender: inject<() => void>(Keys.clearCustomRenderKey),
134
- }
135
- }
136
-
137
- /** Use app-level globals. */
138
- export const useGlobals = () =>
139
- inject<Lunch.AppGlobals>(Keys.globalsInjectionKey)!
140
-
141
- /** Construct a function to update your app-level globals.
142
- *
143
- * ```js
144
- * // in setup():
145
- * const updateGlobals = useUpdateGlobals()
146
- *
147
- * // ...later, to update the device pixel resolution...
148
- * updateGlobals({ dpr: 2 })
149
- * ```
150
- */
151
- export const useUpdateGlobals = () =>
152
- inject<Lunch.AppGlobalsUpdate>(Keys.updateGlobalsInjectionKey)
153
-
154
- /** Update app-level globals.
155
- *
156
- * Invokes immediately - use `useUpdateGlobals`
157
- * if you need to call somewhere outside of `setup`.
158
- */
159
- export const updateGlobals = (newValue: Partial<Lunch.AppGlobals>) => {
160
- useUpdateGlobals()?.(newValue)
161
- }
162
-
163
- /** Use the current Lunchbox app. Usually used internally by Lunchbox. */
164
- export const useApp = () => inject<Lunch.App>(Keys.appKey)
165
-
166
- /** Obtain a list of the start callback functions. Usually used internally by Lunchbox. */
167
- export const useStartCallbacks = () =>
168
- inject<Lunch.UpdateCallback[]>(Keys.startCallbackKey)
169
-
170
- /** Run a given callback once when the Lunchbox app starts. Include an index to
171
- * splice the callback at that index in the callback queue. */
172
- export const onStart = (cb: Lunch.UpdateCallback, index = Infinity) => {
173
- const callbacks = useStartCallbacks()
174
- if (index === Infinity) {
175
- callbacks?.push(cb)
176
- } else {
177
- callbacks?.splice(index, 0, cb)
178
- }
179
- }
180
-
181
- /** Obtain a list of interactable objects (registered via onClick, onHover, etc events). Usually used internally by Lunchbox. */
182
- export const useLunchboxInteractables = () =>
183
- inject<Ref<Lunch.Node[]>>(Keys.lunchboxInteractables)
184
-
185
- /** Build a computed instance-getter from a specified ref. Defaults to a `toRaw`'d result. */
186
- export const getInstance = <T = unknown>(
187
- target: Ref<Lunch.LunchboxComponent<T> | Lunch.Node<T> | null>,
188
- raw = true
189
- ) =>
190
- computed(() => {
191
- const output =
192
- (target.value as Lunch.LunchboxComponent<T>)?.$el?.instance ??
193
- (target.value as Lunch.Node<T>)?.instance ??
194
- null
195
- if (output && raw) return toRaw(output)
196
- return output
197
- })
198
-
199
- // CREATE APP
200
- // ====================
201
- export const createApp = (
202
- root: Component,
203
- rootProps: Record<string, any> = {}
204
- ) => {
205
- const { nodeOps, interactables } = createNodeOps()
206
- const app = createRenderer(nodeOps).createApp(root, rootProps) as Lunch.App
207
-
208
- // provide Lunchbox interaction handlers flag (modified when user references events via
209
- // @click, etc)
210
- app.provide(Keys.lunchboxInteractables, interactables)
211
-
212
- // register all components
213
- // ====================
214
- Object.keys(components).forEach((key) => {
215
- app?.component(key, (components as any)[key])
216
- })
217
-
218
- // provide custom renderer functions
219
- // ====================
220
- app.provide(
221
- Keys.setCustomRenderKey,
222
- (render: (opts: Lunch.UpdateCallbackProperties) => void) => {
223
- app.setCustomRender(render)
224
- }
225
- )
226
- app.provide(Keys.clearCustomRenderKey, () => {
227
- app.clearCustomRender()
228
- })
229
-
230
- // before render
231
- // ====================
232
- const beforeRender = [] as Lunch.UpdateCallback[]
233
- app.provide(Keys.beforeRenderKey, beforeRender)
234
- app.provide(
235
- Keys.onBeforeRenderKey,
236
- (cb: Lunch.UpdateCallback, index = Infinity) => {
237
- if (index === Infinity) {
238
- beforeRender.push(cb)
239
- } else {
240
- beforeRender.splice(index, 0, cb)
241
- }
242
- }
243
- )
244
- app.provide(
245
- Keys.offBeforeRenderKey,
246
- (cb: Lunch.UpdateCallback | number) => {
247
- if (isFinite(cb as number)) {
248
- beforeRender.splice(cb as number, 1)
249
- } else {
250
- const idx = beforeRender.findIndex((v) => v == cb)
251
- if (idx !== -1) {
252
- beforeRender.splice(idx, 1)
253
- }
254
- }
255
- }
256
- )
257
-
258
- // after render
259
- // ====================
260
- const afterRender = [] as Lunch.UpdateCallback[]
261
- app.provide(Keys.afterRenderKey, afterRender)
262
- app.provide(
263
- Keys.onAfterRenderKey,
264
- (cb: Lunch.UpdateCallback, index = Infinity) => {
265
- if (index === Infinity) {
266
- afterRender.push(cb)
267
- } else {
268
- afterRender.splice(index, 0, cb)
269
- }
270
- }
271
- )
272
- app.provide(Keys.offAfterRenderKey, (cb: Lunch.UpdateCallback | number) => {
273
- if (isFinite(cb as number)) {
274
- afterRender.splice(cb as number, 1)
275
- } else {
276
- const idx = afterRender.findIndex((v) => v == cb)
277
- if (idx !== -1) {
278
- afterRender.splice(idx, 1)
279
- }
280
- }
281
- })
282
-
283
- // save app-level components
284
- // ====================
285
- app.config.globalProperties.lunchbox = reactive({
286
- afterRender,
287
- beforeRender,
288
- camera: null,
289
- dpr: 1,
290
- frameId: -1,
291
- renderer: null,
292
- scene: null,
293
- watchStopHandle: null,
294
-
295
- // TODO: inputActive, mousePos
296
- })
297
-
298
- // provide app-level globals & globals update method
299
- // ====================
300
- app.provide(Keys.globalsInjectionKey, app.config.globalProperties.lunchbox)
301
- app.provide<Lunch.AppGlobalsUpdate>(
302
- Keys.updateGlobalsInjectionKey,
303
- (newGlobals: Partial<Lunch.AppGlobals>) => {
304
- Object.keys(newGlobals).forEach((key) => {
305
- const typedKey = key as keyof Lunch.AppGlobals
306
- // TODO: fix
307
- app.config.globalProperties.lunchbox[typedKey] = newGlobals[
308
- typedKey
309
- ] as any
310
- })
311
- }
312
- )
313
-
314
- // frame ID (used for update functions)
315
- // ====================
316
- app.provide(Keys.frameIdKey, app.config.globalProperties.lunchbox.frameId)
317
-
318
- // watch stop handler (used for conditional update loop)
319
- // ====================
320
- app.provide(
321
- Keys.watchStopHandleKey,
322
- app.config.globalProperties.lunchbox.watchStopHandle
323
- )
324
-
325
- // update mount function to match Lunchbox.Node
326
- // ====================
327
- const { mount } = app
328
- app.mount = (root, ...args) => {
329
- // find DOM element to use as app root
330
- const domElement = (
331
- typeof root === 'string' ? document.querySelector(root) : root
332
- ) as HTMLElement
333
- // create or find root node
334
- const rootNode = new MiniDom.RendererRootNode({
335
- domElement,
336
- isLunchboxRootNode: true,
337
- name: 'root',
338
- metaType: 'rootMeta',
339
- type: 'root',
340
- uuid: 'LUNCHBOX_ROOT',
341
- })
342
- app.rootNode = rootNode
343
- app.provide(Keys.appRootNodeKey, rootNode)
344
- const mounted = mount(rootNode, ...args)
345
- return mounted
346
- }
347
-
348
- // embed .extend function
349
- // ====================
350
- app.extend = (targets: Record<string, any>) => {
351
- extend({ app: app!, ...targets })
352
- return app!
353
- }
354
-
355
- // start callback functions
356
- // ====================
357
- const startCallbacks: Lunch.UpdateCallback[] = []
358
- app.provide(Keys.startCallbackKey, startCallbacks)
359
-
360
- // prep for custom render support
361
- // ====================
362
- app.setCustomRender = (
363
- newRender: (opts: Lunch.UpdateCallbackProperties) => void
364
- ) => {
365
- if (app) {
366
- app.customRender = newRender
367
- }
368
- }
369
-
370
- // add custom render removal
371
- app.clearCustomRender = () => {
372
- if (app) {
373
- app.customRender = null
374
- }
375
- }
376
-
377
- // provide app
378
- // ====================
379
- app.provide(Keys.appKey, app)
380
- app.provide(
381
- Keys.appRenderersKey,
382
- computed(() => app.config.globalProperties.lunchbox.renderer)
383
- )
384
- app.provide(
385
- Keys.appSceneKey,
386
- computed(() => app.config.globalProperties.lunchbox.scene)
387
- )
388
- app.provide(
389
- Keys.appCameraKey,
390
- computed(() => app.config.globalProperties.lunchbox.camera)
391
- )
392
-
393
- app._props
394
-
395
- // done
396
- return app
397
- }
398
-
399
- /** Use this plugin to add a <lunchbox> component in your HTML app. */
400
- export { bridge as lunchbox } from './plugins/bridge/bridge'
package/src/keys.ts DELETED
@@ -1,31 +0,0 @@
1
- // These keys originally used Symbols per Vue instructions,
2
- // but differing dev/build values made dev difficult.
3
- // These strings have some risk of namespace collision,
4
- // but that's a low enough risk that they're worth hardcoding
5
- // as strings, in my opinion.
6
-
7
- export const globalsInjectionKey = 'lunchbox-globals' // Symbol()
8
- export const updateGlobalsInjectionKey = 'lunchbox-updateGlobals' // Symbol()
9
-
10
- export const setCustomRenderKey = 'lunchbox-setCustomRender' // Symbol()
11
- export const clearCustomRenderKey = 'lunchbox-clearCustomRender' //Symbol()
12
-
13
- export const beforeRenderKey = 'lunchbox-beforeRender' // Symbol()
14
- export const onBeforeRenderKey = 'lunchbox-onBeforeRender' //Symbol()
15
- export const offBeforeRenderKey = 'lunchbox-offBeforeRender' // Symbol()
16
-
17
- export const afterRenderKey = 'lunchbox-afterRender' // Symbol()
18
- export const onAfterRenderKey = 'lunchbox-onAfterRender' // Symbol()
19
- export const offAfterRenderKey = 'lunchbox-offAfterRender' // Symbol()
20
-
21
- export const frameIdKey = 'lunchbox-frameId' // Symbol()
22
- export const watchStopHandleKey = 'lunchbox-watchStopHandle' // Symbol()
23
-
24
- export const appRootNodeKey = 'lunchbox-appRootNode' // Symbol()
25
- export const appKey = 'lunchbox-appKey' // Symbol()
26
- export const appRenderersKey = 'lunchbox-renderer' //Symbol()
27
- export const appSceneKey = 'lunchbox-scene' // Symbol()
28
- export const appCameraKey = 'lunchbox-camera' //Symbol()
29
- export const lunchboxInteractables = 'lunchbox-interactables' // Symbol()
30
-
31
- export const startCallbackKey = 'lunchbox-startCallback' // Symbol()
@@ -1,34 +0,0 @@
1
- import { createDomNode, createNode } from '../core'
2
- import { isLunchboxDomComponent } from '../utils'
3
- import { Lunch } from '..'
4
-
5
- const autoAttach = ['geometry', 'material']
6
-
7
- export const createElement = (
8
- type: string,
9
- isSVG?: boolean,
10
- isCustomizedBuiltin?: string,
11
- vnodeProps?: Lunch.LunchboxMetaProps
12
- ) => {
13
- const options: Partial<Lunch.MetaBase> = { type, props: vnodeProps }
14
-
15
- // handle dom node
16
- const isDomNode = isLunchboxDomComponent(options)
17
- if (isDomNode) {
18
- const node = createDomNode(options)
19
- return node
20
- }
21
-
22
- // handle standard node
23
- const node = createNode(options)
24
-
25
- // autoattach
26
- autoAttach.forEach((key) => {
27
- if (type.toLowerCase().endsWith(key)) {
28
- node.props.attach = key
29
- }
30
- })
31
- // TODO: array autoattach
32
-
33
- return node
34
- }
@@ -1,83 +0,0 @@
1
- import { RendererOptions, ref } from 'vue'
2
- import { createElement } from './createElement'
3
- import { insert } from './insert'
4
- import { remove } from './remove'
5
- import { isLunchboxDomComponent, isLunchboxRootNode } from '../utils'
6
- import { createCommentNode, createTextNode, updateObjectProp } from '../core'
7
- import type { MiniDom } from '../core'
8
- import type { Lunch } from '..'
9
-
10
- /*
11
- Elements are `create`d from the outside in, then `insert`ed from the inside out.
12
- */
13
-
14
- export const createNodeOps = () => {
15
- // APP-LEVEL GLOBALS
16
- // ====================
17
- // These need to exist at the app level in a place where the node ops can access them.
18
- // It'd be better to set these via `app.provide` at app creation, but the node ops need access
19
- // to these values before the app is instantiated, so this is the next-best place for them to exist.
20
- const interactables = ref([] as Lunch.Node[])
21
-
22
- // NODE OPS
23
- // ====================
24
- const nodeOps: RendererOptions<
25
- MiniDom.RendererBaseNode,
26
- MiniDom.RendererBaseNode
27
- > = {
28
- createElement,
29
- createText(text) {
30
- return createTextNode({ text })
31
- },
32
- createComment(text) {
33
- return createCommentNode({ text })
34
- },
35
- insert,
36
- nextSibling(node) {
37
- const result = node.nextSibling
38
- if (!result) return null
39
- return result as MiniDom.RendererBaseNode
40
- },
41
- parentNode(node) {
42
- const result = node.parentNode
43
- if (!result) return null
44
- return result as MiniDom.RendererBaseNode
45
- },
46
- patchProp(node, key, prevValue, nextValue) {
47
- if (isLunchboxDomComponent(node)) {
48
- // handle DOM node
49
- if (key === 'style') {
50
- // special handling for style
51
- Object.keys(nextValue).forEach((k) => {
52
- ;(node.domElement.style as any)[k] = nextValue[k]
53
- })
54
- } else {
55
- node.domElement.setAttribute(key, nextValue)
56
- }
57
- return
58
- }
59
-
60
- // ignore if root node, or Lunchbox internal prop
61
- if (isLunchboxRootNode(node) || key.startsWith('$')) {
62
- return
63
- }
64
-
65
- // otherwise, update prop
66
- updateObjectProp({
67
- node: node as Lunch.Node,
68
- key,
69
- interactables,
70
- value: nextValue,
71
- })
72
- },
73
- remove,
74
- setElementText() {
75
- // noop
76
- },
77
- setText() {
78
- // noop
79
- },
80
- }
81
-
82
- return { nodeOps, interactables }
83
- }