|
96 | 96 | :default "re-com.dropdown/backdrop" |
97 | 97 | :type "part" |
98 | 98 | :validate-fn part? |
99 | | - :description (str "Renders a visual overlay, behind the `:anchor` and `:body` parts, when the dropdown is open.")} |
| 99 | + :description "Renders a visual overlay, behind the `:anchor` and `:body` parts, when the dropdown is open."} |
100 | 100 | {:name :show-backdrop? |
101 | 101 | :required? false |
102 | 102 | :type "boolean" |
|
113 | 113 | {:name :body-header |
114 | 114 | :type "part" |
115 | 115 | :validate-fn part? |
116 | | - :description (str "Appears at the top of the :body part.")} |
| 116 | + :description "Appears at the top of the :body part."} |
117 | 117 | {:name :body-footer |
118 | 118 | :type "part" |
119 | 119 | :validate-fn part? |
120 | | - :description (str "Appears at the bottom of the :body part.")} |
| 120 | + :description "Appears at the bottom of the :body part."} |
| 121 | + {:name :offset-x |
| 122 | + :type "number" |
| 123 | + :description [:span [:code ":dropdown"] " adds this to the body's dynamically-generated x-position."]} |
| 124 | + {:name :offset-y |
| 125 | + :type "number" |
| 126 | + :description [:span [:code ":dropdown"] " adds this to the body's dynamically-generated y-position."]} |
121 | 127 | {:name :disabled? |
122 | 128 | :required false |
123 | 129 | :type "boolean | r/atom"} |
|
249 | 255 |
|
250 | 256 | In other words, the body slides left & right within the anchor width, |
251 | 257 | and blinks up & down, to find the least cut-off position." |
252 | | - [anchor-el body-el & {:keys [direction]}] |
| 258 | + [anchor-el body-el & {:keys [direction offset-y offset-x]}] |
253 | 259 | (let [a-rect (.getBoundingClientRect anchor-el) |
254 | 260 | a-x (.-x a-rect) |
255 | 261 | a-y (.-y a-rect) |
|
280 | 286 | best-y (case v-pos :low lo-y :high hi-y) |
281 | 287 | best-y (case direction :up hi-y :down lo-y best-y)] |
282 | 288 | (->> [best-x best-y] |
283 | | - (mapv + [a-x a-y])))) |
| 289 | + (map + [a-x a-y]) |
| 290 | + (mapv + [offset-x offset-y])))) |
284 | 291 |
|
285 | | -(defn body-wrapper [{:keys [anchor-ref body-ref anchor-position direction parts]}] |
| 292 | +(defn body-wrapper [{:keys [anchor-ref body-ref anchor-position direction parts offset-y offset-x]}] |
286 | 293 | (let [set-body-ref! #(reset! body-ref %) |
287 | 294 | optimize-position! #(reset! anchor-position |
288 | 295 | (optimize-position! @anchor-ref @body-ref |
289 | | - {:direction direction})) |
| 296 | + {:direction direction |
| 297 | + :offset-y (u/deref-or-value offset-y) |
| 298 | + :offset-x (u/deref-or-value offset-x)})) |
290 | 299 | animation-id (atom nil) |
291 | 300 | start-loop! (fn start-loop [] |
292 | 301 | (reset! animation-id |
|
306 | 315 | (fn [{:keys [theme children post-props]}] |
307 | 316 | (let [[left top] (deref anchor-position)] |
308 | 317 | (u/part (get parts :body-wrapper (get parts ::body-wrapper)) |
309 | | - {:theme theme |
310 | | - :part ::body-wrapper |
311 | | - :props |
312 | | - {:position :fixed |
313 | | - :anchor-top top |
314 | | - :anchor-left left |
315 | | - :top top |
316 | | - :left left |
317 | | - :attr {:ref set-body-ref!} |
318 | | - :children children} |
319 | | - :post-props post-props})))}))) |
| 318 | + {:theme theme |
| 319 | + :part ::body-wrapper |
| 320 | + :props |
| 321 | + {:position :fixed |
| 322 | + :anchor-top top |
| 323 | + :anchor-left left |
| 324 | + :top top |
| 325 | + :left left |
| 326 | + :attr {:ref set-body-ref!} |
| 327 | + :children children} |
| 328 | + :post-props post-props})))}))) |
320 | 329 |
|
321 | 330 | (defn indicator [{:keys [state style]}] |
322 | 331 | [:span {:style style} |
|
328 | 337 |
|
329 | 338 | (defn dropdown |
330 | 339 | "A clickable anchor above an openable, floating body." |
331 | | - [& {:keys [model no-clip?] :or {model (reagent/atom nil)}}] |
| 340 | + [& {:keys [model no-clip? offset-x offset-y] :or {model (reagent/atom nil)}}] |
332 | 341 | (let [default-model model |
333 | 342 | [focused? anchor-ref body-ref anchor-position] (repeatedly #(reagent/atom nil)) |
334 | 343 | anchor-ref! #(reset! anchor-ref %) |
|
443 | 452 | (when (= :open (:openable state)) |
444 | 453 | [body-wrapper |
445 | 454 | {:anchor-ref anchor-ref |
| 455 | + :offset-x offset-x |
| 456 | + :offset-y offset-y |
446 | 457 | :body-ref body-ref |
447 | 458 | :anchor-position anchor-position |
448 | 459 | :direction direction |
|
0 commit comments