mirror of
https://github.com/penpot/penpot.git
synced 2025-07-13 08:47:16 +02:00
Merge pull request #6667 from penpot/niwinz-develop-enhacements-2
✨ Add internal changes to tooltip* ds component
This commit is contained in:
commit
2af1feafb6
9 changed files with 204 additions and 116 deletions
|
@ -36,4 +36,4 @@
|
|||
(on-ref node)))})]
|
||||
[:> "button" props
|
||||
(when icon [:> icon* {:icon-id icon :size "m"}])
|
||||
[:span {:class (stl/css :label-wrapper)} children]]))
|
||||
[:span {:class (stl/css :label-wrapper)} children]]))
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
(ns app.main.ui.ds.buttons.icon-button
|
||||
(:require-macros
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]]
|
||||
[app.main.ui.ds.tooltip.tooltip :refer [tooltip*]]
|
||||
[app.main.ui.ds.tooltip :refer [tooltip*]]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ^:private schema:icon-button
|
||||
|
@ -24,18 +24,30 @@
|
|||
[:maybe [:enum "primary" "secondary" "ghost" "destructive" "action"]]]])
|
||||
|
||||
(mf/defc icon-button*
|
||||
{::mf/schema schema:icon-button}
|
||||
{::mf/schema schema:icon-button
|
||||
::mf/memo true}
|
||||
[{:keys [class icon icon-class variant aria-label children] :rest props}]
|
||||
(let [variant (or variant "primary")
|
||||
tooltip-id (mf/use-id)
|
||||
class (dm/str class " " (stl/css-case :icon-button true
|
||||
:icon-button-primary (= variant "primary")
|
||||
:icon-button-secondary (= variant "secondary")
|
||||
:icon-button-ghost (= variant "ghost")
|
||||
:icon-button-action (= variant "action")
|
||||
:icon-button-destructive (= variant "destructive")))
|
||||
props (mf/spread-props props {:class class
|
||||
:aria-labelledby tooltip-id})]
|
||||
[:> tooltip* {:tooltip-content aria-label
|
||||
(let [variant
|
||||
(d/nilv variant "primary")
|
||||
|
||||
tooltip-id
|
||||
(mf/use-id)
|
||||
|
||||
button-class
|
||||
(stl/css-case :icon-button true
|
||||
:icon-button-primary (identical? variant "primary")
|
||||
:icon-button-secondary (identical? variant "secondary")
|
||||
:icon-button-ghost (identical? variant "ghost")
|
||||
:icon-button-action (identical? variant "action")
|
||||
:icon-button-destructive (identical? variant "destructive"))
|
||||
|
||||
props
|
||||
(mf/spread-props props
|
||||
{:class [class button-class]
|
||||
:aria-labelledby tooltip-id})]
|
||||
|
||||
[:> tooltip* {:content aria-label
|
||||
:id tooltip-id}
|
||||
[:> "button" props [:> icon* {:icon-id icon :aria-hidden true :class icon-class}] children]]))
|
||||
[:> :button props
|
||||
[:> icon* {:icon-id icon :aria-hidden true :class icon-class}]
|
||||
children]]))
|
||||
|
|
12
frontend/src/app/main/ui/ds/tooltip.cljs
Normal file
12
frontend/src/app/main/ui/ds/tooltip.cljs
Normal file
|
@ -0,0 +1,12 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.ds.tooltip
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.ui.ds.tooltip.tooltip :as impl]))
|
||||
|
||||
(dm/export impl/tooltip*)
|
|
@ -15,21 +15,48 @@
|
|||
[app.util.timers :as ts]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defn- calculate-tooltip-rect [tooltip trigger-rect placement offset]
|
||||
(def ^:private ^:const arrow-height 12)
|
||||
(def ^:private ^:const half-arrow-height (/ arrow-height 2))
|
||||
(def ^:private ^:const overlay-offset 32)
|
||||
|
||||
(defn- clear-schedule
|
||||
[ref]
|
||||
(when-let [schedule (mf/ref-val ref)]
|
||||
(ts/dispose! schedule)
|
||||
(mf/set-ref-val! ref nil)))
|
||||
|
||||
(defn- add-schedule
|
||||
[ref delay f]
|
||||
(mf/set-ref-val! ref (ts/schedule delay f)))
|
||||
|
||||
(defn- show-popover
|
||||
[node]
|
||||
(when (.-isConnected ^js node)
|
||||
(.showPopover ^js node)))
|
||||
|
||||
(defn- hide-popover
|
||||
[node]
|
||||
(dom/unset-css-property! node "display")
|
||||
(.hidePopover ^js node))
|
||||
|
||||
(defn- calculate-placement-bounding-rect
|
||||
"Given a placement, calcultates the bounding rect for it taking in
|
||||
account provided tooltip bounding rect and the origin bounding
|
||||
rect."
|
||||
[placement tooltip-brect origin-brect offset]
|
||||
(let [{trigger-top :top
|
||||
trigger-left :left
|
||||
trigger-right :right
|
||||
trigger-bottom :bottom
|
||||
trigger-width :width
|
||||
trigger-height :height} trigger-rect
|
||||
trigger-height :height}
|
||||
origin-brect
|
||||
|
||||
{tooltip-width :width
|
||||
tooltip-height :height} (dom/get-bounding-rect tooltip)
|
||||
tooltip-height :height}
|
||||
tooltip-brect
|
||||
|
||||
offset (d/nilv offset 2)
|
||||
arrow-height 12
|
||||
half-arrow-height (/ arrow-height 2)
|
||||
overlay-offset 32]
|
||||
offset (d/nilv offset 2)]
|
||||
|
||||
(case placement
|
||||
"bottom"
|
||||
|
@ -95,7 +122,10 @@
|
|||
:width tooltip-width
|
||||
:height tooltip-height})))
|
||||
|
||||
(defn- get-fallback-order [placement]
|
||||
(defn- get-fallback-order
|
||||
"Get a vector of placement followed with ordered fallback pacements
|
||||
for the specified placement"
|
||||
[placement]
|
||||
(case placement
|
||||
"top" ["top" "right" "bottom" "left" "top-right" "bottom-right" "bottom-left" "top-left"]
|
||||
"bottom" ["bottom" "left" "top" "right" "bottom-right" "bottom-left" "top-left" "top-right"]
|
||||
|
@ -106,65 +136,93 @@
|
|||
"bottom-left" ["bottom-left" "left" "top" "right" "bottom" "top-left" "top-right" "bottom-right"]
|
||||
"top-left" ["top-left" "top" "right" "bottom" "left" "bottom-left" "top-right" "bottom-right"]))
|
||||
|
||||
(defn- find-matching-placement
|
||||
"Algorithm for find a correct placement and placement-brect for the
|
||||
provided placement, if the current placement does not matches, it
|
||||
uses the predefined fallbacks. Returns an array of matched placement
|
||||
and its bounding rect."
|
||||
[placement tooltip-brect origin-brect window-size offset]
|
||||
(loop [placements (seq (get-fallback-order placement))]
|
||||
(when-let [placement (first placements)]
|
||||
(let [placement-brect (calculate-placement-bounding-rect placement tooltip-brect origin-brect offset)]
|
||||
(if (dom/is-bounding-rect-outside? placement-brect window-size)
|
||||
(recur (rest placements))
|
||||
#js [placement placement-brect])))))
|
||||
|
||||
(defn- update-tooltip-position
|
||||
"Update the tooltip position having in account the current window
|
||||
size, placement. It calculates the appropriate placement and updates
|
||||
the dom with the result."
|
||||
[tooltip placement origin-brect offset]
|
||||
(show-popover tooltip)
|
||||
(let [tooltip-brect (dom/get-bounding-rect tooltip)
|
||||
window-size (dom/get-window-size)]
|
||||
(when-let [[placement placement-rect] (find-matching-placement placement tooltip-brect origin-brect window-size offset)]
|
||||
|
||||
(let [height (if (or (= placement "right") (= placement "left"))
|
||||
(- (:height placement-rect) arrow-height)
|
||||
(:height placement-rect))]
|
||||
(dom/set-css-property! tooltip "display" "grid")
|
||||
(dom/set-css-property! tooltip "block-size" (dm/str height "px"))
|
||||
(dom/set-css-property! tooltip "inset-block-start" (dm/str (:top placement-rect) "px"))
|
||||
(dom/set-css-property! tooltip "inset-inline-start" (dm/str (:left placement-rect) "px")))
|
||||
placement)))
|
||||
|
||||
(def ^:private schema:tooltip
|
||||
[:map
|
||||
[:class {:optional true} :string]
|
||||
[:id {:optional true} :string]
|
||||
[:offset {:optional true} :int]
|
||||
[:delay {:optional true} :int]
|
||||
[:content [:or fn? :string [:fn mf/element?]]]
|
||||
[:placement {:optional true}
|
||||
[:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]]])
|
||||
|
||||
(mf/defc tooltip*
|
||||
{::mf/schema schema:tooltip}
|
||||
[{:keys [class id children tooltip-content placement offset delay] :rest props}]
|
||||
(let [id (or id (mf/use-id))
|
||||
placement* (mf/use-state #(d/nilv placement "top"))
|
||||
placement (deref placement*)
|
||||
delay (d/nilv delay 300)
|
||||
[{:keys [class id children content placement offset delay] :rest props}]
|
||||
(let [internal-id
|
||||
(mf/use-id)
|
||||
|
||||
schedule-ref (mf/use-ref nil)
|
||||
id
|
||||
(d/nilv id internal-id)
|
||||
|
||||
position-tooltip
|
||||
(fn [^js tooltip trigger-rect]
|
||||
(let [all-placements (get-fallback-order placement)]
|
||||
(when (.-isConnected tooltip)
|
||||
(.showPopover ^js tooltip))
|
||||
(loop [[current-placement & remaining-placements] all-placements]
|
||||
(when current-placement
|
||||
(reset! placement* current-placement)
|
||||
(let [tooltip-rect (calculate-tooltip-rect tooltip trigger-rect current-placement offset)]
|
||||
(if (dom/is-bounding-rect-outside? tooltip-rect)
|
||||
(recur remaining-placements)
|
||||
(do (dom/set-css-property! tooltip "display" "grid")
|
||||
(dom/set-css-property! tooltip "inset-block-start" (dm/str (:top tooltip-rect) "px"))
|
||||
(dom/set-css-property! tooltip "inset-inline-start" (dm/str (:left tooltip-rect) "px")))))))))
|
||||
placement*
|
||||
(mf/use-state #(d/nilv placement "top"))
|
||||
|
||||
placement
|
||||
(deref placement*)
|
||||
|
||||
delay
|
||||
(d/nilv delay 300)
|
||||
|
||||
schedule-ref
|
||||
(mf/use-ref nil)
|
||||
|
||||
on-show
|
||||
(mf/use-fn
|
||||
(mf/deps id placement)
|
||||
(mf/deps id placement offset)
|
||||
(fn [event]
|
||||
(when-let [schedule (mf/ref-val schedule-ref)]
|
||||
(ts/dispose! schedule)
|
||||
(mf/set-ref-val! schedule-ref nil))
|
||||
(clear-schedule schedule-ref)
|
||||
(when-let [tooltip (dom/get-element id)]
|
||||
(let [trigger-rect (->> (dom/get-target event)
|
||||
(dom/get-bounding-rect))]
|
||||
(mf/set-ref-val!
|
||||
schedule-ref
|
||||
(ts/schedule
|
||||
delay
|
||||
#(position-tooltip tooltip trigger-rect)))))))
|
||||
(let [origin-brect
|
||||
(->> (dom/get-target event)
|
||||
(dom/get-bounding-rect))
|
||||
|
||||
update-position
|
||||
(fn []
|
||||
(let [placement (update-tooltip-position tooltip placement origin-brect offset)]
|
||||
(reset! placement* placement)))]
|
||||
|
||||
(add-schedule schedule-ref delay update-position)))))
|
||||
|
||||
on-hide
|
||||
(mf/use-fn
|
||||
(mf/deps id)
|
||||
(fn [] (when-let [tooltip (dom/get-element id)]
|
||||
(when-let [schedule (mf/ref-val schedule-ref)]
|
||||
(ts/dispose! schedule)
|
||||
(mf/set-ref-val! schedule-ref nil))
|
||||
(dom/unset-css-property! tooltip "display")
|
||||
(.hidePopover ^js tooltip))))
|
||||
(fn []
|
||||
(when-let [tooltip (dom/get-element id)]
|
||||
(clear-schedule schedule-ref)
|
||||
(hide-popover tooltip))))
|
||||
|
||||
handle-key-down
|
||||
(mf/use-fn
|
||||
|
@ -173,33 +231,38 @@
|
|||
(when (kbd/esc? event)
|
||||
(on-hide))))
|
||||
|
||||
class (d/append-class class (stl/css-case
|
||||
:tooltip true
|
||||
:tooltip-top (= placement "top")
|
||||
:tooltip-bottom (= placement "bottom")
|
||||
:tooltip-left (= placement "left")
|
||||
:tooltip-right (= placement "right")
|
||||
:tooltip-top-right (= placement "top-right")
|
||||
:tooltip-bottom-right (= placement "bottom-right")
|
||||
:tooltip-bottom-left (= placement "bottom-left")
|
||||
:tooltip-top-left (= placement "top-left")))
|
||||
tooltip-class
|
||||
(stl/css-case
|
||||
:tooltip true
|
||||
:tooltip-top (identical? placement "top")
|
||||
:tooltip-bottom (identical? placement "bottom")
|
||||
:tooltip-left (identical? placement "left")
|
||||
:tooltip-right (identical? placement "right")
|
||||
:tooltip-top-right (identical? placement "top-right")
|
||||
:tooltip-bottom-right (identical? placement "bottom-right")
|
||||
:tooltip-bottom-left (identical? placement "bottom-left")
|
||||
:tooltip-top-left (identical? placement "top-left"))
|
||||
|
||||
props
|
||||
(mf/spread-props props
|
||||
{:on-mouse-enter on-show
|
||||
:on-mouse-leave on-hide
|
||||
:on-focus on-show
|
||||
:on-blur on-hide
|
||||
:on-key-down handle-key-down
|
||||
:class (stl/css :tooltip-trigger)
|
||||
:aria-describedby id})
|
||||
content
|
||||
(if (fn? content)
|
||||
(content)
|
||||
content)]
|
||||
|
||||
props (mf/spread-props props {:on-mouse-enter on-show
|
||||
:on-mouse-leave on-hide
|
||||
:on-focus on-show
|
||||
:on-blur on-hide
|
||||
:on-key-down handle-key-down
|
||||
:class (stl/css :tooltip-trigger)
|
||||
:aria-describedby id})]
|
||||
[:> :div props
|
||||
children
|
||||
[:div {:class class
|
||||
[:div {:class [class tooltip-class]
|
||||
:id id
|
||||
:popover "auto"
|
||||
:role "tooltip"}
|
||||
[:div {:class (stl/css :tooltip-content)}
|
||||
(if (fn? tooltip-content)
|
||||
(tooltip-content)
|
||||
tooltip-content)]
|
||||
[:div {:class (stl/css :tooltip-content)} content]
|
||||
[:div {:class (stl/css :tooltip-arrow)
|
||||
:id "tooltip-arrow"}]]]))
|
||||
:id "tooltip-arrow"}]]]))
|
||||
|
|
|
@ -32,7 +32,7 @@ If `placement` is not provided, the tooltip will default to "top".
|
|||
|
||||
[:> tlp/tooltip* {:id "test-tooltip"
|
||||
:placement "bottom"
|
||||
:tooltip-content "Tooltip content"}
|
||||
:content "Tooltip content"}
|
||||
[:div "Trigger component"]])
|
||||
```
|
||||
|
||||
|
@ -44,8 +44,7 @@ Tooltip content can include HTML elements:
|
|||
|
||||
[:> tlp/tooltip* {:id "test-tooltip"
|
||||
:placement "bottom"
|
||||
:tooltip-content (mf/html
|
||||
[:span "Tooltip content"])}
|
||||
:content (mf/html [:span "Tooltip content"])}
|
||||
[:div "Trigger component"]])
|
||||
```
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ $arrow-side: 12px;
|
|||
background-color: transparent;
|
||||
overflow: hidden;
|
||||
inline-size: fit-content;
|
||||
block-size: fit-content;
|
||||
}
|
||||
|
||||
.tooltip-arrow {
|
||||
|
@ -145,6 +146,7 @@ $arrow-side: 12px;
|
|||
border: $b-1 solid var(--color-accent-primary-muted);
|
||||
padding: var(--sp-s) var(--sp-m);
|
||||
grid-area: content;
|
||||
block-size: fit-content;
|
||||
}
|
||||
|
||||
.tooltip-trigger {
|
||||
|
|
|
@ -37,10 +37,10 @@ export default {
|
|||
},
|
||||
args: {
|
||||
children: (
|
||||
<button popovertarget="popover-example">Hover this element</button>
|
||||
<button popoverTarget="popover-example">Hover this element</button>
|
||||
),
|
||||
id: "popover-example",
|
||||
tooltipContent: "This is the tooltip content",
|
||||
content: "This is the tooltip content",
|
||||
delay: 300,
|
||||
},
|
||||
render: ({ children, ...args }) => (
|
||||
|
@ -74,18 +74,18 @@ export const Corners = {
|
|||
>
|
||||
<Tooltip
|
||||
id="popover-example10"
|
||||
tooltipContent="This is the tooltip content, and must be shown in two lines."
|
||||
content="This is the tooltip content, it's very long, and must be shown in three lines to check how it respond to different sizes."
|
||||
style={{
|
||||
placeSelf: "start start",
|
||||
width: "fit-content",
|
||||
height: "fit-content",
|
||||
}}
|
||||
>
|
||||
<button popovertarget="popover-example10">Hover here</button>
|
||||
<button popoverTarget="popover-example10">Hover here</button>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
id="popover-example2"
|
||||
tooltipContent="This is the tooltip content, and must be shown in two lines."
|
||||
content="This is the tooltip content, it's very long, and must be shown in three lines to check how it respond to different sizes."
|
||||
style={{
|
||||
alignSelf: "start",
|
||||
justifySelf: "center",
|
||||
|
@ -94,7 +94,7 @@ export const Corners = {
|
|||
}}
|
||||
>
|
||||
<button
|
||||
popovertarget="popover-example2"
|
||||
popoverTarget="popover-example2"
|
||||
style={{
|
||||
alignSelf: "start",
|
||||
justifySelf: "center",
|
||||
|
@ -106,7 +106,7 @@ export const Corners = {
|
|||
</Tooltip>
|
||||
<Tooltip
|
||||
id="popover-example3"
|
||||
tooltipContent="This is the tooltip content, and must be shown in two lines."
|
||||
content="This is the tooltip content, it's very long, and must be shown in three lines to check how it respond to different sizes."
|
||||
style={{
|
||||
alignSelf: "start",
|
||||
justifySelf: "end",
|
||||
|
@ -114,11 +114,11 @@ export const Corners = {
|
|||
height: "fit-content",
|
||||
}}
|
||||
>
|
||||
<button popovertarget="popover-example3">Hover here</button>
|
||||
<button popoverTarget="popover-example3">Hover here</button>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
id="popover-example4"
|
||||
tooltipContent="This is the tooltip content, and must be shown in two lines."
|
||||
content="This is the tooltip content, it's very long, and must be shown in three lines to check how it respond to different sizes."
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
justifySelf: "start",
|
||||
|
@ -126,11 +126,11 @@ export const Corners = {
|
|||
height: "fit-content",
|
||||
}}
|
||||
>
|
||||
<button popovertarget="popover-example4">Hover here</button>
|
||||
<button popoverTarget="popover-example4">Hover here</button>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
id="popover-example5"
|
||||
tooltipContent="This is the tooltip content, and must be shown in two lines."
|
||||
content="This is the tooltip content, it's very long, and must be shown in three lines to check how it respond to different sizes."
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
justifySelf: "center",
|
||||
|
@ -138,11 +138,11 @@ export const Corners = {
|
|||
height: "fit-content",
|
||||
}}
|
||||
>
|
||||
<button popovertarget="popover-example5">Hover here</button>
|
||||
<button popoverTarget="popover-example5">Hover here</button>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
id="popover-example6"
|
||||
tooltipContent="This is the tooltip content, and must be shown in two lines."
|
||||
content="This is the tooltip content, it's very long, and must be shown in three lines to check how it respond to different sizes."
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
justifySelf: "end",
|
||||
|
@ -150,11 +150,11 @@ export const Corners = {
|
|||
height: "fit-content",
|
||||
}}
|
||||
>
|
||||
<button popovertarget="popover-example6">Hover here</button>
|
||||
<button popoverTarget="popover-example6">Hover here</button>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
id="popover-example7"
|
||||
tooltipContent="This is the tooltip content, and must be shown in two lines."
|
||||
content="This is the tooltip content, it's very long, and must be shown in three lines to check how it respond to different sizes."
|
||||
style={{
|
||||
alignSelf: "end",
|
||||
justifySelf: "start",
|
||||
|
@ -162,11 +162,11 @@ export const Corners = {
|
|||
height: "fit-content",
|
||||
}}
|
||||
>
|
||||
<button popovertarget="popover-example7">Hover here</button>
|
||||
<button popoverTarget="popover-example7">Hover here</button>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
id="popover-example8"
|
||||
tooltipContent="This is the tooltip content, and must be shown in two lines."
|
||||
content="This is the tooltip content, it's very long, and must be shown in three lines to check how it respond to different sizes."
|
||||
style={{
|
||||
alignSelf: "end",
|
||||
justifySelf: "center",
|
||||
|
@ -174,11 +174,11 @@ export const Corners = {
|
|||
height: "fit-content",
|
||||
}}
|
||||
>
|
||||
<button popovertarget="popover-example8">Hover here</button>
|
||||
<button popoverTarget="popover-example8">Hover here</button>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
id="popover-example9"
|
||||
tooltipContent="This is the tooltip content, and must be shown in two lines."
|
||||
content="This is the tooltip content, it's very long, and must be shown in three lines to check how it respond to different sizes."
|
||||
style={{
|
||||
alignSelf: "end",
|
||||
justifySelf: "end",
|
||||
|
@ -186,7 +186,7 @@ export const Corners = {
|
|||
height: "fit-content",
|
||||
}}
|
||||
>
|
||||
<button popovertarget="popover-example9">Hover here</button>
|
||||
<button popoverTarget="popover-example9">Hover here</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
),
|
||||
|
|
|
@ -421,17 +421,16 @@
|
|||
:height (.-height ^js rect)}))
|
||||
|
||||
(defn is-bounding-rect-outside?
|
||||
[rect]
|
||||
(let [{:keys [left top right bottom]} rect
|
||||
{:keys [width height]} (get-window-size)]
|
||||
(or (< left 0)
|
||||
(< top 0)
|
||||
(> right width)
|
||||
(> bottom height))))
|
||||
[{:keys [left top right bottom]} {:keys [width height]}]
|
||||
(or (< left 0)
|
||||
(< top 0)
|
||||
(> right width)
|
||||
(> bottom height)))
|
||||
|
||||
(defn is-element-outside?
|
||||
[element]
|
||||
(is-bounding-rect-outside? (get-bounding-rect element)))
|
||||
(is-bounding-rect-outside? (get-bounding-rect element)
|
||||
(get-window-size)))
|
||||
|
||||
(defn bounding-rect->rect
|
||||
[rect]
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
extensions"
|
||||
(:require
|
||||
[promesa.impl :as pi])
|
||||
(:import goog.async.Deferred))
|
||||
(:import
|
||||
goog.async.Deferred))
|
||||
|
||||
(pi/extend-promise! Deferred)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue