playbook_ui 12.13.0 → 12.14.0.pre.alpha.PLAY603datepickerquickpickinputpresetdropdown456
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_card/_card.scss +2 -3
- data/app/pb_kits/playbook/pb_card/card.rb +1 -1
- data/app/pb_kits/playbook/pb_card/docs/_card_background.html.erb +22 -35
- data/app/pb_kits/playbook/pb_card/docs/_card_background.jsx +34 -37
- data/app/pb_kits/playbook/pb_card/docs/_card_header.html.erb +27 -44
- data/app/pb_kits/playbook/pb_card/docs/_card_header.jsx +21 -33
- data/app/pb_kits/playbook/pb_card/docs/_card_highlight.html.erb +7 -7
- data/app/pb_kits/playbook/pb_card/docs/_card_highlight.jsx +6 -8
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +26 -0
- data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +105 -95
- data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +1 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +60 -1
- data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +16 -3
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_close.jsx +43 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_close.md +3 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.html.erb +8 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.jsx +18 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range.jsx +1 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +3 -0
- data/app/pb_kits/playbook/pb_date_picker/docs/index.js +2 -0
- data/app/pb_kits/playbook/pb_date_picker/plugins/quickPick.ts +166 -0
- data/app/pb_kits/playbook/pb_date_picker/sass_partials/_quick_pick_styles.scss +56 -0
- data/app/pb_kits/playbook/pb_layout/_layout.tsx +6 -1
- data/app/pb_kits/playbook/pb_legend/docs/_legend_colors.html.erb +4 -4
- data/app/pb_kits/playbook/pb_legend/docs/_legend_colors.jsx +5 -5
- data/app/pb_kits/playbook/pb_legend/docs/_legend_custom_colors.html.erb +3 -3
- data/app/pb_kits/playbook/pb_legend/docs/_legend_custom_colors.jsx +3 -3
- data/app/pb_kits/playbook/pb_nav/_item.tsx +5 -5
- data/app/pb_kits/playbook/pb_nav/_nav.tsx +2 -2
- data/app/pb_kits/playbook/pb_nav/_subtle_mixin.scss +1 -1
- data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +23 -9
- data/app/pb_kits/playbook/pb_table/docs/_table_side_highlight.html.erb +6 -6
- data/app/pb_kits/playbook/pb_table/docs/_table_side_highlight.jsx +6 -6
- data/app/pb_kits/playbook/tokens/_colors.scss +55 -15
- data/app/pb_kits/playbook/tokens/_positioning.scss +13 -0
- data/app/pb_kits/playbook/utilities/_colors.scss +7 -13
- data/app/pb_kits/playbook/utilities/_positioning.scss +20 -0
- data/app/pb_kits/playbook/utilities/globalProps.ts +11 -2
- data/lib/playbook/classnames.rb +1 -0
- data/lib/playbook/kit_base.rb +2 -0
- data/lib/playbook/position.rb +33 -0
- data/lib/playbook/version.rb +2 -2
- metadata +14 -7
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { useEffect
|
1
|
+
import React, { useEffect} from 'react'
|
2
2
|
import classnames from 'classnames'
|
3
3
|
|
4
4
|
import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
|
@@ -30,7 +30,7 @@ type DatePickerProps = {
|
|
30
30
|
inputAria?: { [key: string]: string },
|
31
31
|
inputData?: { [key: string]: string },
|
32
32
|
inputOnChange?: (e: React.FormEvent<HTMLInputElement>) => void,
|
33
|
-
inputValue?:
|
33
|
+
inputValue?: string,
|
34
34
|
label?: string,
|
35
35
|
maxDate: string,
|
36
36
|
minDate: string,
|
@@ -39,7 +39,7 @@ type DatePickerProps = {
|
|
39
39
|
placeholder?: string,
|
40
40
|
positionElement?: HTMLElement | null,
|
41
41
|
scrollContainer?: string,
|
42
|
-
selectionType?: "month" | "week",
|
42
|
+
selectionType?: "month" | "week"| "quickpick",
|
43
43
|
showTimezone?: boolean,
|
44
44
|
staticPosition: boolean,
|
45
45
|
timeFormat?: string,
|
@@ -78,6 +78,7 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
|
|
78
78
|
mode = 'single',
|
79
79
|
name,
|
80
80
|
onChange = () => { void 0 },
|
81
|
+
onClose,
|
81
82
|
pickerId,
|
82
83
|
placeholder = 'Select Date',
|
83
84
|
plugins = false,
|
@@ -95,40 +96,46 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
|
|
95
96
|
const inputAriaProps = buildAriaProps(inputAria)
|
96
97
|
const inputDataProps = buildDataProps(inputData)
|
97
98
|
|
99
|
+
useEffect(() => {
|
100
|
+
datePickerHelper({
|
101
|
+
allowInput,
|
102
|
+
defaultDate,
|
103
|
+
disableDate,
|
104
|
+
disableRange,
|
105
|
+
disableWeekdays,
|
106
|
+
enableTime,
|
107
|
+
format,
|
108
|
+
hideIcon,
|
109
|
+
inLine,
|
110
|
+
maxDate,
|
111
|
+
minDate,
|
112
|
+
mode,
|
113
|
+
onChange,
|
114
|
+
onClose,
|
115
|
+
pickerId,
|
116
|
+
plugins,
|
117
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
118
|
+
// @ts-ignore
|
119
|
+
position,
|
120
|
+
positionElement,
|
121
|
+
selectionType,
|
122
|
+
showTimezone,
|
123
|
+
staticPosition,
|
124
|
+
yearRange,
|
125
|
+
required: false,
|
126
|
+
}, scrollContainer)
|
127
|
+
})
|
128
|
+
const filteredProps = {...props}
|
129
|
+
delete filteredProps?.position
|
130
|
+
|
98
131
|
const classes = classnames(
|
99
132
|
buildCss('pb_date_picker_kit'),
|
100
|
-
|
133
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
134
|
+
//@ts-ignore
|
135
|
+
globalProps(filteredProps),
|
101
136
|
error ? 'error' : null,
|
102
137
|
className
|
103
138
|
)
|
104
|
-
|
105
|
-
useEffect(() => {
|
106
|
-
datePickerHelper({
|
107
|
-
allowInput,
|
108
|
-
defaultDate,
|
109
|
-
disableDate,
|
110
|
-
disableRange,
|
111
|
-
disableWeekdays,
|
112
|
-
enableTime,
|
113
|
-
format,
|
114
|
-
hideIcon,
|
115
|
-
inLine,
|
116
|
-
maxDate,
|
117
|
-
minDate,
|
118
|
-
mode,
|
119
|
-
onChange,
|
120
|
-
pickerId,
|
121
|
-
plugins,
|
122
|
-
position,
|
123
|
-
positionElement,
|
124
|
-
selectionType,
|
125
|
-
showTimezone,
|
126
|
-
staticPosition,
|
127
|
-
yearRange,
|
128
|
-
required: false,
|
129
|
-
}, scrollContainer)
|
130
|
-
})
|
131
|
-
|
132
139
|
const iconWrapperClass = () => {
|
133
140
|
let base = 'cal_icon_wrapper'
|
134
141
|
if (dark) {
|
@@ -145,78 +152,81 @@ const DatePicker = (props: DatePickerProps): React.ReactElement => {
|
|
145
152
|
|
146
153
|
return (
|
147
154
|
<div
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
155
|
+
{...ariaProps}
|
156
|
+
{...dataProps}
|
157
|
+
className={classes}
|
158
|
+
id={id}
|
152
159
|
>
|
153
160
|
<div
|
154
|
-
|
155
|
-
|
156
|
-
|
161
|
+
{...inputAriaProps}
|
162
|
+
{...inputDataProps}
|
163
|
+
className="input_wrapper"
|
164
|
+
>
|
157
165
|
|
158
166
|
<Caption
|
159
|
-
|
160
|
-
|
167
|
+
className="pb_date_picker_kit_label"
|
168
|
+
text={hideLabel ? null : label}
|
161
169
|
/>
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
/>
|
174
|
-
|
175
|
-
{error && <Body
|
176
|
-
status="negative"
|
177
|
-
text={error}
|
178
|
-
variant={null}
|
179
|
-
/>
|
180
|
-
}
|
181
|
-
</div>
|
182
|
-
|
183
|
-
{!hideIcon &&
|
184
|
-
<div
|
185
|
-
className={iconWrapperClass()}
|
186
|
-
id={`cal-icon-${pickerId}`}
|
187
|
-
>
|
188
|
-
<Icon
|
189
|
-
className="cal_icon"
|
190
|
-
icon="calendar-alt"
|
191
|
-
/>
|
192
|
-
</div>
|
193
|
-
}
|
194
|
-
|
195
|
-
{hideIcon && inLine ?
|
196
|
-
<div>
|
197
|
-
<div
|
198
|
-
className={iconWrapperClass()}
|
199
|
-
id={`${pickerId}-icon-plus`}
|
200
|
-
>
|
201
|
-
<Icon
|
202
|
-
className="date-picker-plus-icon"
|
203
|
-
icon="plus"
|
204
|
-
/>
|
205
|
-
</div>
|
206
|
-
<div
|
207
|
-
className={iconWrapperClass()}
|
208
|
-
id={`${pickerId}-angle-down`}
|
209
|
-
>
|
210
|
-
<Icon
|
211
|
-
className="angle_down_icon"
|
212
|
-
icon="angle-down"
|
170
|
+
<>
|
171
|
+
<div className="date_picker_input_wrapper">
|
172
|
+
<input
|
173
|
+
autoComplete="off"
|
174
|
+
className="date_picker_input"
|
175
|
+
disabled={disableInput}
|
176
|
+
id={pickerId}
|
177
|
+
name={name}
|
178
|
+
onChange={inputOnChange}
|
179
|
+
placeholder={placeholder}
|
180
|
+
value={inputValue}
|
213
181
|
/>
|
182
|
+
|
183
|
+
{error &&
|
184
|
+
<Body
|
185
|
+
status="negative"
|
186
|
+
text={error}
|
187
|
+
variant={null}
|
188
|
+
/>
|
189
|
+
}
|
214
190
|
</div>
|
215
|
-
|
216
|
-
|
191
|
+
|
192
|
+
{!hideIcon &&
|
193
|
+
<div
|
194
|
+
className={iconWrapperClass()}
|
195
|
+
id={`cal-icon-${pickerId}`}
|
196
|
+
>
|
197
|
+
<Icon
|
198
|
+
className="cal_icon"
|
199
|
+
icon="calendar-alt"
|
200
|
+
/>
|
201
|
+
</div>
|
202
|
+
}
|
203
|
+
|
204
|
+
{hideIcon && inLine ?
|
205
|
+
<div>
|
206
|
+
<div
|
207
|
+
className={iconWrapperClass()}
|
208
|
+
id={`${pickerId}-icon-plus`}
|
209
|
+
>
|
210
|
+
<Icon
|
211
|
+
className="date-picker-plus-icon"
|
212
|
+
icon="plus"
|
213
|
+
/>
|
214
|
+
</div>
|
215
|
+
<div
|
216
|
+
className={iconWrapperClass()}
|
217
|
+
id={`${pickerId}-angle-down`}
|
218
|
+
>
|
219
|
+
<Icon
|
220
|
+
className="angle_down_icon"
|
221
|
+
icon="angle-down"
|
222
|
+
/>
|
223
|
+
</div>
|
224
|
+
</div>
|
225
|
+
: null
|
226
|
+
}
|
227
|
+
</>
|
217
228
|
</div>
|
218
229
|
</div>
|
219
230
|
)
|
220
231
|
}
|
221
|
-
|
222
232
|
export default DatePicker
|
@@ -51,7 +51,7 @@ module Playbook
|
|
51
51
|
prop :position_element, type: Playbook::Props::String
|
52
52
|
prop :scroll_container, type: Playbook::Props::String
|
53
53
|
prop :selection_type, type: Playbook::Props::Enum,
|
54
|
-
values: %w[week month none],
|
54
|
+
values: %w[week month quickpick none],
|
55
55
|
default: "none"
|
56
56
|
prop :show_timezone, type: Playbook::Props::Boolean,
|
57
57
|
default: false
|
@@ -103,6 +103,65 @@ module Playbook
|
|
103
103
|
class_string += error_class
|
104
104
|
class_string
|
105
105
|
end
|
106
|
+
|
107
|
+
def format_date(date)
|
108
|
+
date.strftime("%m/%d/%Y")
|
109
|
+
end
|
110
|
+
|
111
|
+
def date_ranges
|
112
|
+
[
|
113
|
+
{
|
114
|
+
label: "Today",
|
115
|
+
start_date: format_date(::Date.current),
|
116
|
+
end_date: format_date(::Date.current),
|
117
|
+
},
|
118
|
+
{
|
119
|
+
label: "Yesterday",
|
120
|
+
start_date: format_date(::Date.current.yesterday),
|
121
|
+
end_date: format_date(::Date.current.yesterday),
|
122
|
+
},
|
123
|
+
{
|
124
|
+
label: "This Week",
|
125
|
+
start_date: format_date(::Date.current.beginning_of_week),
|
126
|
+
end_date: format_date(::Date.current.end_of_week),
|
127
|
+
},
|
128
|
+
{
|
129
|
+
label: "This Month",
|
130
|
+
start_date: format_date(::Date.current.beginning_of_month),
|
131
|
+
end_date: format_date(::Date.current),
|
132
|
+
},
|
133
|
+
{
|
134
|
+
label: "This Quarter",
|
135
|
+
start_date: format_date(::Date.current.beginning_of_quarter),
|
136
|
+
end_date: format_date(::Date.current),
|
137
|
+
},
|
138
|
+
{
|
139
|
+
label: "This Year",
|
140
|
+
start_date: format_date(::Date.current.beginning_of_year),
|
141
|
+
end_date: format_date(::Date.current),
|
142
|
+
},
|
143
|
+
{
|
144
|
+
label: "Last Week",
|
145
|
+
start_date: format_date(::Date.current.last_week.beginning_of_week),
|
146
|
+
end_date: format_date(::Date.current.last_week.end_of_week),
|
147
|
+
},
|
148
|
+
{
|
149
|
+
label: "Last Month",
|
150
|
+
start_date: format_date(::Date.current.last_month.beginning_of_month),
|
151
|
+
end_date: format_date(::Date.current.last_month.end_of_month),
|
152
|
+
},
|
153
|
+
{
|
154
|
+
label: "Last Quarter",
|
155
|
+
start_date: format_date(::Date.current.last_quarter.beginning_of_quarter),
|
156
|
+
end_date: format_date(::Date.current.last_quarter.end_of_quarter),
|
157
|
+
},
|
158
|
+
{
|
159
|
+
label: "Last Year",
|
160
|
+
start_date: format_date(::Date.current.last_year.beginning_of_year),
|
161
|
+
end_date: format_date(::Date.current.last_year.end_of_year),
|
162
|
+
},
|
163
|
+
]
|
164
|
+
end
|
106
165
|
end
|
107
166
|
end
|
108
167
|
end
|
@@ -3,6 +3,7 @@ import { BaseOptions } from 'flatpickr/dist/types/options'
|
|
3
3
|
import monthSelectPlugin from 'flatpickr/dist/plugins/monthSelect'
|
4
4
|
import weekSelect from "flatpickr/dist/plugins/weekSelect/weekSelect"
|
5
5
|
import timeSelectPlugin from './plugins/timeSelect'
|
6
|
+
import quickPickPlugin from './plugins/quickPick'
|
6
7
|
|
7
8
|
const getPositionElement = (element: string | Element) => {
|
8
9
|
return (typeof element === 'string') ? document.querySelectorAll(element)[0] : element
|
@@ -19,7 +20,8 @@ type DatePickerConfig = {
|
|
19
20
|
hideIcon?: boolean;
|
20
21
|
inLine?: boolean,
|
21
22
|
onChange: (dateStr: string, selectedDates: Date[]) => void,
|
22
|
-
selectionType?: "month" | "week" | "",
|
23
|
+
selectionType?: "month" | "week" | "quickpick" | "",
|
24
|
+
onClose: (dateStr: Date[] | string, selectedDates: Date[] | string) => void,
|
23
25
|
showTimezone?: boolean,
|
24
26
|
staticPosition: boolean,
|
25
27
|
timeCaption?: string,
|
@@ -41,6 +43,7 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
|
|
41
43
|
minDate,
|
42
44
|
mode,
|
43
45
|
onChange = () => {},
|
46
|
+
onClose = () => {},
|
44
47
|
pickerId,
|
45
48
|
plugins,
|
46
49
|
position = "auto",
|
@@ -88,18 +91,23 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
|
|
88
91
|
}
|
89
92
|
|
90
93
|
const setPlugins = () => {
|
91
|
-
|
94
|
+
const pluginList = []
|
92
95
|
|
93
96
|
// month and week selection
|
94
97
|
if (selectionType === "month" || plugins.length > 0) {
|
95
98
|
pluginList.push(monthSelectPlugin({ shorthand: true, dateFormat: 'F Y', altFormat: 'F Y' }))
|
96
99
|
} else if ( selectionType === "week") {
|
97
100
|
pluginList.push(weekSelect())
|
101
|
+
|
102
|
+
} else if (selectionType === "quickpick") {
|
103
|
+
//------- QUICKPICK VARIANT PLUGIN -------------//
|
104
|
+
pluginList.push(quickPickPlugin())
|
98
105
|
}
|
99
106
|
|
100
107
|
// time selection
|
101
108
|
if (enableTime) pluginList.push(timeSelectPlugin({ caption: timeCaption, showTimezone: showTimezone}))
|
102
109
|
|
110
|
+
|
103
111
|
return pluginList
|
104
112
|
}
|
105
113
|
|
@@ -142,6 +150,9 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
|
|
142
150
|
},
|
143
151
|
] : disabledParser(),
|
144
152
|
enableTime,
|
153
|
+
locale: {
|
154
|
+
rangeSeparator: ' → '
|
155
|
+
},
|
145
156
|
maxDate,
|
146
157
|
minDate,
|
147
158
|
mode,
|
@@ -151,9 +162,10 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
|
|
151
162
|
window.addEventListener('resize', calendarResizer)
|
152
163
|
if (!staticPosition && scrollContainer) attachToScroll(scrollContainer)
|
153
164
|
}],
|
154
|
-
onClose: [() => {
|
165
|
+
onClose: [(selectedDates, dateStr) => {
|
155
166
|
window.removeEventListener('resize', calendarResizer)
|
156
167
|
if (!staticPosition && scrollContainer) detachFromScroll(scrollContainer as HTMLElement)
|
168
|
+
onClose(selectedDates, dateStr)
|
157
169
|
}],
|
158
170
|
onChange: [(selectedDates, dateStr) => {
|
159
171
|
onChange(dateStr, selectedDates)
|
@@ -168,6 +180,7 @@ const datePickerHelper = (config: DatePickerConfig, scrollContainer: string | HT
|
|
168
180
|
static: staticPosition,
|
169
181
|
})
|
170
182
|
|
183
|
+
|
171
184
|
// ===========================================================
|
172
185
|
// Additional JS Functionality |
|
173
186
|
// ===========================================================
|
@@ -0,0 +1,43 @@
|
|
1
|
+
/* eslint-disable react/no-multi-comp */
|
2
|
+
import React, { useState } from 'react'
|
3
|
+
import { DatePicker,LabelValue } from '../..'
|
4
|
+
|
5
|
+
|
6
|
+
const DatePickerOnClose = (props) => {
|
7
|
+
const today = new Date()
|
8
|
+
const [dateString, setDateString] = useState(today.toLocaleDateString())
|
9
|
+
const [dateObj, setDateObj] = useState([today])
|
10
|
+
|
11
|
+
const handleOnClose = (selectedDates, dateStr) => {
|
12
|
+
setDateString(dateStr)
|
13
|
+
setDateObj(selectedDates)
|
14
|
+
}
|
15
|
+
|
16
|
+
|
17
|
+
return (
|
18
|
+
<div>
|
19
|
+
<DatePicker
|
20
|
+
defaultDate={dateString}
|
21
|
+
enableTime
|
22
|
+
marginBottom="lg"
|
23
|
+
onClose={handleOnClose}
|
24
|
+
pickerId="date-picker-on-close"
|
25
|
+
showTimezone
|
26
|
+
{...props}
|
27
|
+
/>
|
28
|
+
<LabelValue
|
29
|
+
label="Date Object"
|
30
|
+
marginBottom="lg"
|
31
|
+
value={dateObj[0] ? dateObj[0].toString() : ''}
|
32
|
+
{...props}
|
33
|
+
/>
|
34
|
+
<LabelValue
|
35
|
+
label="Date String"
|
36
|
+
value={dateString}
|
37
|
+
{...props}
|
38
|
+
/>
|
39
|
+
</div>
|
40
|
+
)
|
41
|
+
}
|
42
|
+
|
43
|
+
export default DatePickerOnClose
|
@@ -0,0 +1,3 @@
|
|
1
|
+
The `onClose` handler function has access to two arguments: `dateStr` and `selectedDates`.
|
2
|
+
|
3
|
+
The first, `dateStr`, is a string of the chosen date. The second, `selectedDates`, is an array of selected date objects. In many use cases `selectedDates` will have only one value but you'll still need to access it from index 0.
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import React from 'react'
|
2
|
+
|
3
|
+
import DatePicker from '../_date_picker'
|
4
|
+
|
5
|
+
const DatePickerQuickPick = (props) => (
|
6
|
+
<div>
|
7
|
+
<DatePicker
|
8
|
+
allowInput
|
9
|
+
mode="range"
|
10
|
+
pickerId="date-picker-quick-pick"
|
11
|
+
placeholder="mm/dd/yyyy → mm/dd/yyyy"
|
12
|
+
selectionType="quickpick"
|
13
|
+
{...props}
|
14
|
+
/>
|
15
|
+
</div>
|
16
|
+
)
|
17
|
+
|
18
|
+
export default DatePickerQuickPick
|
@@ -21,6 +21,7 @@ examples:
|
|
21
21
|
- date_picker_week: Week
|
22
22
|
- date_picker_time: Time Selection
|
23
23
|
- date_picker_positions: Custom Positions
|
24
|
+
- date_picker_quick_pick: Quick Pick
|
24
25
|
- date_picker_positions_element: Custom Position (based on element)
|
25
26
|
|
26
27
|
react:
|
@@ -31,6 +32,7 @@ examples:
|
|
31
32
|
- date_picker_input: Input Field
|
32
33
|
- date_picker_label: Label
|
33
34
|
- date_picker_on_change: onChange
|
35
|
+
- date_picker_on_close: onClose
|
34
36
|
- date_picker_range: Range
|
35
37
|
- date_picker_format: Format
|
36
38
|
- date_picker_disabled: Disabled Dates
|
@@ -44,4 +46,5 @@ examples:
|
|
44
46
|
- date_picker_week: Week
|
45
47
|
- date_picker_time: Time Selection
|
46
48
|
- date_picker_positions: Custom Positions
|
49
|
+
- date_picker_quick_pick: Quick Pick
|
47
50
|
- date_picker_positions_element: Custom Position (based on element)
|
@@ -19,3 +19,5 @@ export { default as DatePickerWeek } from './_date_picker_week.jsx'
|
|
19
19
|
export { default as DatePickerPositions } from './_date_picker_positions.jsx'
|
20
20
|
export { default as DatePickerPositionsElement } from './_date_picker_positions_element.jsx'
|
21
21
|
export { default as DatePickerAllowInput } from './_date_picker_allow_input'
|
22
|
+
export { default as DatePickerQuickPick } from './_date_picker_quick_pick'
|
23
|
+
export { default as DatePickerOnClose } from './_date_picker_on_close.jsx'
|
@@ -0,0 +1,166 @@
|
|
1
|
+
import moment from 'moment'
|
2
|
+
|
3
|
+
type FpTypes = {
|
4
|
+
setDate: (arg0: any, arg1: boolean) => void,
|
5
|
+
config: { [key: string]: string },
|
6
|
+
clear: (arg0: boolean, arg1: boolean) => void,
|
7
|
+
close: () => void,
|
8
|
+
calendarContainer?: {
|
9
|
+
classList: { add: (arg0: string) => void };
|
10
|
+
prepend: (arg0: HTMLDivElement) => void;
|
11
|
+
append: (arg0: HTMLDivElement) => void;
|
12
|
+
},
|
13
|
+
loadedPlugins: string[],
|
14
|
+
};
|
15
|
+
|
16
|
+
type pluginDataType = {
|
17
|
+
ranges: { [key: string]: Date[] },
|
18
|
+
rangesNav: HTMLUListElement,
|
19
|
+
rangesButtons: [] | any,
|
20
|
+
}
|
21
|
+
|
22
|
+
const quickPickPlugin = () => {
|
23
|
+
return function (fp: FpTypes & any): any {
|
24
|
+
|
25
|
+
// variable that holds the ranges available
|
26
|
+
const ranges = {
|
27
|
+
'Today': [new Date(), new Date()],
|
28
|
+
'Yesterday': [moment().subtract(1, 'days').toDate(), moment().subtract(1, 'days').toDate()],
|
29
|
+
'This week': [moment().startOf('week').toDate(), moment().endOf('week').toDate()],
|
30
|
+
'This month': [moment().startOf('month').toDate(), moment().endOf('month').toDate()],
|
31
|
+
'This quarter': [moment().startOf('quarter').toDate(), moment().endOf('quarter').toDate()],
|
32
|
+
'This year': [moment().startOf('year').toDate(), moment().endOf('year').toDate()],
|
33
|
+
'Last week': [
|
34
|
+
moment().subtract(1, 'week').startOf('week').toDate(),
|
35
|
+
moment().subtract(1, 'week').endOf('week').toDate()
|
36
|
+
],
|
37
|
+
'Last month': [
|
38
|
+
moment().subtract(1, 'month').startOf('month').toDate(),
|
39
|
+
moment().subtract(1, 'month').endOf('month').toDate()
|
40
|
+
],
|
41
|
+
'Last quarter': [
|
42
|
+
moment().subtract(1, 'quarter').startOf('quarter').toDate(),
|
43
|
+
moment().subtract(1, 'quarter').endOf('quarter').toDate()
|
44
|
+
],
|
45
|
+
'Last year': [
|
46
|
+
moment().subtract(1, 'year').startOf('year').toDate(),
|
47
|
+
moment().subtract(1, 'year').endOf('year').toDate()
|
48
|
+
]
|
49
|
+
}
|
50
|
+
//creating the ul element for the nav dropdown and giving it classnames
|
51
|
+
const rangesNav = document.createElement('ul');
|
52
|
+
|
53
|
+
// creating the pluginData object that will hold the properties of this plugin
|
54
|
+
const pluginData: pluginDataType = {
|
55
|
+
ranges: ranges,
|
56
|
+
rangesNav: rangesNav,
|
57
|
+
rangesButtons: [],
|
58
|
+
};
|
59
|
+
|
60
|
+
/**
|
61
|
+
* @param {string} label
|
62
|
+
* @returns HTML Element
|
63
|
+
*/
|
64
|
+
|
65
|
+
//funciton for creating the range buttons in the nav
|
66
|
+
const addRangeButton = (label: string) => {
|
67
|
+
|
68
|
+
// create the button element and add class and text
|
69
|
+
const button = document.createElement('a');
|
70
|
+
button.className = "nav-item-link";
|
71
|
+
const itemLabel = document.createElement('span')
|
72
|
+
itemLabel.className = "nav-item-text"
|
73
|
+
itemLabel.innerHTML = label;
|
74
|
+
|
75
|
+
// create li elements inside the dropdown
|
76
|
+
const item = document.createElement('li');
|
77
|
+
item.className = "nav-item";
|
78
|
+
|
79
|
+
pluginData.rangesButtons[label] = button;
|
80
|
+
|
81
|
+
// append span text to anchor tag
|
82
|
+
pluginData.rangesButtons[label].appendChild(itemLabel)
|
83
|
+
|
84
|
+
// append those anchor tags to the li items
|
85
|
+
item.appendChild(pluginData.rangesButtons[label]);
|
86
|
+
|
87
|
+
// append the li item to the ul rangeNav prop
|
88
|
+
pluginData.rangesNav.appendChild(item);
|
89
|
+
|
90
|
+
// return the ranges buton prop
|
91
|
+
return pluginData.rangesButtons[label];
|
92
|
+
};
|
93
|
+
|
94
|
+
const selectActiveRangeButton = (selectedDates: Array<string>) => {
|
95
|
+
const current = pluginData.rangesNav.querySelector('.active');
|
96
|
+
|
97
|
+
if (current) {
|
98
|
+
current.classList.remove('active');
|
99
|
+
}
|
100
|
+
/** conditional statment to extract start and end dates from selectedDates,
|
101
|
+
* then loop through ranges prop in pluginData
|
102
|
+
* and check if chosen dates equal to a date in the ranges prop
|
103
|
+
* if they are equal, add the active class
|
104
|
+
*/
|
105
|
+
if (selectedDates.length > 0) {
|
106
|
+
|
107
|
+
const startDate = moment(selectedDates[0]);
|
108
|
+
const endDate = selectedDates.length > 1 ? moment(selectedDates[1]) : startDate;
|
109
|
+
|
110
|
+
for (const [label, range] of Object.entries(pluginData.ranges)) {
|
111
|
+
if (startDate.isSame(moment(range[0]), 'day') && endDate.isSame(moment(range[1]), 'day')) {
|
112
|
+
pluginData.rangesButtons[label].classList.add('active');
|
113
|
+
break;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
}
|
119
|
+
|
120
|
+
|
121
|
+
return {
|
122
|
+
// onReady is a hook from flatpickr that runs when calender is in a ready state
|
123
|
+
onReady(selectedDates: Array<string>) {
|
124
|
+
// loop through the ranges and create an anchor tag for each range and add an event listiner to set the date when user clicks on a date range
|
125
|
+
for (const [label, range] of Object.entries(pluginData.ranges)) {
|
126
|
+
addRangeButton(label).addEventListener('click', function () {
|
127
|
+
|
128
|
+
const start = moment(range[0]).toDate();
|
129
|
+
const end = moment(range[1]).toDate();
|
130
|
+
|
131
|
+
if (!start) {
|
132
|
+
fp.clear();
|
133
|
+
}
|
134
|
+
else {
|
135
|
+
fp.setDate([start, end], true);
|
136
|
+
}
|
137
|
+
|
138
|
+
fp.close();
|
139
|
+
});
|
140
|
+
}
|
141
|
+
|
142
|
+
// conditional to check if there is a dropdown to add it to the calendar container and git it the classes it needs
|
143
|
+
if (pluginData.rangesNav.children.length > 0) {
|
144
|
+
|
145
|
+
fp.calendarContainer.prepend(pluginData.rangesNav);
|
146
|
+
pluginData.rangesNav.classList.add('quick-pick-ul')
|
147
|
+
fp.calendarContainer.classList.add('quick-pick-drop-down');
|
148
|
+
|
149
|
+
/**
|
150
|
+
*
|
151
|
+
* @param {Array} selectedDates
|
152
|
+
*/
|
153
|
+
|
154
|
+
// function to give the active butto the active class
|
155
|
+
selectActiveRangeButton(selectedDates);
|
156
|
+
}
|
157
|
+
|
158
|
+
},
|
159
|
+
onValueUpdate(selectedDates: Array<string>) {
|
160
|
+
selectActiveRangeButton(selectedDates);
|
161
|
+
}
|
162
|
+
};
|
163
|
+
};
|
164
|
+
}
|
165
|
+
|
166
|
+
export default quickPickPlugin;
|