@lumx/react 3.5.2 → 3.5.4-alpha-remove-moment.0

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/index.d.ts CHANGED
@@ -542,7 +542,7 @@ interface DatePickerProps extends GenericProps {
542
542
  /** Default month. */
543
543
  defaultMonth?: Date;
544
544
  /** Locale (language or region) to use. */
545
- locale: string;
545
+ locale?: string;
546
546
  /** Date after which dates can't be selected. */
547
547
  maxDate?: Date;
548
548
  /** Date before which dates can't be selected. */
@@ -597,7 +597,7 @@ interface DatePickerFieldProps extends GenericProps {
597
597
  /** Whether the component is disabled or not. */
598
598
  isDisabled?: boolean;
599
599
  /** Locale (language or region) to use. */
600
- locale: string;
600
+ locale?: string;
601
601
  /** Date after which dates can't be selected. */
602
602
  maxDate?: Date;
603
603
  /** Date before which dates can't be selected. */
package/index.js CHANGED
@@ -5,9 +5,6 @@ import isEmpty from 'lodash/isEmpty';
5
5
  import noop from 'lodash/noop';
6
6
  import get from 'lodash/get';
7
7
  import isFunction from 'lodash/isFunction';
8
- import moment$1 from 'moment';
9
- import range from 'lodash/range';
10
- import { extendMoment } from 'moment-range';
11
8
  import last from 'lodash/last';
12
9
  import pull from 'lodash/pull';
13
10
  import { createPortal } from 'react-dom';
@@ -23,6 +20,7 @@ import isInteger from 'lodash/isInteger';
23
20
  import isObject from 'lodash/isObject';
24
21
  import take from 'lodash/take';
25
22
  import uniqueId from 'lodash/uniqueId';
23
+ import range from 'lodash/range';
26
24
  import chunk from 'lodash/chunk';
27
25
  import isUndefined from 'lodash/isUndefined';
28
26
  import set from 'lodash/set';
@@ -279,9 +277,9 @@ function commonjsRequire () {
279
277
 
280
278
  var classnames = createCommonjsModule(function (module) {
281
279
  /*!
282
- Copyright (c) 2017 Jed Watson.
283
- Licensed under the MIT License (MIT), see
284
- http://jedwatson.github.io/classnames
280
+ Copyright (c) 2018 Jed Watson.
281
+ Licensed under the MIT License (MIT), see
282
+ http://jedwatson.github.io/classnames
285
283
  */
286
284
  /* global define */
287
285
 
@@ -289,7 +287,7 @@ var classnames = createCommonjsModule(function (module) {
289
287
 
290
288
  var hasOwn = {}.hasOwnProperty;
291
289
 
292
- function classNames () {
290
+ function classNames() {
293
291
  var classes = [];
294
292
 
295
293
  for (var i = 0; i < arguments.length; i++) {
@@ -300,12 +298,19 @@ var classnames = createCommonjsModule(function (module) {
300
298
 
301
299
  if (argType === 'string' || argType === 'number') {
302
300
  classes.push(arg);
303
- } else if (Array.isArray(arg) && arg.length) {
304
- var inner = classNames.apply(null, arg);
305
- if (inner) {
306
- classes.push(inner);
301
+ } else if (Array.isArray(arg)) {
302
+ if (arg.length) {
303
+ var inner = classNames.apply(null, arg);
304
+ if (inner) {
305
+ classes.push(inner);
306
+ }
307
307
  }
308
308
  } else if (argType === 'object') {
309
+ if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {
310
+ classes.push(arg.toString());
311
+ continue;
312
+ }
313
+
309
314
  for (var key in arg) {
310
315
  if (hasOwn.call(arg, key) && arg[key]) {
311
316
  classes.push(key);
@@ -2019,6 +2024,21 @@ CommentBlock.displayName = COMPONENT_NAME$c;
2019
2024
  CommentBlock.className = CLASSNAME$b;
2020
2025
  CommentBlock.defaultProps = DEFAULT_PROPS$b;
2021
2026
 
2027
+ /**
2028
+ * Add a number of months from a date while resetting the day to prevent month length mismatches.
2029
+ */
2030
+ function addMonthResetDay(date, monthOffset) {
2031
+ const newDate = new Date(date.getTime());
2032
+ newDate.setDate(1);
2033
+ newDate.setMonth(date.getMonth() + monthOffset);
2034
+ return newDate;
2035
+ }
2036
+
2037
+ /**
2038
+ * Check if given date is valid.
2039
+ */
2040
+ const isDateValid = date => date instanceof Date && !Number.isNaN(date.getTime());
2041
+
2022
2042
  /**
2023
2043
  * Component display name.
2024
2044
  */
@@ -2029,56 +2049,169 @@ const COMPONENT_NAME$d = 'DatePicker';
2029
2049
  */
2030
2050
  const CLASSNAME$c = getRootClassName(COMPONENT_NAME$d);
2031
2051
 
2032
- const moment = extendMoment(moment$1);
2033
- const DAYS_PER_WEEK = 7;
2034
2052
  /**
2035
- * Get the list of days in a week based on locale.
2036
- *
2037
- * @param locale The locale using to generate the order of days in a week.
2038
- * @return The list of days in a week based on locale.
2053
+ * Get current browser locale.
2039
2054
  */
2040
- function getWeekDays(locale) {
2041
- return range(DAYS_PER_WEEK).map((_, i) => moment().locale(locale).weekday(i));
2042
- }
2055
+ const getCurrentLocale = () => {
2056
+ var _navigator$languages;
2057
+ return ((_navigator$languages = navigator.languages) === null || _navigator$languages === void 0 ? void 0 : _navigator$languages[0]) || navigator.language;
2058
+ };
2043
2059
 
2044
2060
  /**
2045
- * Get month calendar based on locale and start date.
2046
- *
2047
- * @param locale The locale using to generate the order of days in a week.
2048
- * @param selectedMonth The selected month.
2049
- * @return The list of days in a week based on locale.
2061
+ * Get the language part of a locale code.
2062
+ * ex: `en-us` => `en`
2050
2063
  */
2051
- function getMonthCalendar(locale, selectedMonth) {
2052
- const firstDayOfMonth = moment(selectedMonth).startOf('month');
2053
- const endDayOfMonth = moment(selectedMonth).endOf('month');
2054
- // The first day of the week depends on the locale used. In FR the first day is a monday but in EN the first day is sunday
2055
- const firstDay = firstDayOfMonth.locale(locale).startOf('week');
2056
- const monthRange = moment.range(firstDay.toDate(), endDayOfMonth.toDate());
2057
- return Array.from(monthRange.by('day'));
2058
- }
2064
+ const getLocaleLang = locale => locale.split('-')[0];
2065
+
2066
+ /** Get first day of week for locale from the browser API */
2067
+ const getFromBrowser = locale => {
2068
+ try {
2069
+ var _localeMetadata$getWe;
2070
+ const localeMetadata = new Intl.Locale(locale);
2071
+ const {
2072
+ firstDay
2073
+ } = ((_localeMetadata$getWe = localeMetadata.getWeekInfo) === null || _localeMetadata$getWe === void 0 ? void 0 : _localeMetadata$getWe.call(localeMetadata)) || localeMetadata.weekInfo;
2074
+ // Sunday is represented as `0` in Date.getDay()
2075
+ if (firstDay === 7) return 0;
2076
+ return firstDay;
2077
+ } catch (e) {
2078
+ return undefined;
2079
+ }
2080
+ };
2081
+
2082
+ /** List first day for each locale (could be removed when all browser implement Locale weekInfo) */
2083
+ const FIRST_DAY_FOR_LOCALES = [{
2084
+ // Locales with Sunday as the first day of the week
2085
+ localeRX: /^(af|ar-(dz|eg|sa)|bn|cy|en-(ca|us|za)|fr-ca|gd|he|hi|ja|km|ko|pt-br|te|th|ug|zh-hk)$/i,
2086
+ firstDay: 0
2087
+ }, {
2088
+ // Locales with Monday as the first day of the week
2089
+ localeRX: /^(ar-(ma|tn)|az|be|bg|bs|ca|cs|da|de|el|en-(au|gb|ie|in|nz)|eo|es|et|eu|fi|fr|fy|gl|gu|hr|ht|hu|hy|id|is|it|ka|kk|kn|lb|lt|lv|mk|mn|ms|mt|nb|nl|nn|oc|pl|pt|ro|ru|sk|sl|sq|sr|sv|ta|tr|uk|uz|vi|zh-(cn|tw))$/i,
2090
+ firstDay: 1
2091
+ }, {
2092
+ // Locales with Saturday as the first day of the week
2093
+ localeRX: /^(ar|fa-ir)$/i,
2094
+ firstDay: 6
2095
+ }];
2096
+
2097
+ /** Find first day of week for locale from the constant */
2098
+ const getFromConstant = locale => {
2099
+ // Search for locale (lang + region)
2100
+ for (const {
2101
+ localeRX,
2102
+ firstDay
2103
+ } of FIRST_DAY_FOR_LOCALES) {
2104
+ if (localeRX.test(locale)) return firstDay;
2105
+ }
2106
+ // Fallback search for locale lang
2107
+ const localeLang = getLocaleLang(locale);
2108
+ if (localeLang !== locale) {
2109
+ return getFromConstant(localeLang);
2110
+ }
2111
+ return undefined;
2112
+ };
2059
2113
 
2060
2114
  /**
2061
- * Get month calendar based on locale and start date.
2062
- * Each day is annotated to know if they are displayed and/or clickable.
2063
- *
2064
- * @param locale The locale using to generate the order of days in a week.
2065
- * @param minDate The first selectable date.
2066
- * @param maxDate The last selectable date.
2067
- * @param selectedMonth The selected month.
2068
- * @return The list of days in a week based on locale.
2115
+ * Get first day of the week for the given locale code (language + region).
2069
2116
  */
2070
- function getAnnotatedMonthCalendar(locale, minDate, maxDate, selectedMonth) {
2071
- const month = moment(selectedMonth).locale(locale).month();
2072
- const clickableRange = moment.range(minDate, maxDate);
2073
- return getMonthCalendar(locale, selectedMonth).map(date => {
2074
- return {
2075
- date,
2076
- isClickable: clickableRange.contains(date),
2077
- isDisplayed: date.month() === month,
2078
- isToday: date.isSame(moment(), 'day')
2117
+ const getFirstDayOfWeek = locale => {
2118
+ // Get from browser API
2119
+ const firstDay = getFromBrowser(locale);
2120
+ if (firstDay !== undefined) return firstDay;
2121
+
2122
+ // Get from constant
2123
+ return getFromConstant(locale);
2124
+ };
2125
+
2126
+ const DAYS_PER_WEEK = 7;
2127
+
2128
+ /**
2129
+ * List week days (based on locale) with the week day letter (ex: "M" for "Monday") and week day number
2130
+ * (0-based index starting on Sunday).
2131
+ */
2132
+ const getWeekDays = function () {
2133
+ var _getFirstDayOfWeek;
2134
+ let locale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getCurrentLocale();
2135
+ let referenceDate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Date();
2136
+ const iterDate = new Date(referenceDate.getTime());
2137
+ const firstDay = (_getFirstDayOfWeek = getFirstDayOfWeek(locale)) !== null && _getFirstDayOfWeek !== void 0 ? _getFirstDayOfWeek : 1;
2138
+
2139
+ // Go to start of the week
2140
+ const offset = firstDay - iterDate.getDay();
2141
+ iterDate.setDate(iterDate.getDate() + offset);
2142
+
2143
+ // Iterate through the days of the week
2144
+ const weekDays = [];
2145
+ for (let i = 0; i < DAYS_PER_WEEK; i++) {
2146
+ // Single letter week day (ex: "M" for "Monday", "L" for "Lundi", etc.)
2147
+ const letter = iterDate.toLocaleDateString(locale, {
2148
+ weekday: 'narrow'
2149
+ });
2150
+ // Day number (1-based index starting on Monday)
2151
+ const number = iterDate.getDay();
2152
+ weekDays.push({
2153
+ letter,
2154
+ number
2155
+ });
2156
+ iterDate.setDate(iterDate.getDate() + 1);
2157
+ }
2158
+ return weekDays;
2159
+ };
2160
+
2161
+ /**
2162
+ * Get month calendar.
2163
+ * A list of weeks with days indexed by week day number
2164
+ */
2165
+ const getMonthCalendar = function () {
2166
+ let locale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getCurrentLocale();
2167
+ let referenceDate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Date();
2168
+ let rangeMinDate = arguments.length > 2 ? arguments[2] : undefined;
2169
+ let rangeMaxDate = arguments.length > 3 ? arguments[3] : undefined;
2170
+ const month = referenceDate.getMonth();
2171
+ const iterDate = new Date(referenceDate.getTime());
2172
+ iterDate.setDate(1);
2173
+ const weekDays = getWeekDays(locale, referenceDate);
2174
+ const lastDayOfWeek = last(weekDays);
2175
+ const weeks = [];
2176
+ let week = {};
2177
+ while (iterDate.getMonth() === month) {
2178
+ const weekDayNumber = iterDate.getDay();
2179
+ const day = {
2180
+ date: new Date(iterDate.getTime())
2079
2181
  };
2080
- });
2081
- }
2182
+
2183
+ // If a range is specified, check if the day is out of range.
2184
+ if (rangeMinDate && iterDate <= rangeMinDate || rangeMaxDate && iterDate >= rangeMaxDate) {
2185
+ day.isOutOfRange = true;
2186
+ }
2187
+ week[weekDayNumber] = day;
2188
+ if (weekDayNumber === lastDayOfWeek.number) {
2189
+ weeks.push(week);
2190
+ week = {};
2191
+ }
2192
+ iterDate.setDate(iterDate.getDate() + 1);
2193
+ }
2194
+ if (Object.keys(week).length) weeks.push(week);
2195
+ return {
2196
+ weeks,
2197
+ weekDays
2198
+ };
2199
+ };
2200
+
2201
+ /**
2202
+ * Check `date1` is on the same day as `date2`.
2203
+ */
2204
+ const isSameDay = (date1, date2) => date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
2205
+
2206
+ const formatMonthYear = (date, locale) => date.toLocaleDateString(locale, {
2207
+ year: 'numeric',
2208
+ month: 'long'
2209
+ });
2210
+
2211
+ /** Format date month day number */
2212
+ const formatDayNumber = (date, locale) => date.toLocaleDateString(locale, {
2213
+ day: 'numeric'
2214
+ });
2082
2215
 
2083
2216
  /**
2084
2217
  * Defines the props of the component.
@@ -2098,7 +2231,7 @@ const COMPONENT_NAME$e = 'DatePickerControlled';
2098
2231
  */
2099
2232
  const DatePickerControlled = /*#__PURE__*/forwardRef((props, ref) => {
2100
2233
  const {
2101
- locale,
2234
+ locale = getCurrentLocale(),
2102
2235
  maxDate,
2103
2236
  minDate,
2104
2237
  nextButtonProps,
@@ -2110,12 +2243,12 @@ const DatePickerControlled = /*#__PURE__*/forwardRef((props, ref) => {
2110
2243
  todayOrSelectedDateRef,
2111
2244
  value
2112
2245
  } = props;
2113
- const days = React.useMemo(() => {
2114
- return getAnnotatedMonthCalendar(locale, minDate, maxDate, moment$1(selectedMonth));
2246
+ const {
2247
+ weeks,
2248
+ weekDays
2249
+ } = React.useMemo(() => {
2250
+ return getMonthCalendar(locale, selectedMonth, minDate, maxDate);
2115
2251
  }, [locale, minDate, maxDate, selectedMonth]);
2116
- const weekDays = React.useMemo(() => {
2117
- return getWeekDays(locale);
2118
- }, [locale]);
2119
2252
  return /*#__PURE__*/React.createElement("div", {
2120
2253
  ref: ref,
2121
2254
  className: `${CLASSNAME$c}`
@@ -2133,37 +2266,46 @@ const DatePickerControlled = /*#__PURE__*/forwardRef((props, ref) => {
2133
2266
  })),
2134
2267
  label: /*#__PURE__*/React.createElement("span", {
2135
2268
  className: `${CLASSNAME$c}__month`
2136
- }, moment$1(selectedMonth).locale(locale).format('MMMM YYYY'))
2269
+ }, formatMonthYear(selectedMonth, locale))
2137
2270
  }), /*#__PURE__*/React.createElement("div", {
2138
2271
  className: `${CLASSNAME$c}__calendar`
2139
2272
  }, /*#__PURE__*/React.createElement("div", {
2140
2273
  className: `${CLASSNAME$c}__week-days ${CLASSNAME$c}__days-wrapper`
2141
- }, weekDays.map(weekDay => /*#__PURE__*/React.createElement("div", {
2142
- key: weekDay.unix(),
2143
- className: `${CLASSNAME$c}__day-wrapper`
2144
- }, /*#__PURE__*/React.createElement("span", {
2145
- className: `${CLASSNAME$c}__week-day`
2146
- }, weekDay.format('dddd').slice(0, 1).toLocaleUpperCase())))), /*#__PURE__*/React.createElement("div", {
2274
+ }, weekDays.map(_ref => {
2275
+ let {
2276
+ letter,
2277
+ number
2278
+ } = _ref;
2279
+ return /*#__PURE__*/React.createElement("div", {
2280
+ key: number,
2281
+ className: `${CLASSNAME$c}__day-wrapper`
2282
+ }, /*#__PURE__*/React.createElement("span", {
2283
+ className: `${CLASSNAME$c}__week-day`
2284
+ }, letter.toLocaleUpperCase()));
2285
+ })), /*#__PURE__*/React.createElement("div", {
2147
2286
  className: `${CLASSNAME$c}__month-days ${CLASSNAME$c}__days-wrapper`
2148
- }, days.map(annotatedDate => {
2149
- if (annotatedDate.isDisplayed) {
2287
+ }, weeks.flatMap((week, weekIndex) => {
2288
+ return weekDays.map((weekDay, dayIndex) => {
2289
+ const {
2290
+ date,
2291
+ isOutOfRange
2292
+ } = week[weekDay.number] || {};
2293
+ const key = `${weekIndex}-${dayIndex}`;
2294
+ const isToday = !isOutOfRange && date && isSameDay(date, new Date());
2295
+ const isSelected = date && value && isSameDay(value, date);
2150
2296
  return /*#__PURE__*/React.createElement("div", {
2151
- key: annotatedDate.date.unix(),
2297
+ key: key,
2152
2298
  className: `${CLASSNAME$c}__day-wrapper`
2153
- }, /*#__PURE__*/React.createElement("button", {
2154
- ref: value && annotatedDate.date.isSame(value, 'day') || !value && annotatedDate.isToday ? todayOrSelectedDateRef : null,
2299
+ }, date && /*#__PURE__*/React.createElement("button", {
2300
+ ref: isSelected || !value && isToday ? todayOrSelectedDateRef : null,
2155
2301
  className: classnames(`${CLASSNAME$c}__month-day`, {
2156
- [`${CLASSNAME$c}__month-day--is-selected`]: value && annotatedDate.date.isSame(value, 'day'),
2157
- [`${CLASSNAME$c}__month-day--is-today`]: annotatedDate.isClickable && annotatedDate.isToday
2302
+ [`${CLASSNAME$c}__month-day--is-selected`]: isSelected,
2303
+ [`${CLASSNAME$c}__month-day--is-today`]: isToday
2158
2304
  }),
2159
- disabled: !annotatedDate.isClickable,
2305
+ disabled: isOutOfRange,
2160
2306
  type: "button",
2161
- onClick: () => onChange(moment$1(annotatedDate.date).toDate())
2162
- }, /*#__PURE__*/React.createElement("span", null, annotatedDate.date.format('DD'))));
2163
- }
2164
- return /*#__PURE__*/React.createElement("div", {
2165
- key: annotatedDate.date.unix(),
2166
- className: `${CLASSNAME$c}__day-wrapper`
2307
+ onClick: () => onChange(date)
2308
+ }, /*#__PURE__*/React.createElement("span", null, formatDayNumber(date, locale))));
2167
2309
  });
2168
2310
  }))));
2169
2311
  });
@@ -2186,17 +2328,12 @@ const DatePicker = /*#__PURE__*/forwardRef((props, ref) => {
2186
2328
  onChange
2187
2329
  } = props,
2188
2330
  forwardedProps = _objectWithoutProperties(props, _excluded$f);
2189
- let castedValue;
2190
- if (value) {
2191
- castedValue = moment$1(value);
2192
- } else if (defaultMonth) {
2193
- castedValue = moment$1(defaultMonth);
2194
- }
2195
- if (castedValue && !castedValue.isValid()) {
2331
+ let referenceDate = value || defaultMonth || new Date();
2332
+ if (!isDateValid(referenceDate)) {
2196
2333
  // eslint-disable-next-line no-console
2197
- console.warn(`[@lumx/react/DatePicker] Invalid date provided ${castedValue}`);
2334
+ console.warn(`[@lumx/react/DatePicker] Invalid date provided ${referenceDate}`);
2335
+ referenceDate = new Date();
2198
2336
  }
2199
- const selectedDay = castedValue && castedValue.isValid() ? castedValue : moment$1();
2200
2337
  const [monthOffset, setMonthOffset] = useState(0);
2201
2338
  const setPrevMonth = () => setMonthOffset(monthOffset - 1);
2202
2339
  const setNextMonth = () => setMonthOffset(monthOffset + 1);
@@ -2204,7 +2341,7 @@ const DatePicker = /*#__PURE__*/forwardRef((props, ref) => {
2204
2341
  onChange(newDate);
2205
2342
  setMonthOffset(0);
2206
2343
  };
2207
- const selectedMonth = moment$1(selectedDay).locale(locale).add(monthOffset, 'months').toDate();
2344
+ const selectedMonth = addMonthResetDay(referenceDate, monthOffset);
2208
2345
  return /*#__PURE__*/React.createElement(DatePickerControlled, _extends({
2209
2346
  ref: ref
2210
2347
  }, forwardedProps, {
@@ -2362,6 +2499,15 @@ function useFocusTrap(focusZoneElement, focusElement) {
2362
2499
  }, [focusElement, focusZoneElement]);
2363
2500
  }
2364
2501
 
2502
+ /**
2503
+ * Standard date format based on locale.
2504
+ */
2505
+ const formatDate = (value, locale) => value.toLocaleDateString(locale, {
2506
+ year: 'numeric',
2507
+ month: 'long',
2508
+ day: 'numeric'
2509
+ });
2510
+
2365
2511
  const _excluded$g = ["defaultMonth", "disabled", "isDisabled", "locale", "maxDate", "minDate", "name", "nextButtonProps", "onChange", "previousButtonProps", "value"];
2366
2512
 
2367
2513
  /**
@@ -2385,7 +2531,7 @@ const DatePickerField = /*#__PURE__*/forwardRef((props, ref) => {
2385
2531
  defaultMonth,
2386
2532
  disabled,
2387
2533
  isDisabled = disabled,
2388
- locale,
2534
+ locale = getCurrentLocale(),
2389
2535
  maxDate,
2390
2536
  minDate,
2391
2537
  name,
@@ -2429,7 +2575,7 @@ const DatePickerField = /*#__PURE__*/forwardRef((props, ref) => {
2429
2575
  name: name,
2430
2576
  forceFocusStyle: isOpen,
2431
2577
  textFieldRef: anchorRef,
2432
- value: value ? moment$1(value).locale(locale).format('LL') : '',
2578
+ value: value ? formatDate(value, locale) : '',
2433
2579
  onClick: toggleSimpleMenu,
2434
2580
  onChange: onTextFieldChange,
2435
2581
  onKeyPress: handleKeyboardNav,