Skip to content

Commit

Permalink
feat(ListView): initial LV implementation
Browse files Browse the repository at this point in the history
A first pass of implementing a ListView, with vue slots.
  • Loading branch information
rigor789 committed Apr 25, 2020
1 parent 742f638 commit ff8b032
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 8 deletions.
46 changes: 46 additions & 0 deletions apps/test/app/ListViewComp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ListView } from 'nativescript-vue'

export default {
components: {
ListView,
},
template: `
<ListView :items="items" _tap="items.push('Item ' + (items.length + 1))">
<template v-slot:default="{item, index, even, odd}">
<Label textWrap="true">
Item: {{ item }}
Index: {{ index }}
Even: {{ even }}
Odd: {{ odd }}
</Label>
</template>
<!--<template v-slot:other="{item}">-->
<!-- <Label >{{ item }}Other</Label>-->
<!--</template>-->
</ListView>`,
data() {
return {
items: [
'Item 1',
'Item 2',
'Item 3',
'Item 4',
'Item 5',
'Item 6',
'Item 7',
'Item 8',
'Item 9',
'Item 10',
'Item 11',
'Item 12',
'Item 13',
'Item 14',
'Item 15',
'Item 16',
'Item 17',
'Item 18',
'Item 19',
],
}
},
}
15 changes: 7 additions & 8 deletions apps/test/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from 'nativescript-vue'

import Comp from './Comp'
import ListViewComp from './ListViewComp'

// todo: figure out why isOn is undefined in Vue - causes a crash...
global.isOn = (name) => name.startsWith('on')
Expand Down Expand Up @@ -47,13 +48,10 @@ const testComp = defineComponent({
},
})

trace.setCategories(trace.categories.Debug)
// trace.setCategories(trace.categories.Debug)
trace.setCategories('ListView')
trace.enable()

const testTemplate = '<StackLayout />'
console.log(`Compilation of ${testTemplate}`)
console.log(compile(testTemplate).toString())

function dumpViewTree(root) {
const mapNode = (node) => {
return {
Expand All @@ -73,6 +71,7 @@ function useInterval(cb, ms) {

const app = createApp({
render() {
return h('GridLayout', h(ListViewComp))
return h(Comp)

const labelAt = (row, col) =>
Expand Down Expand Up @@ -274,9 +273,9 @@ const app = createApp({

onMounted(() => {
// dump the Node tree
setTimeout(() => {
console.log(JSON.stringify(dumpViewTree(app.$el), null, 2))
}, 1000)
// setTimeout(() => {
// console.log(JSON.stringify(dumpViewTree(app.$el), null, 2))
// }, 1000)
})

let inputText = ref('Text to change')
Expand Down
72 changes: 72 additions & 0 deletions packages/runtime/src/components/ListView.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { FunctionalComponent, h } from '@vue/runtime-core'
import { nodeOps, NSVRoot, render } from '@nativescript-vue/runtime'
import { ItemEventData } from '@nativescript/core/ui/list-view'
import { debug } from '@nativescript-vue/shared'

type ListViewProps = {
items: Array<string>
}
const NSV_LVR_REF = Symbol('NSV_LVR_REF')
const isListViewThingSymbol = Symbol()

interface ListViewRealized {
[isListViewThingSymbol]: true
container: NSVRoot | null
}

export const ListView: FunctionalComponent<ListViewProps> = (props, ctx) => {
const defaultKeyedTemplate = {
key: 'test',
createView(): ListViewRealized {
// debug('createView for test template')
return {
[isListViewThingSymbol]: true,
container: null,
}
},
}

return h('InternalListView', {
items: props.items,
itemTemplates: [defaultKeyedTemplate],
itemTemplateSelector: (item: any, index: any) => {
// debug('itemTemplateSelector', item, index)
return 'test'
},

onitemLoading(args: ItemEventData) {
// debug('item loading', args.view)

const item = props.items[args.index]

const getSlotVnode = (slotName: string) =>
ctx.slots[slotName]!({
item,
index: args.index,
even: !!(args.index % 2),
odd: !(args.index % 2),
})[0]
let view
if ((args.view as any)[isListViewThingSymbol]) {
debug('INITIAL LVR CREATING' + args.index, 'ListView')
// it is an initial render into this view holder
const lvr = (args.view as unknown) as ListViewRealized
// lets create an initial root
lvr.container = nodeOps.createRoot()
render(getSlotVnode('default'), lvr.container)

if (lvr.container.el) {
lvr.container.el.nativeView[NSV_LVR_REF] = lvr
view = lvr.container.el.nativeView
}
} else {
debug('LVR UPDATING' + args.index, 'ListView')
const lvr = (args.view as any)[NSV_LVR_REF] as ListViewRealized
render(getSlotVnode('default'), lvr.container!)
view = lvr.container!.el!.nativeView
}

args.view = view
},
})
}
1 change: 1 addition & 0 deletions packages/runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export { resolveComponent } from './resolveAssets'
// runtime directive helpers
export { vModel } from './directives/vModel'
export { vShow } from './directives/vShow'
export { ListView } from './components/ListView'

// Runtime components
export { ActionBar } from './components/ActionBar'
Expand Down
7 changes: 7 additions & 0 deletions packages/runtime/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,13 @@ if (!__TEST__) {
}
}
)
registerElement(
'InternalListView',
() => require('@nativescript/core').ListView,
{
viewFlags: NSVViewFlags.NO_CHILDREN
}
)
registerElement(
'Placeholder',
() => require('@nativescript/core').Placeholder,
Expand Down

0 comments on commit ff8b032

Please sign in to comment.