@lumx/react 3.5.4-alpha-optimize-lumx-react-bundle.0 → 3.5.4-alpha-remove-moment.2

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';
@@ -2026,6 +2024,21 @@ CommentBlock.displayName = COMPONENT_NAME$c;
2026
2024
  CommentBlock.className = CLASSNAME$b;
2027
2025
  CommentBlock.defaultProps = DEFAULT_PROPS$b;
2028
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
+
2029
2042
  /**
2030
2043
  * Component display name.
2031
2044
  */
@@ -2036,55 +2049,175 @@ const COMPONENT_NAME$d = 'DatePicker';
2036
2049
  */
2037
2050
  const CLASSNAME$c = getRootClassName(COMPONENT_NAME$d);
2038
2051
 
2039
- const moment = extendMoment(moment$1);
2052
+ /** Get first day of week for locale from the browser API */
2053
+ const getFromBrowser = locale => {
2054
+ try {
2055
+ var _localeMetadata$getWe;
2056
+ const localeMetadata = new Intl.Locale(locale.code);
2057
+ const {
2058
+ firstDay
2059
+ } = ((_localeMetadata$getWe = localeMetadata.getWeekInfo) === null || _localeMetadata$getWe === void 0 ? void 0 : _localeMetadata$getWe.call(localeMetadata)) || localeMetadata.weekInfo;
2060
+ // Sunday is represented as `0` in Date.getDay()
2061
+ if (firstDay === 7) return 0;
2062
+ return firstDay;
2063
+ } catch (e) {
2064
+ return undefined;
2065
+ }
2066
+ };
2067
+
2068
+ /** List first day for each locale (could be removed when all browser implement Locale weekInfo) */
2069
+ const FIRST_DAY_FOR_LOCALES = [{
2070
+ // Locales with Sunday as the first day of the week
2071
+ 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,
2072
+ firstDay: 0
2073
+ }, {
2074
+ // Locales with Monday as the first day of the week
2075
+ 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,
2076
+ firstDay: 1
2077
+ }, {
2078
+ // Locales with Saturday as the first day of the week
2079
+ localeRX: /^(ar|fa-ir)$/i,
2080
+ firstDay: 6
2081
+ }];
2082
+
2083
+ /** Find first day of week for locale from the constant */
2084
+ const getFromConstant = function (locale) {
2085
+ let searchBy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'code';
2086
+ // Search for locale (lang + region)
2087
+ for (const {
2088
+ localeRX,
2089
+ firstDay
2090
+ } of FIRST_DAY_FOR_LOCALES) {
2091
+ if (localeRX.test(locale[searchBy])) return firstDay;
2092
+ }
2093
+ // Fallback search for locale lang
2094
+ if (locale.code !== locale.language) {
2095
+ return getFromConstant(locale, 'language');
2096
+ }
2097
+ return undefined;
2098
+ };
2099
+
2100
+ /**
2101
+ * Get first day of the week for the given locale code (language + region).
2102
+ */
2103
+ const getFirstDayOfWeek = locale => {
2104
+ // Get from browser API
2105
+ const firstDay = getFromBrowser(locale);
2106
+ if (firstDay !== undefined) return firstDay;
2107
+
2108
+ // Get from constant
2109
+ return getFromConstant(locale);
2110
+ };
2111
+
2040
2112
  const DAYS_PER_WEEK = 7;
2113
+
2041
2114
  /**
2042
- * Get the list of days in a week based on locale.
2043
- *
2044
- * @param locale The locale using to generate the order of days in a week.
2045
- * @return The list of days in a week based on locale.
2115
+ * List week days (based on locale) with the week day letter (ex: "M" for "Monday") and week day number
2116
+ * (0-based index starting on Sunday).
2046
2117
  */
2047
- function getWeekDays(locale) {
2048
- return range(DAYS_PER_WEEK).map((_, i) => moment().locale(locale).weekday(i));
2049
- }
2118
+ const getWeekDays = locale => {
2119
+ var _getFirstDayOfWeek;
2120
+ const iterDate = new Date();
2121
+ const firstDay = (_getFirstDayOfWeek = getFirstDayOfWeek(locale)) !== null && _getFirstDayOfWeek !== void 0 ? _getFirstDayOfWeek : 1;
2122
+
2123
+ // Go to start of the week
2124
+ const offset = firstDay - iterDate.getDay();
2125
+ iterDate.setDate(iterDate.getDate() + offset);
2126
+
2127
+ // Iterate through the days of the week
2128
+ const weekDays = [];
2129
+ for (let i = 0; i < DAYS_PER_WEEK; i++) {
2130
+ // Single letter week day (ex: "M" for "Monday", "L" for "Lundi", etc.)
2131
+ const letter = iterDate.toLocaleDateString(locale.code, {
2132
+ weekday: 'narrow'
2133
+ });
2134
+ // Day number (1-based index starting on Monday)
2135
+ const number = iterDate.getDay();
2136
+ weekDays.push({
2137
+ letter,
2138
+ number
2139
+ });
2140
+ iterDate.setDate(iterDate.getDate() + 1);
2141
+ }
2142
+ return weekDays;
2143
+ };
2144
+
2145
+ /**
2146
+ * Get month calendar.
2147
+ * A list of weeks with days indexed by week day number
2148
+ */
2149
+ const getMonthCalendar = function (locale) {
2150
+ let referenceDate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Date();
2151
+ let rangeMinDate = arguments.length > 2 ? arguments[2] : undefined;
2152
+ let rangeMaxDate = arguments.length > 3 ? arguments[3] : undefined;
2153
+ const month = referenceDate.getMonth();
2154
+ const iterDate = new Date(referenceDate.getTime());
2155
+ iterDate.setDate(1);
2156
+ const weekDays = getWeekDays(locale);
2157
+ const lastDayOfWeek = last(weekDays);
2158
+ const weeks = [];
2159
+ let week = {};
2160
+ while (iterDate.getMonth() === month) {
2161
+ const weekDayNumber = iterDate.getDay();
2162
+ const day = {
2163
+ date: new Date(iterDate.getTime())
2164
+ };
2165
+
2166
+ // If a range is specified, check if the day is out of range.
2167
+ if (rangeMinDate && iterDate <= rangeMinDate || rangeMaxDate && iterDate >= rangeMaxDate) {
2168
+ day.isOutOfRange = true;
2169
+ }
2170
+ week[weekDayNumber] = day;
2171
+ if (weekDayNumber === lastDayOfWeek.number) {
2172
+ weeks.push(week);
2173
+ week = {};
2174
+ }
2175
+ iterDate.setDate(iterDate.getDate() + 1);
2176
+ }
2177
+ if (Object.keys(week).length) weeks.push(week);
2178
+ return {
2179
+ weeks,
2180
+ weekDays
2181
+ };
2182
+ };
2050
2183
 
2051
2184
  /**
2052
- * Get month calendar based on locale and start date.
2053
- *
2054
- * @param locale The locale using to generate the order of days in a week.
2055
- * @param selectedMonth The selected month.
2056
- * @return The list of days in a week based on locale.
2185
+ * Check `date1` is on the same day as `date2`.
2057
2186
  */
2058
- function getMonthCalendar(locale, selectedMonth) {
2059
- const firstDayOfMonth = moment(selectedMonth).startOf('month');
2060
- const endDayOfMonth = moment(selectedMonth).endOf('month');
2061
- // 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
2062
- const firstDay = firstDayOfMonth.locale(locale).startOf('week');
2063
- const monthRange = moment.range(firstDay.toDate(), endDayOfMonth.toDate());
2064
- return Array.from(monthRange.by('day'));
2065
- }
2187
+ const isSameDay = (date1, date2) => isDateValid(date1) && isDateValid(date2) && date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth() && date1.getDate() === date2.getDate();
2066
2188
 
2067
2189
  /**
2068
- * Get month calendar based on locale and start date.
2069
- * Each day is annotated to know if they are displayed and/or clickable.
2070
- *
2071
- * @param locale The locale using to generate the order of days in a week.
2072
- * @param minDate The first selectable date.
2073
- * @param maxDate The last selectable date.
2074
- * @param selectedMonth The selected month.
2075
- * @return The list of days in a week based on locale.
2190
+ * Get current browser locale.
2076
2191
  */
2077
- function getAnnotatedMonthCalendar(locale, minDate, maxDate, selectedMonth) {
2078
- const month = moment(selectedMonth).locale(locale).month();
2079
- const clickableRange = moment.range(minDate, maxDate);
2080
- return getMonthCalendar(locale, selectedMonth).map(date => {
2081
- return {
2082
- date,
2083
- isClickable: clickableRange.contains(date),
2084
- isDisplayed: date.month() === month,
2085
- isToday: date.isSame(moment(), 'day')
2086
- };
2087
- });
2192
+ const getCurrentLocale = () => {
2193
+ var _navigator$languages;
2194
+ return ((_navigator$languages = navigator.languages) === null || _navigator$languages === void 0 ? void 0 : _navigator$languages[0]) || navigator.language;
2195
+ };
2196
+
2197
+ /**
2198
+ * Parse locale code
2199
+ * @example
2200
+ * parseLocale('EN') // => { code: 'en', language: 'en' }
2201
+ * parseLocale('en_us') // => { code: 'en-US', language: 'en', region: 'US' }
2202
+ * parseLocale('EN-US') // => { code: 'en-US', language: 'en', region: 'US' }
2203
+ */
2204
+ function parseLocale(locale) {
2205
+ const [rawLanguage, rawRegion] = locale.split(/[-_]/);
2206
+ if (!rawLanguage) {
2207
+ return undefined;
2208
+ }
2209
+ const language = rawLanguage.toLowerCase();
2210
+ let region;
2211
+ let code = language;
2212
+ if (rawRegion) {
2213
+ region = rawRegion.toUpperCase();
2214
+ code += `-${region}`;
2215
+ }
2216
+ return {
2217
+ code,
2218
+ region,
2219
+ language
2220
+ };
2088
2221
  }
2089
2222
 
2090
2223
  /**
@@ -2105,7 +2238,7 @@ const COMPONENT_NAME$e = 'DatePickerControlled';
2105
2238
  */
2106
2239
  const DatePickerControlled = /*#__PURE__*/forwardRef((props, ref) => {
2107
2240
  const {
2108
- locale,
2241
+ locale = getCurrentLocale(),
2109
2242
  maxDate,
2110
2243
  minDate,
2111
2244
  nextButtonProps,
@@ -2117,12 +2250,13 @@ const DatePickerControlled = /*#__PURE__*/forwardRef((props, ref) => {
2117
2250
  todayOrSelectedDateRef,
2118
2251
  value
2119
2252
  } = props;
2120
- const days = React.useMemo(() => {
2121
- return getAnnotatedMonthCalendar(locale, minDate, maxDate, moment$1(selectedMonth));
2253
+ const {
2254
+ weeks,
2255
+ weekDays
2256
+ } = React.useMemo(() => {
2257
+ const localeObj = parseLocale(locale);
2258
+ return getMonthCalendar(localeObj, selectedMonth, minDate, maxDate);
2122
2259
  }, [locale, minDate, maxDate, selectedMonth]);
2123
- const weekDays = React.useMemo(() => {
2124
- return getWeekDays(locale);
2125
- }, [locale]);
2126
2260
  return /*#__PURE__*/React.createElement("div", {
2127
2261
  ref: ref,
2128
2262
  className: `${CLASSNAME$c}`
@@ -2140,37 +2274,51 @@ const DatePickerControlled = /*#__PURE__*/forwardRef((props, ref) => {
2140
2274
  })),
2141
2275
  label: /*#__PURE__*/React.createElement("span", {
2142
2276
  className: `${CLASSNAME$c}__month`
2143
- }, moment$1(selectedMonth).locale(locale).format('MMMM YYYY'))
2277
+ }, selectedMonth.toLocaleDateString(locale, {
2278
+ year: 'numeric',
2279
+ month: 'long'
2280
+ }))
2144
2281
  }), /*#__PURE__*/React.createElement("div", {
2145
2282
  className: `${CLASSNAME$c}__calendar`
2146
2283
  }, /*#__PURE__*/React.createElement("div", {
2147
2284
  className: `${CLASSNAME$c}__week-days ${CLASSNAME$c}__days-wrapper`
2148
- }, weekDays.map(weekDay => /*#__PURE__*/React.createElement("div", {
2149
- key: weekDay.unix(),
2150
- className: `${CLASSNAME$c}__day-wrapper`
2151
- }, /*#__PURE__*/React.createElement("span", {
2152
- className: `${CLASSNAME$c}__week-day`
2153
- }, weekDay.format('dddd').slice(0, 1).toLocaleUpperCase())))), /*#__PURE__*/React.createElement("div", {
2285
+ }, weekDays.map(_ref => {
2286
+ let {
2287
+ letter,
2288
+ number
2289
+ } = _ref;
2290
+ return /*#__PURE__*/React.createElement("div", {
2291
+ key: number,
2292
+ className: `${CLASSNAME$c}__day-wrapper`
2293
+ }, /*#__PURE__*/React.createElement("span", {
2294
+ className: `${CLASSNAME$c}__week-day`
2295
+ }, letter.toLocaleUpperCase()));
2296
+ })), /*#__PURE__*/React.createElement("div", {
2154
2297
  className: `${CLASSNAME$c}__month-days ${CLASSNAME$c}__days-wrapper`
2155
- }, days.map(annotatedDate => {
2156
- if (annotatedDate.isDisplayed) {
2298
+ }, weeks.flatMap((week, weekIndex) => {
2299
+ return weekDays.map((weekDay, dayIndex) => {
2300
+ const {
2301
+ date,
2302
+ isOutOfRange
2303
+ } = week[weekDay.number] || {};
2304
+ const key = `${weekIndex}-${dayIndex}`;
2305
+ const isToday = !isOutOfRange && date && isSameDay(date, new Date());
2306
+ const isSelected = date && value && isSameDay(value, date);
2157
2307
  return /*#__PURE__*/React.createElement("div", {
2158
- key: annotatedDate.date.unix(),
2308
+ key: key,
2159
2309
  className: `${CLASSNAME$c}__day-wrapper`
2160
- }, /*#__PURE__*/React.createElement("button", {
2161
- ref: value && annotatedDate.date.isSame(value, 'day') || !value && annotatedDate.isToday ? todayOrSelectedDateRef : null,
2310
+ }, date && /*#__PURE__*/React.createElement("button", {
2311
+ ref: isSelected || !value && isToday ? todayOrSelectedDateRef : null,
2162
2312
  className: classnames(`${CLASSNAME$c}__month-day`, {
2163
- [`${CLASSNAME$c}__month-day--is-selected`]: value && annotatedDate.date.isSame(value, 'day'),
2164
- [`${CLASSNAME$c}__month-day--is-today`]: annotatedDate.isClickable && annotatedDate.isToday
2313
+ [`${CLASSNAME$c}__month-day--is-selected`]: isSelected,
2314
+ [`${CLASSNAME$c}__month-day--is-today`]: isToday
2165
2315
  }),
2166
- disabled: !annotatedDate.isClickable,
2316
+ disabled: isOutOfRange,
2167
2317
  type: "button",
2168
- onClick: () => onChange(moment$1(annotatedDate.date).toDate())
2169
- }, /*#__PURE__*/React.createElement("span", null, annotatedDate.date.format('DD'))));
2170
- }
2171
- return /*#__PURE__*/React.createElement("div", {
2172
- key: annotatedDate.date.unix(),
2173
- className: `${CLASSNAME$c}__day-wrapper`
2318
+ onClick: () => onChange(date)
2319
+ }, /*#__PURE__*/React.createElement("span", null, date.toLocaleDateString(locale, {
2320
+ day: 'numeric'
2321
+ }))));
2174
2322
  });
2175
2323
  }))));
2176
2324
  });
@@ -2193,17 +2341,12 @@ const DatePicker = /*#__PURE__*/forwardRef((props, ref) => {
2193
2341
  onChange
2194
2342
  } = props,
2195
2343
  forwardedProps = _objectWithoutProperties(props, _excluded$f);
2196
- let castedValue;
2197
- if (value) {
2198
- castedValue = moment$1(value);
2199
- } else if (defaultMonth) {
2200
- castedValue = moment$1(defaultMonth);
2201
- }
2202
- if (castedValue && !castedValue.isValid()) {
2344
+ let referenceDate = value || defaultMonth || new Date();
2345
+ if (!isDateValid(referenceDate)) {
2203
2346
  // eslint-disable-next-line no-console
2204
- console.warn(`[@lumx/react/DatePicker] Invalid date provided ${castedValue}`);
2347
+ console.warn(`[@lumx/react/DatePicker] Invalid date provided ${referenceDate}`);
2348
+ referenceDate = new Date();
2205
2349
  }
2206
- const selectedDay = castedValue && castedValue.isValid() ? castedValue : moment$1();
2207
2350
  const [monthOffset, setMonthOffset] = useState(0);
2208
2351
  const setPrevMonth = () => setMonthOffset(monthOffset - 1);
2209
2352
  const setNextMonth = () => setMonthOffset(monthOffset + 1);
@@ -2211,7 +2354,7 @@ const DatePicker = /*#__PURE__*/forwardRef((props, ref) => {
2211
2354
  onChange(newDate);
2212
2355
  setMonthOffset(0);
2213
2356
  };
2214
- const selectedMonth = moment$1(selectedDay).locale(locale).add(monthOffset, 'months').toDate();
2357
+ const selectedMonth = addMonthResetDay(referenceDate, monthOffset);
2215
2358
  return /*#__PURE__*/React.createElement(DatePickerControlled, _extends({
2216
2359
  ref: ref
2217
2360
  }, forwardedProps, {
@@ -2392,7 +2535,7 @@ const DatePickerField = /*#__PURE__*/forwardRef((props, ref) => {
2392
2535
  defaultMonth,
2393
2536
  disabled,
2394
2537
  isDisabled = disabled,
2395
- locale,
2538
+ locale = getCurrentLocale(),
2396
2539
  maxDate,
2397
2540
  minDate,
2398
2541
  name,
@@ -2430,13 +2573,20 @@ const DatePickerField = /*#__PURE__*/forwardRef((props, ref) => {
2430
2573
  onChange(newDate, name);
2431
2574
  onClose();
2432
2575
  };
2576
+
2577
+ // Format date for text field
2578
+ const textFieldValue = (value === null || value === void 0 ? void 0 : value.toLocaleDateString(locale, {
2579
+ year: 'numeric',
2580
+ month: 'long',
2581
+ day: 'numeric'
2582
+ })) || '';
2433
2583
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TextField, _extends({
2434
2584
  ref: ref
2435
2585
  }, forwardedProps, {
2436
2586
  name: name,
2437
2587
  forceFocusStyle: isOpen,
2438
2588
  textFieldRef: anchorRef,
2439
- value: value ? moment$1(value).locale(locale).format('LL') : '',
2589
+ value: textFieldValue,
2440
2590
  onClick: toggleSimpleMenu,
2441
2591
  onChange: onTextFieldChange,
2442
2592
  onKeyPress: handleKeyboardNav,