From 37af4af16c5417f3cceae8ef6aa92932a367757b Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Tue, 10 Mar 2026 16:15:20 +0100 Subject: [PATCH 01/10] 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 02/10] 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 03/10] 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 04/10] 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 05/10] 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 From 7fb4abab592a27a578ac5269f7abf98a5a840438 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Mon, 6 Apr 2026 18:41:58 +0200 Subject: [PATCH 06/10] node textContent could be null --- 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 409369fc8..6651ed98a 100644 --- a/src/types/DOMAPI.res +++ b/src/types/DOMAPI.res @@ -17,7 +17,7 @@ type readOnlyNode<'node, 'document, 'element> = { parentElement: Js.Null.t<'element>, parentNode: Js.Null.t<'node>, previousSibling: Js.Null.t<'node>, - textContent: string, + textContent: Js.Null.t, } type unknownNativeElement From a5887c24afcd0a29ab62b7f2fb75258c7e91b575 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Mon, 6 Apr 2026 21:20:21 +0200 Subject: [PATCH 07/10] bring back NativeElement.ref as deprecated --- src/elements/NativeElement.bs.js | 6 +++++- src/elements/NativeElement.res | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/elements/NativeElement.bs.js b/src/elements/NativeElement.bs.js index b9d5c466a..b2d6dbcf7 100644 --- a/src/elements/NativeElement.bs.js +++ b/src/elements/NativeElement.bs.js @@ -9,5 +9,9 @@ function Impl(T) { return {}; } +NativeMethods$ReactNative.Make({}); + +DOMAPI$ReactNative.$$Element.Impl({}); + exports.Impl = Impl; -/* No side effect */ +/* Not a pure module */ diff --git a/src/elements/NativeElement.res b/src/elements/NativeElement.res index 72c244f56..40fd55eb1 100644 --- a/src/elements/NativeElement.res +++ b/src/elements/NativeElement.res @@ -14,3 +14,10 @@ module Impl = ( type t = element }) } + +@deprecated( + "Bindings maintainers: please use NativeElement.Impl instead of accessing the types directly." +) +include Impl({ + type t = DOMAPI.anyElement +}) From 70d7e8ecdb7837abe396ca926b5dfaf8334d1ce1 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Mon, 6 Apr 2026 21:26:28 +0200 Subject: [PATCH 08/10] dom api: unsafe conversion helper for elements --- src/components/ActivityIndicator.res | 2 -- src/components/Button.res | 2 -- src/components/Image.res | 2 -- src/components/ImageBackground.res | 2 -- src/components/KeyboardAvoidingView.res | 2 -- src/components/Modal.res | 2 -- src/components/Pressable.res | 2 -- src/components/ProgressBarAndroid.res | 2 -- src/components/RefreshControl.res | 2 -- src/components/SafeAreaView.res | 2 -- src/components/Switch.res | 2 -- src/components/Text.res | 2 -- src/components/TouchableHighlight.res | 2 -- src/components/TouchableNativeFeedback.res | 2 -- src/components/TouchableWithoutFeedback.res | 2 -- src/components/View.res | 2 -- src/elements/DrawerLayoutAndroidElement.res | 2 -- src/elements/NativeElement.res | 2 ++ src/elements/ScrollViewElement.res | 2 -- src/elements/TextInputElement.res | 2 -- src/elements/TouchableOpacityElement.res | 2 -- src/elements/VirtualizedListElement.res | 2 -- src/elements/VirtualizedSectionListElement.res | 2 -- 23 files changed, 2 insertions(+), 44 deletions(-) diff --git a/src/components/ActivityIndicator.res b/src/components/ActivityIndicator.res index 1cbccea78..5a2df2a6c 100644 --- a/src/components/ActivityIndicator.res +++ b/src/components/ActivityIndicator.res @@ -4,8 +4,6 @@ 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.res b/src/components/Button.res index 511aef405..3c853c083 100644 --- a/src/components/Button.res +++ b/src/components/Button.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asButtonElement: DOMAPI.anyElement => element = "%identity" - type props = { ref?: ref, accessibilityActions?: array, diff --git a/src/components/Image.res b/src/components/Image.res index 91e228126..bf259dbab 100644 --- a/src/components/Image.res +++ b/src/components/Image.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asImageElement: DOMAPI.anyElement => element = "%identity" - type cache = [ | #default | #reload diff --git a/src/components/ImageBackground.res b/src/components/ImageBackground.res index 6f0caa2f0..5d49f0118 100644 --- a/src/components/ImageBackground.res +++ b/src/components/ImageBackground.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asImageBackgroundElement: DOMAPI.anyElement => element = "%identity" - type props = { ref?: ref, imageRef?: Image.ref, diff --git a/src/components/KeyboardAvoidingView.res b/src/components/KeyboardAvoidingView.res index 1d11544c8..563ad12e9 100644 --- a/src/components/KeyboardAvoidingView.res +++ b/src/components/KeyboardAvoidingView.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asKeyboardAvoidingViewElement: DOMAPI.anyElement => element = "%identity" - type behavior = [#height | #position | #padding] type props = { diff --git a/src/components/Modal.res b/src/components/Modal.res index 549bd80a4..0c9e961aa 100644 --- a/src/components/Modal.res +++ b/src/components/Modal.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asModalElement: DOMAPI.anyElement => element = "%identity" - type orientation = [ | #landscape | #"landscape-left" diff --git a/src/components/Pressable.res b/src/components/Pressable.res index 1aeaf6035..0fe0a907c 100644 --- a/src/components/Pressable.res +++ b/src/components/Pressable.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asPressableElement: DOMAPI.anyElement => element = "%identity" - type rippleConfig = { borderless?: bool, color?: Color.t, diff --git a/src/components/ProgressBarAndroid.res b/src/components/ProgressBarAndroid.res index 832948cd6..4a4a888a9 100644 --- a/src/components/ProgressBarAndroid.res +++ b/src/components/ProgressBarAndroid.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asProgressBarAndroidElement: DOMAPI.anyElement => element = "%identity" - type styleAttr = [ | #Horizontal | #Normal diff --git a/src/components/RefreshControl.res b/src/components/RefreshControl.res index 184f56d2d..71410e85f 100644 --- a/src/components/RefreshControl.res +++ b/src/components/RefreshControl.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asRefreshControlElement: DOMAPI.anyElement => element = "%identity" - type props = { ref?: ref, ...View.viewProps, diff --git a/src/components/SafeAreaView.res b/src/components/SafeAreaView.res index 9cd9987a0..6475a9942 100644 --- a/src/components/SafeAreaView.res +++ b/src/components/SafeAreaView.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asSafeAreaViewElement: DOMAPI.anyElement => element = "%identity" - type props = { ref?: ref, ...View.viewProps, diff --git a/src/components/Switch.res b/src/components/Switch.res index b97276844..9c4bf54bb 100644 --- a/src/components/Switch.res +++ b/src/components/Switch.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asSwitchElement: DOMAPI.anyElement => element = "%identity" - type trackColor = { \"true"?: Color.t, \"false"?: Color.t, diff --git a/src/components/Text.res b/src/components/Text.res index c855e15ee..db2ab8c59 100644 --- a/src/components/Text.res +++ b/src/components/Text.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asTextElement: DOMAPI.anyElement => element = "%identity" - type android_hyphenationFrequency = [ | #normal | #none diff --git a/src/components/TouchableHighlight.res b/src/components/TouchableHighlight.res index ce582a6de..1696d5d84 100644 --- a/src/components/TouchableHighlight.res +++ b/src/components/TouchableHighlight.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asTouchableHighlightElement: DOMAPI.anyElement => element = "%identity" - type props = { ref?: ref, ...TouchableWithoutFeedback.coreProps, diff --git a/src/components/TouchableNativeFeedback.res b/src/components/TouchableNativeFeedback.res index 4abb0d4c9..60dfbf672 100644 --- a/src/components/TouchableNativeFeedback.res +++ b/src/components/TouchableNativeFeedback.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asTouchableNativeFeedbackElement: DOMAPI.anyElement => element = "%identity" - module Background = { type t diff --git a/src/components/TouchableWithoutFeedback.res b/src/components/TouchableWithoutFeedback.res index f11089fd1..b23d7495d 100644 --- a/src/components/TouchableWithoutFeedback.res +++ b/src/components/TouchableWithoutFeedback.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asTouchableWithoutFeedbackElement: DOMAPI.anyElement => element = "%identity" - type coreProps = { accessible?: bool, accessibilityElementsHidden?: bool, diff --git a/src/components/View.res b/src/components/View.res index 0848bd1b1..fda0be949 100644 --- a/src/components/View.res +++ b/src/components/View.res @@ -4,8 +4,6 @@ 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.res b/src/elements/DrawerLayoutAndroidElement.res index 616b1722b..e9e8daf12 100644 --- a/src/elements/DrawerLayoutAndroidElement.res +++ b/src/elements/DrawerLayoutAndroidElement.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asDrawerLayoutAndroidElement: DOMAPI.anyElement => element = "%identity" - include DrawerLayoutAndroidMethods.Make({ type t = element }) diff --git a/src/elements/NativeElement.res b/src/elements/NativeElement.res index 40fd55eb1..3602fff26 100644 --- a/src/elements/NativeElement.res +++ b/src/elements/NativeElement.res @@ -6,6 +6,8 @@ module Impl = ( type element = DOMAPI.element type ref = Ref.t + external unsafeFromAnyElement: DOMAPI.anyElement => element = "%identity" + include NativeMethods.Make({ type t = element }) diff --git a/src/elements/ScrollViewElement.res b/src/elements/ScrollViewElement.res index ded62f898..290e8d54d 100644 --- a/src/elements/ScrollViewElement.res +++ b/src/elements/ScrollViewElement.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asScrollViewElement: DOMAPI.anyElement => element = "%identity" - include ScrollViewMethods.Make({ type t = element }) diff --git a/src/elements/TextInputElement.res b/src/elements/TextInputElement.res index 1c7987789..4f26ee666 100644 --- a/src/elements/TextInputElement.res +++ b/src/elements/TextInputElement.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asTextInputElement: DOMAPI.anyElement => element = "%identity" - include TextInputMethods.Make({ type t = element }) diff --git a/src/elements/TouchableOpacityElement.res b/src/elements/TouchableOpacityElement.res index 8b1909d06..61b2ade5d 100644 --- a/src/elements/TouchableOpacityElement.res +++ b/src/elements/TouchableOpacityElement.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asTouchableOpacityElement: DOMAPI.anyElement => element = "%identity" - include TouchableOpacityMethods.Make({ type t = element }) diff --git a/src/elements/VirtualizedListElement.res b/src/elements/VirtualizedListElement.res index 4572c16a8..0cb65266a 100644 --- a/src/elements/VirtualizedListElement.res +++ b/src/elements/VirtualizedListElement.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asVirtualizedListElement: DOMAPI.anyElement => element = "%identity" - include VirtualizedListMethods.Make({ type t = element }) diff --git a/src/elements/VirtualizedSectionListElement.res b/src/elements/VirtualizedSectionListElement.res index ba4525b9d..2897e90a4 100644 --- a/src/elements/VirtualizedSectionListElement.res +++ b/src/elements/VirtualizedSectionListElement.res @@ -4,8 +4,6 @@ include NativeElement.Impl({ type t = nativeElement }) -external asVirtualizedSectionListElement: DOMAPI.anyElement => element = "%identity" - include VirtualizedSectionListMethods.Make({ type t = element }) From 56afdd7345cdef44610eddd00477c5cd91df7211 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Fri, 10 Apr 2026 10:06:33 +0200 Subject: [PATCH 09/10] fix deprecated for NativeElement.element --- src/elements/NativeElement.bs.js | 2 -- src/elements/NativeElement.res | 12 +++++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/elements/NativeElement.bs.js b/src/elements/NativeElement.bs.js index b2d6dbcf7..5706b3617 100644 --- a/src/elements/NativeElement.bs.js +++ b/src/elements/NativeElement.bs.js @@ -11,7 +11,5 @@ function Impl(T) { NativeMethods$ReactNative.Make({}); -DOMAPI$ReactNative.$$Element.Impl({}); - exports.Impl = Impl; /* Not a pure module */ diff --git a/src/elements/NativeElement.res b/src/elements/NativeElement.res index 3602fff26..6c0870689 100644 --- a/src/elements/NativeElement.res +++ b/src/elements/NativeElement.res @@ -18,8 +18,14 @@ module Impl = ( } @deprecated( - "Bindings maintainers: please use NativeElement.Impl instead of accessing the types directly." + "Bindings maintainers: please use NativeElement.Impl instead of accessing element type directly." ) -include Impl({ - type t = DOMAPI.anyElement +type element + +@warning("-3") +type ref = Ref.t + +@warning("-3") +include NativeMethods.Make({ + type t = element }) From a36c34f517ce97c5402471200d7741d4cbfe0ecb Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Fri, 10 Apr 2026 10:37:53 +0200 Subject: [PATCH 10/10] change depreated message --- src/elements/NativeElement.res | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/elements/NativeElement.res b/src/elements/NativeElement.res index 6c0870689..a7fb20461 100644 --- a/src/elements/NativeElement.res +++ b/src/elements/NativeElement.res @@ -17,9 +17,7 @@ module Impl = ( }) } -@deprecated( - "Bindings maintainers: please use NativeElement.Impl instead of accessing element type directly." -) +@deprecated("Use NativeElement.Impl instead of accessing element type directly.") type element @warning("-3")