x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- Default --><input type="text" name="default_datepicker" id="default_datepicker" placeholder="Pick a date" class="input" data-controller="datepicker" /><!-- Datetime --><input type="text" name="datetime_datepicker" id="datetime_datepicker" placeholder="Pick a date" class="input" data-controller="datepicker" data-datepicker-type-value="datetime" /><!-- Disabled Dates --><input type="text" name="disabled_dates_datepicker" id="disabled_dates_datepicker" value="2028-01-01" placeholder="Pick a date" class="input" data-controller="datepicker" data-datepicker-disable-value="["2028-01-10","2028-01-11","2028-01-12"]" /><!-- Multiple --><input type="text" name="multiple_datepicker" id="multiple_datepicker" placeholder="Pick dates" class="input" data-controller="datepicker" data-datepicker-mode-value="multiple" /><!-- Range --><input type="text" name="range_datepicker" id="range_datepicker" placeholder="Pick dates" class="input" data-controller="datepicker" data-datepicker-mode-value="range" data-datepicker-show-months-value="2" /><!-- Time --><input type="text" name="time_datepicker" id="time_datepicker" placeholder="Pick a time" class="input" data-controller="datepicker" data-datepicker-type-value="time" />
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%# Default %><%= text_field_tag "default_datepicker", nil, placeholder: "Pick a date", class: "input", data: { controller: "datepicker" } %><%# Datetime %><%= text_field_tag "datetime_datepicker", nil, placeholder: "Pick a date", class: "input", data: { controller: "datepicker", datepicker_type_value: "datetime" } %><%# Disabled Dates %><%= text_field_tag "disabled_dates_datepicker", "2028-01-01", placeholder: "Pick a date", class: "input", data: { controller: "datepicker", datepicker_disable_value: ["2028-01-10", "2028-01-11", "2028-01-12"] } %><%# Multiple %><%= text_field_tag "multiple_datepicker", nil, placeholder: "Pick dates", class: "input", data: { controller: "datepicker", datepicker_mode_value: "multiple" } %><%# Range %><%= text_field_tag "range_datepicker", nil, placeholder: "Pick dates", class: "input", data: { controller: "datepicker", datepicker_mode_value: "range", datepicker_show_months_value: 2 } %><%# Time %><%= text_field_tag "time_datepicker", nil, placeholder: "Pick a time", class: "input", data: { controller: "datepicker", datepicker_type_value: "time" } %>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
@import url("https://esm.sh/flatpickr@4.6.13/dist/flatpickr.min.css");.flatpickr-calendar { --calendar-size: 250px; --container-size: 220px; --day-size: var(--size-8); background: var(--color-bg); border: 1px solid var(--color-border); border-radius: var(--rounded-md); box-shadow: var(--shadow-md); font-size: var(--text-sm); inline-size: var(--calendar-size); .flatpickr-innerContainer { justify-content: center; padding-block-end: var(--size-3); } .flatpickr-days { inline-size: var(--container-size); } .dayContainer { inline-size: var(--container-size); min-inline-size: var(--container-size); max-inline-size: var(--container-size); } .dayContainer + .dayContainer { box-shadow: -1px 0 0 var(--color-border); } .flatpickr-months { .flatpickr-month { color: var(--color-text); } span.cur-month { font-size: var(--text-sm); font-weight: var(--font-medium); } svg { fill: var(--color-border-dark); } .flatpickr-prev-month:hover svg { fill: var(--color-text); } .flatpickr-next-month:hover svg { fill: var(--color-text); } } .flatpickr-monthDropdown-months { appearance: none; border-radius: var(--rounded-md); font-size: var(--text-sm); font-weight: var(--font-medium); line-height: var(--leading-normal); padding: 0; text-align: center; &:hover { background: var(--color-border-light); } } .numInputWrapper { input { border-radius: var(--rounded-md); color: var(--color-text); font-size: var(--text-sm); font-weight: var(--font-medium); line-height: var(--leading-normal); padding: 0; text-align: center; } span { border-color: var(--color-border); } span:hover { background: transparent; } span.arrowUp::after { border-bottom-color: var(--color-text); } span.arrowDown::after { border-top-color: var(--color-text); } &:hover { background: transparent; } } .flatpickr-weekday { color: var(--color-text-subtle); font-weight: var(--font-normal); } .flatpickr-time { .hasTime & { border-top-color: var(--color-border); } .hasTime.noCalendar & { border: 0; } .numInput { background: transparent; color: var(--color-text); } .flatpickr-time-separator { color: var(--color-text); } .flatpickr-am-pm { background: transparent; color: var(--color-text); } } .flatpickr-day { border-radius: var(--rounded-md); border-color: transparent !important; box-shadow: none !important; color: var(--color-text); height: var(--day-size); line-height: var(--day-size); margin-block-start: var(--size-2); max-width: var(--day-size); &:is(.inRange) { border-radius: 0; } &:is(.today, .inRange, :hover, :focus) { background: var(--color-border-light); color: var(--color-text); } &:is( .flatpickr-disabled, .flatpickr-disabled:hover, .prevMonthDay, .nextMonthDay, .notAllowed, .notAllowed.prevMonthDay, .notAllowed.nextMonthDay ) { color: var(--color-text-subtle); } &:is( .selected, .startRange, .endRange, .selected.inRange, .startRange.inRange, .endRange.inRange, .selected:focus, .startRange:focus, .endRange:focus, .selected:hover, .startRange:hover, .endRange:hover, .selected.prevMonthDay, .startRange.prevMonthDay, .endRange.prevMonthDay, .selected.nextMonthDay, .startRange.nextMonthDay, .endRange.nextMonthDay ) { background: var(--color-primary); color: var(--color-text-reversed); } } &::before, &::after { display: none; }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { Controller } from "@hotwired/stimulus"import flatpickr from "https://esm.sh/flatpickr@4.6.13?standalone"export default class extends Controller { static values = { type: String, disable: Array, mode: { type: String, default: "single" }, showMonths: { type: Number, default: 1 }, dateFormat: { type: String, default: "F d, Y" }, dateTimeFormat: { type: String, default: "F d, Y H:i" } } connect() { if (this.typeValue == "time") { this.flatpickr = flatpickr(this.element, this.#timeOptions) } else if (this.typeValue == "datetime") { this.flatpickr = flatpickr(this.element, this.#dateTimeOptions) } else { this.flatpickr = flatpickr(this.element, this.#basicOptions) } } disconnect() { this.flatpickr.destroy() } get #timeOptions() { return { dateFormat: "H:i", enableTime: true, noCalendar: true } } get #dateTimeOptions() { return { ...this.#baseOptions, altFormat: this.dateTimeFormatValue, dateFormat: "Y-m-d H:i", enableTime: true } } get #basicOptions() { return { ...this.#baseOptions, altFormat: this.dateFormatValue, dateFormat: "Y-m-d" } } get #baseOptions() { return { altInput: true, disable: this.disableValue, mode: this.modeValue, showMonths: this.showMonthsValue } }}