diff --git a/src/components/Template.svelte b/src/components/Template.svelte
new file mode 100644
index 00000000..c4c41ae2
--- /dev/null
+++ b/src/components/Template.svelte
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/index.ts b/src/components/index.ts
index 5ebbe57c..487d7965 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -1,3 +1,3 @@
export { AsComponent } from "./AsComponent";
-
+export { default as Template } from "./Template.svelte";
diff --git a/src/dom/SvelteElements.ts b/src/dom/SvelteElements.ts
deleted file mode 100644
index 6d3218ac..00000000
--- a/src/dom/SvelteElements.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { registerCustomElementNode, ElementNode } from "./basicdom";
-import HeadElement from "./HeadElement";
-import StyleElement from "./StyleElement";
-
-// Dom elements that svelte expects to be able to create or use.
-
-export function registerSvelteElements() {
- registerCustomElementNode('head', () => new HeadElement());
- registerCustomElementNode('style', () => new StyleElement())
- registerCustomElementNode('fragment', () => new ElementNode('fragment'))
-}
\ No newline at end of file
diff --git a/src/dom/basicdom/element-registry.ts b/src/dom/basicdom/element-registry.ts
index 53708b2a..a8112990 100644
--- a/src/dom/basicdom/element-registry.ts
+++ b/src/dom/basicdom/element-registry.ts
@@ -1,10 +1,8 @@
import { normalizeElementName } from './ViewNode'
import ElementNode from './ElementNode';
-export type NodeResolver = () => ElementNode;
-
interface ElementEntry {
- resolver: NodeResolver,
+ resolver: () => ElementNode,
}
const elementMap: { [index: string]: ElementEntry } = {}
@@ -17,7 +15,7 @@ function registerElementResolver(elementName: string, entry: ElementEntry) {
elementMap[normalizedName] = entry
}
-export function registerCustomElementNode(elementName: string, resolver: NodeResolver) {
+export function registerElement(elementName: string, resolver: () => ElementNode) {
registerElementResolver(elementName, { resolver: resolver })
}
diff --git a/src/dom/basicdom/index.ts b/src/dom/basicdom/index.ts
index 7728065f..533ea685 100644
--- a/src/dom/basicdom/index.ts
+++ b/src/dom/basicdom/index.ts
@@ -4,4 +4,4 @@ export { default as CommentNode } from "./CommentNode"
export { default as PropertyNode } from "./PropertyNode"
export { default as ViewNode, normalizeElementName } from "./ViewNode"
export { default as TextNode } from "./TextNode"
-export { registerCustomElementNode, createElement } from "./element-registry"
\ No newline at end of file
+export { registerElement, createElement } from "./element-registry"
\ No newline at end of file
diff --git a/src/dom/index.ts b/src/dom/index.ts
index a3e4fbc9..3aea75e4 100644
--- a/src/dom/index.ts
+++ b/src/dom/index.ts
@@ -1,11 +1,12 @@
-import { registerSvelteElements } from './SvelteElements'
-import { registerNativeElements } from './NativescriptElements'
-import SvelteNativeDocument from './SvelteNativeDocument'
-import NativeElementNode from './NativeElementNode'
-export { default as FrameElement } from "./FrameElement"
-export { default as SvelteNativeDocument } from './SvelteNativeDocument'
-export { default as NativeElementNode } from './NativeElementNode'
-export { registerCustomElementNode, createElement, ViewNode } from './basicdom'
+import { registerSvelteElements } from './svelte-elements'
+import { registerNativeElements } from './nativescript-elements'
+import SvelteNativeDocument from './svelte/SvelteNativeDocument'
+import NativeElementNode from './native/NativeElementNode'
+
+export { default as FrameElement } from "./native/FrameElement"
+export { default as SvelteNativeDocument } from './svelte/SvelteNativeDocument'
+export { default as NativeElementNode } from './native/NativeElementNode'
+export { registerElement, createElement, ViewNode } from './basicdom'
export { navigate, goBack, showModal, NavigationOptions, BackNavigationOptions } from './navigation'
diff --git a/src/dom/FrameElement.ts b/src/dom/native/FrameElement.ts
similarity index 95%
rename from src/dom/FrameElement.ts
rename to src/dom/native/FrameElement.ts
index 5f2c63d5..11ae08c7 100644
--- a/src/dom/FrameElement.ts
+++ b/src/dom/native/FrameElement.ts
@@ -1,4 +1,4 @@
-import { createElement, ViewNode } from "./basicdom";
+import { createElement, ViewNode } from "../basicdom";
import { Frame } from 'tns-core-modules/ui/frame'
import NativeElementNode from "./NativeElementNode";
import PageElement from "./PageElement";
diff --git a/src/dom/native/ListViewElement.ts b/src/dom/native/ListViewElement.ts
new file mode 100644
index 00000000..45970533
--- /dev/null
+++ b/src/dom/native/ListViewElement.ts
@@ -0,0 +1,62 @@
+import { ListView, ItemEventData, ItemsSource } from 'tns-core-modules/ui/list-view'
+import NativeElementNode from "./NativeElementNode";
+import TemplateElement from '../svelte/TemplateElement';
+import { createElement } from '../basicdom';
+
+
+export default class ListViewElement extends NativeElementNode {
+ constructor() {
+ super('listview', ListView, null);
+
+ this.nativeView.on(ListView.itemLoadingEvent, (args) => { this.updateListItem(args as ItemEventData) });
+ }
+
+ updateListItem(args: ItemEventData) {
+ let item;
+ let listView = this.nativeView;
+ let items = listView.items;
+
+ if (args.index >= items.length) {
+ console.log("Got request for item at index that didn't exists", items, args.index)
+ return;
+ }
+
+ if ((items as ItemsSource).getItem) {
+ item = (items as ItemsSource).getItem(args.index);
+ } else {
+ item = (items as any)[args.index]
+ }
+
+ if (!args.view || !(args.view as any).__SvelteComponent__) {
+ console.log("creating view for ", args.index, item.name)
+ let wrapper = createElement('StackLayout') as NativeElementNode;
+ let componentInstance = new (this.itemTemplateComponent)({
+ target: wrapper,
+ props: {
+ item
+ }
+ });
+
+ let nativeEl = wrapper.nativeView;
+ (nativeEl as any).__SvelteComponent__ = componentInstance;
+ args.view = nativeEl;
+ } else {
+ let componentInstance: SvelteComponent = (args.view as any).__SvelteComponent__
+ console.log("updating view for ", args.index, item.name, args.view)
+ componentInstance.$set({ item })
+ }
+ }
+
+ get itemTemplateComponent(): typeof SvelteComponent {
+ const templateNode = this.childNodes.find(x => x instanceof TemplateElement) as TemplateElement
+ return templateNode ? templateNode.component : null;
+ }
+
+ get nativeView(): ListView {
+ return super.nativeView as ListView
+ }
+
+ set nativeView(view: ListView) {
+ super.nativeView = view
+ }
+}
\ No newline at end of file
diff --git a/src/dom/NativeElementNode.ts b/src/dom/native/NativeElementNode.ts
similarity index 99%
rename from src/dom/NativeElementNode.ts
rename to src/dom/native/NativeElementNode.ts
index 618a26c3..d1f7bfe0 100644
--- a/src/dom/NativeElementNode.ts
+++ b/src/dom/native/NativeElementNode.ts
@@ -1,9 +1,9 @@
-import ViewNode from './basicdom/ViewNode'
+import ViewNode from '../basicdom/ViewNode'
import { KeyframeAnimation } from 'tns-core-modules/ui/animation/keyframe-animation';
import { CssAnimationParser } from 'tns-core-modules/ui/styling/css-animation-parser';
import { Page, View, isAndroid, isIOS, EventData, ContentView } from 'tns-core-modules/ui/page/page';
-import ElementNode from './basicdom/ElementNode';
+import ElementNode from '../basicdom/ElementNode';
import { LayoutBase } from 'tns-core-modules/ui/layouts/layout-base';
interface IStyleProxy {
diff --git a/src/dom/PageElement.ts b/src/dom/native/PageElement.ts
similarity index 89%
rename from src/dom/PageElement.ts
rename to src/dom/native/PageElement.ts
index 03b936e1..5ad870ac 100644
--- a/src/dom/PageElement.ts
+++ b/src/dom/native/PageElement.ts
@@ -1,4 +1,3 @@
-import { createElement } from "./basicdom";
import { Page } from 'tns-core-modules/ui/page'
import NativeElementNode from "./NativeElementNode";
diff --git a/src/dom/NativescriptElements.ts b/src/dom/nativescript-elements.ts
similarity index 59%
rename from src/dom/NativescriptElements.ts
rename to src/dom/nativescript-elements.ts
index 8270dbff..b77a78d0 100644
--- a/src/dom/NativescriptElements.ts
+++ b/src/dom/nativescript-elements.ts
@@ -1,42 +1,37 @@
-import { registerCustomElementNode } from './basicdom'
-import NativeElementNode, { ComponentMeta } from './NativeElementNode'
+import { registerElement } from './basicdom'
+import NativeElementNode, { ComponentMeta } from './native/NativeElementNode'
import { View } from 'tns-core-modules/ui/page/page'
-import FrameElement from './FrameElement';
-import PageElement from './PageElement';
+import FrameElement from './native/FrameElement';
+import PageElement from './native/PageElement';
+import ListViewElement from './native/ListViewElement';
-export function registerElement(elementName: string, resolver: () => typeof View, meta: ComponentMeta = null) {
- registerCustomElementNode(elementName, () => new NativeElementNode(elementName, resolver(), meta));
+export function registerNativeElement(elementName: string, resolver: () => typeof View, meta: ComponentMeta = null) {
+ registerElement(elementName, () => new NativeElementNode(elementName, resolver(), meta));
}
export function registerNativeElements() {
- registerElement(
+ registerNativeElement(
'ActionBar',
() => require('tns-core-modules/ui/action-bar').ActionBar
)
- registerElement(
+ registerNativeElement(
'ActionItem',
() => require('tns-core-modules/ui/action-bar').ActionItem
)
-
- registerElement(
- 'ListView',
- () => require('tns-core-modules/ui/list-view').ListView
- )
-
- registerElement(
+ registerNativeElement(
'NavigationButton',
() => require('tns-core-modules/ui/action-bar').NavigationButton
)
- registerElement(
+ registerNativeElement(
'TabView',
() => require('tns-core-modules/ui/tab-view').TabView
)
- registerElement(
+ registerNativeElement(
'TabViewItem',
() => require('tns-core-modules/ui/tab-view').TabViewItem
)
@@ -45,54 +40,54 @@ export function registerNativeElements() {
// NS components which uses the automatic registerElement Vue wrapper
// as they do not need any special logic
- registerElement('Label', () => require('tns-core-modules/ui/label').Label)
+ registerNativeElement('Label', () => require('tns-core-modules/ui/label').Label)
- registerElement(
+ registerNativeElement(
'DatePicker',
() => require('tns-core-modules/ui/date-picker').DatePicker,
)
- registerElement(
+ registerNativeElement(
'AbsoluteLayout',
() => require('tns-core-modules/ui/layouts/absolute-layout').AbsoluteLayout
)
- registerElement(
+ registerNativeElement(
'ActivityIndicator',
() => require('tns-core-modules/ui/activity-indicator').ActivityIndicator
)
- registerElement('Border', () => require('tns-core-modules/ui/border').Border)
- registerElement('Button', () => require('tns-core-modules/ui/button').Button)
- registerElement(
+ registerNativeElement('Border', () => require('tns-core-modules/ui/border').Border)
+ registerNativeElement('Button', () => require('tns-core-modules/ui/button').Button)
+ registerNativeElement(
'ContentView',
() => require('tns-core-modules/ui/content-view').ContentView
)
- registerElement(
+ registerNativeElement(
'DockLayout',
() => require('tns-core-modules/ui/layouts/dock-layout').DockLayout
)
- registerElement(
+ registerNativeElement(
'GridLayout',
() => require('tns-core-modules/ui/layouts/grid-layout').GridLayout
)
- registerElement(
+ registerNativeElement(
'HtmlView',
() => require('tns-core-modules/ui/html-view').HtmlView
)
- registerElement('Image', () => require('tns-core-modules/ui/image').Image)
- registerElement(
+ registerNativeElement('Image', () => require('tns-core-modules/ui/image').Image)
+ registerNativeElement(
'ListPicker',
() => require('tns-core-modules/ui/list-picker').ListPicker,
)
- registerElement(
+ registerNativeElement(
'Placeholder',
() => require('tns-core-modules/ui/placeholder').Placeholder
)
- registerElement(
+ registerNativeElement(
'Progress',
() => require('tns-core-modules/ui/progress').Progress,
)
- registerElement(
+ registerNativeElement(
'ProxyViewContainer',
() => require('tns-core-modules/ui/proxy-view-container').ProxyViewContainer
)
@@ -100,69 +95,63 @@ export function registerNativeElements() {
// 'Repeater',
// () => require('tns-core-modules/ui/repeater').Repeater
// )
- registerElement(
+ registerNativeElement(
'ScrollView',
() => require('tns-core-modules/ui/scroll-view').ScrollView
)
- registerElement(
+ registerNativeElement(
'SearchBar',
() => require('tns-core-modules/ui/search-bar').SearchBar,
)
- registerElement(
+ registerNativeElement(
'SegmentedBar',
() => require('tns-core-modules/ui/segmented-bar').SegmentedBar,
)
- registerElement(
+ registerNativeElement(
'SegmentedBarItem',
() => require('tns-core-modules/ui/segmented-bar').SegmentedBarItem
)
- registerElement('Slider', () => require('tns-core-modules/ui/slider').Slider)
- registerElement(
+ registerNativeElement('Slider', () => require('tns-core-modules/ui/slider').Slider)
+ registerNativeElement(
'StackLayout',
() => require('tns-core-modules/ui/layouts/stack-layout').StackLayout
)
- registerElement(
+ registerNativeElement(
'FlexboxLayout',
() => require('tns-core-modules/ui/layouts/flexbox-layout').FlexboxLayout
)
- registerElement('Switch', () => require('tns-core-modules/ui/switch').Switch)
+ registerNativeElement('Switch', () => require('tns-core-modules/ui/switch').Switch)
- registerElement(
+ registerNativeElement(
'TextField',
() => require('tns-core-modules/ui/text-field').TextField,
)
- registerElement(
+ registerNativeElement(
'TextView',
() => require('tns-core-modules/ui/text-view').TextView,
)
- registerElement(
+ registerNativeElement(
'TimePicker',
() => require('tns-core-modules/ui/time-picker').TimePicker,
)
- registerElement(
+ registerNativeElement(
'WebView',
() => require('tns-core-modules/ui/web-view').WebView
)
- registerElement(
+ registerNativeElement(
'WrapLayout',
() => require('tns-core-modules/ui/layouts/wrap-layout').WrapLayout
)
- registerElement(
+ registerNativeElement(
'FormattedString',
() => require('tns-core-modules/text/formatted-string').FormattedString
)
- registerElement('Span', () => require('tns-core-modules/text/span').Span)
-
- /*
- registerElement('Frame', () => require('tns-core-modules/ui/frame').Frame, {
- insertChild() {
- //dont bother
- }
- })
- */
- registerCustomElementNode('Frame', () => new FrameElement())
- registerCustomElementNode('Page', () => new PageElement())
+ registerNativeElement('Span', () => require('tns-core-modules/text/span').Span)
+
+ registerElement('Frame', () => new FrameElement())
+ registerElement('Page', () => new PageElement())
+ registerElement('ListView', () => new ListViewElement())
}
\ No newline at end of file
diff --git a/src/dom/navigation.ts b/src/dom/navigation.ts
index ca8eea7d..f4a7124c 100644
--- a/src/dom/navigation.ts
+++ b/src/dom/navigation.ts
@@ -1,8 +1,8 @@
import { topmost, NavigationTransition, Frame, getFrameById, Page, BackstackEntry, ViewBase } from "tns-core-modules/ui/frame/frame";
-import FrameElement from "./FrameElement";
+import FrameElement from "./native/FrameElement";
import { createElement } from "./basicdom";
-import PageElement from "./PageElement";
-import NativeElementNode from "./NativeElementNode";
+import PageElement from "./native/PageElement";
+import NativeElementNode from "./native/NativeElementNode";
export type FrameSpec = Frame | FrameElement | string
export type PageSpec = typeof SvelteComponent;
diff --git a/src/dom/svelte-elements.ts b/src/dom/svelte-elements.ts
new file mode 100644
index 00000000..12d5ab7d
--- /dev/null
+++ b/src/dom/svelte-elements.ts
@@ -0,0 +1,14 @@
+import { registerElement, ElementNode } from "./basicdom";
+import HeadElement from "./svelte/HeadElement";
+import StyleElement from "./svelte/StyleElement";
+import TemplateElement from "./svelte/TemplateElement";
+
+// Dom elements that svelte expects to be able to create or use.
+// or custom additions to make life easier
+
+export function registerSvelteElements() {
+ registerElement('head', () => new HeadElement());
+ registerElement('style', () => new StyleElement());
+ registerElement('fragment', () => new ElementNode('fragment'));
+ registerElement('template', () => new TemplateElement());
+}
\ No newline at end of file
diff --git a/src/dom/HeadElement.ts b/src/dom/svelte/HeadElement.ts
similarity index 89%
rename from src/dom/HeadElement.ts
rename to src/dom/svelte/HeadElement.ts
index de40688d..181e005a 100644
--- a/src/dom/HeadElement.ts
+++ b/src/dom/svelte/HeadElement.ts
@@ -1,5 +1,4 @@
-import { ElementNode, ViewNode, normalizeElementName } from "./basicdom";
-import NativeElementNode from "./NativeElementNode";
+import { ElementNode, ViewNode } from "../basicdom";
import StyleElement from "./StyleElement";
import { topmost } from "tns-core-modules/ui/frame"
diff --git a/src/dom/StyleElement.ts b/src/dom/svelte/StyleElement.ts
similarity index 97%
rename from src/dom/StyleElement.ts
rename to src/dom/svelte/StyleElement.ts
index 38c15bc6..bac9e1f8 100644
--- a/src/dom/StyleElement.ts
+++ b/src/dom/svelte/StyleElement.ts
@@ -1,4 +1,4 @@
-import { ElementNode } from './basicdom'
+import { ElementNode } from '../basicdom'
import { StyleScope } from 'tns-core-modules/ui/styling/style-scope'
import { topmost, Frame } from 'tns-core-modules/ui/frame'
diff --git a/src/dom/SvelteNativeDocument.ts b/src/dom/svelte/SvelteNativeDocument.ts
similarity index 97%
rename from src/dom/SvelteNativeDocument.ts
rename to src/dom/svelte/SvelteNativeDocument.ts
index 6e484b6b..86c99776 100644
--- a/src/dom/SvelteNativeDocument.ts
+++ b/src/dom/svelte/SvelteNativeDocument.ts
@@ -1,5 +1,5 @@
-import { DocumentNode, ElementNode, createElement, TextNode } from './basicdom';
+import { DocumentNode, ElementNode, createElement, TextNode } from '../basicdom';
export default class SvelteNativeDocument extends DocumentNode {
head: ElementNode;
diff --git a/src/dom/svelte/TemplateElement.ts b/src/dom/svelte/TemplateElement.ts
new file mode 100644
index 00000000..1c08f7ba
--- /dev/null
+++ b/src/dom/svelte/TemplateElement.ts
@@ -0,0 +1,15 @@
+import { ElementNode } from '../basicdom';
+
+export default class TemplateElement extends ElementNode {
+ constructor() {
+ super('template');
+ }
+
+ set component(value: typeof SvelteComponent) {
+ this.setAttribute('component', value)
+ }
+
+ get component(): typeof SvelteComponent {
+ return this.getAttribute('component')
+ }
+}
\ No newline at end of file
diff --git a/src/dom/style-scope.d.ts b/src/dom/svelte/style-scope.d.ts
similarity index 100%
rename from src/dom/style-scope.d.ts
rename to src/dom/svelte/style-scope.d.ts