-
Notifications
You must be signed in to change notification settings - Fork 985
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#16377] feat: add calendar component in quo2 preview
- Loading branch information
1 parent
54747d4
commit b2ec274
Showing
23 changed files
with
536 additions
and
30 deletions.
There are no files selected for viewing
65 changes: 65 additions & 0 deletions
65
src/quo2/components/calendar/__tests__/calendar_component_spec.cljs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
(ns quo2.components.calendar.--tests--.calendar-component-spec | ||
(:require [quo2.components.calendar.calendar.view :as calendar] | ||
[test-helpers.component :as h] | ||
[cljs-time.core :as t])) | ||
|
||
(def start-date (t/date-time (t/year (t/now)) (t/month (t/now)) 5)) | ||
(def end-date (t/date-time (t/plus start-date (t/days 2)))) | ||
|
||
(h/describe "calendar component" | ||
(h/test "default render of calendar component" | ||
(h/render | ||
[calendar/calendar | ||
{:start-date start-date | ||
:end-date end-date}]) | ||
(-> (h/expect (h/query-by-translation-text "Mo")) | ||
(h/is-truthy))) | ||
|
||
(h/test "should call on-change with selected date on first click" | ||
(let [on-change (h/mock-fn)] | ||
(h/render | ||
[calendar/calendar | ||
{:start-date nil | ||
:end-date nil | ||
:on-change on-change}]) | ||
(h/fire-event :press (h/query-by-text (str (t/day start-date)))) | ||
(h/was-called-with on-change {:start-date start-date :end-date nil}))) | ||
|
||
(h/test "should call on-change with start and end date on second click" | ||
(let [on-change (h/mock-fn)] | ||
(h/render | ||
[calendar/calendar | ||
{:start-date start-date :end-date nil :on-change on-change}]) | ||
(h/fire-event :press (h/query-by-text (str (t/day end-date)))) | ||
(h/was-called-with on-change {:start-date start-date :end-date end-date}))) | ||
|
||
(h/test "should reset the dates on third click" | ||
(let [on-change (h/mock-fn)] | ||
(h/render | ||
[calendar/calendar | ||
{:start-date start-date | ||
:end-date end-date | ||
:on-change on-change}]) | ||
(h/fire-event :press (h/query-by-text (str (t/day start-date)))) | ||
(h/was-called-with on-change {:start-date start-date :end-date nil}))) | ||
|
||
(h/test "should reset dates when start date is clicked again" | ||
(let [on-change (h/mock-fn)] | ||
(h/render | ||
[calendar/calendar | ||
{:start-date start-date | ||
:end-date nil | ||
:on-change on-change}]) | ||
(h/fire-event :press (h/query-by-text (str (t/day start-date)))) | ||
(h/was-called-with on-change {:start-date nil :end-date nil}))) | ||
|
||
|
||
(h/test "should assign start and end date correctly when upper range selected first" | ||
(let [on-change (h/mock-fn)] | ||
(h/render | ||
[calendar/calendar | ||
{:start-date end-date | ||
:end-date nil | ||
:on-change on-change}]) | ||
(h/fire-event :press (h/query-by-text (str (t/day start-date)))) | ||
(h/was-called-with on-change {:start-date start-date :end-date end-date})))) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
(ns quo2.components.calendar.calendar.days-grid.style) | ||
|
||
(def container-days | ||
{:flex-grow 1 | ||
:margin-top 4 | ||
:margin-horizontal 8 | ||
:overflow :hidden}) |
66 changes: 66 additions & 0 deletions
66
src/quo2/components/calendar/calendar/days_grid/utils.cljs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
(ns quo2.components.calendar.calendar.days-grid.utils | ||
(:require | ||
[utils.number :as number-utils] | ||
[cljs-time.core :as t])) | ||
|
||
(defn- day-of-week | ||
[date] | ||
(let [day (t/day-of-week date)] | ||
(mod day 7))) | ||
|
||
(defn- add-days | ||
[date days] | ||
(t/plus date (t/days days))) | ||
|
||
(defn day-grid | ||
[year month] | ||
(let [year (number-utils/parse-int year) | ||
month (number-utils/parse-int month) | ||
first-day (t/date-time year month 1) | ||
start-day (add-days first-day (- 0 (day-of-week first-day))) | ||
end-day (add-days start-day 34)] | ||
(loop [days [] | ||
current-day start-day] | ||
(if (t/after? current-day end-day) | ||
days | ||
(recur (conj days current-day) (add-days current-day 1)))))) | ||
|
||
(defn get-day-state | ||
[day today year month start-date end-date] | ||
(cond | ||
(and start-date (t/equal? day start-date)) :selected | ||
(and end-date (t/equal? day end-date)) :selected | ||
(and (= (t/year day) (t/year today)) | ||
(= (t/month day) (t/month today)) | ||
(= (t/day day) (t/day today))) :today | ||
(and (= (t/year day) year) (= (t/month day) month)) :default | ||
:else :disabled)) | ||
|
||
(defn update-range | ||
[day start-date end-date] | ||
(let [new-state (cond | ||
(and start-date end-date) {:start-date day :end-date nil} | ||
(and start-date (t/equal? day start-date)) {:start-date nil :end-date nil} | ||
(and end-date (t/equal? day end-date)) {:start-date nil :end-date nil} | ||
(nil? start-date) {:start-date day :end-date nil} | ||
(nil? end-date) {:start-date start-date :end-date day} | ||
:else {:start-date start-date | ||
:end-date end-date})] | ||
(if (and (:start-date new-state) | ||
(:end-date new-state) | ||
(t/after? (:start-date new-state) (:end-date new-state))) | ||
{:start-date (:end-date new-state) :end-date (:start-date new-state)} | ||
new-state))) | ||
|
||
(defn in-range? | ||
[day start-date end-date] | ||
(and start-date end-date (t/after? day start-date) (t/before? day end-date))) | ||
|
||
(defn get-in-range-pos | ||
[day start-date end-date] | ||
(cond | ||
(or (nil? start-date) (nil? end-date)) nil | ||
(and start-date (t/equal? day start-date)) :start | ||
(and end-date (t/equal? day end-date)) :end | ||
(in-range? day start-date end-date) :middle | ||
:else nil)) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
(ns quo2.components.calendar.calendar.days-grid.view | ||
(:require [react-native.core :as rn] | ||
[quo2.theme :as theme] | ||
[cljs-time.core :as t] | ||
[quo2.components.calendar.calendar.days-grid.utils :as utils] | ||
[quo2.components.calendar.calendar-day.view :as calendar-day] | ||
[quo2.components.calendar.calendar.days-grid.style :as style])) | ||
|
||
(defn render-day | ||
[{:keys [year month day selection-range on-press]}] | ||
(let [today (t/now) | ||
start-date (:start-date selection-range) | ||
end-date (:end-date selection-range) | ||
state (utils/get-day-state day today year month start-date end-date) | ||
in-range (utils/get-in-range-pos day start-date end-date) | ||
on-press #(on-press (t/date-time day))] | ||
[calendar-day/calendar-day | ||
{:state state | ||
:in-range in-range | ||
:on-press on-press} | ||
(str (t/day day))])) | ||
|
||
(defn- days-grid-internal | ||
[{:keys [year month on-change start-date end-date]}] | ||
(let [on-day-press (fn [day] | ||
(let [new-selection (utils/update-range day start-date end-date)] | ||
(on-change new-selection)))] | ||
[rn/view | ||
{:style style/container-days} | ||
[rn/flat-list | ||
{:data (utils/day-grid year month) | ||
:key-fn str | ||
:numColumns 7 | ||
:content-container-style {:margin-horizontal -2} | ||
:render-fn (fn [item] | ||
(render-day | ||
{:year year | ||
:month month | ||
:day item | ||
:on-press on-day-press | ||
:selection-range {:start-date start-date :end-date end-date}}))}]])) | ||
|
||
(def days-grid (theme/with-theme days-grid-internal)) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
(ns quo2.components.calendar.calendar.style | ||
(:require | ||
[quo2.foundations.colors :as colors] | ||
[quo2.foundations.typography :as typography])) | ||
|
||
(defn container | ||
[] | ||
{:flex-direction :row | ||
:height 270 | ||
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80) | ||
:border-radius 12 | ||
:border-width 1 | ||
:background-color (colors/theme-colors colors/white colors/neutral-80-opa-40)}) | ||
|
||
(def container-main | ||
{:flex-grow 1}) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
(ns quo2.components.calendar.calendar.utils | ||
(:require [utils.datetime :as dt] | ||
[utils.number :as number-utils] | ||
[clojure.string :as string])) | ||
|
||
(defn generate-years | ||
[current-year] | ||
(let [current-year current-year] | ||
(reverse (vec (range (- current-year 100) (+ current-year 1)))))) | ||
|
||
(defn current-year | ||
[] | ||
(-> (dt/now) | ||
dt/timestamp->year-month-day-date | ||
(string/split #"-") | ||
first | ||
number-utils/parse-int)) | ||
|
||
(defn current-month | ||
[] | ||
(-> (dt/now) | ||
dt/timestamp->year-month-day-date | ||
(string/split #"-") | ||
second | ||
number-utils/parse-int)) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
(ns quo2.components.calendar.calendar.view | ||
(:require [react-native.core :as rn] | ||
[quo2.theme :as theme] | ||
[reagent.core :as reagent] | ||
[utils.number :as number-utils] | ||
[quo2.components.calendar.calendar.utils :as utils] | ||
[quo2.components.calendar.calendar.style :as style] | ||
[quo2.components.calendar.calendar.years-list.view :as years-list] | ||
[quo2.components.calendar.calendar.days-grid.view :as days-grid] | ||
[quo2.components.calendar.calendar.weekdays-header.view :as weekdays-header] | ||
[quo2.components.calendar.calendar-month.view :as calendar-month])) | ||
|
||
(defn- calendar-internal | ||
[] | ||
(let [selected-year (reagent/atom (utils/current-year)) | ||
selected-month (reagent/atom (utils/current-month)) | ||
on-change-year #(reset! selected-year %) | ||
on-change-month (fn [new-date] | ||
(reset! selected-year (number-utils/parse-int (:year new-date))) | ||
(reset! selected-month (number-utils/parse-int (:month new-date))))] | ||
(fn [{:keys [on-change start-date end-date]}] | ||
[rn/view | ||
{:style (style/container)} | ||
[years-list/years-list-view | ||
{:on-change-year on-change-year | ||
:year @selected-year}] | ||
[rn/view | ||
{:style style/container-main} | ||
[calendar-month/calendar-month | ||
{:year @selected-year | ||
:month @selected-month | ||
:on-change on-change-month}] | ||
[weekdays-header/weekdays-header] | ||
[days-grid/days-grid | ||
{:year @selected-year | ||
:month @selected-month | ||
:start-date start-date | ||
:end-date end-date | ||
:on-change on-change}]]]))) | ||
|
||
(def calendar (theme/with-theme calendar-internal)) |
22 changes: 22 additions & 0 deletions
22
src/quo2/components/calendar/calendar/weekdays_header/style.cljs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
(ns quo2.components.calendar.calendar.weekdays-header.style | ||
(:require [quo2.foundations.typography :as typography] | ||
[quo2.foundations.colors :as colors])) | ||
|
||
(def container-weekday-row | ||
{:flex-direction :row | ||
:justify-content :space-between | ||
:padding-horizontal 8}) | ||
|
||
(def container-weekday | ||
{:width 32 | ||
:height 30 | ||
:padding-top 2 | ||
:justify-content :center | ||
:align-items :center}) | ||
|
||
(defn text-weekdays | ||
[] | ||
(-> typography/paragraph-2 | ||
(merge typography/font-medium) | ||
(merge {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}))) | ||
|
21 changes: 21 additions & 0 deletions
21
src/quo2/components/calendar/calendar/weekdays_header/view.cljs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
(ns quo2.components.calendar.calendar.weekdays-header.view | ||
(:require [react-native.core :as rn] | ||
[quo2.theme :as theme] | ||
[utils.datetime :as dt] | ||
[utils.i18n :as i18n] | ||
[quo2.components.calendar.calendar.weekdays-header.style :as style])) | ||
|
||
(defn- weekdays-header-internal | ||
[] | ||
[rn/view | ||
{:style style/container-weekday-row} | ||
(doall | ||
(for [name dt/weekday-names] | ||
[rn/view | ||
{:style style/container-weekday | ||
:key name} | ||
[rn/text | ||
{:style (style/text-weekdays)} | ||
(str (i18n/label name))]]))]) | ||
|
||
(def weekdays-header (theme/with-theme weekdays-header-internal)) |
35 changes: 35 additions & 0 deletions
35
src/quo2/components/calendar/calendar/years_list/style.cljs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
(ns quo2.components.calendar.calendar.years-list.style | ||
(:require | ||
[quo2.foundations.colors :as colors])) | ||
|
||
(defn gradient-start-color | ||
[] | ||
(colors/theme-colors colors/white colors/neutral-90)) | ||
|
||
(defn gradient-end-color | ||
[] | ||
(colors/theme-colors colors/white-opa-0 colors/neutral-100-opa-0)) | ||
|
||
(def gradient-view | ||
{:position :absolute | ||
:height 50 | ||
:border-top-left-radius 12 | ||
:top 0 | ||
:left 0 | ||
:right 0}) | ||
|
||
(defn container-years | ||
[] | ||
{:border-width 1 | ||
:overflow :hidden | ||
:padding-left 8 | ||
:padding-right 7 | ||
:padding-vertical 8 | ||
:margin-left -1 | ||
:margin-top -1 | ||
:margin-bottom -1 | ||
:border-style :dashed | ||
:border-top-left-radius 12 | ||
:border-bottom-left-radius 12 | ||
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80)}) | ||
|
Oops, something went wrong.