a good experience for dates.

This commit is contained in:
2022-07-17 06:40:46 -07:00
parent 2830004092
commit eba3a5dce3
8 changed files with 240 additions and 619 deletions

View File

@@ -12,7 +12,10 @@
[react-transition-group :as react-transition-group]
#_{:clj-kondo/ignore [:unused-namespace]}
[react-datepicker :as react-datepicker]
[reagent.core :as reagent])
[reagent.core :as reagent]
[reagent.core :as r]
[react :as react]
[auto-ap.entities.shared :as shared])
(:import
(goog.i18n NumberFormat)
(goog.i18n.NumberFormat Format)))
@@ -351,7 +354,7 @@
(c/to-date selected)
:else
selected )
selected )
keys (assoc keys
:on-change (if (:cljs-date? keys)
(dispatch-cljs-date-change (conj event field))
@@ -363,6 +366,21 @@
keys (dissoc keys :field :subscription :event :spec)]
(into [dom keys] (with-keys rest))))
(defmethod do-bind "date2" [dom {:keys [field event subscription class spec] :as keys} & rest]
(let [field (if (keyword? field) [field] field)
event (if (keyword? event) [event] event)
selected (get-in subscription field)
keys (assoc keys
:on-change (fn [v]
(re-frame/dispatch (-> event (conj field) (conj v))))
:value selected
:class (str class
(when (and spec (not (s/valid? spec (get-in subscription field))))
" is-danger")))
keys (dissoc keys :field :subscription :event :spec)]
(into [dom keys] (with-keys rest))))
(defmethod do-bind "expense-accounts" [dom {:keys [field event subscription class spec] :as keys} & rest]
(let [field (if (keyword? field) [field] field)
event (if (keyword? event) [event] event)
@@ -475,8 +493,10 @@
(reagent/adapt-react-class (.-default react-datepicker)))
(defn date-picker-friendly [params]
[date-picker (assoc params
[date-picker (assoc params
:class-name "input"
:disabled-keyboard-navigation true
:start-open false
:class "input"
:format-week-number (fn [] "")
:previous-month-button-label ""
@@ -484,6 +504,71 @@
:next-month-label ""
:type "date")])
(defn coerce-date [d]
(cond (and (string? d)
(some->> (re-find #"^(\d{4})" d)
second
(js/parseInt)
(#(> % 2000))))
(try
(c/to-date-time (t/to-default-time-zone (t/from-default-time-zone (str->date d standard))))
(catch js/Error _
nil))
(instance? goog.date.DateTime d)
(c/to-date-time (t/to-default-time-zone (t/from-default-time-zone d)))
(instance? goog.date.Date d)
(c/to-date-time d)
:else
nil ))
(defn date-picker-optional-internal [params]
(let [[text set-text ] (react/useState (some-> params :value coerce-date (date->str standard)))
[value set-value ] (react/useState (some-> params :value coerce-date))
swap-external-value (fn [new-value]
((:on-change params)
(cond (= :text (:output params))
(some-> new-value (date->str standard))
(= :cljs-date (:output params))
new-value
:else
(c/to-date new-value))))]
(react/useEffect (fn []
(let [prop-date (some-> params :value coerce-date)]
(when (not (t/= prop-date
value))
(set-value prop-date)
(if prop-date
(set-text (date->str prop-date standard))
(set-text ""))))))
[:div.field.has-addons
[:div.control
[:input.input (assoc params
:value text
:on-change (fn [e]
(set-text (.. e -target -value))
;; if it's a perfect match, change it on the spot
;; especially important for calendar clicking, don't
;; want to wait for blur
(when (or (re-matches shared/date-regex (.. e -target -value))
(nil? (.. e -target -value)))
(swap-external-value (some-> (.. e -target -value) coerce-date))))
:on-blur (fn []
(swap-external-value (some-> text coerce-date)))
:type "date" :placeholder "12/1/2021")]
]]))
(defn date-picker-optional []
[:f> date-picker-optional-internal
(r/props (r/current-component))])
(defn local-now []
(t/to-default-time-zone (t/now)))