fulcro-rad-carbon/src/main/com/fulcrologic/rad/rendering/semantic_ui/controls/instant_inputs.cljc

88 lines
4.0 KiB
Clojure

(ns com.fulcrologic.rad.rendering.semantic-ui.controls.instant-inputs
(:require
[clojure.string :as str]
[com.fulcrologic.guardrails.core :refer [>defn => ?]]
[com.fulcrologic.rad.type-support.date-time :as dt]
[com.fulcrologic.rad.rendering.semantic-ui.controls.control :as control]
[cljc.java-time.local-time :as lt]
[com.fulcrologic.fulcro.dom.events :as evt]
#?(:clj [com.fulcrologic.fulcro.dom-server :as dom]
:cljs [com.fulcrologic.fulcro.dom :as dom])
[cljc.java-time.local-date-time :as ldt]
[cljc.java-time.local-date :as ld]
#?@(:cljs [[ch.lyrion.carbon.date-picker.ui-date-picker :refer [ui-date-picker]]
[ch.lyrion.carbon.date-picker-input.ui-date-picker-input :refer [ui-date-picker-input]]])))
(defn ui-date-instant-input [{::keys [default-local-time]} {:keys [value onChange local-time] :as props}]
#?(:cljs
(let [value (dt/inst->html-date (or value (dt/now)))
local-time (or local-time default-local-time)]
(ui-date-picker
{:id (str (hash props) "-picker")
:datePickerType "single"
:dateFormat "Y-m-d"
:value value
:onChange (fn [evt]
(when onChange
(let [date (.toJSON (first evt))
date-string (first (str/split date "T"))
instant (dt/html-date->inst date-string local-time)]
(onChange instant))))}
(ui-date-picker-input
{:id (str (dt/now) "ui-date-instant-input")})))))
(defn ui-ending-date-instant-input
"Display the date the user selects, but control a value that is midnight on the next date. Used for generating ending
instants that can be used for a proper non-inclusive end date."
[_ {:keys [value onChange] :as props}]
#?(:cljs
(let [today (dt/inst->local-datetime (or value (dt/now)))
display-date (ldt/to-local-date (ldt/minus-days today 1))
value (dt/local-date->html-date-string display-date)]
(ui-date-picker
{:id (str (hash props) "-picker")
:datePickerType "single"
:dateFormat "Y-m-d"
:value value
:onChange (fn [evt]
(when onChange
(let [date (.toJSON (first evt))
date-string (first (str/split date "T"))
tomorrow (ld/at-time (ld/plus-days (dt/html-date-string->local-date date-string) 1)
lt/midnight)
instant (dt/local-datetime->inst tomorrow)]
(onChange instant))))}
(ui-date-picker-input
{:id (str (hash props) "-picker-input")})))))
(defn ui-date-time-instant-input [_ {:keys [disabled? value onChange] :as props}]
(let [value (dt/inst->html-datetime-string (or value (dt/now)))]
(dom/input
(merge props
(cond->
{:value value
:type "date"
:onChange (fn [evt]
(when onChange
(let [date-time-string (evt/target-value evt)
instant (dt/html-datetime-string->inst date-time-string)]
(onChange instant))))}
disabled? (assoc :readOnly true))))))
(defn date-time-control [render-env]
(control/ui-control (assoc render-env :input-factory ui-date-time-instant-input)))
(defn midnight-on-date-control [render-env]
(control/ui-control (assoc render-env
:input-factory ui-date-instant-input
::default-local-time lt/midnight)))
(defn midnight-next-date-control [render-env]
(control/ui-control (assoc render-env
:input-factory ui-ending-date-instant-input)))
(defn date-at-noon-control [render-env]
(control/ui-control (assoc render-env
::default-local-time lt/noon
:input-factory ui-date-instant-input)))