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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/pb_card/_card.scss +2 -3
  3. data/app/pb_kits/playbook/pb_card/card.rb +1 -1
  4. data/app/pb_kits/playbook/pb_card/docs/_card_background.html.erb +22 -35
  5. data/app/pb_kits/playbook/pb_card/docs/_card_background.jsx +34 -37
  6. data/app/pb_kits/playbook/pb_card/docs/_card_header.html.erb +27 -44
  7. data/app/pb_kits/playbook/pb_card/docs/_card_header.jsx +21 -33
  8. data/app/pb_kits/playbook/pb_card/docs/_card_highlight.html.erb +7 -7
  9. data/app/pb_kits/playbook/pb_card/docs/_card_highlight.jsx +6 -8
  10. data/app/pb_kits/playbook/pb_date_picker/_date_picker.scss +26 -0
  11. data/app/pb_kits/playbook/pb_date_picker/_date_picker.tsx +105 -95
  12. data/app/pb_kits/playbook/pb_date_picker/date_picker.html.erb +1 -1
  13. data/app/pb_kits/playbook/pb_date_picker/date_picker.rb +60 -1
  14. data/app/pb_kits/playbook/pb_date_picker/date_picker_helper.ts +16 -3
  15. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_close.jsx +43 -0
  16. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_on_close.md +3 -0
  17. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.html.erb +8 -0
  18. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_quick_pick.jsx +18 -0
  19. data/app/pb_kits/playbook/pb_date_picker/docs/_date_picker_range.jsx +1 -0
  20. data/app/pb_kits/playbook/pb_date_picker/docs/example.yml +3 -0
  21. data/app/pb_kits/playbook/pb_date_picker/docs/index.js +2 -0
  22. data/app/pb_kits/playbook/pb_date_picker/plugins/quickPick.ts +166 -0
  23. data/app/pb_kits/playbook/pb_date_picker/sass_partials/_quick_pick_styles.scss +56 -0
  24. data/app/pb_kits/playbook/pb_layout/_layout.tsx +6 -1
  25. data/app/pb_kits/playbook/pb_legend/docs/_legend_colors.html.erb +4 -4
  26. data/app/pb_kits/playbook/pb_legend/docs/_legend_colors.jsx +5 -5
  27. data/app/pb_kits/playbook/pb_legend/docs/_legend_custom_colors.html.erb +3 -3
  28. data/app/pb_kits/playbook/pb_legend/docs/_legend_custom_colors.jsx +3 -3
  29. data/app/pb_kits/playbook/pb_nav/_item.tsx +5 -5
  30. data/app/pb_kits/playbook/pb_nav/_nav.tsx +2 -2
  31. data/app/pb_kits/playbook/pb_nav/_subtle_mixin.scss +1 -1
  32. data/app/pb_kits/playbook/pb_phone_number_input/_phone_number_input.tsx +23 -9
  33. data/app/pb_kits/playbook/pb_table/docs/_table_side_highlight.html.erb +6 -6
  34. data/app/pb_kits/playbook/pb_table/docs/_table_side_highlight.jsx +6 -6
  35. data/app/pb_kits/playbook/tokens/_colors.scss +55 -15
  36. data/app/pb_kits/playbook/tokens/_positioning.scss +13 -0
  37. data/app/pb_kits/playbook/utilities/_colors.scss +7 -13
  38. data/app/pb_kits/playbook/utilities/_positioning.scss +20 -0
  39. data/app/pb_kits/playbook/utilities/globalProps.ts +11 -2
  40. data/lib/playbook/classnames.rb +1 -0
  41. data/lib/playbook/kit_base.rb +2 -0
  42. data/lib/playbook/position.rb +33 -0
  43. data/lib/playbook/version.rb +2 -2
  44. metadata +14 -7
@@ -1,4 +1,4 @@
1
- import React, { useEffect } from 'react'
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?: any,
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
- globalProps(props),
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
- {...ariaProps}
149
- {...dataProps}
150
- className={classes}
151
- id={id}
155
+ {...ariaProps}
156
+ {...dataProps}
157
+ className={classes}
158
+ id={id}
152
159
  >
153
160
  <div
154
- {...inputAriaProps}
155
- {...inputDataProps}
156
- className="input_wrapper">
161
+ {...inputAriaProps}
162
+ {...inputDataProps}
163
+ className="input_wrapper"
164
+ >
157
165
 
158
166
  <Caption
159
- className="pb_date_picker_kit_label"
160
- text={hideLabel ? null : label}
167
+ className="pb_date_picker_kit_label"
168
+ text={hideLabel ? null : label}
161
169
  />
162
-
163
- <div className="date_picker_input_wrapper">
164
- <input
165
- autoComplete="off"
166
- className="date_picker_input"
167
- disabled={disableInput}
168
- id={pickerId}
169
- name={name}
170
- onChange={inputOnChange}
171
- placeholder={placeholder}
172
- value={inputValue}
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
- </div>
216
- : null}
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
@@ -64,4 +64,4 @@
64
64
  datePickerHelper(<%= object.date_picker_config %>, "<%= object.scroll_container %>")
65
65
  })
66
66
  <% end %>
67
- <% end %>
67
+ <% end %>
@@ -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
- let pluginList = []
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,8 @@
1
+ <%= pb_rails("date_picker", props: {
2
+ allow_input: true,
3
+ mode: "range",
4
+ picker_id: "date-picker-quick-pick",
5
+ placeholder: "mm/dd/yyyy → mm/dd/yyyy",
6
+ selection_type: "quickpick"
7
+ }) %>
8
+
@@ -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
@@ -5,6 +5,7 @@ import DatePicker from '../_date_picker'
5
5
  const DatePickerRange = (props) => (
6
6
  <div>
7
7
  <DatePicker
8
+ allowInput
8
9
  defaultDate={[new Date(), new Date().fp_incr(7)]}
9
10
  mode="range"
10
11
  pickerId="date-picker-range"
@@ -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;