mirror of
https://github.com/penpot/penpot.git
synced 2025-07-13 22:57:53 +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)))})]
|
(on-ref node)))})]
|
||||||
[:> "button" props
|
[:> "button" props
|
||||||
(when icon [:> icon* {:icon-id icon :size "m"}])
|
(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
|
(ns app.main.ui.ds.buttons.icon-button
|
||||||
(:require-macros
|
(:require-macros
|
||||||
[app.common.data.macros :as dm]
|
|
||||||
[app.main.style :as stl])
|
[app.main.style :as stl])
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]]
|
[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]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def ^:private schema:icon-button
|
(def ^:private schema:icon-button
|
||||||
|
@ -24,18 +24,30 @@
|
||||||
[:maybe [:enum "primary" "secondary" "ghost" "destructive" "action"]]]])
|
[:maybe [:enum "primary" "secondary" "ghost" "destructive" "action"]]]])
|
||||||
|
|
||||||
(mf/defc icon-button*
|
(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}]
|
[{:keys [class icon icon-class variant aria-label children] :rest props}]
|
||||||
(let [variant (or variant "primary")
|
(let [variant
|
||||||
tooltip-id (mf/use-id)
|
(d/nilv variant "primary")
|
||||||
class (dm/str class " " (stl/css-case :icon-button true
|
|
||||||
:icon-button-primary (= variant "primary")
|
tooltip-id
|
||||||
:icon-button-secondary (= variant "secondary")
|
(mf/use-id)
|
||||||
:icon-button-ghost (= variant "ghost")
|
|
||||||
:icon-button-action (= variant "action")
|
button-class
|
||||||
:icon-button-destructive (= variant "destructive")))
|
(stl/css-case :icon-button true
|
||||||
props (mf/spread-props props {:class class
|
:icon-button-primary (identical? variant "primary")
|
||||||
:aria-labelledby tooltip-id})]
|
:icon-button-secondary (identical? variant "secondary")
|
||||||
[:> tooltip* {:tooltip-content aria-label
|
: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}
|
: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]
|
[app.util.timers :as ts]
|
||||||
[rumext.v2 :as mf]))
|
[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
|
(let [{trigger-top :top
|
||||||
trigger-left :left
|
trigger-left :left
|
||||||
trigger-right :right
|
trigger-right :right
|
||||||
trigger-bottom :bottom
|
trigger-bottom :bottom
|
||||||
trigger-width :width
|
trigger-width :width
|
||||||
trigger-height :height} trigger-rect
|
trigger-height :height}
|
||||||
|
origin-brect
|
||||||
|
|
||||||
{tooltip-width :width
|
{tooltip-width :width
|
||||||
tooltip-height :height} (dom/get-bounding-rect tooltip)
|
tooltip-height :height}
|
||||||
|
tooltip-brect
|
||||||
|
|
||||||
offset (d/nilv offset 2)
|
offset (d/nilv offset 2)]
|
||||||
arrow-height 12
|
|
||||||
half-arrow-height (/ arrow-height 2)
|
|
||||||
overlay-offset 32]
|
|
||||||
|
|
||||||
(case placement
|
(case placement
|
||||||
"bottom"
|
"bottom"
|
||||||
|
@ -95,7 +122,10 @@
|
||||||
:width tooltip-width
|
:width tooltip-width
|
||||||
:height tooltip-height})))
|
: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
|
(case placement
|
||||||
"top" ["top" "right" "bottom" "left" "top-right" "bottom-right" "bottom-left" "top-left"]
|
"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"]
|
"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"]
|
"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"]))
|
"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
|
(def ^:private schema:tooltip
|
||||||
[:map
|
[:map
|
||||||
[:class {:optional true} :string]
|
[:class {:optional true} :string]
|
||||||
[:id {:optional true} :string]
|
[:id {:optional true} :string]
|
||||||
[:offset {:optional true} :int]
|
[:offset {:optional true} :int]
|
||||||
[:delay {:optional true} :int]
|
[:delay {:optional true} :int]
|
||||||
|
[:content [:or fn? :string [:fn mf/element?]]]
|
||||||
[:placement {:optional true}
|
[:placement {:optional true}
|
||||||
[:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]]])
|
[:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]]])
|
||||||
|
|
||||||
(mf/defc tooltip*
|
(mf/defc tooltip*
|
||||||
{::mf/schema schema:tooltip}
|
{::mf/schema schema:tooltip}
|
||||||
[{:keys [class id children tooltip-content placement offset delay] :rest props}]
|
[{:keys [class id children content placement offset delay] :rest props}]
|
||||||
(let [id (or id (mf/use-id))
|
(let [internal-id
|
||||||
placement* (mf/use-state #(d/nilv placement "top"))
|
(mf/use-id)
|
||||||
placement (deref placement*)
|
|
||||||
delay (d/nilv delay 300)
|
|
||||||
|
|
||||||
schedule-ref (mf/use-ref nil)
|
id
|
||||||
|
(d/nilv id internal-id)
|
||||||
|
|
||||||
position-tooltip
|
placement*
|
||||||
(fn [^js tooltip trigger-rect]
|
(mf/use-state #(d/nilv placement "top"))
|
||||||
(let [all-placements (get-fallback-order placement)]
|
|
||||||
(when (.-isConnected tooltip)
|
placement
|
||||||
(.showPopover ^js tooltip))
|
(deref placement*)
|
||||||
(loop [[current-placement & remaining-placements] all-placements]
|
|
||||||
(when current-placement
|
delay
|
||||||
(reset! placement* current-placement)
|
(d/nilv delay 300)
|
||||||
(let [tooltip-rect (calculate-tooltip-rect tooltip trigger-rect current-placement offset)]
|
|
||||||
(if (dom/is-bounding-rect-outside? tooltip-rect)
|
schedule-ref
|
||||||
(recur remaining-placements)
|
(mf/use-ref nil)
|
||||||
(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")))))))))
|
|
||||||
|
|
||||||
on-show
|
on-show
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps id placement)
|
(mf/deps id placement offset)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when-let [schedule (mf/ref-val schedule-ref)]
|
(clear-schedule schedule-ref)
|
||||||
(ts/dispose! schedule)
|
|
||||||
(mf/set-ref-val! schedule-ref nil))
|
|
||||||
(when-let [tooltip (dom/get-element id)]
|
(when-let [tooltip (dom/get-element id)]
|
||||||
(let [trigger-rect (->> (dom/get-target event)
|
(let [origin-brect
|
||||||
(dom/get-bounding-rect))]
|
(->> (dom/get-target event)
|
||||||
(mf/set-ref-val!
|
(dom/get-bounding-rect))
|
||||||
schedule-ref
|
|
||||||
(ts/schedule
|
update-position
|
||||||
delay
|
(fn []
|
||||||
#(position-tooltip tooltip trigger-rect)))))))
|
(let [placement (update-tooltip-position tooltip placement origin-brect offset)]
|
||||||
|
(reset! placement* placement)))]
|
||||||
|
|
||||||
|
(add-schedule schedule-ref delay update-position)))))
|
||||||
|
|
||||||
on-hide
|
on-hide
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(mf/deps id)
|
(mf/deps id)
|
||||||
(fn [] (when-let [tooltip (dom/get-element id)]
|
(fn []
|
||||||
(when-let [schedule (mf/ref-val schedule-ref)]
|
(when-let [tooltip (dom/get-element id)]
|
||||||
(ts/dispose! schedule)
|
(clear-schedule schedule-ref)
|
||||||
(mf/set-ref-val! schedule-ref nil))
|
(hide-popover tooltip))))
|
||||||
(dom/unset-css-property! tooltip "display")
|
|
||||||
(.hidePopover ^js tooltip))))
|
|
||||||
|
|
||||||
handle-key-down
|
handle-key-down
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
|
@ -173,33 +231,38 @@
|
||||||
(when (kbd/esc? event)
|
(when (kbd/esc? event)
|
||||||
(on-hide))))
|
(on-hide))))
|
||||||
|
|
||||||
class (d/append-class class (stl/css-case
|
tooltip-class
|
||||||
:tooltip true
|
(stl/css-case
|
||||||
:tooltip-top (= placement "top")
|
:tooltip true
|
||||||
:tooltip-bottom (= placement "bottom")
|
:tooltip-top (identical? placement "top")
|
||||||
:tooltip-left (= placement "left")
|
:tooltip-bottom (identical? placement "bottom")
|
||||||
:tooltip-right (= placement "right")
|
:tooltip-left (identical? placement "left")
|
||||||
:tooltip-top-right (= placement "top-right")
|
:tooltip-right (identical? placement "right")
|
||||||
:tooltip-bottom-right (= placement "bottom-right")
|
:tooltip-top-right (identical? placement "top-right")
|
||||||
:tooltip-bottom-left (= placement "bottom-left")
|
:tooltip-bottom-right (identical? placement "bottom-right")
|
||||||
:tooltip-top-left (= placement "top-left")))
|
: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
|
[:> :div props
|
||||||
children
|
children
|
||||||
[:div {:class class
|
[:div {:class [class tooltip-class]
|
||||||
:id id
|
:id id
|
||||||
:popover "auto"
|
:popover "auto"
|
||||||
:role "tooltip"}
|
:role "tooltip"}
|
||||||
[:div {:class (stl/css :tooltip-content)}
|
[:div {:class (stl/css :tooltip-content)} content]
|
||||||
(if (fn? tooltip-content)
|
|
||||||
(tooltip-content)
|
|
||||||
tooltip-content)]
|
|
||||||
[:div {:class (stl/css :tooltip-arrow)
|
[: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"
|
[:> tlp/tooltip* {:id "test-tooltip"
|
||||||
:placement "bottom"
|
:placement "bottom"
|
||||||
:tooltip-content "Tooltip content"}
|
:content "Tooltip content"}
|
||||||
[:div "Trigger component"]])
|
[:div "Trigger component"]])
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -44,8 +44,7 @@ Tooltip content can include HTML elements:
|
||||||
|
|
||||||
[:> tlp/tooltip* {:id "test-tooltip"
|
[:> tlp/tooltip* {:id "test-tooltip"
|
||||||
:placement "bottom"
|
:placement "bottom"
|
||||||
:tooltip-content (mf/html
|
:content (mf/html [:span "Tooltip content"])}
|
||||||
[:span "Tooltip content"])}
|
|
||||||
[:div "Trigger component"]])
|
[:div "Trigger component"]])
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ $arrow-side: 12px;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
inline-size: fit-content;
|
inline-size: fit-content;
|
||||||
|
block-size: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-arrow {
|
.tooltip-arrow {
|
||||||
|
@ -145,6 +146,7 @@ $arrow-side: 12px;
|
||||||
border: $b-1 solid var(--color-accent-primary-muted);
|
border: $b-1 solid var(--color-accent-primary-muted);
|
||||||
padding: var(--sp-s) var(--sp-m);
|
padding: var(--sp-s) var(--sp-m);
|
||||||
grid-area: content;
|
grid-area: content;
|
||||||
|
block-size: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-trigger {
|
.tooltip-trigger {
|
||||||
|
|
|
@ -37,10 +37,10 @@ export default {
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
children: (
|
children: (
|
||||||
<button popovertarget="popover-example">Hover this element</button>
|
<button popoverTarget="popover-example">Hover this element</button>
|
||||||
),
|
),
|
||||||
id: "popover-example",
|
id: "popover-example",
|
||||||
tooltipContent: "This is the tooltip content",
|
content: "This is the tooltip content",
|
||||||
delay: 300,
|
delay: 300,
|
||||||
},
|
},
|
||||||
render: ({ children, ...args }) => (
|
render: ({ children, ...args }) => (
|
||||||
|
@ -74,18 +74,18 @@ export const Corners = {
|
||||||
>
|
>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="popover-example10"
|
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={{
|
style={{
|
||||||
placeSelf: "start start",
|
placeSelf: "start start",
|
||||||
width: "fit-content",
|
width: "fit-content",
|
||||||
height: "fit-content",
|
height: "fit-content",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button popovertarget="popover-example10">Hover here</button>
|
<button popoverTarget="popover-example10">Hover here</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="popover-example2"
|
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={{
|
style={{
|
||||||
alignSelf: "start",
|
alignSelf: "start",
|
||||||
justifySelf: "center",
|
justifySelf: "center",
|
||||||
|
@ -94,7 +94,7 @@ export const Corners = {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
popovertarget="popover-example2"
|
popoverTarget="popover-example2"
|
||||||
style={{
|
style={{
|
||||||
alignSelf: "start",
|
alignSelf: "start",
|
||||||
justifySelf: "center",
|
justifySelf: "center",
|
||||||
|
@ -106,7 +106,7 @@ export const Corners = {
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="popover-example3"
|
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={{
|
style={{
|
||||||
alignSelf: "start",
|
alignSelf: "start",
|
||||||
justifySelf: "end",
|
justifySelf: "end",
|
||||||
|
@ -114,11 +114,11 @@ export const Corners = {
|
||||||
height: "fit-content",
|
height: "fit-content",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button popovertarget="popover-example3">Hover here</button>
|
<button popoverTarget="popover-example3">Hover here</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="popover-example4"
|
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={{
|
style={{
|
||||||
alignSelf: "center",
|
alignSelf: "center",
|
||||||
justifySelf: "start",
|
justifySelf: "start",
|
||||||
|
@ -126,11 +126,11 @@ export const Corners = {
|
||||||
height: "fit-content",
|
height: "fit-content",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button popovertarget="popover-example4">Hover here</button>
|
<button popoverTarget="popover-example4">Hover here</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="popover-example5"
|
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={{
|
style={{
|
||||||
alignSelf: "center",
|
alignSelf: "center",
|
||||||
justifySelf: "center",
|
justifySelf: "center",
|
||||||
|
@ -138,11 +138,11 @@ export const Corners = {
|
||||||
height: "fit-content",
|
height: "fit-content",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button popovertarget="popover-example5">Hover here</button>
|
<button popoverTarget="popover-example5">Hover here</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="popover-example6"
|
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={{
|
style={{
|
||||||
alignSelf: "center",
|
alignSelf: "center",
|
||||||
justifySelf: "end",
|
justifySelf: "end",
|
||||||
|
@ -150,11 +150,11 @@ export const Corners = {
|
||||||
height: "fit-content",
|
height: "fit-content",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button popovertarget="popover-example6">Hover here</button>
|
<button popoverTarget="popover-example6">Hover here</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="popover-example7"
|
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={{
|
style={{
|
||||||
alignSelf: "end",
|
alignSelf: "end",
|
||||||
justifySelf: "start",
|
justifySelf: "start",
|
||||||
|
@ -162,11 +162,11 @@ export const Corners = {
|
||||||
height: "fit-content",
|
height: "fit-content",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button popovertarget="popover-example7">Hover here</button>
|
<button popoverTarget="popover-example7">Hover here</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="popover-example8"
|
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={{
|
style={{
|
||||||
alignSelf: "end",
|
alignSelf: "end",
|
||||||
justifySelf: "center",
|
justifySelf: "center",
|
||||||
|
@ -174,11 +174,11 @@ export const Corners = {
|
||||||
height: "fit-content",
|
height: "fit-content",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button popovertarget="popover-example8">Hover here</button>
|
<button popoverTarget="popover-example8">Hover here</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="popover-example9"
|
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={{
|
style={{
|
||||||
alignSelf: "end",
|
alignSelf: "end",
|
||||||
justifySelf: "end",
|
justifySelf: "end",
|
||||||
|
@ -186,7 +186,7 @@ export const Corners = {
|
||||||
height: "fit-content",
|
height: "fit-content",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button popovertarget="popover-example9">Hover here</button>
|
<button popoverTarget="popover-example9">Hover here</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
|
|
|
@ -421,17 +421,16 @@
|
||||||
:height (.-height ^js rect)}))
|
:height (.-height ^js rect)}))
|
||||||
|
|
||||||
(defn is-bounding-rect-outside?
|
(defn is-bounding-rect-outside?
|
||||||
[rect]
|
[{:keys [left top right bottom]} {:keys [width height]}]
|
||||||
(let [{:keys [left top right bottom]} rect
|
(or (< left 0)
|
||||||
{:keys [width height]} (get-window-size)]
|
(< top 0)
|
||||||
(or (< left 0)
|
(> right width)
|
||||||
(< top 0)
|
(> bottom height)))
|
||||||
(> right width)
|
|
||||||
(> bottom height))))
|
|
||||||
|
|
||||||
(defn is-element-outside?
|
(defn is-element-outside?
|
||||||
[element]
|
[element]
|
||||||
(is-bounding-rect-outside? (get-bounding-rect element)))
|
(is-bounding-rect-outside? (get-bounding-rect element)
|
||||||
|
(get-window-size)))
|
||||||
|
|
||||||
(defn bounding-rect->rect
|
(defn bounding-rect->rect
|
||||||
[rect]
|
[rect]
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
extensions"
|
extensions"
|
||||||
(:require
|
(:require
|
||||||
[promesa.impl :as pi])
|
[promesa.impl :as pi])
|
||||||
(:import goog.async.Deferred))
|
(:import
|
||||||
|
goog.async.Deferred))
|
||||||
|
|
||||||
(pi/extend-promise! Deferred)
|
(pi/extend-promise! Deferred)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue