package virtual_dom_toplayer
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
OCaml bindings for the floating positioning library for 'toplevel' virtual dom components
Install
dune-project
Dependency
Authors
Maintainers
Sources
virtual_dom_toplayer-v0.17.0.tar.gz
sha256=b525b0ba3607f142d417fe6edf1a08dbed86ae4e817680fb9bc191959b7a3aea
doc/src/virtual_dom_toplayer.popover/portal.ml.html
Source file portal.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77open! Core open Virtual_dom open Js_of_ocaml type t = { parent : Dom_html.element Js.t ; mutable element : Dom_html.element Js.t ; mutable vdom : Vdom.Node.t } [@@deriving fields ~getters] let apply_patch portal vdom = let patch = Vdom.Node.Patch.create ~previous:portal.vdom ~current:vdom in match Vdom.Node.Patch.is_empty patch with | true -> () | false -> portal.element <- Vdom.Node.Patch.apply patch portal.element; portal.vdom <- vdom ;; let create parent vdom = let portal = let element = Dom_html.createDiv Dom_html.document in Dom.appendChild parent element; { parent; element; vdom = Vdom.Node.div [] } in apply_patch portal vdom; portal ;; let destroy portal = Dom.removeChild portal.parent portal.element; (* After removing the portal from the dom, we still need to apply a patch that removes any existing elements from [contents], so that the apppropriate hooks are triggered by [Vdom]. We could do this before removing the portal as well, but this way we get to visually remove the portal immediately before computing the patch. *) apply_patch portal Vdom.Node.none ;; module For_popovers = struct let with_hash ~__LOC__:loc txt = let hash = Md5.digest_string (txt ^ loc) |> Md5.to_hex in [%string "%{txt}-%{hash}"] ;; let nested_popover_root_const = with_hash ~__LOC__ "nested-popover-root-priv" let nestable_popover_const = with_hash ~__LOC__ "data-bonsai-popover" let find_popover_portal_root (anchor : Dom_html.element Js.t) = let (root : Dom_html.element Js.t option) = let%bind.Option popover_ancestor = anchor##closest (Js.string [%string "[%{nestable_popover_const}]"]) |> Js.Opt.to_option in Js.Unsafe.get popover_ancestor "lastElementChild" |> Js.Opt.to_option in match root with | Some node -> node | None -> Dom_html.document##.body ;; let portal_root class_ = let id = Type_equal.Id.create ~name:class_ Sexplib.Conv.sexp_of_opaque in let init () = let div = Dom_html.createDiv Dom_html.document in div##setAttribute (Js.string "class") (Js.string class_); div##setAttribute (Js.string "style") (Js.string "display: contents"); (), (div :> Dom_html.element Js.t) in Vdom.Node.widget ~id ~init () ;; let nestable_popover_attr = Vdom.Attr.create nestable_popover_const "" let nested_popover_root = portal_root nested_popover_root_const end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>