@spaced-out/ui-design-system 0.1.110 → 0.1.111

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.
@@ -4,6 +4,17 @@ import * as React from 'react';
4
4
  // $FlowFixMe[untyped-import]
5
5
  import moment from 'moment-timezone';
6
6
 
7
+ import type {DateRange, DateRangeWithTimezone} from '../../types';
8
+ import {
9
+ addTimezone,
10
+ generateAvailableYears,
11
+ getAvailableMonths,
12
+ getMonthEndDate,
13
+ getTimezones,
14
+ MARKERS,
15
+ MONTHS,
16
+ NAVIGATION_ACTION,
17
+ } from '../../utils';
7
18
  import classify from '../../utils/classify';
8
19
  import {Button} from '../Button';
9
20
  import {
@@ -19,24 +30,14 @@ import {FocusManager} from '../FocusManager';
19
30
  import {ClickableIcon} from '../Icon';
20
31
 
21
32
  import {Calendar} from './Calendar.js';
22
- import type {DateRange, DateRangeWithTimezone} from './utils';
23
- import {
24
- addTimezone,
25
- generateAvailableYears,
26
- getAddedDate,
27
- getAvailableMonths,
28
- getMonthStartDate,
29
- getTimezones,
30
- MARKERS,
31
- MONTHS,
32
- NAVIGATION_ACTION,
33
- } from './utils';
34
33
 
35
34
  import css from './DateRangeWrapper.module.css';
36
35
 
37
36
 
38
37
  type HeaderProps = {
39
38
  date: string,
39
+ minDate: string,
40
+ maxDate: string,
40
41
  rangeStartMonth: string,
41
42
  rangeEndMonth: string,
42
43
  nextDisabled: boolean,
@@ -50,6 +51,8 @@ type HeaderProps = {
50
51
  type DateRangeWrapperProps = {
51
52
  dateRange: DateRange,
52
53
  hoverDay: string,
54
+ minDate: string,
55
+ maxDate: string,
53
56
  rangeStartMonth: string,
54
57
  rangeEndMonth: string,
55
58
  cardWrapperClass: ?string,
@@ -74,6 +77,8 @@ type DateRangeWrapperProps = {
74
77
  const CalendarHeader = ({
75
78
  date,
76
79
  marker,
80
+ minDate,
81
+ maxDate,
77
82
  setMonth,
78
83
  rangeStartMonth,
79
84
  rangeEndMonth,
@@ -81,64 +86,73 @@ const CalendarHeader = ({
81
86
  nextDisabled,
82
87
  prevDisabled,
83
88
  onClickPrevious,
84
- }: HeaderProps): React.Node => (
85
- <div className={css.calendarHeader}>
86
- <ClickableIcon
87
- ariaLabel="Select Previous Month"
88
- size="small"
89
- name="chevron-left"
90
- className={classify(css.headerIcon, {
91
- [css.disabledIcon]: prevDisabled,
92
- })}
93
- onClick={onClickPrevious}
94
- color={prevDisabled ? 'disabled' : 'secondary'}
95
- />
96
- <Dropdown
97
- size="small"
98
- menu={{
99
- selectedKeys: [moment(date).month().toString()],
100
- options: getAvailableMonths(
101
- MONTHS,
102
- rangeStartMonth,
103
- rangeEndMonth,
104
- marker,
105
- ),
106
- }}
107
- onChange={(event) => {
108
- setMonth(getMonthStartDate(moment(date).set('M', event.key)));
109
- }}
110
- dropdownInputText={MONTHS[moment(date).month()].label}
111
- scrollMenuToBottom
112
- />
113
- <Dropdown
114
- menu={{
115
- selectedKeys: [moment(date).year().toString()],
116
- options: generateAvailableYears(
117
- 45,
118
- rangeStartMonth,
119
- rangeEndMonth,
120
- marker,
121
- ),
122
- }}
123
- size="small"
124
- onChange={(event) => {
125
- setMonth(getMonthStartDate(moment(date).set('y', event.key)));
126
- }}
127
- dropdownInputText={moment(date).year()}
128
- scrollMenuToBottom
129
- />
130
- <ClickableIcon
131
- size="small"
132
- ariaLabel="Select Next Month"
133
- name="chevron-right"
134
- className={classify(css.headerIcon, {
135
- [css.disabledIcon]: nextDisabled,
136
- })}
137
- onClick={onClickNext}
138
- color={nextDisabled ? 'disabled' : 'secondary'}
139
- />
140
- </div>
141
- );
89
+ }: HeaderProps): React.Node => {
90
+ const availableYears = generateAvailableYears({
91
+ marker,
92
+ minDate,
93
+ maxDate,
94
+ rangeStartMonth,
95
+ rangeEndMonth,
96
+ });
97
+ const availableMonths = getAvailableMonths({
98
+ marker,
99
+ minDate,
100
+ maxDate,
101
+ rangeStartMonth,
102
+ rangeEndMonth,
103
+ });
104
+
105
+ return (
106
+ <div className={css.calendarHeader}>
107
+ <ClickableIcon
108
+ ariaLabel="Select Previous Month"
109
+ size="small"
110
+ name="chevron-left"
111
+ className={classify(css.headerIcon, {
112
+ [css.disabledIcon]: prevDisabled,
113
+ })}
114
+ onClick={onClickPrevious}
115
+ color={prevDisabled ? 'disabled' : 'secondary'}
116
+ />
117
+ <Dropdown
118
+ size="small"
119
+ disabled={!availableMonths.length || moment(minDate).isAfter(maxDate)}
120
+ menu={{
121
+ selectedKeys: [moment(date).month().toString()],
122
+ options: availableMonths,
123
+ }}
124
+ onChange={(event) => {
125
+ setMonth(getMonthEndDate(moment(date).set('M', event.key)));
126
+ }}
127
+ dropdownInputText={MONTHS[moment(date).month()].label}
128
+ scrollMenuToBottom
129
+ />
130
+ <Dropdown
131
+ disabled={!availableYears.length || moment(minDate).isAfter(maxDate)}
132
+ menu={{
133
+ selectedKeys: [moment(date).year().toString()],
134
+ options: availableYears,
135
+ }}
136
+ size="small"
137
+ onChange={(event) => {
138
+ setMonth(getMonthEndDate(moment(date).set('y', event.key)));
139
+ }}
140
+ dropdownInputText={moment(date).year()}
141
+ scrollMenuToBottom
142
+ />
143
+ <ClickableIcon
144
+ size="small"
145
+ ariaLabel="Select Next Month"
146
+ name="chevron-right"
147
+ className={classify(css.headerIcon, {
148
+ [css.disabledIcon]: nextDisabled,
149
+ })}
150
+ onClick={onClickNext}
151
+ color={nextDisabled ? 'disabled' : 'secondary'}
152
+ />
153
+ </div>
154
+ );
155
+ };
142
156
 
143
157
  export const DateRangeWrapper: React$AbstractComponent<
144
158
  DateRangeWrapperProps,
@@ -150,6 +164,8 @@ export const DateRangeWrapper: React$AbstractComponent<
150
164
  onCancel,
151
165
  handlers,
152
166
  hoverDay,
167
+ minDate,
168
+ maxDate,
153
169
  timezone,
154
170
  dateRange,
155
171
  rangeStartMonth,
@@ -189,6 +205,8 @@ export const DateRangeWrapper: React$AbstractComponent<
189
205
  handlers,
190
206
  hoverDay,
191
207
  dateRange,
208
+ minDate,
209
+ maxDate,
192
210
  };
193
211
 
194
212
  return (
@@ -207,7 +225,12 @@ export const DateRangeWrapper: React$AbstractComponent<
207
225
  date={rangeStartMonth}
208
226
  setMonth={setRangeStartMonth}
209
227
  nextDisabled={!canNavigateCloser}
210
- prevDisabled={false}
228
+ prevDisabled={moment(rangeStartMonth).isSameOrBefore(
229
+ minDate,
230
+ 'M',
231
+ )}
232
+ minDate={minDate}
233
+ maxDate={maxDate}
211
234
  onClickNext={() =>
212
235
  onMonthNavigate(
213
236
  MARKERS.DATE_RANGE_START,
@@ -227,10 +250,10 @@ export const DateRangeWrapper: React$AbstractComponent<
227
250
  rangeEndMonth={rangeEndMonth}
228
251
  date={rangeEndMonth}
229
252
  setMonth={setRangeEndMonth}
230
- nextDisabled={moment(
231
- getAddedDate(rangeEndMonth, 1, 'M'),
232
- ).isSameOrAfter(moment())}
253
+ nextDisabled={moment(rangeEndMonth).isSameOrAfter(maxDate, 'M')}
233
254
  prevDisabled={!canNavigateCloser}
255
+ minDate={minDate}
256
+ maxDate={maxDate}
234
257
  onClickNext={() =>
235
258
  onMonthNavigate(MARKERS.DATE_RANGE_END, NAVIGATION_ACTION.NEXT)
236
259
  }
@@ -257,6 +280,7 @@ export const DateRangeWrapper: React$AbstractComponent<
257
280
  {!hideTimezone && (
258
281
  <SimpleDropdown
259
282
  options={getTimezones()}
283
+ disabled={moment(minDate).isAfter(maxDate)}
260
284
  classNames={{
261
285
  box: css.timezoneDropdown,
262
286
  }}
@@ -1,4 +1,3 @@
1
1
  // @flow strict
2
2
 
3
3
  export * from './DateRangePicker';
4
- export type {DateRange, DateRangeWithTimezone} from './utils';
@@ -27,6 +27,7 @@ const RenderOption = _ref => {
27
27
  groupTitleOptions,
28
28
  classNames,
29
29
  searchText = '',
30
+ showResultText = true,
30
31
  ...restProps
31
32
  } = _ref;
32
33
  const {
@@ -46,7 +47,7 @@ const RenderOption = _ref => {
46
47
  menuHeight,
47
48
  itemHeight
48
49
  } = virtualization;
49
- return /*#__PURE__*/React.createElement(React.Fragment, null, allowSearch && /*#__PURE__*/React.createElement(_Text.FormLabelSmall, {
50
+ return /*#__PURE__*/React.createElement(React.Fragment, null, allowSearch && showResultText && /*#__PURE__*/React.createElement(_Text.FormLabelSmall, {
50
51
  className: _MenuModule.default.filterOptionsResultText,
51
52
  color: "tertiary"
52
53
  }, resultText), virtualization && isVirtualizationEnabled ? /*#__PURE__*/React.createElement(_reactWindow.FixedSizeList, {
@@ -80,7 +81,7 @@ const RenderOption = _ref => {
80
81
  if (composeOptions && Array.isArray(composeOptions) && composeOptions.length) {
81
82
  const optionsFiltered = !allowSearch ? composeOptions : (0, _menu.getFilteredComposeOptionsFromSearchText)(composeOptions, searchText);
82
83
  const resultText = !allowSearch ? '' : (0, _menu.getFilteredComposeOptionsResultText)(optionsFiltered);
83
- return /*#__PURE__*/React.createElement(React.Fragment, null, allowSearch && /*#__PURE__*/React.createElement(_Text.FormLabelSmall, {
84
+ return /*#__PURE__*/React.createElement(React.Fragment, null, allowSearch && showResultText && /*#__PURE__*/React.createElement(_Text.FormLabelSmall, {
84
85
  className: _MenuModule.default.filterOptionsResultText,
85
86
  color: "tertiary"
86
87
  }, resultText), optionsFiltered.map((composeMenuOptions, index) =>
@@ -101,7 +102,7 @@ const RenderOption = _ref => {
101
102
  if (groupTitleOptions && Array.isArray(groupTitleOptions) && groupTitleOptions.length) {
102
103
  const optionsFiltered = !allowSearch ? groupTitleOptions : (0, _menu.getFilteredGroupTitleOptionsFromSearchText)(groupTitleOptions, searchText);
103
104
  const resultText = !allowSearch ? '' : (0, _menu.getFilteredGroupTitleOptionsResultText)(optionsFiltered);
104
- return /*#__PURE__*/React.createElement(React.Fragment, null, allowSearch && /*#__PURE__*/React.createElement(_Text.FormLabelSmall, {
105
+ return /*#__PURE__*/React.createElement(React.Fragment, null, allowSearch && showResultText && /*#__PURE__*/React.createElement(_Text.FormLabelSmall, {
105
106
  className: _MenuModule.default.filterOptionsResultText,
106
107
  color: "tertiary"
107
108
  }, resultText), optionsFiltered.map((optionsGroup, index) =>
@@ -163,7 +164,7 @@ const Menu = /*#__PURE__*/React.forwardRef((props, ref) => {
163
164
  },
164
165
  ref: ref
165
166
  }, hasHeader && /*#__PURE__*/React.createElement("div", {
166
- className: _MenuModule.default.menuHeader
167
+ className: (0, _classify.classify)(_MenuModule.default.menuHeader, classNames?.header)
167
168
  }, header), allowSearch && /*#__PURE__*/React.createElement(_SearchInput.SearchInput, {
168
169
  value: searchText,
169
170
  onChange: e => setSearchText(e.target.value),
@@ -172,7 +173,7 @@ const Menu = /*#__PURE__*/React.forwardRef((props, ref) => {
172
173
  }), /*#__PURE__*/React.createElement(RenderOption, _extends({}, props, {
173
174
  searchText: searchText
174
175
  })), hasFooter && /*#__PURE__*/React.createElement("div", {
175
- className: _MenuModule.default.menuFooter
176
+ className: (0, _classify.classify)(_MenuModule.default.menuFooter, classNames?.footer)
176
177
  }, footer));
177
178
  });
178
179
  exports.Menu = Menu;
@@ -75,6 +75,7 @@ export type BaseMenuProps = {
75
75
  virtualization?: Virtualization,
76
76
  header?: React.Node,
77
77
  footer?: React.Node,
78
+ showResultText?: boolean,
78
79
  };
79
80
 
80
81
  export type MenuOptionTypes = {
@@ -114,6 +115,7 @@ const RenderOption = ({
114
115
  groupTitleOptions,
115
116
  classNames,
116
117
  searchText = '',
118
+ showResultText = true,
117
119
  ...restProps
118
120
  }: RenderOptionProps): React.Node => {
119
121
  const {
@@ -141,7 +143,7 @@ const RenderOption = ({
141
143
 
142
144
  return (
143
145
  <>
144
- {allowSearch && (
146
+ {allowSearch && showResultText && (
145
147
  <FormLabelSmall
146
148
  className={css.filterOptionsResultText}
147
149
  color="tertiary"
@@ -204,7 +206,7 @@ const RenderOption = ({
204
206
 
205
207
  return (
206
208
  <>
207
- {allowSearch && (
209
+ {allowSearch && showResultText && (
208
210
  <FormLabelSmall
209
211
  className={css.filterOptionsResultText}
210
212
  color="tertiary"
@@ -250,7 +252,7 @@ const RenderOption = ({
250
252
 
251
253
  return (
252
254
  <>
253
- {allowSearch && (
255
+ {allowSearch && showResultText && (
254
256
  <FormLabelSmall
255
257
  className={css.filterOptionsResultText}
256
258
  color="tertiary"
@@ -348,7 +350,11 @@ export const Menu: React$AbstractComponent<MenuProps, HTMLDivElement> =
348
350
  }}
349
351
  ref={ref}
350
352
  >
351
- {hasHeader && <div className={css.menuHeader}>{header}</div>}
353
+ {hasHeader && (
354
+ <div className={classify(css.menuHeader, classNames?.header)}>
355
+ {header}
356
+ </div>
357
+ )}
352
358
  {allowSearch && (
353
359
  <SearchInput
354
360
  value={searchText}
@@ -358,7 +364,11 @@ export const Menu: React$AbstractComponent<MenuProps, HTMLDivElement> =
358
364
  />
359
365
  )}
360
366
  <RenderOption {...props} searchText={searchText} />
361
- {hasFooter && <div className={css.menuFooter}>{footer}</div>}
367
+ {hasFooter && (
368
+ <div className={classify(css.menuFooter, classNames?.footer)}>
369
+ {footer}
370
+ </div>
371
+ )}
362
372
  </div>
363
373
  );
364
374
  },
@@ -92,7 +92,7 @@
92
92
  }
93
93
 
94
94
  .smallWithHeader,
95
- .smallWithHeaderAndFooter {
95
+ .smallWithFooter {
96
96
  max-height: calc(size228 + size50);
97
97
  }
98
98
 
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+
3
+ var _dateRangePicker = require("../utils/date-range-picker");
@@ -0,0 +1,18 @@
1
+ // @flow strict
2
+
3
+ import {DATE_RANGE_PICKER_ERRORS} from '../utils/date-range-picker';
4
+
5
+
6
+ export type TimeUnit = 'years' | 'months' | 'days' | 'd' | 'M' | 'y';
7
+ export type DateRange = {startDate?: ?string, endDate?: ?string};
8
+ export type DateRangePickerErrorTypes = $Keys<typeof DATE_RANGE_PICKER_ERRORS>;
9
+ export type DateRangePickerError = {
10
+ type: string,
11
+ description: string,
12
+ };
13
+ export type DateRangeWithTimezone = {|
14
+ ...DateRange,
15
+ startDateUTC?: ?string,
16
+ endDateUTC?: ?string,
17
+ timezone?: string,
18
+ |};
@@ -25,6 +25,17 @@ Object.keys(_common).forEach(function (key) {
25
25
  }
26
26
  });
27
27
  });
28
+ var _dateRangePicker = require("./date-range-picker");
29
+ Object.keys(_dateRangePicker).forEach(function (key) {
30
+ if (key === "default" || key === "__esModule") return;
31
+ if (key in exports && exports[key] === _dateRangePicker[key]) return;
32
+ Object.defineProperty(exports, key, {
33
+ enumerable: true,
34
+ get: function () {
35
+ return _dateRangePicker[key];
36
+ }
37
+ });
38
+ });
28
39
  var _menu = require("./menu");
29
40
  Object.keys(_menu).forEach(function (key) {
30
41
  if (key === "default" || key === "__esModule") return;
@@ -2,6 +2,7 @@
2
2
 
3
3
  export * from './charts';
4
4
  export * from './common';
5
+ export * from './date-range-picker';
5
6
  export * from './menu';
6
7
  export * from './toast';
7
8
  export * from './typography';
@@ -6,4 +6,6 @@ export type MenuClassNames = $ReadOnly<{
6
6
  groupTitle?: string,
7
7
  optionTextContainer?: string,
8
8
  optionTextLabel?: string,
9
+ header?: string,
10
+ footer?: string,
9
11
  }>;