swinging-needle-meter/resources/public/js/compiled/out/re_com/box.cljs
2020-10-20 14:44:11 +01:00

505 lines
41 KiB
Clojure

(ns re-com.box
(:require [clojure.string :as string]
[re-com.validate :refer [justify-style? justify-options-list align-style? align-options-list
scroll-style? scroll-options-list string-or-hiccup? css-style? html-attr?] :refer-macros [validate-args-macro]]))
(def debug false)
;; ------------------------------------------------------------------------------------
;; Private Helper functions
;; ------------------------------------------------------------------------------------
(defn flex-child-style
"Determines the value for the 'flex' attribute (which has grow, shrink and basis), based on the :size parameter.
IMPORTANT: The term 'size' means width of the item in the case of flex-direction 'row' OR height of the item in the case of flex-direction 'column'.
Flex property explanation:
- grow Integer ratio (used with other siblings) to determined how a flex item grows it's size if there is extra space to distribute. 0 for no growing.
- shrink Integer ratio (used with other siblings) to determined how a flex item shrinks it's size if space needs to be removed. 0 for no shrinking.
- basis Initial size (width, actually) of item before any growing or shrinking. Can be any size value, e.g. 60%, 100px, auto
Note: auto will cause the initial size to be calculated to take up as much space as possible, in conjunction with it's siblings :flex settings.
Supported values:
- initial '0 1 auto' - Use item's width/height for dimensions (or content dimensions if w/h not specifed). Never grow. Shrink (to min-size) if necessary.
Good for creating boxes with fixed maximum size, but that can shrink to a fixed smaller size (min-width/height) if space becomes tight.
NOTE: When using initial, you should also set a width/height value (depending on flex-direction) to specify it's default size
and an optional min-width/height value to specify the size it can shrink to.
- auto '1 1 auto' - Use item's width/height for dimensions. Grow if necessary. Shrink (to min-size) if necessary.
Good for creating really flexible boxes that will gobble as much available space as they are allowed or shrink as much as they are forced to.
- none '0 0 auto' - Use item's width/height for dimensions (or content dimensions if not specifed). Never grow. Never shrink.
Good for creating rigid boxes that stick to their width/height if specified, otherwise their content size.
- 100px '0 0 100px' - Non flexible 100px size (in the flex direction) box.
Good for fixed headers/footers and side bars of an exact size.
- 60% '60 1 0px' - Set the item's size (it's width/height depending on flex-direction) to be 60% of the parent container's width/height.
NOTE: If you use this, then all siblings with percentage values must add up to 100%.
- 60 '60 1 0px' - Same as percentage above.
- grow shrink basis 'grow shrink basis' - If none of the above common valaues above meet your needs, this gives you precise control.
If number of words is not 1 or 3, an exception is thrown.
Reference: http://www.w3.org/TR/css3-flexbox/#flexibility
Diagram: http://www.w3.org/TR/css3-flexbox/#flex-container
Regex101 testing: ^(initial|auto|none)|(\\d+)(px|%|em)|(\\d+)\\w(\\d+)\\w(.*) - remove double backslashes"
[size]
;; TODO: Could make initial/auto/none into keywords???
(let [split-size (string/split (string/trim size) #"\s+") ;; Split into words separated by whitespace
split-count (count split-size)
_ (assert (contains? #{1 3} split-count) "Must pass either 1 or 3 words to flex-child-style")
size-only (when (= split-count 1) (first split-size)) ;; Contains value when only one word passed (e.g. auto, 60px)
split-size-only (when size-only (string/split size-only #"(\d+)(.*)")) ;; Split into number + string
[_ num units] (when size-only split-size-only) ;; grab number and units
pass-through? (nil? num) ;; If we can't split, then we'll pass this straign through
grow-ratio? (or (= units "%") (= units "") (nil? units)) ;; Determine case for using grow ratio
grow (if grow-ratio? num "0") ;; Set grow based on percent or integer, otherwise no grow
shrink (if grow-ratio? "1" "0") ;; If grow set, then set shrink to even shrinkage as well
basis (if grow-ratio? "0px" size) ;; If grow set, then even growing, otherwise set basis size to the passed in size (e.g. 100px, 5em)
flex (if (and size-only (not pass-through?))
(str grow " " shrink " " basis)
size)]
{:-webkit-flex flex
:flex flex}))
(defn flex-flow-style
"A cross-browser helper function to output flex-flow with all it's potential browser prefixes"
[flex-flow]
{:-webkit-flex-flow flex-flow
:flex-flow flex-flow})
(defn justify-style
"Determines the value for the flex 'justify-content' attribute.
This parameter determines how children are aligned along the main axis.
The justify parameter is a keyword.
Reference: http://www.w3.org/TR/css3-flexbox/#justify-content-property"
[justify]
(let [js (case justify
:start "flex-start"
:end "flex-end"
:center "center"
:between "space-between"
:around "space-around")]
{:-webkit-justify-content js
:justify-content js}))
(defn align-style
"Determines the value for the flex align type attributes.
This parameter determines how children are aligned on the cross axis.
The justify parameter is a keyword.
Reference: http://www.w3.org/TR/css3-flexbox/#align-items-property"
[attribute align]
(let [attribute-wk (->> attribute name (str "-webkit-") keyword)
as (case align
:start "flex-start"
:end "flex-end"
:center "center"
:baseline "baseline"
:stretch "stretch")]
{attribute-wk as
attribute as}))
(defn scroll-style
"Determines the value for the 'overflow' attribute.
The scroll parameter is a keyword.
Because we're translating scroll into overflow, the keyword doesn't appear to match the attribute value"
[attribute scroll]
{attribute (case scroll
:auto "auto"
:off "hidden"
:on "scroll"
:spill "visible")})
;; ------------------------------------------------------------------------------------
;; Private Component: box-base (debug color: lightblue)
;; ------------------------------------------------------------------------------------
(defn- box-base
"This should generally NOT be used as it is the basis for the box, scroller and border components"
[& {:keys [size scroll h-scroll v-scroll width height min-width min-height max-width max-height justify align align-self
margin padding border l-border r-border t-border b-border radius bk-color child class-name class style attr]}]
(let [s (merge
(flex-flow-style "inherit")
(flex-child-style size)
(when scroll (scroll-style :overflow scroll))
(when h-scroll (scroll-style :overflow-x h-scroll))
(when v-scroll (scroll-style :overflow-y v-scroll))
(when width {:width width})
(when height {:height height})
(when min-width {:min-width min-width})
(when min-height {:min-height min-height})
(when max-width {:max-width max-width})
(when max-height {:max-height max-height})
(when justify (justify-style justify))
(when align (align-style :align-items align))
(when align-self (align-style :align-self align-self))
(when margin {:margin margin}) ;; margin and padding: "all" OR "top&bottom right&left" OR "top right bottom left"
(when padding {:padding padding})
(when border {:border border})
(when l-border {:border-left l-border})
(when r-border {:border-right r-border})
(when t-border {:border-top t-border})
(when b-border {:border-bottom b-border})
(when radius {:border-radius radius})
(if bk-color
{:background-color bk-color}
(if debug {:background-color "lightblue"} {}))
style)]
[:div
(merge
{:class (str class-name "display-flex " class) :style s}
attr)
child]))
;; ------------------------------------------------------------------------------------
;; Component: gap (debug color: chocolate)
;; ------------------------------------------------------------------------------------
(def gap-args-desc
[{:name :size :required true :type "string" :validate-fn string? :description "the length of the whitespace. Typically, an absolute CSS length like 10px or 10em, but can be a stretchy proportional amount like 2"}
{:name :width :required false :type "string" :validate-fn string? :description "a CSS width style"}
{:name :height :required false :type "string" :validate-fn string? :description "a CSS height style"}
{:name :class :required false :type "string" :validate-fn string? :description "CSS class names, space separated"}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override"}
{:name :attr :required false :type "HTML attr map" :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}])
(defn gap
"Returns a component which produces a gap between children in a v-box/h-box along the main axis"
[& {:keys [size width height class style attr]
:as args}]
{:pre [(validate-args-macro gap-args-desc args "gap")]}
(let [s (merge
(when size (flex-child-style size))
(when width {:width width})
(when height {:height height})
(when debug {:background-color "chocolate"})
style)]
[:div
(merge
{:class (str "rc-gap " class) :style s}
attr)]))
;; ------------------------------------------------------------------------------------
;; Component: line
;; ------------------------------------------------------------------------------------
(def line-args-desc
[{:name :size :required false :default "1px" :type "string" :validate-fn string? :description "a CSS style for the thickness of the line. Usually px, % or em"}
{:name :color :required false :default "lightgray" :type "string" :validate-fn string? :description "a CSS color"}
{:name :class :required false :type "string" :validate-fn string? :description "CSS class names, space separated"}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override"}
{:name :attr :required false :type "HTML attr map" :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}])
(defn line
"Returns a component which produces a line between children in a v-box/h-box along the main axis.
Specify size in pixels and a stancard CSS color. Defaults to a 1px lightgray line"
[& {:keys [size color class style attr]
:or {size "1px" color "lightgray"}
:as args}]
{:pre [(validate-args-macro line-args-desc args "line")]}
(let [s (merge
(flex-child-style (str "0 0 " size))
{:background-color color}
style)]
[:div
(merge
{:class (str "rc-line " class) :style s}
attr)]))
;; ------------------------------------------------------------------------------------
;; Component: h-box (debug color: gold)
;; ------------------------------------------------------------------------------------
(def h-box-args-desc
[{:name :children :required true :type "vector" :validate-fn sequential? :description "a vector (or list) of components"}
{:name :size :required false :default "none" :type "string" :validate-fn string? :description [:span "equivalent to CSS style " [:span.bold "flex"] "." [:br] "Examples: " [:code "initial"] ", " [:code "auto"] ", " [:code "none"]", " [:code "100px"] ", " [:code "2"] " or a generic triple of " [:code "grow shrink basis"]]}
{:name :width :required false :type "string" :validate-fn string? :description "a CSS width style"}
{:name :height :required false :type "string" :validate-fn string? :description "a CSS height style"}
{:name :min-width :required false :type "string" :validate-fn string? :description "a CSS width style. The minimum width to which the box can shrink"}
{:name :min-height :required false :type "string" :validate-fn string? :description "a CSS height style. The minimum height to which the box can shrink"}
{:name :max-width :required false :type "string" :validate-fn string? :description "a CSS width style. The maximum width to which the box can grow"}
{:name :max-height :required false :type "string" :validate-fn string? :description "a CSS height style. The maximum height to which the box can grow"}
{:name :justify :required false :default :start :type "keyword" :validate-fn justify-style? :description [:span "equivalent to CSS style " [:span.bold "justify-content"] "." [:br] "One of " justify-options-list]}
{:name :align :required false :default :stretch :type "keyword" :validate-fn align-style? :description [:span "equivalent to CSS style " [:span.bold "align-items"] "." [:br] " One of " align-options-list]}
{:name :align-self :required false :type "keyword" :validate-fn align-style? :description [:span "equivalent to CSS style " [:span.bold "align-self"] "." [:br] "Used when a child must override the parent's align-items setting."]}
{:name :margin :required false :type "string" :validate-fn string? :description "a CSS margin style"}
{:name :padding :required false :type "string" :validate-fn string? :description "a CSS padding style"}
{:name :gap :required false :type "string" :validate-fn string? :description "the amount of whitespace to put between each child. Typically, an absolute CSS length like 10px or 10em, but can be a stretchy proportional amount like 2"}
{:name :class :required false :type "string" :validate-fn string? :description "CSS class names, space separated"}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override"}
{:name :attr :required false :type "HTML attr map" :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}])
(defn h-box
"Returns hiccup which produces a horizontal box.
It's primary role is to act as a container for components and lays it's children from left to right.
By default, it also acts as a child under it's parent"
[& {:keys [size width height min-width min-height max-width max-height justify align align-self margin padding gap children class style attr]
:or {size "none" justify :start align :stretch}
:as args}]
{:pre [(validate-args-macro h-box-args-desc args "h-box")]}
(let [s (merge
(flex-flow-style "row nowrap")
(flex-child-style size)
(when width {:width width})
(when height {:height height})
(when min-width {:min-width min-width})
(when min-height {:min-height min-height})
(when max-width {:max-width max-width})
(when max-height {:max-height max-height})
(justify-style justify)
(align-style :align-items align)
(when align-self (align-style :align-self align-self))
(when margin {:margin margin}) ;; margin and padding: "all" OR "top&bottom right&left" OR "top right bottom left"
(when padding {:padding padding})
(when debug {:background-color "gold"})
style)
gap-form (when gap [re-com.box/gap
:size gap
:width gap]) ;; TODO: required to get around a Chrome bug: https://code.google.com/p/chromium/issues/detail?id=423112. Remove once fixed.
children (if gap
(interpose gap-form (filter identity children)) ;; filter is to remove possible nils so we don't add unwanted gaps
children)]
(into [:div
(merge
{:class (str "rc-h-box display-flex " class) :style s}
attr)]
children)))
;; ------------------------------------------------------------------------------------
;; Component: v-box (debug color: antiquewhite)
;; ------------------------------------------------------------------------------------
(def v-box-args-desc
[{:name :children :required true :type "vector" :validate-fn sequential? :description "a vector (or list) of components"}
{:name :size :required false :default "none" :type "string" :validate-fn string? :description [:span "equivalent to CSS style " [:span.bold "flex"] "." [:br] "Examples: " [:code "initial"] ", " [:code "auto"] ", " [:code "none"]", " [:code "100px"] ", " [:code "2"] " or a generic triple of " [:code "grow shrink basis"]]}
{:name :width :required false :type "string" :validate-fn string? :description "a CSS width style"}
{:name :height :required false :type "string" :validate-fn string? :description "a CSS height style"}
{:name :min-width :required false :type "string" :validate-fn string? :description "a CSS width style. The minimum width to which the box can shrink"}
{:name :min-height :required false :type "string" :validate-fn string? :description "a CSS height style. The minimum height to which the box can shrink"}
{:name :max-width :required false :type "string" :validate-fn string? :description "a CSS width style. The maximum width to which the box can grow"}
{:name :max-height :required false :type "string" :validate-fn string? :description "a CSS height style. The maximum height to which the box can grow"}
{:name :justify :required false :default :start :type "keyword" :validate-fn justify-style? :description [:span "equivalent to CSS style " [:span.bold "justify-content"] "." [:br] "One of " justify-options-list]}
{:name :align :required false :default :stretch :type "keyword" :validate-fn align-style? :description [:span "equivalent to CSS style " [:span.bold "align-items"] "." [:br] " One of " align-options-list]}
{:name :align-self :required false :type "keyword" :validate-fn align-style? :description [:span "equivalent to CSS style " [:span.bold "align-self"] "." [:br] "Used when a child must override the parent's align-items setting."]}
{:name :margin :required false :type "string" :validate-fn string? :description "a CSS margin style"}
{:name :padding :required false :type "string" :validate-fn string? :description "a CSS padding style"}
{:name :gap :required false :type "string" :validate-fn string? :description "the amount of whitespace to put between each child. Typically, an absolute CSS length like 10px or 10em, but can be a stretchy proportional amount like 2"}
{:name :class :required false :type "string" :validate-fn string? :description "CSS class names, space separated"}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override"}
{:name :attr :required false :type "HTML attr map" :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}])
(defn v-box
"Returns hiccup which produces a vertical box.
It's primary role is to act as a container for components and lays it's children from top to bottom.
By default, it also acts as a child under it's parent"
[& {:keys [size width height min-width min-height max-width max-height justify align align-self margin padding gap children class style attr]
:or {size "none" justify :start align :stretch}
:as args}]
{:pre [(validate-args-macro v-box-args-desc args "v-box")]}
(let [s (merge
(flex-flow-style "column nowrap")
(flex-child-style size)
(when width {:width width})
(when height {:height height})
(when min-width {:min-width min-width})
(when min-height {:min-height min-height})
(when max-width {:max-width max-width})
(when max-height {:max-height max-height})
(justify-style justify)
(align-style :align-items align)
(when align-self (align-style :align-self align-self))
(when margin {:margin margin}) ;; margin and padding: "all" OR "top&bottom right&left" OR "top right bottom left"
(when padding {:padding padding})
(when debug {:background-color "antiquewhite"})
style)
gap-form (when gap [re-com.box/gap
:size gap
:height gap]) ;; TODO: required to get around a Chrome bug: https://code.google.com/p/chromium/issues/detail?id=423112. Remove once fixed.
children (if gap
(interpose gap-form (filter identity children)) ;; filter is to remove possible nils so we don't add unwanted gaps
children)]
(into [:div
(merge
{:class (str "rc-v-box display-flex " class) :style s}
attr)]
children)))
;; ------------------------------------------------------------------------------------
;; Component: box
;; ------------------------------------------------------------------------------------
(def box-args-desc
[{:name :child :required true :type "string | hiccup" :validate-fn string-or-hiccup? :description "a component (or string)"}
{:name :size :required false :default "none" :type "string" :validate-fn string? :description [:span "equivalent to CSS style " [:span.bold "flex"] "." [:br] "Examples: " [:code "initial"] ", " [:code "auto"] ", " [:code "none"]", " [:code "100px"] ", " [:code "2"] " or a generic triple of " [:code "grow shrink basis"]]}
{:name :width :required false :type "string" :validate-fn string? :description "a CSS width style"}
{:name :height :required false :type "string" :validate-fn string? :description "a CSS height style"}
{:name :min-width :required false :type "string" :validate-fn string? :description "a CSS width style. The minimum width to which the box can shrink"}
{:name :min-height :required false :type "string" :validate-fn string? :description "a CSS height style. The minimum height to which the box can shrink"}
{:name :max-width :required false :type "string" :validate-fn string? :description "a CSS width style. The maximum width to which the box can grow"}
{:name :max-height :required false :type "string" :validate-fn string? :description "a CSS height style. The maximum height to which the box can grow"}
{:name :justify :required false :default :start :type "keyword" :validate-fn justify-style? :description [:span "equivalent to CSS style " [:span.bold "justify-content"] "." [:br] "One of " justify-options-list]}
{:name :align :required false :default :stretch :type "keyword" :validate-fn align-style? :description [:span "equivalent to CSS style " [:span.bold "align-items"] "." [:br] " One of " align-options-list]}
{:name :align-self :required false :type "keyword" :validate-fn align-style? :description [:span "equivalent to CSS style " [:span.bold "align-self"] "." [:br] "Used when a child must override the parent's align-items setting."]}
{:name :margin :required false :type "string" :validate-fn string? :description "a CSS margin style"}
{:name :padding :required false :type "string" :validate-fn string? :description "a CSS padding style"}
{:name :class :required false :type "string" :validate-fn string? :description "CSS class names, space separated"}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override"}
{:name :attr :required false :type "HTML attr map" :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}])
(defn box
"Returns hiccup which produces a box, which is generally used as a child of a v-box or an h-box.
By default, it also acts as a container for further child compenents, or another h-box or v-box"
[& {:keys [size width height min-width min-height max-width max-height justify align align-self margin padding child class style attr]
:or {size "none"}
:as args}]
{:pre [(validate-args-macro box-args-desc args "box")]}
(box-base :size size
:width width
:height height
:min-width min-width
:min-height min-height
:max-width max-width
:max-height max-height
:justify justify
:align align
:align-self align-self
:margin margin
:padding padding
:child child
:class-name "rc-box "
:class class
:style style
:attr attr))
;; ------------------------------------------------------------------------------------
;; Component: scroller
;; ------------------------------------------------------------------------------------
(def scroller-args-desc
[{:name :child :required true :type "string | hiccup" :validate-fn string-or-hiccup? :description "a component (or string)"}
{:name :size :required false :default "auto" :type "string" :validate-fn string? :description [:span "equivalent to CSS style " [:span.bold "flex"] "." [:br] "Examples: " [:code "initial"] ", " [:code "auto"] ", " [:code "none"]", " [:code "100px"] ", " [:code "2"] " or a generic triple of " [:code "grow shrink basis"]]}
{:name :scroll :required false :default "auto" :type "keyword" :validate-fn scroll-style? :description [:span "Sets both h-scroll and v-scroll at once: " [:br]
[:code ":auto"] ": only show scroll bar(s) if the content is larger than the scroller" [:br]
[:code ":on"] ": always show scroll bars" [:br]
[:code ":off"] ": never show scroll bar(s). Content which is not in the bounds of the scroller can not be seen" [:br]
[:code ":spill"] ": never show scroll bar(s). Content which is not in the bounds of the scroller spills all over the place"]}
{:name :h-scroll :required false :type "keyword" :validate-fn scroll-style? :description [:span "see " [:code ":scroll"] ". Overrides that setting"]}
{:name :v-scroll :required false :type "keyword" :validate-fn scroll-style? :description [:span "see " [:code ":scroll"] ". Overrides that setting"]}
{:name :width :required false :type "string" :validate-fn string? :description "initial width"}
{:name :height :required false :type "string" :validate-fn string? :description "initial height"}
{:name :min-width :required false :type "string" :validate-fn string? :description "a CSS width style. The minimum width to which the box can shrink"}
{:name :min-height :required false :type "string" :validate-fn string? :description "a CSS height style. The minimum height to which the box can shrink"}
{:name :max-width :required false :type "string" :validate-fn string? :description "a CSS width style. The maximum width to which the box can grow"}
{:name :max-height :required false :type "string" :validate-fn string? :description "a CSS height style. The maximum height to which the box can grow"}
{:name :justify :required false :default :start :type "keyword" :validate-fn justify-style? :description [:span "equivalent to CSS style " [:span.bold "justify-content"] "." [:br] "One of " justify-options-list]}
{:name :align :required false :default :stretch :type "keyword" :validate-fn align-style? :description [:span "equivalent to CSS style " [:span.bold "align-items"] "." [:br] " One of " align-options-list]}
{:name :align-self :required false :type "keyword" :validate-fn align-style? :description [:span "equivalent to CSS style " [:span.bold "align-self"] "." [:br] "Used when a child must override the parent's align-items setting."]}
{:name :margin :required false :type "string" :validate-fn string? :description "a CSS margin style"}
{:name :padding :required false :type "string" :validate-fn string? :description "a CSS padding style"}
{:name :class :required false :type "string" :validate-fn string? :description "CSS class names, space separated"}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override"}
{:name :attr :required false :type "HTML attr map" :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}])
(defn scroller
"Returns hiccup which produces a scoller component.
This is the way scroll bars are added to boxes, in favour of adding the scroll attributes directly to the boxes themselves.
IMPORTANT: Because this component becomes the flex child in place of the component it is wrapping, you must copy the size attibutes to this componenet.
There are three scroll types:
- h-scroll Determines how the horizontal scroll bar will be displayed.
- v-scroll Determines how the vertical scroll bar will be displayed.
- scroll Sets both h-scroll and v-scroll at once.
Syntax: :auto [DEFAULT] Only show scroll bar(s) if the content is larger than the scroller.
:on Always show scroll bar(s).
:off Never show scroll bar(s). Content which is not in the bounds of the scroller can not be seen.
:spill Never show scroll bar(s). Content which is not in the bounds of the scroller spills all over the place.
Note: If scroll is set, then setting h-scroll or v-scroll overrides the scroll value"
[& {:keys [size scroll h-scroll v-scroll width height min-width min-height max-width max-height justify align align-self margin padding child class style attr]
:or {size "auto"}
:as args}]
{:pre [(validate-args-macro scroller-args-desc args "scroller")]}
(let [not-v-or-h (and (nil? v-scroll) (nil? h-scroll))
scroll (if (and (nil? scroll) not-v-or-h) :auto scroll)]
(box-base :size size
:scroll scroll
:h-scroll h-scroll
:v-scroll v-scroll
:width width
:height height
:min-width min-width
:min-height min-height
:max-width max-width
:max-height max-height
:justify justify
:align align
:align-self align-self
:margin margin
:padding padding
:child child
:class-name "rc-scroller "
:class class
:style style
:attr attr)))
;; ------------------------------------------------------------------------------------
;; Component: border
;; ------------------------------------------------------------------------------------
(def border-args-desc
[{:name :child :required true :type "string | hiccup" :validate-fn string-or-hiccup? :description "a component (or string)"}
{:name :border :required false :default "1px solid lightgrey" :type "string" :validate-fn string? :description "a CSS border style. A convenience to describe all borders in one parameter"}
{:name :l-border :required false :type "string" :validate-fn string? :description [:span "a CSS border style for the left border. Overrides " [:code ":border"]]}
{:name :r-border :required false :type "string" :validate-fn string? :description [:span "a CSS border style for the right border. Overrides " [:code ":border"]]}
{:name :t-border :required false :type "string" :validate-fn string? :description [:span "a CSS border style for the top border. Overrides " [:code ":border"]]}
{:name :b-border :required false :type "string" :validate-fn string? :description [:span "a CSS border style for the bottom. Overrides " [:code ":border"]]}
{:name :radius :required false :type "string" :validate-fn string? :description "a CSS radius style eg.\"2px\""}
{:name :size :required false :default "none" :type "string" :validate-fn string? :description [:span "equivalent to CSS style " [:span.bold "flex"] "." [:br] "Examples: " [:code "initial"] ", " [:code "auto"] ", " [:code "none"]", " [:code "100px"] ", " [:code "2"] " or a generic triple of " [:code "grow shrink basis"]]}
{:name :width :required false :type "string" :validate-fn string? :description "a CSS style describing the initial width"}
{:name :height :required false :type "string" :validate-fn string? :description "a CSS style describing the initial height"}
{:name :min-width :required false :type "string" :validate-fn string? :description "a CSS width style. The minimum width to which the box can shrink"}
{:name :min-height :required false :type "string" :validate-fn string? :description "a CSS height style. The minimum height to which the box can shrink"}
{:name :max-width :required false :type "string" :validate-fn string? :description "a CSS width style. The maximum width to which the box can grow"}
{:name :max-height :required false :type "string" :validate-fn string? :description "a CSS height style. The maximum height to which the box can grow"}
{:name :margin :required false :type "string" :validate-fn string? :description "a CSS margin style"}
{:name :padding :required false :type "string" :validate-fn string? :description "a CSS padding style"}
{:name :class :required false :type "string" :validate-fn string? :description "CSS class names, space separated"}
{:name :style :required false :type "CSS style map" :validate-fn css-style? :description "CSS styles to add or override"}
{:name :attr :required false :type "HTML attr map" :validate-fn html-attr? :description [:span "HTML attributes, like " [:code ":on-mouse-move"] [:br] "No " [:code ":class"] " or " [:code ":style"] "allowed"]}])
(defn border
"Returns hiccup which produces a border component.
This is the way borders are added to boxes, in favour of adding the border attributes directly to the boxes themselves.
border property syntax: '<border-width> || <border-style> || <color>'
- border-width: thin, medium, thick or standard CSS size (e.g. 2px, 0.5em)
- border-style: none, hidden, dotted, dashed, solid, double, groove, ridge, inset, outset
- color: standard CSS color (e.g. grey #88ffee)"
[& {:keys [size width height min-width min-height max-width max-height margin padding border l-border r-border t-border b-border radius child class style attr]
:or {size "none"}
:as args}]
{:pre [(validate-args-macro border-args-desc args "border")]}
(let [no-border (every? nil? [border l-border r-border t-border b-border])
default-border "1px solid lightgrey"]
(box-base :size size
:width width
:height height
:min-width min-width
:min-height min-height
:max-width max-width
:max-height max-height
:margin margin
:padding padding
:border (if no-border default-border border)
:l-border l-border
:r-border r-border
:t-border t-border
:b-border b-border
:radius radius
:child child
:class-name "rc-border "
:class class
:style style
:attr attr)))