added listview

This commit is contained in:
hariroshan 2023-01-10 19:44:10 +05:30
parent 4caa8fa78d
commit 87b77c2ae0
10 changed files with 129 additions and 58 deletions

View File

@ -9,6 +9,7 @@ module Native exposing
, image
, label
, listPicker
, listView
, navigationButton
, progress
, scrollView
@ -151,3 +152,8 @@ actionItem =
navigationButton : List (Attribute msg) -> List (Html msg) -> Html msg
navigationButton =
buildElement "ns-navigation-button"
listView : List (Attribute msg) -> List (Html msg) -> Html msg
listView =
buildElement "ns-list-view"

View File

@ -1128,3 +1128,18 @@ iosSystemIcon =
androidSystemIcon : String -> Attribute msg
androidSystemIcon =
attribute "android.system-icon"
iosEstimatedRowHeight : String -> Attribute msg
iosEstimatedRowHeight =
attribute "ios-estimated-row-height"
rowHeight : String -> Attribute msg
rowHeight =
attribute "row-height"
separatorColor : String -> Attribute msg
separatorColor =
attribute "separator-color"

View File

@ -372,18 +372,14 @@ let actionItem =
),
]->Belt.Array.concatMany
let listView =
[
view,
["iosEstimatedRowHeight", "rowHeight", "separatorColor"]->Belt.Array.map(dashed),
]->Belt.Array.concatMany
// Js.log("****************************")
// [
// "hour",
// "iosPreferredDatePickerStyle",
// "maxHour",
// "maxMinute",
// "minHour",
// "minMinute",
// "minute",
// "minuteInterval",
// "time",
// ]
// ["iosEstimatedRowHeight", "rowHeight", "separatorColor"]
// ->Belt.Array.map(dashed)
// ->Belt.Array.forEach(prop =>
// Js.log(

View File

@ -140,13 +140,12 @@ module ListPicker = {
%%private(
@module("@nativescript/core") @new
external new: unit => Types.nativeObject = "ListPicker"
let setItems = (current: Types.htmlElement, data) => {
data->Types.setItems(current.items)
}
)
let setItems = (current: Types.htmlElement, data) => {
data->Types.setItems(current.items)
}
let tagName = "ns-list-picker"
/* TODO: Listen for changes in items property */
let handler: Types.handler = {
init: (. ()) => new(),
observedAttributes: Constants.listPicker,
@ -301,6 +300,28 @@ module WebView = {
let handler: Types.handler = buildHandler(new, Constants.webView, Helper.addView)
}
module ListView = {
%%private(
@module("@nativescript/core") @new
external new: unit => Types.nativeObject = "ListView"
)
let tagName = "ns-list-view"
let handler: Types.handler = {
init: (. ()) => new(),
observedAttributes: Constants.listView,
render: Js.Nullable.return((. current: Types.htmlElement, _) => {
current.data->Js.Nullable.toOption->Belt.Option.forEach(ListPicker.setItems(current))
Types.definePropertyInHtml(. current, "items", {set: ListPicker.setItems(current)})
Helper.addView(. current.parentElement, current)
}),
handlerKind: Types.Element,
update: NativescriptCore.update,
dispose: NativescriptCore.dispose,
addEventListener: NativescriptCore.addEventListener,
removeEventListener: NativescriptCore.removeEventListener,
}
}
let all: array<Types.customElement> = [
{
@ -403,4 +424,8 @@ let all: array<Types.customElement> = [
tagName: NavigationButton.tagName,
handler: NavigationButton.handler,
},
{
tagName: ListView.tagName,
handler: ListView.handler,
},
]

View File

@ -13,8 +13,11 @@ let rec assignDeep: (Obj.t, array<string>, int, 'a) => unit = (object, keys, i,
})
}
let setAttribute: (Obj.t, string, 'a) => unit = (object, key, value) => {
if !(key->Js.String2.includes(".")) {
let setAttribute: (Obj.t, string, string) => unit = (object, key, value) => {
if value->Js.String2.startsWith("{{") {
let expression = value->String.sub(2, value->String.length - 4)
object->Types.bindExpression({expression, targetProperty: key})
} else if !(key->Js.String2.includes(".")) {
Js.Dict.set(Obj.magic(object), key, value)
} else {
let keys = key->Js.String2.split(".")
@ -22,12 +25,6 @@ let setAttribute: (Obj.t, string, 'a) => unit = (object, key, value) => {
}
}
let init = (object, props) => {
Js.Dict.keys(Obj.magic(props))->Belt.Array.forEach(key =>
setAttribute(object, key, Js.Dict.unsafeGet(props, key))
)
}
let update = setAttribute
external typeOf: 'a => string = "typeof"
@ -35,7 +32,7 @@ external typeOf: 'a => string = "typeof"
let addView: (. Types.htmlElement, Types.htmlElement) => unit = %raw(`
function(parentElement, thisElement) {
if (parentElement.data == null) return
requestAnimationFrame(() => {
// requestAnimationFrame(() => {
const children = Array.from(parentElement.children)
const hasActionBar = children.some(x => x.tagName.toLowerCase() === "ns-action-bar")
const index = children.indexOf(thisElement)
@ -50,69 +47,80 @@ let addView: (. Types.htmlElement, Types.htmlElement) => unit = %raw(`
if (parentElement.data.constructor.name == "ActionBar")
return (parentElement.data.titleView = thisElement.data)
if (parentElement.data.constructor.name == "ListView") {
parentElement.data.itemTemplate =
function() {
const div = document.createElement("div")
const cloned = thisElement.cloneAll()
div.appendChild(cloned)
cloned.manualRender()
return cloned.data;
}
return
}
return (parentElement.data.content = thisElement.data)
})
// })
}
`)
let addFormattedText: (. Types.htmlElement, Types.htmlElement) => unit = %raw(`
function(parentElement, thisElement) {
if (parentElement.data == null) return
requestAnimationFrame(() => {
// requestAnimationFrame(() => {
const children = Array.from(parentElement.children)
const index = children.indexOf(thisElement)
parentElement.data.formattedText = thisElement.data
})
// })
}
`)
let addSpan: (. Types.htmlElement, Types.htmlElement) => unit = %raw(`
function(parentElement, thisElement) {
if (parentElement.data == null) return
requestAnimationFrame(() => {
// requestAnimationFrame(() => {
const children = Array.from(parentElement.children)
const index = children.indexOf(thisElement)
parentElement.data.spans.push(thisElement.data)
})
// })
}
`)
let addActionBar: (. Types.htmlElement, Types.htmlElement) => unit = %raw(`
function(parentElement, thisElement) {
if (parentElement.data == null) return
requestAnimationFrame(() => {
// requestAnimationFrame(() => {
parentElement.data.actionBar = thisElement.data
})
// })
}
`)
let addActionItem: (. Types.htmlElement, Types.htmlElement) => unit = %raw(`
function(parentElement, thisElement) {
if (parentElement.data == null) return
requestAnimationFrame(() => {
// requestAnimationFrame(() => {
parentElement.data.actionItems.addItem(thisElement.data)
})
// })
}
`)
let addNavigationButton: (. Types.htmlElement, Types.htmlElement) => unit = %raw(`
function(parentElement, thisElement) {
if (parentElement.data == null) return
requestAnimationFrame(() => {
console.log(thisElement.data, parentElement.data.navigationButton)
// requestAnimationFrame(() => {
parentElement.data.navigationButton = thisElement.data
})
// })
}
`)
let addItems: (. Types.htmlElement, Types.htmlElement) => unit = %raw(`
function(parentElement, thisElement) {
if (parentElement.data == null) return
requestAnimationFrame(() => {
// requestAnimationFrame(() => {
if (parentElement.data.items == null)
return (parentElement.data.items = [thisElement.data])
parentElement.data.items.push(thisElement.data)
})
// })
}
`)

View File

@ -35,10 +35,6 @@ module Page = {
%%private(
@module("@nativescript/core") @new
external new: unit => Types.nativeObject = "Page"
let getData = (children, idx) =>
children
->Belt.Array.get(idx)
->Belt.Option.flatMap((x: Types.htmlElement) => x.data->Js.Nullable.toOption)
)
let tagName = "ns-page"
@ -46,7 +42,7 @@ module Page = {
init: (. ()) => new(),
observedAttributes: Constants.pageBase,
update: NativescriptCore.update,
render: Js.Nullable.return((. current: Types.htmlElement, nativeObject) => {
render: Js.Nullable.return((. current: Types.htmlElement, _) => {
Types.requestAnimationFrame(._ => {
current.parentElement.handler
->Js.Nullable.toOption

View File

@ -1,12 +1,13 @@
type event
type constructorRec = {name: string}
type bindingOptions = {expression: string, targetProperty: string}
type rec nativeObject = {
on: (. event, event => unit) => unit,
off: (. event, event => unit) => unit,
destroyNode: (. unit) => unit,
insertChild: Js.Nullable.t<(. nativeObject, int) => unit>,
constructor: constructorRec,
constructor: constructorRec
}
type constructor = {
@ -30,6 +31,9 @@ type navigationConfig = {create: unit => nativeObject}
@send
external navigate: (nativeObject, navigationConfig) => unit = "navigate"
@send
external bindExpression: (Obj.t, bindingOptions) => unit = "bind"
type rec handler = {
init: (. unit) => nativeObject,
observedAttributes: array<string>,

View File

@ -1,4 +1,3 @@
export const withCustomElements = (UIElement, handler) =>
class extends UIElement {
constructor() {
@ -19,7 +18,6 @@ export const withCustomElements = (UIElement, handler) =>
this.handler.render(this, this.data)
}
console.log(`${this.tagName} connected`)
}
disconnectedCallback() {
this.handler.dispose(this.data)
@ -33,4 +31,23 @@ export const withCustomElements = (UIElement, handler) =>
super.removeEventListener(event, callback);
this.handler.removeEventListener(this.data, event, callback);
}
cloneAll() {
const tag = document.createElement(this.tagName)
const children =
Array.from(this.children).forEach(child => tag.appendChild(child.cloneAll()))
Object.keys(this.attributes).forEach(key => {
const attr = this.attributes[key]
if (attr && attr.name !== undefined && attr.value !== undefined) {
tag.setAttribute(attr.name, attr.value)
}
})
return tag
}
manualRender() {
Array.from(this.children).forEach(child =>
child.manualRender()
)
this.handler.render(this, this.data)
}
}

View File

@ -6,7 +6,6 @@
"scripts": {
"res:build": "rescript",
"res:dev": "rescript build -w",
"build:elm": "elm make src/Main.elm --output ./dist/elm.js",
"run:ios": "ns run ios",
"build:webpack": "webpack --mode development"
},

View File

@ -223,18 +223,23 @@ detailsPage model =
Page.pageWithActionBar []
-- Event.on "navigatedTo" (D.succeed Destory)
-- [ Native.actionBar []
[ Native.actionBar [ NA.flat "true", NA.title "Home" ]
[]
, Layout.asElement <|
Layout.rootLayout []
[ Native.label
[ NA.text "Elm Counter"
, NA.textAlignment "center"
, NA.color "#610fc8"
, NA.fontSize "40"
[ Native.listView
[ E.list E.string
[ "2022", "2021", "2020" ]
|> NA.items
, NA.separatorColor "orange"
, NA.class "list-group"
]
[ Layout.asElement <|
Layout.stackLayout [ NA.class "list-group-item" ]
[ Native.label [ NA.text "{{ $value }}", NA.color "green" ] []
]
[]
]
]
-- Native.actionBar [ NA.flat "true", NA.title "Home" ]
-- []
-- , Layout.asElement <|
--
]