From 37af4af16c5417f3cceae8ef6aa92932a367757b Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Tue, 10 Mar 2026 16:15:20 +0100 Subject: [PATCH 1/5] DOM Node APIs --- src/elements/NativeElement.bs.js | 3 + src/elements/NativeElement.res | 6 +- src/types/DOMAPI.bs.js | 61 +++++++++++ src/types/DOMAPI.res | 180 +++++++++++++++++++++++++++++++ 4 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 src/types/DOMAPI.bs.js create mode 100644 src/types/DOMAPI.res diff --git a/src/elements/NativeElement.bs.js b/src/elements/NativeElement.bs.js index b690878ca..37a7b7d24 100644 --- a/src/elements/NativeElement.bs.js +++ b/src/elements/NativeElement.bs.js @@ -1,7 +1,10 @@ 'use strict'; +var DOMAPI$ReactNative = require("../types/DOMAPI.bs.js"); var NativeMethods$ReactNative = require("./NativeMethods.bs.js"); NativeMethods$ReactNative.Make({}); +DOMAPI$ReactNative.$$Element.Impl({}); + /* Not a pure module */ diff --git a/src/elements/NativeElement.res b/src/elements/NativeElement.res index 620b9a2fc..8816d08d0 100644 --- a/src/elements/NativeElement.res +++ b/src/elements/NativeElement.res @@ -1,6 +1,10 @@ -type element +type element = DOMAPI.element type ref = Ref.t include NativeMethods.Make({ type t = element }) + +include DOMAPI.Element.Impl({ + type t = element +}) diff --git a/src/types/DOMAPI.bs.js b/src/types/DOMAPI.bs.js new file mode 100644 index 000000000..d63f5fff3 --- /dev/null +++ b/src/types/DOMAPI.bs.js @@ -0,0 +1,61 @@ +'use strict'; + + +var $$NodeList = {}; + +var $$HTMLCollection = {}; + +function Impl(T) { + return {}; +} + +var $$Node = { + Impl: Impl +}; + +function Impl$1(T) { + return {}; +} + +var $$Element = { + Impl: Impl$1 +}; + +var $$Document = {}; + +var $$Text = {}; + +function findNodeType(node) { + switch (node.nodeType) { + case 1 : + return { + TAG: "Element", + _0: node + }; + case 3 : + return { + TAG: "Text", + _0: node + }; + case 9 : + return { + TAG: "Document", + _0: node + }; + default: + return "Unknown"; + } +} + +var NodeTypeHelper = { + findNodeType: findNodeType +}; + +exports.$$NodeList = $$NodeList; +exports.$$HTMLCollection = $$HTMLCollection; +exports.$$Node = $$Node; +exports.$$Element = $$Element; +exports.$$Document = $$Document; +exports.$$Text = $$Text; +exports.NodeTypeHelper = NodeTypeHelper; +/* No side effect */ diff --git a/src/types/DOMAPI.res b/src/types/DOMAPI.res new file mode 100644 index 000000000..099313232 --- /dev/null +++ b/src/types/DOMAPI.res @@ -0,0 +1,180 @@ +@@warning("-30") + +type nodeList<'node> = {length: int} +type htmlCollection<'element> = {length: int} + +type readOnlyNode<'node, 'document, 'element> = { + // Node + childNodes: nodeList<'node>, + firstChild: Js.Null.t<'node>, + isConnected: bool, + lastChild: Js.Null.t<'node>, + nextSibling: Js.Null.t<'node>, + nodeType: int, + nodeName: string, + nodeValue: Js.Null.t, + ownerDocument: Js.Null.t<'document>, + parentElement: Js.Null.t<'element>, + parentNode: Js.Null.t<'node>, + previousSibling: Js.Null.t<'node>, + textContent: string, +} + +type rec node = { + ...readOnlyNode, +} + +and element = { + // Node + ...readOnlyNode, + // Element + childElementCount: int, + children: htmlCollection, + clientHeight: int, + clientLeft: int, + clientTop: int, + clientWidth: int, + firstElementChild: Js.Null.t, + id: string, + lastElementChild: Js.Null.t, + nextElementSibling: Js.Null.t, + previousElementSibling: Js.Null.t, + scrollHeight: int, + scrollLeft: int, + scrollTop: int, + scrollWidth: int, + tagName: string, + // HTMLElement + offsetHeight: int, + offsetLeft: int, + offsetTop: int, + offsetWidth: int, + offsetParent: Js.Null.t, +} + +and text = { + // Node + ...readOnlyNode, + // CharacterData + data: string, + length: int, + nextElementSibling: Js.Null.t, + previousElementSibling: Js.Null.t, +} + +and document = { + ...readOnlyNode, + childElementCount: int, + children: htmlCollection, + documentElement: element, + firstElementChild: Js.Null.t, + lastElementChild: Js.Null.t, +} + +module NodeList = { + @send + external item: (nodeList<'node>, int) => Js.Null.t<'node> = "item" +} + +module HTMLCollection = { + @send + external item: (htmlCollection<'element>, int) => Js.Null.t<'element> = "item" + + @send + external namedItem: (htmlCollection<'element>, string) => Js.Null.t<'element> = "namedItem" +} + +module Node = { + module Impl = ( + T: { + type t + }, + ) => { + external asNode: T.t => node = "%identity" + + @send + external compareDocumentPosition: (T.t, node) => int = "compareDocumentPosition" + @send external contains: (T.t, node) => bool = "contains" + @send external getRootNode: T.t => T.t = "getRootNode" + @send external hasChildNodes: T.t => bool = "hasChildNodes" + } + + include Impl({ + type t = node + }) +} + +module Element = { + module Impl = ( + T: { + type t + }, + ) => { + include Node.Impl({ + type t = T.t + }) + + @send + external getBoundingClientRect: T.t => ReactNative.Rect.t = "getBoundingClientRect" + @send + external hasPointerCapture: (T.t, int) => bool = "hasPointerCapture" + @send + external releasePointerCapture: (T.t, int) => unit = "releasePointerCapture" + @send + external setPointerCapture: (T.t, int) => unit = "setPointerCapture" + @send external focus: T.t => unit = "focus" + @send external blur: T.t => unit = "blur" + + @send external setNativeProps: (T.t, {..}) => unit = "setNativeProps" + } + + include Impl({ + type t = element + }) +} + +module Document = { + include Node.Impl({ + type t = element + }) + + @send external getElementById: (document, string) => element = "getElementById" +} + +module Text = { + include Node.Impl({ + type t = element + }) + + @send external substringData: (text, ~offset: int, ~count: int) => unit = "substringData" +} + +module NodeTypeHelper = { + /* + Helper for handle NodeType + Waiting for this issue : + https://github.com/rescript-lang/rescript/issues/8280 + to use this type for node instead + + @tag("nodeType") + type rec node = + | @as(1) Element(element) + | @as(3) Text(text) + | @as(9) Document(document) + + and remove this helper + */ + type t = + | Element(element) + | Text(text) + | Document(document) + | Unknown + + let findNodeType = (node: node) => + switch node { + | {nodeType: 1} => Element(node->Obj.magic) + | {nodeType: 3} => Text(node->Obj.magic) + | {nodeType: 9} => Document(node->Obj.magic) + | _ => Unknown + } +} From 589652e01232deab6b5225af532bcf2e5b1c9528 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Tue, 10 Mar 2026 17:08:21 +0100 Subject: [PATCH 2/5] fix ci --- src/types/DOMAPI.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/DOMAPI.res b/src/types/DOMAPI.res index 099313232..f2afc3f40 100644 --- a/src/types/DOMAPI.res +++ b/src/types/DOMAPI.res @@ -115,7 +115,7 @@ module Element = { }) @send - external getBoundingClientRect: T.t => ReactNative.Rect.t = "getBoundingClientRect" + external getBoundingClientRect: T.t => Rect.t = "getBoundingClientRect" @send external hasPointerCapture: (T.t, int) => bool = "hasPointerCapture" @send From ea50e5e47728db32f6ff0f9398dfdcc027190a8a Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Wed, 18 Mar 2026 11:42:08 +0100 Subject: [PATCH 3/5] fix type and rename NodeType --- src/types/DOMAPI.bs.js | 8 ++++---- src/types/DOMAPI.res | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/types/DOMAPI.bs.js b/src/types/DOMAPI.bs.js index d63f5fff3..203971287 100644 --- a/src/types/DOMAPI.bs.js +++ b/src/types/DOMAPI.bs.js @@ -25,7 +25,7 @@ var $$Document = {}; var $$Text = {}; -function findNodeType(node) { +function classify(node) { switch (node.nodeType) { case 1 : return { @@ -47,8 +47,8 @@ function findNodeType(node) { } } -var NodeTypeHelper = { - findNodeType: findNodeType +var NodeType = { + classify: classify }; exports.$$NodeList = $$NodeList; @@ -57,5 +57,5 @@ exports.$$Node = $$Node; exports.$$Element = $$Element; exports.$$Document = $$Document; exports.$$Text = $$Text; -exports.NodeTypeHelper = NodeTypeHelper; +exports.NodeType = NodeType; /* No side effect */ diff --git a/src/types/DOMAPI.res b/src/types/DOMAPI.res index f2afc3f40..5b00aa8f2 100644 --- a/src/types/DOMAPI.res +++ b/src/types/DOMAPI.res @@ -135,7 +135,7 @@ module Element = { module Document = { include Node.Impl({ - type t = element + type t = document }) @send external getElementById: (document, string) => element = "getElementById" @@ -143,13 +143,13 @@ module Document = { module Text = { include Node.Impl({ - type t = element + type t = text }) @send external substringData: (text, ~offset: int, ~count: int) => unit = "substringData" } -module NodeTypeHelper = { +module NodeType = { /* Helper for handle NodeType Waiting for this issue : @@ -170,7 +170,7 @@ module NodeTypeHelper = { | Document(document) | Unknown - let findNodeType = (node: node) => + let classify = (node: node) => switch node { | {nodeType: 1} => Element(node->Obj.magic) | {nodeType: 3} => Text(node->Obj.magic) From 951414af43ccd1f49a291f2623b9d619eeadbab2 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Wed, 18 Mar 2026 20:14:20 +0100 Subject: [PATCH 4/5] codex review --- src/types/DOMAPI.res | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/types/DOMAPI.res b/src/types/DOMAPI.res index 5b00aa8f2..2f62e6bb1 100644 --- a/src/types/DOMAPI.res +++ b/src/types/DOMAPI.res @@ -95,7 +95,7 @@ module Node = { @send external compareDocumentPosition: (T.t, node) => int = "compareDocumentPosition" @send external contains: (T.t, node) => bool = "contains" - @send external getRootNode: T.t => T.t = "getRootNode" + @send external getRootNode: T.t => node = "getRootNode" @send external hasChildNodes: T.t => bool = "hasChildNodes" } @@ -138,7 +138,7 @@ module Document = { type t = document }) - @send external getElementById: (document, string) => element = "getElementById" + @send external getElementById: (document, string) => Js.Null.t = "getElementById" } module Text = { @@ -146,7 +146,7 @@ module Text = { type t = text }) - @send external substringData: (text, ~offset: int, ~count: int) => unit = "substringData" + @send external substringData: (text, ~offset: int, ~count: int) => string = "substringData" } module NodeType = { From 7346c82edd861e8595038a46e38a20cfbd9436e0 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Sat, 4 Apr 2026 17:13:51 +0200 Subject: [PATCH 5/5] dom api phantom-specialized type for element --- src/apis/AccessibilityInfo.res | 6 ++- src/components/ActivityIndicator.bs.js | 3 +- src/components/ActivityIndicator.res | 8 +++- src/components/Button.bs.js | 3 +- src/components/Button.res | 8 +++- src/components/Image.bs.js | 2 + src/components/Image.res | 8 +++- src/components/ImageBackground.bs.js | 3 +- src/components/ImageBackground.res | 8 +++- src/components/KeyboardAvoidingView.bs.js | 3 +- src/components/KeyboardAvoidingView.res | 8 +++- src/components/Modal.bs.js | 2 + src/components/Modal.res | 8 +++- src/components/Pressable.bs.js | 3 +- src/components/Pressable.res | 8 +++- src/components/ProgressBarAndroid.bs.js | 3 +- src/components/ProgressBarAndroid.res | 8 +++- src/components/RefreshControl.bs.js | 3 +- src/components/RefreshControl.res | 8 +++- src/components/SafeAreaView.bs.js | 3 +- src/components/SafeAreaView.res | 8 +++- src/components/Switch.bs.js | 3 +- src/components/Switch.res | 8 +++- src/components/Text.bs.js | 3 +- src/components/Text.res | 8 +++- src/components/TouchableHighlight.bs.js | 3 +- src/components/TouchableHighlight.res | 8 +++- src/components/TouchableNativeFeedback.bs.js | 4 +- src/components/TouchableNativeFeedback.res | 8 +++- src/components/TouchableWithoutFeedback.bs.js | 3 +- src/components/TouchableWithoutFeedback.res | 8 +++- src/components/View.bs.js | 3 +- src/components/View.res | 8 +++- src/elements/DrawerLayoutAndroidElement.bs.js | 6 +-- src/elements/DrawerLayoutAndroidElement.res | 11 ++--- src/elements/NativeElement.bs.js | 13 +++--- src/elements/NativeElement.res | 22 +++++---- src/elements/ScrollViewElement.bs.js | 3 ++ src/elements/ScrollViewElement.res | 9 +++- src/elements/TextInputElement.bs.js | 6 +-- src/elements/TextInputElement.res | 11 ++--- src/elements/TouchableOpacityElement.bs.js | 6 +-- src/elements/TouchableOpacityElement.res | 11 ++--- src/elements/VirtualizedListElement.bs.js | 3 ++ src/elements/VirtualizedListElement.res | 9 +++- .../VirtualizedSectionListElement.bs.js | 3 ++ .../VirtualizedSectionListElement.res | 9 +++- src/types/DOMAPI.res | 45 ++++++++++--------- 48 files changed, 253 insertions(+), 95 deletions(-) diff --git a/src/apis/AccessibilityInfo.res b/src/apis/AccessibilityInfo.res index f13a309e9..4eea5267c 100644 --- a/src/apis/AccessibilityInfo.res +++ b/src/apis/AccessibilityInfo.res @@ -67,8 +67,10 @@ type accessibilityEventTypes = [ ] @scope("AccessibilityInfo") @module("react-native") -external sendAccessibilityEvent: (NativeElement.ref, accessibilityEventTypes) => unit = - "sendAccessibilityEvent" +external sendAccessibilityEvent: ( + Ref.t>, + accessibilityEventTypes, +) => unit = "sendAccessibilityEvent" @scope("AccessibilityInfo") @module("react-native") external prefersCrossFadeTransitions: unit => promise = "prefersCrossFadeTransitions" diff --git a/src/components/ActivityIndicator.bs.js b/src/components/ActivityIndicator.bs.js index 24e54d233..484019b94 100644 --- a/src/components/ActivityIndicator.bs.js +++ b/src/components/ActivityIndicator.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/ActivityIndicator.res b/src/components/ActivityIndicator.res index 09199ef70..1cbccea78 100644 --- a/src/components/ActivityIndicator.res +++ b/src/components/ActivityIndicator.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asActivityIndicatorElement: DOMAPI.anyElement => element = "%identity" @unboxed type size = | @as("small") Small | @as("large") Large | Number(float) diff --git a/src/components/Button.bs.js b/src/components/Button.bs.js index 24e54d233..484019b94 100644 --- a/src/components/Button.bs.js +++ b/src/components/Button.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/Button.res b/src/components/Button.res index b1e619c9f..511aef405 100644 --- a/src/components/Button.res +++ b/src/components/Button.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asButtonElement: DOMAPI.anyElement => element = "%identity" type props = { ref?: ref, diff --git a/src/components/Image.bs.js b/src/components/Image.bs.js index f7d8b0e67..26125b48f 100644 --- a/src/components/Image.bs.js +++ b/src/components/Image.bs.js @@ -3,6 +3,8 @@ var Event$ReactNative = require("../apis/Event.bs.js"); var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); + var Source = {}; Event$ReactNative.SyntheticEvent({}); diff --git a/src/components/Image.res b/src/components/Image.res index 14a1b45c7..91e228126 100644 --- a/src/components/Image.res +++ b/src/components/Image.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asImageElement: DOMAPI.anyElement => element = "%identity" type cache = [ | #default diff --git a/src/components/ImageBackground.bs.js b/src/components/ImageBackground.bs.js index 24e54d233..484019b94 100644 --- a/src/components/ImageBackground.bs.js +++ b/src/components/ImageBackground.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/ImageBackground.res b/src/components/ImageBackground.res index 6d28a7cef..6f0caa2f0 100644 --- a/src/components/ImageBackground.res +++ b/src/components/ImageBackground.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asImageBackgroundElement: DOMAPI.anyElement => element = "%identity" type props = { ref?: ref, diff --git a/src/components/KeyboardAvoidingView.bs.js b/src/components/KeyboardAvoidingView.bs.js index 24e54d233..484019b94 100644 --- a/src/components/KeyboardAvoidingView.bs.js +++ b/src/components/KeyboardAvoidingView.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/KeyboardAvoidingView.res b/src/components/KeyboardAvoidingView.res index 9d0bc81c1..1d11544c8 100644 --- a/src/components/KeyboardAvoidingView.res +++ b/src/components/KeyboardAvoidingView.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asKeyboardAvoidingViewElement: DOMAPI.anyElement => element = "%identity" type behavior = [#height | #position | #padding] diff --git a/src/components/Modal.bs.js b/src/components/Modal.bs.js index 173c3869d..a71650344 100644 --- a/src/components/Modal.bs.js +++ b/src/components/Modal.bs.js @@ -3,6 +3,8 @@ var Event$ReactNative = require("../apis/Event.bs.js"); var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); + Event$ReactNative.SyntheticEvent({}); var OrientationChangeEvent = {}; diff --git a/src/components/Modal.res b/src/components/Modal.res index 7ba6035e5..549bd80a4 100644 --- a/src/components/Modal.res +++ b/src/components/Modal.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asModalElement: DOMAPI.anyElement => element = "%identity" type orientation = [ | #landscape diff --git a/src/components/Pressable.bs.js b/src/components/Pressable.bs.js index 24e54d233..484019b94 100644 --- a/src/components/Pressable.bs.js +++ b/src/components/Pressable.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/Pressable.res b/src/components/Pressable.res index 627bc802c..1aeaf6035 100644 --- a/src/components/Pressable.res +++ b/src/components/Pressable.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asPressableElement: DOMAPI.anyElement => element = "%identity" type rippleConfig = { borderless?: bool, diff --git a/src/components/ProgressBarAndroid.bs.js b/src/components/ProgressBarAndroid.bs.js index 24e54d233..484019b94 100644 --- a/src/components/ProgressBarAndroid.bs.js +++ b/src/components/ProgressBarAndroid.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/ProgressBarAndroid.res b/src/components/ProgressBarAndroid.res index 9b49fb2b6..832948cd6 100644 --- a/src/components/ProgressBarAndroid.res +++ b/src/components/ProgressBarAndroid.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asProgressBarAndroidElement: DOMAPI.anyElement => element = "%identity" type styleAttr = [ | #Horizontal diff --git a/src/components/RefreshControl.bs.js b/src/components/RefreshControl.bs.js index 24e54d233..484019b94 100644 --- a/src/components/RefreshControl.bs.js +++ b/src/components/RefreshControl.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/RefreshControl.res b/src/components/RefreshControl.res index 04d12d304..184f56d2d 100644 --- a/src/components/RefreshControl.res +++ b/src/components/RefreshControl.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asRefreshControlElement: DOMAPI.anyElement => element = "%identity" type props = { ref?: ref, diff --git a/src/components/SafeAreaView.bs.js b/src/components/SafeAreaView.bs.js index 24e54d233..484019b94 100644 --- a/src/components/SafeAreaView.bs.js +++ b/src/components/SafeAreaView.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/SafeAreaView.res b/src/components/SafeAreaView.res index fce05fae2..9cd9987a0 100644 --- a/src/components/SafeAreaView.res +++ b/src/components/SafeAreaView.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asSafeAreaViewElement: DOMAPI.anyElement => element = "%identity" type props = { ref?: ref, diff --git a/src/components/Switch.bs.js b/src/components/Switch.bs.js index 24e54d233..484019b94 100644 --- a/src/components/Switch.bs.js +++ b/src/components/Switch.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/Switch.res b/src/components/Switch.res index a8bb3f336..b97276844 100644 --- a/src/components/Switch.res +++ b/src/components/Switch.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asSwitchElement: DOMAPI.anyElement => element = "%identity" type trackColor = { \"true"?: Color.t, diff --git a/src/components/Text.bs.js b/src/components/Text.bs.js index 24e54d233..484019b94 100644 --- a/src/components/Text.bs.js +++ b/src/components/Text.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/Text.res b/src/components/Text.res index 1d2eb007b..c855e15ee 100644 --- a/src/components/Text.res +++ b/src/components/Text.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asTextElement: DOMAPI.anyElement => element = "%identity" type android_hyphenationFrequency = [ | #normal diff --git a/src/components/TouchableHighlight.bs.js b/src/components/TouchableHighlight.bs.js index 24e54d233..484019b94 100644 --- a/src/components/TouchableHighlight.bs.js +++ b/src/components/TouchableHighlight.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/TouchableHighlight.res b/src/components/TouchableHighlight.res index a8dd96d30..ce582a6de 100644 --- a/src/components/TouchableHighlight.res +++ b/src/components/TouchableHighlight.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asTouchableHighlightElement: DOMAPI.anyElement => element = "%identity" type props = { ref?: ref, diff --git a/src/components/TouchableNativeFeedback.bs.js b/src/components/TouchableNativeFeedback.bs.js index d633edcd1..f1831e1c7 100644 --- a/src/components/TouchableNativeFeedback.bs.js +++ b/src/components/TouchableNativeFeedback.bs.js @@ -2,7 +2,9 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); + var Background = {}; exports.Background = Background; -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/TouchableNativeFeedback.res b/src/components/TouchableNativeFeedback.res index 750cea4d2..4abb0d4c9 100644 --- a/src/components/TouchableNativeFeedback.res +++ b/src/components/TouchableNativeFeedback.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asTouchableNativeFeedbackElement: DOMAPI.anyElement => element = "%identity" module Background = { type t diff --git a/src/components/TouchableWithoutFeedback.bs.js b/src/components/TouchableWithoutFeedback.bs.js index 24e54d233..484019b94 100644 --- a/src/components/TouchableWithoutFeedback.bs.js +++ b/src/components/TouchableWithoutFeedback.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/TouchableWithoutFeedback.res b/src/components/TouchableWithoutFeedback.res index 0660295bb..f11089fd1 100644 --- a/src/components/TouchableWithoutFeedback.res +++ b/src/components/TouchableWithoutFeedback.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asTouchableWithoutFeedbackElement: DOMAPI.anyElement => element = "%identity" type coreProps = { accessible?: bool, diff --git a/src/components/View.bs.js b/src/components/View.bs.js index 24e54d233..484019b94 100644 --- a/src/components/View.bs.js +++ b/src/components/View.bs.js @@ -2,5 +2,6 @@ var NativeElement$ReactNative = require("../elements/NativeElement.bs.js"); +NativeElement$ReactNative.Impl({}); -/* NativeElement-ReactNative Not a pure module */ +/* Not a pure module */ diff --git a/src/components/View.res b/src/components/View.res index 1176f1cae..0848bd1b1 100644 --- a/src/components/View.res +++ b/src/components/View.res @@ -1,4 +1,10 @@ -include NativeElement +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asViewElement: DOMAPI.anyElement => element = "%identity" // @todo in 0.71.0 // after adding `aria-*` props, make sure `aria-checked` can be true, false or "mixed" diff --git a/src/elements/DrawerLayoutAndroidElement.bs.js b/src/elements/DrawerLayoutAndroidElement.bs.js index 7c3ecfe5f..9417c111c 100644 --- a/src/elements/DrawerLayoutAndroidElement.bs.js +++ b/src/elements/DrawerLayoutAndroidElement.bs.js @@ -1,10 +1,10 @@ 'use strict'; -var NativeMethods$ReactNative = require("./NativeMethods.bs.js"); +var NativeElement$ReactNative = require("./NativeElement.bs.js"); var DrawerLayoutAndroidMethods$ReactNative = require("./DrawerLayoutAndroidMethods.bs.js"); -DrawerLayoutAndroidMethods$ReactNative.Make({}); +NativeElement$ReactNative.Impl({}); -NativeMethods$ReactNative.Make({}); +DrawerLayoutAndroidMethods$ReactNative.Make({}); /* Not a pure module */ diff --git a/src/elements/DrawerLayoutAndroidElement.res b/src/elements/DrawerLayoutAndroidElement.res index 51df4e6f1..616b1722b 100644 --- a/src/elements/DrawerLayoutAndroidElement.res +++ b/src/elements/DrawerLayoutAndroidElement.res @@ -1,10 +1,11 @@ -type element -type ref = Ref.t +type nativeElement -include DrawerLayoutAndroidMethods.Make({ - type t = element +include NativeElement.Impl({ + type t = nativeElement }) -include NativeMethods.Make({ +external asDrawerLayoutAndroidElement: DOMAPI.anyElement => element = "%identity" + +include DrawerLayoutAndroidMethods.Make({ type t = element }) diff --git a/src/elements/NativeElement.bs.js b/src/elements/NativeElement.bs.js index 37a7b7d24..b9d5c466a 100644 --- a/src/elements/NativeElement.bs.js +++ b/src/elements/NativeElement.bs.js @@ -3,8 +3,11 @@ var DOMAPI$ReactNative = require("../types/DOMAPI.bs.js"); var NativeMethods$ReactNative = require("./NativeMethods.bs.js"); -NativeMethods$ReactNative.Make({}); - -DOMAPI$ReactNative.$$Element.Impl({}); - -/* Not a pure module */ +function Impl(T) { + NativeMethods$ReactNative.Make({}); + DOMAPI$ReactNative.$$Element.Impl({}); + return {}; +} + +exports.Impl = Impl; +/* No side effect */ diff --git a/src/elements/NativeElement.res b/src/elements/NativeElement.res index 8816d08d0..72c244f56 100644 --- a/src/elements/NativeElement.res +++ b/src/elements/NativeElement.res @@ -1,10 +1,16 @@ -type element = DOMAPI.element -type ref = Ref.t +module Impl = ( + T: { + type t + }, +) => { + type element = DOMAPI.element + type ref = Ref.t -include NativeMethods.Make({ - type t = element -}) + include NativeMethods.Make({ + type t = element + }) -include DOMAPI.Element.Impl({ - type t = element -}) + include DOMAPI.Element.Impl({ + type t = element + }) +} diff --git a/src/elements/ScrollViewElement.bs.js b/src/elements/ScrollViewElement.bs.js index fdd8c3bf0..e75393846 100644 --- a/src/elements/ScrollViewElement.bs.js +++ b/src/elements/ScrollViewElement.bs.js @@ -1,7 +1,10 @@ 'use strict'; +var NativeElement$ReactNative = require("./NativeElement.bs.js"); var ScrollViewMethods$ReactNative = require("./ScrollViewMethods.bs.js"); +NativeElement$ReactNative.Impl({}); + ScrollViewMethods$ReactNative.Make({}); /* Not a pure module */ diff --git a/src/elements/ScrollViewElement.res b/src/elements/ScrollViewElement.res index 8ba5e10a3..ded62f898 100644 --- a/src/elements/ScrollViewElement.res +++ b/src/elements/ScrollViewElement.res @@ -1,5 +1,10 @@ -type element -type ref = Ref.t +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asScrollViewElement: DOMAPI.anyElement => element = "%identity" include ScrollViewMethods.Make({ type t = element diff --git a/src/elements/TextInputElement.bs.js b/src/elements/TextInputElement.bs.js index e91dede9e..2e6eb6a50 100644 --- a/src/elements/TextInputElement.bs.js +++ b/src/elements/TextInputElement.bs.js @@ -1,10 +1,10 @@ 'use strict'; -var NativeMethods$ReactNative = require("./NativeMethods.bs.js"); +var NativeElement$ReactNative = require("./NativeElement.bs.js"); var TextInputMethods$ReactNative = require("./TextInputMethods.bs.js"); -TextInputMethods$ReactNative.Make({}); +NativeElement$ReactNative.Impl({}); -NativeMethods$ReactNative.Make({}); +TextInputMethods$ReactNative.Make({}); /* Not a pure module */ diff --git a/src/elements/TextInputElement.res b/src/elements/TextInputElement.res index 496fb8c0b..1c7987789 100644 --- a/src/elements/TextInputElement.res +++ b/src/elements/TextInputElement.res @@ -1,10 +1,11 @@ -type element -type ref = Ref.t +type nativeElement -include TextInputMethods.Make({ - type t = element +include NativeElement.Impl({ + type t = nativeElement }) -include NativeMethods.Make({ +external asTextInputElement: DOMAPI.anyElement => element = "%identity" + +include TextInputMethods.Make({ type t = element }) diff --git a/src/elements/TouchableOpacityElement.bs.js b/src/elements/TouchableOpacityElement.bs.js index 072e00aca..19bb2c5cf 100644 --- a/src/elements/TouchableOpacityElement.bs.js +++ b/src/elements/TouchableOpacityElement.bs.js @@ -1,10 +1,10 @@ 'use strict'; -var NativeMethods$ReactNative = require("./NativeMethods.bs.js"); +var NativeElement$ReactNative = require("./NativeElement.bs.js"); var TouchableOpacityMethods$ReactNative = require("./TouchableOpacityMethods.bs.js"); -TouchableOpacityMethods$ReactNative.Make({}); +NativeElement$ReactNative.Impl({}); -NativeMethods$ReactNative.Make({}); +TouchableOpacityMethods$ReactNative.Make({}); /* Not a pure module */ diff --git a/src/elements/TouchableOpacityElement.res b/src/elements/TouchableOpacityElement.res index 6ae84974b..8b1909d06 100644 --- a/src/elements/TouchableOpacityElement.res +++ b/src/elements/TouchableOpacityElement.res @@ -1,10 +1,11 @@ -type element -type ref = Ref.t +type nativeElement -include TouchableOpacityMethods.Make({ - type t = element +include NativeElement.Impl({ + type t = nativeElement }) -include NativeMethods.Make({ +external asTouchableOpacityElement: DOMAPI.anyElement => element = "%identity" + +include TouchableOpacityMethods.Make({ type t = element }) diff --git a/src/elements/VirtualizedListElement.bs.js b/src/elements/VirtualizedListElement.bs.js index 9dc2a0d15..c9c3bf1a8 100644 --- a/src/elements/VirtualizedListElement.bs.js +++ b/src/elements/VirtualizedListElement.bs.js @@ -1,8 +1,11 @@ 'use strict'; +var NativeElement$ReactNative = require("./NativeElement.bs.js"); var ScrollViewMethods$ReactNative = require("./ScrollViewMethods.bs.js"); var VirtualizedListMethods$ReactNative = require("./VirtualizedListMethods.bs.js"); +NativeElement$ReactNative.Impl({}); + VirtualizedListMethods$ReactNative.Make({}); ScrollViewMethods$ReactNative.Make({}); diff --git a/src/elements/VirtualizedListElement.res b/src/elements/VirtualizedListElement.res index 3d5ad7235..4572c16a8 100644 --- a/src/elements/VirtualizedListElement.res +++ b/src/elements/VirtualizedListElement.res @@ -1,5 +1,10 @@ -type element -type ref = Ref.t +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asVirtualizedListElement: DOMAPI.anyElement => element = "%identity" include VirtualizedListMethods.Make({ type t = element diff --git a/src/elements/VirtualizedSectionListElement.bs.js b/src/elements/VirtualizedSectionListElement.bs.js index 7794898f6..77d094256 100644 --- a/src/elements/VirtualizedSectionListElement.bs.js +++ b/src/elements/VirtualizedSectionListElement.bs.js @@ -1,7 +1,10 @@ 'use strict'; +var NativeElement$ReactNative = require("./NativeElement.bs.js"); var VirtualizedSectionListMethods$ReactNative = require("./VirtualizedSectionListMethods.bs.js"); +NativeElement$ReactNative.Impl({}); + VirtualizedSectionListMethods$ReactNative.Make({}); /* Not a pure module */ diff --git a/src/elements/VirtualizedSectionListElement.res b/src/elements/VirtualizedSectionListElement.res index 2029818ba..ba4525b9d 100644 --- a/src/elements/VirtualizedSectionListElement.res +++ b/src/elements/VirtualizedSectionListElement.res @@ -1,5 +1,10 @@ -type element -type ref = Ref.t +type nativeElement + +include NativeElement.Impl({ + type t = nativeElement +}) + +external asVirtualizedSectionListElement: DOMAPI.anyElement => element = "%identity" include VirtualizedSectionListMethods.Make({ type t = element diff --git a/src/types/DOMAPI.res b/src/types/DOMAPI.res index 2f62e6bb1..409369fc8 100644 --- a/src/types/DOMAPI.res +++ b/src/types/DOMAPI.res @@ -20,25 +20,27 @@ type readOnlyNode<'node, 'document, 'element> = { textContent: string, } +type unknownNativeElement + type rec node = { - ...readOnlyNode, + ...readOnlyNode, } -and element = { +and element<'nativeElement> = { // Node - ...readOnlyNode, + ...readOnlyNode, // Element childElementCount: int, - children: htmlCollection, + children: htmlCollection, clientHeight: int, clientLeft: int, clientTop: int, clientWidth: int, - firstElementChild: Js.Null.t, + firstElementChild: Js.Null.t, id: string, - lastElementChild: Js.Null.t, - nextElementSibling: Js.Null.t, - previousElementSibling: Js.Null.t, + lastElementChild: Js.Null.t, + nextElementSibling: Js.Null.t, + previousElementSibling: Js.Null.t, scrollHeight: int, scrollLeft: int, scrollTop: int, @@ -49,28 +51,30 @@ and element = { offsetLeft: int, offsetTop: int, offsetWidth: int, - offsetParent: Js.Null.t, + offsetParent: Js.Null.t, } and text = { // Node - ...readOnlyNode, + ...readOnlyNode, // CharacterData data: string, length: int, - nextElementSibling: Js.Null.t, - previousElementSibling: Js.Null.t, + nextElementSibling: Js.Null.t, + previousElementSibling: Js.Null.t, } and document = { - ...readOnlyNode, + ...readOnlyNode, childElementCount: int, - children: htmlCollection, - documentElement: element, - firstElementChild: Js.Null.t, - lastElementChild: Js.Null.t, + children: htmlCollection, + documentElement: anyElement, + firstElementChild: Js.Null.t, + lastElementChild: Js.Null.t, } +and anyElement = element + module NodeList = { @send external item: (nodeList<'node>, int) => Js.Null.t<'node> = "item" @@ -129,7 +133,7 @@ module Element = { } include Impl({ - type t = element + type t = anyElement }) } @@ -138,7 +142,8 @@ module Document = { type t = document }) - @send external getElementById: (document, string) => Js.Null.t = "getElementById" + @send + external getElementById: (document, string) => Js.Null.t = "getElementById" } module Text = { @@ -165,7 +170,7 @@ module NodeType = { and remove this helper */ type t = - | Element(element) + | Element(element) | Text(text) | Document(document) | Unknown