@spaced-out/ui-design-system 0.4.6 → 0.4.8

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.4.8](https://github.com/spaced-out/ui-design-system/compare/v0.4.7...v0.4.8) (2025-07-24)
6
+
7
+
8
+ ### Features
9
+
10
+ * localization in date range picker ([#377](https://github.com/spaced-out/ui-design-system/issues/377)) ([ae21b25](https://github.com/spaced-out/ui-design-system/commit/ae21b255c5f1a0122408000239eaf5c44abbd2b9))
11
+
12
+ ### [0.4.7](https://github.com/spaced-out/ui-design-system/compare/v0.4.6...v0.4.7) (2025-07-24)
13
+
14
+
15
+ ### Features
16
+
17
+ * static lables for simple dropdown ([#376](https://github.com/spaced-out/ui-design-system/issues/376)) ([397a108](https://github.com/spaced-out/ui-design-system/commit/397a1089b95bc3d5136cc81bd4a35c39f42d4fd5))
18
+
5
19
  ### [0.4.6](https://github.com/spaced-out/ui-design-system/compare/v0.4.5...v0.4.6) (2025-07-24)
6
20
 
7
21
  ### [0.4.5](https://github.com/spaced-out/ui-design-system/compare/v0.4.4...v0.4.5) (2025-07-24)
@@ -24,7 +24,8 @@ const Calendar = _ref => {
24
24
  hoverDay,
25
25
  dateRange,
26
26
  inHoverRange,
27
- today
27
+ today,
28
+ t
28
29
  } = _ref;
29
30
  return /*#__PURE__*/React.createElement("div", {
30
31
  className: _CalendarModule.default.calendar
@@ -34,7 +35,7 @@ const Calendar = _ref => {
34
35
  key: day,
35
36
  className: _CalendarModule.default.calendarRowItem,
36
37
  color: _Text.TEXT_COLORS.tertiary
37
- }, day))), (0, _utils.getDaysInMonth)(value).map((week, index) => /*#__PURE__*/React.createElement("div", {
38
+ }, (0, _dateRangePicker.getTranslation)(t, day)))), (0, _utils.getDaysInMonth)(value).map((week, index) => /*#__PURE__*/React.createElement("div", {
38
39
  key: week[index],
39
40
  className: _CalendarModule.default.calendarRow
40
41
  }, week.map(date => {
@@ -16,7 +16,12 @@ import {
16
16
  NAVIGATION_ACTION,
17
17
  WEEKDAYS,
18
18
  } from '../../utils';
19
- import {isAfter, isBefore, isSame} from '../../utils/date-range-picker';
19
+ import {
20
+ getTranslation,
21
+ isAfter,
22
+ isBefore,
23
+ isSame,
24
+ } from '../../utils/date-range-picker';
20
25
  import {BodySmall, TEXT_COLORS} from '../Text';
21
26
 
22
27
  import {Day} from './Day';
@@ -41,6 +46,7 @@ type CalendarProps = {
41
46
  ) => void,
42
47
  },
43
48
  today: string,
49
+ t: ?(key: string, fallback: string) => string,
44
50
  };
45
51
 
46
52
  export const Calendar = ({
@@ -53,6 +59,7 @@ export const Calendar = ({
53
59
  dateRange,
54
60
  inHoverRange,
55
61
  today,
62
+ t,
56
63
  }: CalendarProps): React.Node => (
57
64
  <div className={css.calendar}>
58
65
  <div className={css.calendarRow}>
@@ -62,7 +69,7 @@ export const Calendar = ({
62
69
  className={css.calendarRowItem}
63
70
  color={TEXT_COLORS.tertiary}
64
71
  >
65
- {day}
72
+ {getTranslation(t, day)}
66
73
  </BodySmall>
67
74
  ))}
68
75
  </div>
@@ -26,7 +26,9 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/React.forwardRef(
26
26
  hideTimezone = false,
27
27
  selectedDateRange = {},
28
28
  startDateLabel,
29
- endDateLabel
29
+ endDateLabel,
30
+ t,
31
+ locale
30
32
  } = _ref;
31
33
  const localTimezone = _momentTimezone.default.tz.guess();
32
34
  const {
@@ -43,7 +45,8 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/React.forwardRef(
43
45
  minDate,
44
46
  maxDate,
45
47
  today,
46
- onError
48
+ onError,
49
+ t
47
50
  }), [today]);
48
51
  const {
49
52
  startDate,
@@ -132,6 +135,8 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/React.forwardRef(
132
135
  cardWrapperClass: (0, _classify.default)(_DateRangePickerModule.default.container, classNames?.wrapper),
133
136
  today: today,
134
137
  startDateLabel: startDateLabel,
135
- endDateLabel: endDateLabel
138
+ endDateLabel: endDateLabel,
139
+ t: t,
140
+ locale: locale
136
141
  });
137
142
  });
@@ -47,6 +47,8 @@ export type DateRangePickerProps = {
47
47
  maxDate?: string,
48
48
  startDateLabel?: string,
49
49
  endDateLabel?: string,
50
+ t?: ?(key: string, fallback: string) => string,
51
+ locale?: string,
50
52
  };
51
53
 
52
54
  export const DateRangePicker: React$AbstractComponent<
@@ -65,6 +67,8 @@ export const DateRangePicker: React$AbstractComponent<
65
67
  selectedDateRange = {},
66
68
  startDateLabel,
67
69
  endDateLabel,
70
+ t,
71
+ locale,
68
72
  }: DateRangePickerProps,
69
73
  ref,
70
74
  ): React.Node => {
@@ -87,6 +91,7 @@ export const DateRangePicker: React$AbstractComponent<
87
91
  maxDate,
88
92
  today,
89
93
  onError,
94
+ t,
90
95
  }),
91
96
  [today],
92
97
  );
@@ -201,6 +206,8 @@ export const DateRangePicker: React$AbstractComponent<
201
206
  today={today}
202
207
  startDateLabel={startDateLabel}
203
208
  endDateLabel={endDateLabel}
209
+ t={t}
210
+ locale={locale}
204
211
  />
205
212
  );
206
213
  },
@@ -22,6 +22,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
22
22
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } // $FlowFixMe[untyped-import]
23
23
  const CalendarHeader = _ref => {
24
24
  let {
25
+ t,
25
26
  date,
26
27
  marker,
27
28
  minDate,
@@ -46,12 +47,14 @@ const CalendarHeader = _ref => {
46
47
  minDate,
47
48
  maxDate,
48
49
  rangeStartMonth,
49
- rangeEndMonth
50
+ rangeEndMonth,
51
+ t
50
52
  });
53
+ const MONTHS = (0, _utils.getMonths)(t);
51
54
  return /*#__PURE__*/React.createElement("div", {
52
55
  className: _DateRangeWrapperModule.default.calendarHeader
53
56
  }, /*#__PURE__*/React.createElement(_Icon.ClickableIcon, {
54
- ariaLabel: "Select Previous Month",
57
+ ariaLabel: (0, _dateRangePicker.getTranslation)(t, 'Select Previous Month'),
55
58
  size: "small",
56
59
  name: "chevron-left",
57
60
  className: (0, _classify.default)(_DateRangeWrapperModule.default.headerIcon, {
@@ -69,7 +72,7 @@ const CalendarHeader = _ref => {
69
72
  onChange: event => {
70
73
  setMonth((0, _utils.getMonthEndDate)(_moment.default.utc(date).set('M', event.key)));
71
74
  },
72
- dropdownInputText: _utils.MONTHS[_moment.default.utc(date).month()].label,
75
+ dropdownInputText: MONTHS[_moment.default.utc(date).month()].label,
73
76
  scrollMenuToBottom: true
74
77
  }), /*#__PURE__*/React.createElement(_Dropdown.Dropdown, {
75
78
  disabled: !availableYears.length || (0, _dateRangePicker.isAfter)(minDate, maxDate),
@@ -85,7 +88,7 @@ const CalendarHeader = _ref => {
85
88
  scrollMenuToBottom: true
86
89
  }), /*#__PURE__*/React.createElement(_Icon.ClickableIcon, {
87
90
  size: "small",
88
- ariaLabel: "Select Next Month",
91
+ ariaLabel: (0, _dateRangePicker.getTranslation)(t, 'Select Next Month'),
89
92
  name: "chevron-right",
90
93
  className: (0, _classify.default)(_DateRangeWrapperModule.default.headerIcon, {
91
94
  [_DateRangeWrapperModule.default.disabledIcon]: nextDisabled
@@ -114,7 +117,9 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
114
117
  hideTimezone,
115
118
  today,
116
119
  startDateLabel,
117
- endDateLabel
120
+ endDateLabel,
121
+ t,
122
+ locale
118
123
  } = _ref2;
119
124
  const canNavigateCloser = _moment.default.utc(rangeStartMonth).year() !== _moment.default.utc(rangeEndMonth).year() || Math.abs(_moment.default.utc(rangeStartMonth).month() - _moment.default.utc(rangeEndMonth).month()) > 1;
120
125
  const handleApplyClick = () => {
@@ -142,7 +147,8 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
142
147
  dateRange,
143
148
  minDate,
144
149
  maxDate,
145
- today
150
+ today,
151
+ t
146
152
  };
147
153
  return /*#__PURE__*/React.createElement(_FocusManager.FocusManager, null, /*#__PURE__*/React.createElement(_Card.Card, {
148
154
  classNames: {
@@ -154,7 +160,7 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
154
160
  }, /*#__PURE__*/React.createElement(_Text.BodySmall, {
155
161
  className: _DateRangeWrapperModule.default.selectedDate,
156
162
  color: _Text.TEXT_COLORS.secondary
157
- }, `${startDateLabel || 'Start Date'}: ${(0, _dateRangePicker.getFormattedDate)(_utils.MARKERS.DATE_RANGE_START, dateRange)}`), /*#__PURE__*/React.createElement(_Icon.Icon, {
163
+ }, `${startDateLabel || (0, _dateRangePicker.getTranslation)(t, 'Start Date')}: ${(0, _dateRangePicker.getFormattedDate)(_utils.MARKERS.DATE_RANGE_START, dateRange, locale)}`), /*#__PURE__*/React.createElement(_Icon.Icon, {
158
164
  name: "minus",
159
165
  size: _Icon.ICON_SIZE.small,
160
166
  type: _Icon.ICON_TYPE.regular,
@@ -162,9 +168,10 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
162
168
  }), /*#__PURE__*/React.createElement(_Text.BodySmall, {
163
169
  className: _DateRangeWrapperModule.default.selectedDate,
164
170
  color: _Text.TEXT_COLORS.secondary
165
- }, `${endDateLabel || 'End Date'}: ${(0, _dateRangePicker.getFormattedDate)(_utils.MARKERS.DATE_RANGE_END, dateRange)}`)), /*#__PURE__*/React.createElement("div", {
171
+ }, `${endDateLabel || (0, _dateRangePicker.getTranslation)(t, 'End Date')}: ${(0, _dateRangePicker.getFormattedDate)(_utils.MARKERS.DATE_RANGE_END, dateRange, locale)}`)), /*#__PURE__*/React.createElement("div", {
166
172
  className: _DateRangeWrapperModule.default.calendarMenuContainer
167
173
  }, /*#__PURE__*/React.createElement(CalendarHeader, {
174
+ t: t,
168
175
  marker: _utils.MARKERS.DATE_RANGE_START,
169
176
  rangeStartMonth: rangeStartMonth,
170
177
  rangeEndMonth: rangeEndMonth,
@@ -177,6 +184,7 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
177
184
  onClickNext: () => onMonthNavigate(_utils.MARKERS.DATE_RANGE_START, _utils.NAVIGATION_ACTION.NEXT),
178
185
  onClickPrevious: () => onMonthNavigate(_utils.MARKERS.DATE_RANGE_START, _utils.NAVIGATION_ACTION.PREV)
179
186
  }), /*#__PURE__*/React.createElement(CalendarHeader, {
187
+ t: t,
180
188
  marker: _utils.MARKERS.DATE_RANGE_END,
181
189
  rangeStartMonth: rangeStartMonth,
182
190
  rangeEndMonth: rangeEndMonth,
@@ -202,26 +210,34 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
202
210
  className: _DateRangeWrapperModule.default.cardFooter
203
211
  }, /*#__PURE__*/React.createElement(_Card.CardTitle, {
204
212
  className: _DateRangeWrapperModule.default.timezoneDropdownContainer
205
- }, !hideTimezone && /*#__PURE__*/React.createElement(_Dropdown.SimpleDropdown, {
206
- options: (0, _utils.getTimezones)(),
213
+ }, !hideTimezone && /*#__PURE__*/React.createElement(_Dropdown.Dropdown, {
214
+ menu: {
215
+ selectedKeys: [timezone],
216
+ options: (0, _utils.getTimezones)(t),
217
+ allowSearch: true,
218
+ staticLabels: {
219
+ SEARCH_PLACEHOLDER: `${(0, _dateRangePicker.getTranslation)(t, 'Search')}...`,
220
+ RESULT: (0, _dateRangePicker.getTranslation)(t, 'result'),
221
+ RESULTS: (0, _dateRangePicker.getTranslation)(t, 'results')
222
+ }
223
+ },
224
+ dropdownInputText: (0, _dateRangePicker.getTranslation)(t, _dateRangePicker.TIMEZONES[timezone]),
207
225
  disabled: (0, _dateRangePicker.isAfter)(minDate, maxDate),
208
226
  classNames: {
209
227
  box: _DateRangeWrapperModule.default.timezoneDropdown
210
228
  },
211
- selectedKeys: [timezone],
212
229
  onChange: event => setTimezone(event.key),
213
230
  size: "small",
214
231
  menuVirtualization: {
215
232
  enable: true
216
- },
217
- allowSearch: true
233
+ }
218
234
  })), /*#__PURE__*/React.createElement(_Card.CardActions, null, /*#__PURE__*/React.createElement(_Button.Button, {
219
235
  type: "ghost",
220
236
  onClick: onCancel,
221
237
  size: "small"
222
- }, "Cancel"), /*#__PURE__*/React.createElement(_Button.Button, {
238
+ }, (0, _dateRangePicker.getTranslation)(t, 'Cancel')), /*#__PURE__*/React.createElement(_Button.Button, {
223
239
  onClick: handleApplyClick,
224
240
  size: "small",
225
241
  disabled: !(dateRange.startDate && dateRange.endDate)
226
- }, "Apply")))));
242
+ }, (0, _dateRangePicker.getTranslation)(t, 'Apply'))))));
227
243
  });
@@ -9,9 +9,9 @@ import {
9
9
  generateAvailableYears,
10
10
  getAvailableMonths,
11
11
  getMonthEndDate,
12
+ getMonths,
12
13
  getTimezones,
13
14
  MARKERS,
14
- MONTHS,
15
15
  NAVIGATION_ACTION,
16
16
  } from '../../utils';
17
17
  import classify from '../../utils/classify';
@@ -19,9 +19,11 @@ import {
19
19
  addTimezoneEndOfDay,
20
20
  addTimezoneStartOfDay,
21
21
  getFormattedDate,
22
+ getTranslation,
22
23
  isAfter,
23
24
  isSameOrAfter,
24
25
  isSameOrBefore,
26
+ TIMEZONES,
25
27
  } from '../../utils/date-range-picker';
26
28
  import {Button} from '../Button';
27
29
  import {
@@ -32,7 +34,7 @@ import {
32
34
  CardHeader,
33
35
  CardTitle,
34
36
  } from '../Card';
35
- import {Dropdown, SimpleDropdown} from '../Dropdown';
37
+ import {Dropdown} from '../Dropdown';
36
38
  import {FocusManager} from '../FocusManager';
37
39
  import {ClickableIcon, Icon, ICON_SIZE, ICON_TYPE} from '../Icon';
38
40
  import {BodySmall, TEXT_COLORS} from '../Text';
@@ -54,6 +56,7 @@ type HeaderProps = {
54
56
  onClickPrevious: () => void,
55
57
  marker: $Values<typeof MARKERS>,
56
58
  setMonth: (date: string) => void,
59
+ t: ?(key: string, fallback: string) => string,
57
60
  };
58
61
 
59
62
  type DateRangeWrapperProps = {
@@ -83,9 +86,12 @@ type DateRangeWrapperProps = {
83
86
  today: string,
84
87
  startDateLabel?: string,
85
88
  endDateLabel?: string,
89
+ t?: ?(key: string, fallback: string) => string,
90
+ locale?: string,
86
91
  };
87
92
 
88
93
  const CalendarHeader = ({
94
+ t,
89
95
  date,
90
96
  marker,
91
97
  minDate,
@@ -111,12 +117,14 @@ const CalendarHeader = ({
111
117
  maxDate,
112
118
  rangeStartMonth,
113
119
  rangeEndMonth,
120
+ t,
114
121
  });
122
+ const MONTHS = getMonths(t);
115
123
 
116
124
  return (
117
125
  <div className={css.calendarHeader}>
118
126
  <ClickableIcon
119
- ariaLabel="Select Previous Month"
127
+ ariaLabel={getTranslation(t, 'Select Previous Month')}
120
128
  size="small"
121
129
  name="chevron-left"
122
130
  className={classify(css.headerIcon, {
@@ -153,7 +161,7 @@ const CalendarHeader = ({
153
161
  />
154
162
  <ClickableIcon
155
163
  size="small"
156
- ariaLabel="Select Next Month"
164
+ ariaLabel={getTranslation(t, 'Select Next Month')}
157
165
  name="chevron-right"
158
166
  className={classify(css.headerIcon, {
159
167
  [css.disabledIcon]: nextDisabled,
@@ -190,6 +198,8 @@ export const DateRangeWrapper: React$AbstractComponent<
190
198
  today,
191
199
  startDateLabel,
192
200
  endDateLabel,
201
+ t,
202
+ locale,
193
203
  }: DateRangeWrapperProps,
194
204
  ref,
195
205
  ): React.Node => {
@@ -223,6 +233,7 @@ export const DateRangeWrapper: React$AbstractComponent<
223
233
  minDate,
224
234
  maxDate,
225
235
  today,
236
+ t,
226
237
  };
227
238
 
228
239
  return (
@@ -238,9 +249,12 @@ export const DateRangeWrapper: React$AbstractComponent<
238
249
  className={css.selectedDate}
239
250
  color={TEXT_COLORS.secondary}
240
251
  >
241
- {`${startDateLabel || 'Start Date'}: ${getFormattedDate(
252
+ {`${
253
+ startDateLabel || getTranslation(t, 'Start Date')
254
+ }: ${getFormattedDate(
242
255
  MARKERS.DATE_RANGE_START,
243
256
  dateRange,
257
+ locale,
244
258
  )}`}
245
259
  </BodySmall>
246
260
 
@@ -255,15 +269,19 @@ export const DateRangeWrapper: React$AbstractComponent<
255
269
  className={css.selectedDate}
256
270
  color={TEXT_COLORS.secondary}
257
271
  >
258
- {`${endDateLabel || 'End Date'}: ${getFormattedDate(
272
+ {`${
273
+ endDateLabel || getTranslation(t, 'End Date')
274
+ }: ${getFormattedDate(
259
275
  MARKERS.DATE_RANGE_END,
260
276
  dateRange,
277
+ locale,
261
278
  )}`}
262
279
  </BodySmall>
263
280
  </CardHeader>
264
281
 
265
282
  <div className={css.calendarMenuContainer}>
266
283
  <CalendarHeader
284
+ t={t}
267
285
  marker={MARKERS.DATE_RANGE_START}
268
286
  rangeStartMonth={rangeStartMonth}
269
287
  rangeEndMonth={rangeEndMonth}
@@ -287,6 +305,7 @@ export const DateRangeWrapper: React$AbstractComponent<
287
305
  }
288
306
  />
289
307
  <CalendarHeader
308
+ t={t}
290
309
  marker={MARKERS.DATE_RANGE_END}
291
310
  rangeStartMonth={rangeStartMonth}
292
311
  rangeEndMonth={rangeEndMonth}
@@ -321,32 +340,40 @@ export const DateRangeWrapper: React$AbstractComponent<
321
340
  <CardFooter className={css.cardFooter}>
322
341
  <CardTitle className={css.timezoneDropdownContainer}>
323
342
  {!hideTimezone && (
324
- <SimpleDropdown
325
- options={getTimezones()}
343
+ <Dropdown
344
+ menu={{
345
+ selectedKeys: [timezone],
346
+ options: getTimezones(t),
347
+ allowSearch: true,
348
+ staticLabels: {
349
+ SEARCH_PLACEHOLDER: `${getTranslation(t, 'Search')}...`,
350
+ RESULT: getTranslation(t, 'result'),
351
+ RESULTS: getTranslation(t, 'results'),
352
+ },
353
+ }}
354
+ dropdownInputText={getTranslation(t, TIMEZONES[timezone])}
326
355
  disabled={isAfter(minDate, maxDate)}
327
356
  classNames={{
328
357
  box: css.timezoneDropdown,
329
358
  }}
330
- selectedKeys={[timezone]}
331
359
  onChange={(event) => setTimezone(event.key)}
332
360
  size="small"
333
361
  menuVirtualization={{
334
362
  enable: true,
335
363
  }}
336
- allowSearch
337
364
  />
338
365
  )}
339
366
  </CardTitle>
340
367
  <CardActions>
341
368
  <Button type="ghost" onClick={onCancel} size="small">
342
- Cancel
369
+ {getTranslation(t, 'Cancel')}
343
370
  </Button>
344
371
  <Button
345
372
  onClick={handleApplyClick}
346
373
  size="small"
347
374
  disabled={!(dateRange.startDate && dateRange.endDate)}
348
375
  >
349
- Apply
376
+ {getTranslation(t, 'Apply')}
350
377
  </Button>
351
378
  </CardActions>
352
379
  </CardFooter>
@@ -32,6 +32,7 @@ const SimpleDropdownBase = (props, ref) => {
32
32
  showLabelTooltip,
33
33
  clickAwayRef,
34
34
  allowWrap = false,
35
+ staticLabels,
35
36
  ...inputProps
36
37
  } = props;
37
38
  const [dropdownInputText, setDropdownInputText] = React.useState('');
@@ -83,7 +84,8 @@ const SimpleDropdownBase = (props, ref) => {
83
84
  footer,
84
85
  classNames: menuClassNames,
85
86
  showLabelTooltip,
86
- allowWrap
87
+ allowWrap,
88
+ staticLabels
87
89
  }
88
90
  }));
89
91
  };
@@ -44,6 +44,11 @@ export type SimpleDropdownProps = {
44
44
  menuClassNames?: MenuClassNames,
45
45
  showLabelTooltip?: MenuLabelTooltip,
46
46
  allowWrap?: boolean,
47
+ staticLabels?: {
48
+ RESULT?: string,
49
+ RESULTS?: string,
50
+ SEARCH_PLACEHOLDER?: string,
51
+ },
47
52
 
48
53
  // events
49
54
  onChange?: (option: MenuOption, ?SyntheticEvent<HTMLElement>) => mixed,
@@ -79,6 +84,7 @@ const SimpleDropdownBase = (props: SimpleDropdownProps, ref) => {
79
84
  showLabelTooltip,
80
85
  clickAwayRef,
81
86
  allowWrap = false,
87
+ staticLabels,
82
88
  ...inputProps
83
89
  } = props;
84
90
 
@@ -150,6 +156,7 @@ const SimpleDropdownBase = (props: SimpleDropdownProps, ref) => {
150
156
  classNames: menuClassNames,
151
157
  showLabelTooltip,
152
158
  allowWrap,
159
+ staticLabels,
153
160
  }}
154
161
  />
155
162
  );
@@ -1,3 +1 @@
1
- "use strict";
2
-
3
- var _dateRangePicker = require("../utils/date-range-picker");
1
+ "use strict";
@@ -1,10 +1,10 @@
1
1
  // @flow strict
2
- import {DATE_RANGE_PICKER_ERRORS} from '../utils/date-range-picker';
3
-
4
2
 
5
3
  export type TimeUnit = 'years' | 'months' | 'days' | 'd' | 'M' | 'y';
6
4
  export type DateRange = {startDate?: ?string, endDate?: ?string};
7
- export type DateRangePickerErrorTypes = $Keys<typeof DATE_RANGE_PICKER_ERRORS>;
5
+ export type DateRangePickerErrorTypes = {
6
+ [key: string]: {type: string, description: string},
7
+ };
8
8
  export type DateRangePickerError = {
9
9
  type: string,
10
10
  description: string,
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.wrangleMoment = exports.isValid = exports.isStartOfRange = exports.isStartDateEndDateSame = exports.isSameOrBefore = exports.isSameOrAfter = exports.isSame = exports.isEndOfRange = exports.isBetween = exports.isBefore = exports.isAfter = exports.inDateRange = exports.getValidDates = exports.getTimezones = exports.getSubtractedDate = exports.getMonthEndDate = exports.getFormattedDate = exports.getDaysInMonth = exports.getAvailableMonths = exports.getAddedDate = exports.generateAvailableYears = exports.formatIsoDate = exports.checkRangeValidity = exports.WEEKDAYS = exports.NAVIGATION_ACTION = exports.MONTHS = exports.MARKERS = exports.DATE_RANGE_PICKER_ERRORS = void 0;
6
+ exports.wrangleMoment = exports.makeKey = exports.isValid = exports.isStartOfRange = exports.isStartDateEndDateSame = exports.isSameOrBefore = exports.isSameOrAfter = exports.isSame = exports.isEndOfRange = exports.isBetween = exports.isBefore = exports.isAfter = exports.inDateRange = exports.getValidDates = exports.getTranslation = exports.getTimezones = exports.getSubtractedDate = exports.getMonths = exports.getMonthEndDate = exports.getFormattedDate = exports.getDaysInMonth = exports.getDateRangePickerErrors = exports.getAvailableMonths = exports.getAddedDate = exports.generateAvailableYears = exports.formatIsoDate = exports.checkRangeValidity = exports.WEEKDAYS = exports.NAVIGATION_ACTION = exports.MARKERS = void 0;
7
7
  var _parseISO = _interopRequireDefault(require("date-fns/parseISO"));
8
8
  var _invariant = _interopRequireDefault(require("invariant"));
9
9
  var _lodash = require("lodash");
@@ -12,6 +12,21 @@ var _timezones = require("./timezones");
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  // $FlowFixMe - strict types for date-fns
14
14
  // $FlowFixMe[untyped-import]
15
+ const makeKey = value => {
16
+ try {
17
+ if (value && typeof value === 'string') {
18
+ return value.replace(/\(s\)/gi, '_s') // Replace (s) with _s (case-insensitive)
19
+ .replace(/[^\w\s']/g, '') // Remove special chars except apostrophes
20
+ .replace(/\s+/g, '_') // Spaces → underscores
21
+ .replace(/_+/g, '_') // Collapse multiple ____ into _
22
+ .replace(/^_|_$/g, ''); // Trim leading/trailing _
23
+ }
24
+ return value;
25
+ } catch {
26
+ return value;
27
+ }
28
+ };
29
+ exports.makeKey = makeKey;
15
30
  const NAVIGATION_ACTION = exports.NAVIGATION_ACTION = Object.freeze({
16
31
  NEXT: 'next',
17
32
  PREV: 'prev'
@@ -21,61 +36,63 @@ const MARKERS = exports.MARKERS = Object.freeze({
21
36
  DATE_RANGE_END: 'SECOND'
22
37
  });
23
38
  const WEEKDAYS = exports.WEEKDAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
24
- const MONTHS = exports.MONTHS = [{
39
+ const getMonths = t => [{
25
40
  key: '0',
26
- label: 'Jan'
41
+ label: getTranslation(t, 'Jan')
27
42
  }, {
28
43
  key: '1',
29
- label: 'Feb'
44
+ label: getTranslation(t, 'Feb')
30
45
  }, {
31
46
  key: '2',
32
- label: 'Mar'
47
+ label: getTranslation(t, 'Mar')
33
48
  }, {
34
49
  key: '3',
35
- label: 'Apr'
50
+ label: getTranslation(t, 'Apr')
36
51
  }, {
37
52
  key: '4',
38
- label: 'May'
53
+ label: getTranslation(t, 'May')
39
54
  }, {
40
55
  key: '5',
41
- label: 'Jun'
56
+ label: getTranslation(t, 'Jun')
42
57
  }, {
43
58
  key: '6',
44
- label: 'Jul'
59
+ label: getTranslation(t, 'Jul')
45
60
  }, {
46
61
  key: '7',
47
- label: 'Aug'
62
+ label: getTranslation(t, 'Aug')
48
63
  }, {
49
64
  key: '8',
50
- label: 'Sep'
65
+ label: getTranslation(t, 'Sep')
51
66
  }, {
52
67
  key: '9',
53
- label: 'Oct'
68
+ label: getTranslation(t, 'Oct')
54
69
  }, {
55
70
  key: '10',
56
- label: 'Nov'
71
+ label: getTranslation(t, 'Nov')
57
72
  }, {
58
73
  key: '11',
59
- label: 'Dec'
74
+ label: getTranslation(t, 'Dec')
60
75
  }];
61
- const DATE_RANGE_PICKER_ERRORS = exports.DATE_RANGE_PICKER_ERRORS = Object.freeze({
76
+ exports.getMonths = getMonths;
77
+ const getDateRangePickerErrors = t => ({
62
78
  MIN_MAX_INVALID: {
63
79
  type: 'MIN_MAX_INVALID',
64
- description: 'Given minDate and maxDate are invalid.'
80
+ description: getTranslation(t, 'Given minDate and maxDate are invalid.')
65
81
  },
66
82
  START_DATE_EARLY: {
67
83
  type: 'START_DATE_EARLY',
68
- description: 'Given startDate can not come before minDate.'
84
+ description: getTranslation(t, 'Given startDate can not come before minDate.')
69
85
  },
70
86
  START_DATE_LATE: {
71
87
  type: 'START_DATE_LATE',
72
- description: 'Given startDate can not come after endDate.'
88
+ description: getTranslation(t, 'Given startDate can not come after endDate.')
73
89
  },
74
90
  END_DATE_LATE: {
75
91
  type: 'END_DATE_LATE',
76
- description: 'Given endDate can not come after maxDate.'
92
+ description: getTranslation(t, 'Given endDate can not come after maxDate.')
77
93
  }
78
94
  });
95
+ exports.getDateRangePickerErrors = getDateRangePickerErrors;
79
96
  const checkRangeValidity = (rangeStart, rangeEnd, errorBody, onError) => {
80
97
  const isRangeStartValid = isValid(rangeStart);
81
98
  const isRangeEndValid = isRangeStartValid && isValid(rangeEnd);
@@ -174,10 +191,10 @@ const getSubtractedDate = (date, subtractCount, timeUnit) => formatIsoDate(_mome
174
191
  exports.getSubtractedDate = getSubtractedDate;
175
192
  const getMonthEndDate = date => formatIsoDate(_moment.default.utc(date).endOf('M'));
176
193
  exports.getMonthEndDate = getMonthEndDate;
177
- const getTimezones = () => Object.keys(_timezones.TIMEZONES).reduce((menuOptions, key) => {
194
+ const getTimezones = t => Object.keys(_timezones.TIMEZONES).reduce((menuOptions, key) => {
178
195
  menuOptions.push({
179
196
  key,
180
- label: _timezones.TIMEZONES[key]
197
+ label: getTranslation(t, _timezones.TIMEZONES[key])
181
198
  });
182
199
  return menuOptions;
183
200
  }, []);
@@ -205,12 +222,14 @@ const getAvailableMonths = _ref6 => {
205
222
  minDate,
206
223
  maxDate,
207
224
  rangeStartMonth,
208
- rangeEndMonth
225
+ rangeEndMonth,
226
+ t
209
227
  } = _ref6;
210
228
  const [rangeStartMonthKey, rangeStartYear] = getMonthAndYear(rangeStartMonth);
211
229
  const [rangeEndMonthKey, rangeEndYear] = getMonthAndYear(rangeEndMonth);
212
230
  const [minDateMonth, minDateYear] = getMonthAndYear(minDate);
213
231
  const [maxDateMonth, maxDateYear] = getMonthAndYear(maxDate);
232
+ const MONTHS = getMonths(t);
214
233
  return MONTHS.filter(month => {
215
234
  const isSameYear = rangeStartYear === rangeEndYear;
216
235
  const isFirstAndMinDateYearSame = rangeStartYear === minDateYear;
@@ -241,7 +260,8 @@ const getValidDates = _ref7 => {
241
260
  minDate,
242
261
  maxDate,
243
262
  today,
244
- onError
263
+ onError,
264
+ t
245
265
  } = _ref7;
246
266
  const {
247
267
  startDate,
@@ -252,10 +272,10 @@ const getValidDates = _ref7 => {
252
272
  const isRangeValid = (min, max, errorMessage) => checkRangeValidity(min, max, errorMessage, onError);
253
273
 
254
274
  // minDate should be after maxDate
255
- const isMinMaxRangeInvalid = !isRangeValid(validMinDate, validMaxDate, DATE_RANGE_PICKER_ERRORS.MIN_MAX_INVALID);
275
+ const isMinMaxRangeInvalid = !isRangeValid(validMinDate, validMaxDate, getDateRangePickerErrors(t).MIN_MAX_INVALID);
256
276
 
257
277
  // if startDate is defined and then it should be after minDate
258
- const isStartDateInvalid = isMinMaxRangeInvalid || (0, _lodash.isEmpty)(startDate) || !isRangeValid(validMinDate, startDate, DATE_RANGE_PICKER_ERRORS.START_DATE_EARLY);
278
+ const isStartDateInvalid = isMinMaxRangeInvalid || (0, _lodash.isEmpty)(startDate) || !isRangeValid(validMinDate, startDate, getDateRangePickerErrors(t).START_DATE_EARLY);
259
279
  if (isMinMaxRangeInvalid || isStartDateInvalid) {
260
280
  return {
261
281
  validDateRange: {
@@ -267,10 +287,10 @@ const getValidDates = _ref7 => {
267
287
  };
268
288
  }
269
289
  // if endDate is defined then it should be before maxDate
270
- const isEndDateInvalid = (0, _lodash.isEmpty)(endDate) || !isRangeValid(endDate, validMaxDate, DATE_RANGE_PICKER_ERRORS.END_DATE_LATE);
290
+ const isEndDateInvalid = (0, _lodash.isEmpty)(endDate) || !isRangeValid(endDate, validMaxDate, getDateRangePickerErrors(t).END_DATE_LATE);
271
291
 
272
292
  // startDate should be before endDate
273
- const isStartEndRangeInvalid = isEndDateInvalid || !isRangeValid(startDate, endDate, DATE_RANGE_PICKER_ERRORS.START_DATE_LATE);
293
+ const isStartEndRangeInvalid = isEndDateInvalid || !isRangeValid(startDate, endDate, getDateRangePickerErrors(t).START_DATE_LATE);
274
294
  if (isEndDateInvalid || isStartEndRangeInvalid) {
275
295
  return {
276
296
  validDateRange: {
@@ -319,11 +339,16 @@ const isBetween = (date, startRange, endRange) => _moment.default.utc(date).isBe
319
339
  exports.isBetween = isBetween;
320
340
  const isValid = date => _moment.default.utc(date).isValid();
321
341
  exports.isValid = isValid;
322
- const getFormattedDate = (marker, dateRange) => {
342
+ const getFormattedDate = (marker, dateRange, locale) => {
323
343
  const {
324
344
  startDate,
325
345
  endDate
326
346
  } = dateRange;
347
+
348
+ // set locale if provided
349
+ if (locale) {
350
+ _moment.default.locale(locale);
351
+ }
327
352
  switch (marker) {
328
353
  case MARKERS.DATE_RANGE_START:
329
354
  return startDate ? _moment.default.utc(startDate).format('MMM DD, YYYY') : 'MMM DD, YYYY';
@@ -331,4 +356,6 @@ const getFormattedDate = (marker, dateRange) => {
331
356
  return endDate ? _moment.default.utc(endDate).format('MMM DD, YYYY') : 'MMM DD, YYYY';
332
357
  }
333
358
  };
334
- exports.getFormattedDate = getFormattedDate;
359
+ exports.getFormattedDate = getFormattedDate;
360
+ const getTranslation = (t, labelToTranslate) => t ? t(makeKey(labelToTranslate), labelToTranslate) : labelToTranslate;
361
+ exports.getTranslation = getTranslation;
@@ -9,6 +9,7 @@ import moment from 'moment';
9
9
  import type {
10
10
  DateRange,
11
11
  DateRangePickerError,
12
+ DateRangePickerErrorTypes,
12
13
  DateRangeWithTimezone,
13
14
  TimeUnit,
14
15
  } from 'src/types/date-range-picker';
@@ -18,6 +19,22 @@ import type {MenuOption} from '../../components/Menu';
18
19
  import {TIMEZONES} from './timezones';
19
20
 
20
21
 
22
+ export const makeKey = (value: string): string => {
23
+ try {
24
+ if (value && typeof value === 'string') {
25
+ return value
26
+ .replace(/\(s\)/gi, '_s') // Replace (s) with _s (case-insensitive)
27
+ .replace(/[^\w\s']/g, '') // Remove special chars except apostrophes
28
+ .replace(/\s+/g, '_') // Spaces → underscores
29
+ .replace(/_+/g, '_') // Collapse multiple ____ into _
30
+ .replace(/^_|_$/g, ''); // Trim leading/trailing _
31
+ }
32
+ return value;
33
+ } catch {
34
+ return value;
35
+ }
36
+ };
37
+
21
38
  export const NAVIGATION_ACTION = Object.freeze({
22
39
  NEXT: 'next',
23
40
  PREV: 'prev',
@@ -27,37 +44,47 @@ export const MARKERS = Object.freeze({
27
44
  DATE_RANGE_END: 'SECOND',
28
45
  });
29
46
  export const WEEKDAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
30
- export const MONTHS = [
31
- {key: '0', label: 'Jan'},
32
- {key: '1', label: 'Feb'},
33
- {key: '2', label: 'Mar'},
34
- {key: '3', label: 'Apr'},
35
- {key: '4', label: 'May'},
36
- {key: '5', label: 'Jun'},
37
- {key: '6', label: 'Jul'},
38
- {key: '7', label: 'Aug'},
39
- {key: '8', label: 'Sep'},
40
- {key: '9', label: 'Oct'},
41
- {key: '10', label: 'Nov'},
42
- {key: '11', label: 'Dec'},
47
+ export const getMonths = (
48
+ t: ?(key: string, fallback: string) => string,
49
+ ): Array<MenuOption> => [
50
+ {key: '0', label: getTranslation(t, 'Jan')},
51
+ {key: '1', label: getTranslation(t, 'Feb')},
52
+ {key: '2', label: getTranslation(t, 'Mar')},
53
+ {key: '3', label: getTranslation(t, 'Apr')},
54
+ {key: '4', label: getTranslation(t, 'May')},
55
+ {key: '5', label: getTranslation(t, 'Jun')},
56
+ {key: '6', label: getTranslation(t, 'Jul')},
57
+ {key: '7', label: getTranslation(t, 'Aug')},
58
+ {key: '8', label: getTranslation(t, 'Sep')},
59
+ {key: '9', label: getTranslation(t, 'Oct')},
60
+ {key: '10', label: getTranslation(t, 'Nov')},
61
+ {key: '11', label: getTranslation(t, 'Dec')},
43
62
  ];
44
63
 
45
- export const DATE_RANGE_PICKER_ERRORS = Object.freeze({
64
+ export const getDateRangePickerErrors = (
65
+ t: ?(key: string, fallback: string) => string,
66
+ ): DateRangePickerErrorTypes => ({
46
67
  MIN_MAX_INVALID: {
47
68
  type: 'MIN_MAX_INVALID',
48
- description: 'Given minDate and maxDate are invalid.',
69
+ description: getTranslation(t, 'Given minDate and maxDate are invalid.'),
49
70
  },
50
71
  START_DATE_EARLY: {
51
72
  type: 'START_DATE_EARLY',
52
- description: 'Given startDate can not come before minDate.',
73
+ description: getTranslation(
74
+ t,
75
+ 'Given startDate can not come before minDate.',
76
+ ),
53
77
  },
54
78
  START_DATE_LATE: {
55
79
  type: 'START_DATE_LATE',
56
- description: 'Given startDate can not come after endDate.',
80
+ description: getTranslation(
81
+ t,
82
+ 'Given startDate can not come after endDate.',
83
+ ),
57
84
  },
58
85
  END_DATE_LATE: {
59
86
  type: 'END_DATE_LATE',
60
- description: 'Given endDate can not come after maxDate.',
87
+ description: getTranslation(t, 'Given endDate can not come after maxDate.'),
61
88
  },
62
89
  });
63
90
 
@@ -168,11 +195,13 @@ export const getSubtractedDate = (
168
195
  export const getMonthEndDate = (date: string): string =>
169
196
  formatIsoDate(moment.utc(date).endOf('M'));
170
197
 
171
- export const getTimezones = (): Array<MenuOption> =>
198
+ export const getTimezones = (
199
+ t: ?(key: string, fallback: string) => string,
200
+ ): Array<MenuOption> =>
172
201
  Object.keys(TIMEZONES).reduce((menuOptions, key) => {
173
202
  menuOptions.push({
174
203
  key,
175
- label: TIMEZONES[key],
204
+ label: getTranslation(t, TIMEZONES[key]),
176
205
  });
177
206
  return menuOptions;
178
207
  }, []);
@@ -212,17 +241,20 @@ export const getAvailableMonths = ({
212
241
  maxDate,
213
242
  rangeStartMonth,
214
243
  rangeEndMonth,
244
+ t,
215
245
  }: {
216
246
  marker: $Values<typeof MARKERS>,
217
247
  minDate: string,
218
248
  maxDate: string,
219
249
  rangeStartMonth: string,
220
250
  rangeEndMonth: string,
251
+ t: ?(key: string, fallback: string) => string,
221
252
  }): Array<MenuOption> => {
222
253
  const [rangeStartMonthKey, rangeStartYear] = getMonthAndYear(rangeStartMonth);
223
254
  const [rangeEndMonthKey, rangeEndYear] = getMonthAndYear(rangeEndMonth);
224
255
  const [minDateMonth, minDateYear] = getMonthAndYear(minDate);
225
256
  const [maxDateMonth, maxDateYear] = getMonthAndYear(maxDate);
257
+ const MONTHS = getMonths(t);
226
258
 
227
259
  return MONTHS.filter((month: MenuOption) => {
228
260
  const isSameYear = rangeStartYear === rangeEndYear;
@@ -255,12 +287,14 @@ export const getValidDates = ({
255
287
  maxDate,
256
288
  today,
257
289
  onError,
290
+ t,
258
291
  }: {
259
292
  selectedDateRange: DateRangeWithTimezone,
260
293
  minDate?: ?string,
261
294
  maxDate?: ?string,
262
295
  today: string,
263
296
  onError?: (DateRangePickerError) => void,
297
+ t: ?(key: string, fallback: string) => string,
264
298
  }): {
265
299
  validMinDate: string,
266
300
  validMaxDate: string,
@@ -279,7 +313,7 @@ export const getValidDates = ({
279
313
  const isMinMaxRangeInvalid = !isRangeValid(
280
314
  validMinDate,
281
315
  validMaxDate,
282
- DATE_RANGE_PICKER_ERRORS.MIN_MAX_INVALID,
316
+ getDateRangePickerErrors(t).MIN_MAX_INVALID,
283
317
  );
284
318
 
285
319
  // if startDate is defined and then it should be after minDate
@@ -289,7 +323,7 @@ export const getValidDates = ({
289
323
  !isRangeValid(
290
324
  validMinDate,
291
325
  startDate,
292
- DATE_RANGE_PICKER_ERRORS.START_DATE_EARLY,
326
+ getDateRangePickerErrors(t).START_DATE_EARLY,
293
327
  );
294
328
 
295
329
  if (isMinMaxRangeInvalid || isStartDateInvalid) {
@@ -305,13 +339,17 @@ export const getValidDates = ({
305
339
  !isRangeValid(
306
340
  endDate,
307
341
  validMaxDate,
308
- DATE_RANGE_PICKER_ERRORS.END_DATE_LATE,
342
+ getDateRangePickerErrors(t).END_DATE_LATE,
309
343
  );
310
344
 
311
345
  // startDate should be before endDate
312
346
  const isStartEndRangeInvalid =
313
347
  isEndDateInvalid ||
314
- !isRangeValid(startDate, endDate, DATE_RANGE_PICKER_ERRORS.START_DATE_LATE);
348
+ !isRangeValid(
349
+ startDate,
350
+ endDate,
351
+ getDateRangePickerErrors(t).START_DATE_LATE,
352
+ );
315
353
 
316
354
  if (isEndDateInvalid || isStartEndRangeInvalid) {
317
355
  return {
@@ -376,8 +414,15 @@ export const isValid = (date?: ?string): boolean => moment.utc(date).isValid();
376
414
  export const getFormattedDate = (
377
415
  marker: string,
378
416
  dateRange: DateRange,
417
+ locale?: string,
379
418
  ): string => {
380
419
  const {startDate, endDate} = dateRange;
420
+
421
+ // set locale if provided
422
+ if (locale) {
423
+ moment.locale(locale);
424
+ }
425
+
381
426
  switch (marker) {
382
427
  case MARKERS.DATE_RANGE_START:
383
428
  return startDate
@@ -389,3 +434,9 @@ export const getFormattedDate = (
389
434
  : 'MMM DD, YYYY';
390
435
  }
391
436
  };
437
+
438
+ export const getTranslation = (
439
+ t: ?(key: string, fallback: string) => string,
440
+ labelToTranslate: string,
441
+ ): string =>
442
+ t ? t(makeKey(labelToTranslate), labelToTranslate) : labelToTranslate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaced-out/ui-design-system",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
4
4
  "main": "index.js",
5
5
  "description": "Sense UI components library",
6
6
  "author": {