Last active
August 29, 2015 14:20
-
-
Save martinklepsch/58bf7da3aeec6b748aed to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns ui.flag | |
(:require [reagent.core :as reagent :refer [atom]])) | |
(defn flag | |
"Simple flag object component as described by Harry Roberts: | |
http://csswizardry.com/2013/05/the-flag-object" | |
[& {:keys [image bodies]}] | |
[:div.flag | |
[:div.flag__image image] | |
(for [b bodies] | |
[:div.flag__body b])]) | |
(defn expandable-flag | |
"An extension of the flag object that will maintain initial | |
positioning even if flag body expands. | |
Example (note the +/~ difference): | |
+-----+ | |
| (I) | ++++++++++++++ | |
+-----+ | |
If the flag body is being expanded the vertical centering would | |
be maintained, causing a jump of the flag image (I): | |
++++++++++++++ | |
+-----+ ~~ ~~~~~~~~~ | |
| (I) | ~~~~~~ ~~~~~ | |
+-----+ ~~ ~~~~~~~~~ | |
~~~~~ ~~~ | |
Now the expandable flag object maintains the initial positioning, | |
avoiding any jumps while still achieving perfect vertical alignment | |
of the unexpanded flag (keep in mind that the ++ lines could also be | |
higher than the image): | |
+-----+ | |
| (I) | ++++++++++++++ | |
+-----+ ~~ ~~~~~~~~~ | |
~~~~~~ ~~~~~ | |
~~ ~~~~~~~~~ | |
~~~~~ ~~~ | |
--- Keyword Arguments --- | |
- `image`: simple component which will be rendered as flag image | |
- `bodies`: list of body components. Either plain components or | |
components taking a boolean `expanded` parameter | |
- `expanded?`: Whether the flag is currently expanded or not | |
--- Caveat --- | |
This uses a local atom to store state and any remounting, | |
as it's done by Figwheel and the likes, will cause the values to be reset. | |
Depending on the state the flag is in this can result in odd behaviour. | |
(Should only ever occur in live-reloading workflows.)" | |
[& {:keys [image bodies expanded?]}] | |
(let [pads (atom []) | |
pad (fn [ex i] {:style {:padding-top (if ex (str (get @pads i) "px"))}})] | |
(reagent/create-class | |
{:component-did-mount | |
(fn [cmpnt] | |
(when (and (empty? @pads) (not expanded?)) | |
(let [h (.-offsetHeight (reagent/dom-node cmpnt)) | |
c (array-seq (.-children (reagent/dom-node cmpnt))) | |
ps (mapv #(/ (- h (-> % .-firstChild .-offsetHeight)) 2) c)] | |
(reset! pads ps)))) | |
:reagent-render | |
(fn [& {:keys [image bodies expanded?]}] | |
[:div.flag {:class (if expanded? "flag--top")} | |
[:div.flag__image (pad expanded? 0) image] | |
(map-indexed (fn [i b] | |
[:div.flag__body | |
(pad expanded? (inc i)) | |
(if (fn? b) [b expanded?] b)]) | |
bodies)])}))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment