@transferwise/components 0.0.0-experimental-2825d2d → 0.0.0-experimental-1413ac0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/build/i18n/zh-HK.json +2 -2
  2. package/build/index.esm.js +186 -277
  3. package/build/index.esm.js.map +1 -1
  4. package/build/index.js +159 -250
  5. package/build/index.js.map +1 -1
  6. package/build/types/body/Body.d.ts +1 -1
  7. package/build/types/common/commonProps.d.ts +1 -1
  8. package/build/types/common/commonProps.d.ts.map +1 -1
  9. package/build/types/common/dateUtils/getDayNames/getDayNames.d.ts +1 -1
  10. package/build/types/common/dateUtils/getDayNames/getDayNames.d.ts.map +1 -1
  11. package/build/types/common/dateUtils/getDayNames/index.d.ts +1 -1
  12. package/build/types/common/dateUtils/getDayNames/index.d.ts.map +1 -1
  13. package/build/types/common/dateUtils/getMonthNames/getMonthNames.d.ts +1 -1
  14. package/build/types/common/dateUtils/getMonthNames/getMonthNames.d.ts.map +1 -1
  15. package/build/types/common/dateUtils/getMonthNames/index.d.ts +1 -1
  16. package/build/types/common/dateUtils/getMonthNames/index.d.ts.map +1 -1
  17. package/build/types/common/dateUtils/index.d.ts +6 -6
  18. package/build/types/common/dateUtils/index.d.ts.map +1 -1
  19. package/build/types/common/dateUtils/isDateValid/index.d.ts +1 -1
  20. package/build/types/common/dateUtils/isDateValid/index.d.ts.map +1 -1
  21. package/build/types/common/dateUtils/isDateValid/isDateValid.d.ts +2 -2
  22. package/build/types/common/dateUtils/isDateValid/isDateValid.d.ts.map +1 -1
  23. package/build/types/common/dateUtils/isMonthAndYearFormat/index.d.ts +1 -1
  24. package/build/types/common/dateUtils/isMonthAndYearFormat/index.d.ts.map +1 -1
  25. package/build/types/common/dateUtils/isMonthAndYearFormat/isMonthAndYearFormat.d.ts +1 -1
  26. package/build/types/common/dateUtils/isMonthAndYearFormat/isMonthAndYearFormat.d.ts.map +1 -1
  27. package/build/types/common/dateUtils/isWithinRange/index.d.ts +1 -1
  28. package/build/types/common/dateUtils/isWithinRange/index.d.ts.map +1 -1
  29. package/build/types/common/dateUtils/isWithinRange/isWithinRange.d.ts +1 -1
  30. package/build/types/common/dateUtils/isWithinRange/isWithinRange.d.ts.map +1 -1
  31. package/build/types/common/dateUtils/moveToWithinRange/index.d.ts +1 -1
  32. package/build/types/common/dateUtils/moveToWithinRange/index.d.ts.map +1 -1
  33. package/build/types/common/dateUtils/moveToWithinRange/moveToWithinRange.d.ts +1 -1
  34. package/build/types/common/dateUtils/moveToWithinRange/moveToWithinRange.d.ts.map +1 -1
  35. package/build/types/common/panel/Panel.d.ts +1 -1
  36. package/build/types/common/responsivePanel/ResponsivePanel.d.ts +1 -1
  37. package/build/types/dateInput/DateInput.d.ts +41 -35
  38. package/build/types/dateInput/DateInput.d.ts.map +1 -1
  39. package/build/types/dateInput/DateInput.messages.d.ts +33 -24
  40. package/build/types/dateInput/DateInput.messages.d.ts.map +1 -1
  41. package/build/types/dateInput/index.d.ts +1 -1
  42. package/build/types/dateInput/index.d.ts.map +1 -1
  43. package/build/types/dateInput/utils/convertToLocalMidnight/convertToLocalMidnight.d.ts +1 -1
  44. package/build/types/dateInput/utils/convertToLocalMidnight/convertToLocalMidnight.d.ts.map +1 -1
  45. package/build/types/dateInput/utils/convertToLocalMidnight/index.d.ts +1 -1
  46. package/build/types/dateInput/utils/convertToLocalMidnight/index.d.ts.map +1 -1
  47. package/build/types/dateInput/utils/explodeDate/explodeDate.d.ts +5 -2
  48. package/build/types/dateInput/utils/explodeDate/explodeDate.d.ts.map +1 -1
  49. package/build/types/dateInput/utils/explodeDate/index.d.ts +1 -1
  50. package/build/types/dateInput/utils/explodeDate/index.d.ts.map +1 -1
  51. package/build/types/dateInput/utils/index.d.ts +2 -2
  52. package/build/types/dateInput/utils/index.d.ts.map +1 -1
  53. package/build/types/decision/Decision.d.ts +39 -52
  54. package/build/types/decision/Decision.d.ts.map +1 -1
  55. package/build/types/decision/index.d.ts +1 -2
  56. package/build/types/decision/index.d.ts.map +1 -1
  57. package/build/types/dimmer/Dimmer.d.ts +1 -1
  58. package/build/types/index.d.ts +1 -0
  59. package/build/types/index.d.ts.map +1 -1
  60. package/build/types/promoCard/PromoCard.d.ts +1 -2
  61. package/build/types/promoCard/PromoCard.d.ts.map +1 -1
  62. package/build/types/select/searchBox/SearchBox.d.ts +1 -1
  63. package/package.json +1 -1
  64. package/src/common/commonProps.ts +1 -1
  65. package/src/common/dateUtils/getDayNames/{getDayNames.ts → getDayNames.js} +2 -5
  66. package/src/common/dateUtils/getMonthNames/{getMonthNames.ts → getMonthNames.js} +3 -5
  67. package/src/common/dateUtils/getMonthNames/getMonthNames.spec.js +8 -9
  68. package/src/common/dateUtils/isDateValid/isDateValid.js +6 -0
  69. package/src/common/dateUtils/isDateValid/{isDateValid.spec.ts → isDateValid.spec.js} +2 -2
  70. package/src/common/dateUtils/isMonthAndYearFormat/{isMonthAndYearFormat.ts → isMonthAndYearFormat.js} +1 -1
  71. package/src/common/dateUtils/isMonthAndYearFormat/isMonthAndYearFormat.spec.js +7 -3
  72. package/src/common/dateUtils/isWithinRange/{isWithinRange.ts → isWithinRange.js} +1 -1
  73. package/src/common/dateUtils/isWithinRange/{isWithinRange.spec.ts → isWithinRange.spec.js} +6 -6
  74. package/src/common/dateUtils/moveToWithinRange/{moveToWithinRange.ts → moveToWithinRange.js} +2 -2
  75. package/src/dateInput/{DateInput.tsx → DateInput.js} +97 -120
  76. package/src/dateInput/DateInput.spec.js +55 -6
  77. package/src/dateInput/DateInput.story.tsx +7 -9
  78. package/src/dateInput/utils/convertToLocalMidnight/{convertToLocalMidnight.ts → convertToLocalMidnight.js} +1 -1
  79. package/src/dateInput/utils/explodeDate/{explodeDate.ts → explodeDate.js} +1 -3
  80. package/src/dateLookup/dayCalendar/table/DayCalendarTable.js +0 -1
  81. package/src/decision/Decision.spec.js +53 -59
  82. package/src/decision/{Decision.story.js → Decision.story.tsx} +5 -5
  83. package/src/decision/Decision.tsx +136 -0
  84. package/src/decision/index.ts +1 -0
  85. package/src/i18n/zh-HK.json +2 -2
  86. package/src/index.ts +1 -0
  87. package/src/promoCard/PromoCard.tsx +1 -2
  88. package/src/tile/Tile.js +1 -1
  89. package/build/types/decision/decisionEnums.d.ts +0 -9
  90. package/build/types/decision/decisionEnums.d.ts.map +0 -1
  91. package/build/types/sizeSwapper/SizeSwapper.d.ts +0 -3
  92. package/build/types/sizeSwapper/SizeSwapper.d.ts.map +0 -1
  93. package/build/types/sizeSwapper/index.d.ts +0 -2
  94. package/build/types/sizeSwapper/index.d.ts.map +0 -1
  95. package/src/common/dateUtils/isDateValid/isDateValid.ts +0 -13
  96. package/src/decision/Decision.js +0 -148
  97. package/src/decision/decisionEnums.ts +0 -11
  98. package/src/decision/index.js +0 -2
  99. package/src/sizeSwapper/SizeSwapper.js +0 -69
  100. package/src/sizeSwapper/SizeSwapper.spec.js +0 -100
  101. package/src/sizeSwapper/SizeSwapper.story.js +0 -34
  102. package/src/sizeSwapper/index.js +0 -1
  103. /package/src/common/dateUtils/getDayNames/{index.ts → index.js} +0 -0
  104. /package/src/common/dateUtils/getMonthNames/{index.ts → index.js} +0 -0
  105. /package/src/common/dateUtils/{index.ts → index.js} +0 -0
  106. /package/src/common/dateUtils/isDateValid/{index.ts → index.js} +0 -0
  107. /package/src/common/dateUtils/isMonthAndYearFormat/{index.ts → index.js} +0 -0
  108. /package/src/common/dateUtils/isWithinRange/{index.ts → index.js} +0 -0
  109. /package/src/common/dateUtils/moveToWithinRange/{index.ts → index.js} +0 -0
  110. /package/src/dateInput/{DateInput.messages.ts → DateInput.messages.js} +0 -0
  111. /package/src/dateInput/{index.ts → index.js} +0 -0
  112. /package/src/dateInput/utils/convertToLocalMidnight/{convertToLocalMidnight.spec.ts → convertToLocalMidnight.spec.js} +0 -0
  113. /package/src/dateInput/utils/convertToLocalMidnight/{index.ts → index.js} +0 -0
  114. /package/src/dateInput/utils/explodeDate/{explodeDate.spec.ts → explodeDate.spec.js} +0 -0
  115. /package/src/dateInput/utils/explodeDate/{index.ts → index.js} +0 -0
  116. /package/src/dateInput/utils/{index.ts → index.js} +0 -0
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import { CardProps } from '../common/card';
3
3
  import { PromoCardIndicatorProps } from './PromoCardIndicator';
4
4
  export type ReferenceType = React.Ref<HTMLInputElement>;
5
- export type LinkTarget = '_blank' | '_parent' | '_self' | '_top';
6
5
  export type RelatedTypes = '' | 'alternate' | 'author' | 'bookmark' | 'external' | 'help' | 'license' | 'next' | 'nofollow' | 'noreferrer' | 'noopener' | 'prev' | 'search' | 'tag';
7
6
  export interface PromoCardCommonProps {
8
7
  /** Optional prop to specify classNames onto the PromoCard */
@@ -54,7 +53,7 @@ export interface PromoCardLinkProps extends PromoCardCommonProps, Omit<CardProps
54
53
  */
55
54
  rel?: RelatedTypes;
56
55
  /** Optional prop to to display where the linked URL will show */
57
- target?: LinkTarget;
56
+ target?: React.HTMLAttributeAnchorTarget;
58
57
  /** Only applies to role="radio" or "checkbox" */
59
58
  defaultChecked?: never;
60
59
  isChecked?: never;
@@ -1 +1 @@
1
- {"version":3,"file":"PromoCard.d.ts","sourceRoot":"","sources":["../../../src/promoCard/PromoCard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2E,MAAM,OAAO,CAAC;AAIhG,OAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAMjD,OAA2B,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEnF,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACxD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AACjE,MAAM,MAAM,YAAY,GACpB,EAAE,GACF,WAAW,GACX,QAAQ,GACR,UAAU,GACV,UAAU,GACV,MAAM,GACN,SAAS,GACT,MAAM,GACN,UAAU,GACV,YAAY,GACZ,UAAU,GACV,MAAM,GACN,QAAQ,GACR,KAAK,CAAC;AAEV,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAEzC,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,gFAAgF;IAChF,aAAa,CAAC,EAAE,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAEhD,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,wDAAwD;IACxD,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IAEd,0DAA0D;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAmB,SAAQ,oBAAoB,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAC3F;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;OAGG;IACH,GAAG,CAAC,EAAE,YAAY,CAAC;IAEnB,iEAAiE;IACjE,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB,iDAAiD;IACjD,cAAc,CAAC,EAAE,KAAK,CAAC;IACvB,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,WAAW,qBAAsB,SAAQ,oBAAoB,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9F,6DAA6D;IAC7D,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,iDAAiD;IACjD,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,gEAAgE;IAChE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAE5B,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,MAAM,CAAC,EAAE,KAAK,CAAC;CAChB;AAED,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AAExE,MAAM,MAAM,oBAAoB,GAAG,CACjC,KAAK,EAAE,kBAAkB,GAAG,qBAAqB,KAC9C,GAAG,CAAC,OAAO,CAAC;;AAmOjB,wBAAqC"}
1
+ {"version":3,"file":"PromoCard.d.ts","sourceRoot":"","sources":["../../../src/promoCard/PromoCard.tsx"],"names":[],"mappings":"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"}
@@ -3,6 +3,6 @@ declare const SearchBox: import("react").ForwardRefExoticComponent<{
3
3
  id?: string | undefined;
4
4
  classNames?: Record<string, string> | undefined;
5
5
  focusedOptionId?: string | undefined;
6
- } & Pick<InputHTMLAttributes<HTMLInputElement>, "value" | "placeholder" | "onChange" | "onClick"> & import("react").RefAttributes<HTMLInputElement>>;
6
+ } & Pick<InputHTMLAttributes<HTMLInputElement>, "placeholder" | "onChange" | "onClick" | "value"> & import("react").RefAttributes<HTMLInputElement>>;
7
7
  export default SearchBox;
8
8
  //# sourceMappingURL=SearchBox.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "0.0.0-experimental-2825d2d",
3
+ "version": "0.0.0-experimental-1413ac0",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -14,7 +14,7 @@ export type AriaLabelProperty = {
14
14
 
15
15
  export type LinkProps = {
16
16
  href: string;
17
- target?: '_blank' | '_self' | '_parent' | '_top';
17
+ target?: React.HTMLAttributeAnchorTarget;
18
18
  onClick?: React.MouseEventHandler<HTMLElement>;
19
19
  };
20
20
 
@@ -1,10 +1,7 @@
1
1
  import { formatDate } from '@transferwise/formatting';
2
2
 
3
- export function getDayNames(
4
- locale?: string | undefined,
5
- format: Intl.DateTimeFormatOptions['weekday'] = 'short',
6
- ) {
7
- const days: string[] = [];
3
+ export function getDayNames(locale, format = 'short') {
4
+ const days = [];
8
5
  const date = new Date(2018, 0, 1); // 2018 started with Monday
9
6
  while (days.length < 7) {
10
7
  days.push(formatDate(date, locale, { weekday: format }));
@@ -1,15 +1,13 @@
1
1
  import { formatDate } from '@transferwise/formatting';
2
2
 
3
- export const getMonthNames = (
4
- locale: string | undefined,
5
- format: Intl.DateTimeFormatOptions['month'] = 'long',
6
- ): string[] => {
7
- const months: string[] = [];
3
+ export const getMonthNames = (locale, format = 'long') => {
4
+ const months = [];
8
5
  const date = new Date(2018, 0, 1);
9
6
  const monthFormat = { month: format };
10
7
  while (months.length < 12) {
11
8
  months.push(formatDate(date, locale, monthFormat));
12
9
  date.setMonth(date.getMonth() + 1);
13
10
  }
11
+
14
12
  return months;
15
13
  };
@@ -1,4 +1,8 @@
1
- import { getMonthNames } from './getMonthNames';
1
+ import { getMonthNames } from '..';
2
+
3
+ jest.mock('@transferwise/formatting', () => ({
4
+ formatDate: (month) => month.getMonth(),
5
+ }));
2
6
 
3
7
  describe('getMonthNames', () => {
4
8
  it('returns all months', () => {
@@ -6,13 +10,8 @@ describe('getMonthNames', () => {
6
10
  });
7
11
 
8
12
  it('starts with January and ends with December', () => {
9
- const months = getMonthNames('en', 'long');
10
- expect(months[0]).toBe('January');
11
- expect(months.at(-1)).toBe('December');
12
- });
13
-
14
- it('gets localized month names', () => {
15
- const months = getMonthNames('fr', 'long');
16
- expect(months[0]).toBe('janvier');
13
+ const months = getMonthNames();
14
+ expect(months[0]).toBe(0);
15
+ expect(months[months.length - 1]).toBe(11);
17
16
  });
18
17
  });
@@ -0,0 +1,6 @@
1
+ export const isDateValid = (date) => validDateObject(date) || validDateString(date);
2
+
3
+ export const validDateString = (dateString) =>
4
+ typeof dateString === 'string' && validDateObject(new Date(dateString));
5
+
6
+ const validDateObject = (dateObject) => dateObject instanceof Date && !isNaN(dateObject); // eslint-disable-line no-restricted-globals
@@ -1,4 +1,4 @@
1
- import { isDateValid } from '..';
1
+ import { isDateValid } from '.';
2
2
 
3
3
  describe('isDateValid', () => {
4
4
  it('should return false for invalid format', () => {
@@ -6,6 +6,6 @@ describe('isDateValid', () => {
6
6
  });
7
7
 
8
8
  it('should return true for valid format', () => {
9
- expect(isDateValid(new Date('1995-12-17T03:24:00') as unknown as string)).toBe(true);
9
+ expect(isDateValid(new Date('1995-12-17T03:24:00'))).toBe(true);
10
10
  });
11
11
  });
@@ -1,4 +1,4 @@
1
1
  import { validDateString } from '../isDateValid';
2
2
 
3
- export const isMonthAndYearFormat = (dateString: string) =>
3
+ export const isMonthAndYearFormat = (dateString) =>
4
4
  validDateString(dateString) && dateString.split('-').length < 3;
@@ -1,11 +1,15 @@
1
- import { isMonthAndYearFormat } from '..';
1
+ import { isMonthAndYearFormat } from '.';
2
2
 
3
3
  describe('isDateValid', () => {
4
- it('should return false if day is provided as string', () => {
4
+ it('should return false if day is provided', () => {
5
5
  expect(isMonthAndYearFormat('1998-02-04')).toBe(false);
6
6
  });
7
7
 
8
- it('should return true if day is not provided as string', () => {
8
+ it('should return true if day is not provided', () => {
9
9
  expect(isMonthAndYearFormat('1998-02')).toBe(true);
10
10
  });
11
+
12
+ it('should return false if argument provided is not a string', () => {
13
+ expect(isMonthAndYearFormat([])).toBe(false);
14
+ });
11
15
  });
@@ -1,3 +1,3 @@
1
- export function isWithinRange(date?: Date, min?: Date, max?: Date) {
1
+ export function isWithinRange(date, min, max) {
2
2
  return !date || ((!min || date >= min) && (!max || date <= max));
3
3
  }
@@ -2,17 +2,17 @@ import { isWithinRange } from '..';
2
2
 
3
3
  describe('isWithinRange', () => {
4
4
  it('returns true when no dates are provided', () => {
5
- expect(isWithinRange(undefined, undefined, undefined)).toBe(true);
5
+ expect(isWithinRange()).toBe(true);
6
6
  });
7
7
 
8
8
  it('returns true when no min and max', () => {
9
- expect(isWithinRange(new Date(), undefined, undefined)).toBe(true);
9
+ expect(isWithinRange(new Date())).toBe(true);
10
10
  });
11
11
 
12
12
  it('returns true when date is between min and max', () => {
13
- const date: Date = new Date('1995-12-20');
14
- const min: Date = new Date('1995-12-19');
15
- const max: Date = new Date('1995-12-21');
13
+ const date = new Date('1995-12-20');
14
+ const min = new Date('1995-12-19');
15
+ const max = new Date('1995-12-21');
16
16
  expect(isWithinRange(date, min, max)).toBe(true);
17
17
  });
18
18
 
@@ -35,7 +35,7 @@ describe('isWithinRange', () => {
35
35
  const date = new Date('1995-12-23');
36
36
  const min = new Date('1995-12-20');
37
37
  const max = new Date('1995-12-22');
38
- expect(isWithinRange(date, undefined, max)).toBe(false);
38
+ expect(isWithinRange(date, null, max)).toBe(false);
39
39
  expect(isWithinRange(date, min, max)).toBe(false);
40
40
  });
41
41
  });
@@ -1,6 +1,6 @@
1
- import { isWithinRange } from '..';
1
+ import { isWithinRange } from '../isWithinRange';
2
2
 
3
3
  // Makes sure that date is between min and max dates, returns a cloned min or max
4
- export function moveToWithinRange(date: Date, min: Date, max: Date) {
4
+ export function moveToWithinRange(date, min, max) {
5
5
  return isWithinRange(date, min, max) ? date : new Date(min && date < min ? +min : +max);
6
6
  }
@@ -1,14 +1,9 @@
1
1
  import classNames from 'classnames';
2
- import React, { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { useState } from 'react';
3
4
  import { useIntl } from 'react-intl';
4
5
 
5
- import {
6
- Input,
7
- SelectInput,
8
- SelectInputProps,
9
- SelectInputOptionItem,
10
- SelectInputOptionContent,
11
- } from '..';
6
+ import { Input, SelectInput, SelectInputOptionContent } from '..';
12
7
  import { Size, DateMode, MonthFormat } from '../common';
13
8
  import { getMonthNames, isDateValid, isMonthAndYearFormat } from '../common/dateUtils';
14
9
 
@@ -16,79 +11,44 @@ import messages from './DateInput.messages';
16
11
  import { explodeDate, convertToLocalMidnight } from './utils';
17
12
 
18
13
  const MonthBeforeDay = new Set(['en-US', 'ja-JP']);
19
- const INITIAL_DEFAULT_STATE: ExplodedDate = { year: null, month: null, day: null };
20
-
21
- export interface ExplodedDate {
22
- year: number | null;
23
- month: number | null;
24
- day: number | null;
25
- }
26
-
27
- export interface DateInputProps {
28
- 'aria-label'?: string;
29
- 'aria-labelledby'?: string;
30
- disabled?: boolean;
31
- size?: Size.SMALL | Size.MEDIUM | Size.LARGE;
32
- value?: Date | string | null;
33
- onChange: (value: string | null) => void;
34
- onFocus?: React.FocusEventHandler<HTMLInputElement>;
35
- onBlur?: React.FocusEventHandler<HTMLInputElement>;
36
- dayLabel?: string;
37
- dayAutoComplete?: string;
38
- monthLabel?: string;
39
- yearLabel?: string;
40
- yearAutoComplete?: string;
41
- monthFormat?: MonthFormat;
42
- mode?: DateMode;
43
- placeholders?: {
44
- day?: string;
45
- month?: string;
46
- year?: string;
47
- };
48
- id?: string;
49
- selectProps?: Partial<SelectInputProps<number>>;
50
- }
14
+ const INITIAL_DEFAULT_STATE = { year: null, month: null, day: null };
51
15
 
52
16
  const DateInput = ({
53
17
  'aria-labelledby': ariaLabelledBy,
54
18
  'aria-label': ariaLabel,
55
- disabled = false,
56
- size = Size.MEDIUM,
57
- value = null,
19
+ disabled,
20
+ size,
21
+ value,
58
22
  dayLabel,
59
23
  dayAutoComplete,
60
24
  monthLabel,
61
25
  yearLabel,
62
26
  yearAutoComplete,
63
- monthFormat = MonthFormat.LONG,
64
- mode = DateMode.DAY_MONTH_YEAR,
27
+ monthFormat,
28
+ mode,
65
29
  onChange,
66
30
  onFocus,
67
- onBlur = undefined,
31
+ onBlur,
68
32
  placeholders,
69
- id = '',
33
+ id,
70
34
  selectProps,
71
- }: DateInputProps) => {
35
+ }) => {
72
36
  const { locale, formatMessage } = useIntl();
73
-
74
- const getDateObject = (): Date | null => {
37
+ const getDateObject = () => {
75
38
  if (value && isDateValid(value)) {
76
39
  return typeof value === 'string' ? convertToLocalMidnight(value) : value;
77
40
  }
78
41
  return null;
79
42
  };
80
43
 
81
- const getExplodedDate = (unit: 'year' | 'month' | 'day'): number | null => {
82
- let explodedDate: ExplodedDate = INITIAL_DEFAULT_STATE;
44
+ const getExplodedDate = (unit) => {
45
+ let explodedDate = INITIAL_DEFAULT_STATE;
83
46
 
84
47
  if (value && isDateValid(value)) {
85
48
  const dateObject = getDateObject();
49
+ explodedDate = explodeDate(dateObject);
86
50
 
87
- if (dateObject !== null) {
88
- explodedDate = explodeDate(dateObject);
89
- }
90
-
91
- if (typeof value === 'string' && isMonthAndYearFormat(value)) {
51
+ if (isMonthAndYearFormat(value)) {
92
52
  explodedDate.day = null;
93
53
  }
94
54
  }
@@ -96,11 +56,9 @@ const DateInput = ({
96
56
  };
97
57
 
98
58
  const [day, setDay] = useState(() => getExplodedDate('day'));
99
- const [month, setMonth] = useState<number | null>(() => getExplodedDate('month'));
59
+ const [month, setMonth] = useState(() => getExplodedDate('month'));
100
60
  const [year, setYear] = useState(() => getExplodedDate('year'));
101
- const [lastBroadcastedValue, setLastBroadcastedValue] = useState<Date | ExplodedDate | null>(
102
- getDateObject,
103
- );
61
+ const [lastBroadcastedValue, setLastBroadcastedValue] = useState(getDateObject);
104
62
 
105
63
  dayLabel = dayLabel || formatMessage(messages.dayLabel);
106
64
  monthLabel = monthLabel || formatMessage(messages.monthLabel);
@@ -111,8 +69,8 @@ const DateInput = ({
111
69
  year: placeholders?.year || formatMessage(messages.yearPlaceholder),
112
70
  };
113
71
 
114
- const getDateAsString = (date: Date | null) => {
115
- if (date === null || !isDateValid(date)) {
72
+ const getDateAsString = (date) => {
73
+ if (!isDateValid(date)) {
116
74
  return '';
117
75
  }
118
76
  switch (mode) {
@@ -137,13 +95,11 @@ const DateInput = ({
137
95
  <SelectInput
138
96
  name="month"
139
97
  disabled={disabled}
140
- placeholder={placeholders?.month}
98
+ placeholder={placeholders.month}
141
99
  items={monthOptions}
142
100
  size={size}
143
- value={monthOptions.find((item) => item.value === month)?.value}
144
- renderValue={(selectedValue) => (
145
- <SelectInputOptionContent title={getMonthNames(locale, monthFormat)[selectedValue]} />
146
- )}
101
+ value={monthOptions.find((item) => item.value.value === month)?.value}
102
+ renderValue={({ label }) => <SelectInputOptionContent title={label} />}
147
103
  onChange={(selectedValue) => handleMonthChange(selectedValue)}
148
104
  {...selectProps}
149
105
  />
@@ -152,19 +108,16 @@ const DateInput = ({
152
108
  };
153
109
 
154
110
  const getMonthsOptions = () => {
155
- const options: SelectInputOptionItem<number>[] = [];
111
+ const options = [];
112
+ const months = getMonthNames(locale, monthFormat);
156
113
 
157
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].forEach((index) => {
158
- options.push({ type: 'option', value: index });
114
+ months.forEach((label, index) => {
115
+ options.push({ type: 'option', value: { label, value: index } });
159
116
  });
160
117
  return options;
161
118
  };
162
119
 
163
- const handleInternalValue = (
164
- newDay: number | null = day,
165
- newMonth: number | null = month,
166
- newYear: number | null = year,
167
- ) => {
120
+ const handleInternalValue = (newDay = day, newMonth = month, newYear = year) => {
168
121
  const dateValue =
169
122
  newDay != null && newMonth != null && newYear != null
170
123
  ? new Date(newYear, newMonth, newDay)
@@ -177,12 +130,11 @@ const DateInput = ({
177
130
  }
178
131
 
179
132
  if (mode === DateMode.MONTH_YEAR) {
180
- if (newMonth && newMonth >= 0 && newYear && (newMonth !== month || newYear !== year)) {
133
+ if (newMonth >= 0 && newYear && (newMonth !== month || newYear !== year)) {
181
134
  broadcastNewValue(newValue);
182
135
  }
183
136
  } else if (
184
137
  newDay &&
185
- newMonth !== null &&
186
138
  newMonth >= 0 &&
187
139
  newYear &&
188
140
  (newDay !== day || newMonth !== month || newYear !== year)
@@ -191,75 +143,70 @@ const DateInput = ({
191
143
  }
192
144
  };
193
145
 
194
- const handleDayChange = (event: React.ChangeEvent<HTMLInputElement>) => {
195
- const { checkedDay } = checkDate(parseInt(event.target.value), month, year);
146
+ const handleDayChange = (event) => {
147
+ const { checkedDay } = checkDate(event.target.value, month, year);
196
148
  setDay(checkedDay);
197
149
  handleInternalValue(checkedDay, month, year);
198
150
  };
199
151
 
200
- const handleMonthChange = (selectedValue: number) => {
201
- if (selectedValue === null) {
152
+ const handleMonthChange = (selectedValue) => {
153
+ if (!selectedValue) {
202
154
  setMonth(null);
203
155
  handleInternalValue(day, null, year);
204
156
  return;
205
157
  }
206
- const selectedMonth = selectedValue ? selectedValue : 0;
158
+ const selectedMonth = selectedValue ? selectedValue.value : 0;
207
159
  const { checkedDay } = checkDate(day, selectedMonth, year);
208
160
  setMonth(selectedMonth);
209
- if (day && checkedDay !== day) {
210
- setDay(checkedDay);
161
+ if (day) {
162
+ if (checkedDay !== day) {
163
+ setDay(checkedDay);
164
+ }
211
165
  }
212
166
  handleInternalValue(checkedDay, selectedMonth, year);
213
167
  };
214
168
 
215
- const handleYearChange = (event: React.ChangeEvent<HTMLInputElement>) => {
169
+ const handleYearChange = (event) => {
216
170
  const newValue = event.target.value;
217
171
  const slicedYear = newValue.length > 4 ? newValue.slice(0, 4) : newValue;
218
172
 
219
173
  if (slicedYear.toString().length === 4) {
220
174
  // Correct day based on year and month.
221
- const { checkedDay } = checkDate(day, month, parseInt(newValue));
175
+ const { checkedDay } = checkDate(day, month, newValue);
222
176
 
223
- if (day && checkedDay !== day) {
224
- setDay(checkedDay);
177
+ if (day) {
178
+ if (checkedDay !== day) {
179
+ setDay(checkedDay);
180
+ }
225
181
  }
226
-
227
- setYear(parseInt(slicedYear));
228
- handleInternalValue(checkedDay, month, parseInt(slicedYear));
182
+ setYear(slicedYear);
183
+ handleInternalValue(checkedDay, month, slicedYear);
229
184
  } else {
230
- setYear(parseInt(slicedYear));
185
+ setYear(slicedYear);
231
186
  handleInternalValue(day, month, null);
232
187
  }
233
188
  };
234
189
 
235
- const broadcastNewValue = (newValue: Date | ExplodedDate | null) => {
190
+ const broadcastNewValue = (newValue) => {
236
191
  if (newValue !== lastBroadcastedValue) {
237
192
  setLastBroadcastedValue(newValue);
238
- if (newValue === INITIAL_DEFAULT_STATE) {
239
- onChange(null);
240
- } else {
241
- onChange(getDateAsString(newValue as Date) || null);
242
- }
193
+ onChange(getDateAsString(newValue) || null);
243
194
  }
244
195
  };
245
196
 
246
- const checkDate = (
247
- newDay: number | null = null,
248
- newMonth: number | null = 0,
249
- newYear: number | null = null,
250
- ) => {
197
+ const checkDate = (newDay = null, newMonth = 0, newYear = null) => {
251
198
  let checkedDay = newDay;
252
- const maxDay = new Date(newYear || 2000, newMonth ? newMonth + 1 : 1, 0).getDate();
199
+ const maxDay = new Date(newYear || 2000, newMonth + 1, 0).getDate();
253
200
 
254
201
  if (!newDay) {
255
202
  checkedDay = null;
256
203
  }
257
204
 
258
- if (newDay && newDay < 0) {
205
+ if ((newDay && newDay < 0) || newDay === '00') {
259
206
  checkedDay = 1;
260
207
  }
261
208
 
262
- if ((newDay && newMonth) || (newDay && newDay > 31)) {
209
+ if ((newDay && newMonth) || newDay > 31) {
263
210
  checkedDay = newDay > maxDay ? maxDay : newDay;
264
211
  }
265
212
 
@@ -281,12 +228,11 @@ const DateInput = ({
281
228
  id={id}
282
229
  aria-labelledby={ariaLabelledBy}
283
230
  aria-label={ariaLabel}
284
- role="group" // Add role attribute to indicate container for interactive elements
285
- onFocus={(event: React.FocusEvent<HTMLInputElement>) =>
286
- shouldPropagateOnFocus(event) ? onFocus && onFocus(event) : event.stopPropagation()
231
+ onFocus={(event) =>
232
+ shouldPropagateOnFocus(event) ? onFocus && onFocus() : event.stopPropagation()
287
233
  }
288
- onBlur={(event: React.FocusEvent<HTMLInputElement>) =>
289
- shouldPropagateOnBlur(event) ? onBlur && onBlur(event) : event.stopPropagation()
234
+ onBlur={(event) =>
235
+ shouldPropagateOnBlur(event) ? onBlur && onBlur() : event.stopPropagation()
290
236
  }
291
237
  >
292
238
  <div className="row">
@@ -336,20 +282,14 @@ const DateInput = ({
336
282
  };
337
283
 
338
284
  // Should only propagate if the relatedTarget is not part of this DateInput component.
339
- function shouldPropagateOnFocus({
340
- target,
341
- relatedTarget,
342
- }: Pick<React.FocusEvent, 'target' | 'relatedTarget'>) {
285
+ function shouldPropagateOnFocus({ target, relatedTarget }) {
343
286
  const targetParent = target.closest('.tw-date');
344
287
  const relatedParent = relatedTarget && relatedTarget.closest('.tw-date');
345
288
  return targetParent !== relatedParent;
346
289
  }
347
290
 
348
291
  // Should only propagate if the relatedTarget or the activeElement is not part of this DateInput component.
349
- function shouldPropagateOnBlur({
350
- target,
351
- relatedTarget,
352
- }: Pick<React.FocusEvent, 'target' | 'relatedTarget'>) {
292
+ function shouldPropagateOnBlur({ target, relatedTarget }) {
353
293
  const blurElementParent = target.closest('.tw-date');
354
294
  // Even though FocusEvent.relatedTarget is supported by IE
355
295
  // (https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/relatedTarget)
@@ -363,4 +303,41 @@ function shouldPropagateOnBlur({
363
303
  return blurElementParent !== focusElementParent;
364
304
  }
365
305
 
306
+ DateInput.propTypes = {
307
+ 'aria-label': PropTypes.string,
308
+ 'aria-labelledby': PropTypes.string,
309
+ disabled: PropTypes.bool,
310
+ size: PropTypes.oneOf(['sm', 'md', 'lg']),
311
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
312
+ onChange: PropTypes.func.isRequired,
313
+ onFocus: PropTypes.func,
314
+ onBlur: PropTypes.func,
315
+ dayLabel: PropTypes.string,
316
+ dayAutoComplete: PropTypes.string,
317
+ monthLabel: PropTypes.string,
318
+ yearLabel: PropTypes.string,
319
+ yearAutoComplete: PropTypes.string,
320
+ monthFormat: PropTypes.oneOf(['long', 'short']),
321
+ mode: PropTypes.oneOf(['day-month-year', 'month-year']),
322
+ placeholders: PropTypes.shape({
323
+ day: PropTypes.node,
324
+ month: PropTypes.node,
325
+ year: PropTypes.node,
326
+ }),
327
+ id: PropTypes.string,
328
+ selectProps: PropTypes.object,
329
+ };
330
+
331
+ DateInput.defaultProps = {
332
+ disabled: false,
333
+ size: Size.MEDIUM,
334
+ value: null,
335
+ onFocus: null,
336
+ onBlur: null,
337
+ monthFormat: MonthFormat.LONG,
338
+ mode: DateMode.DAY_MONTH_YEAR,
339
+ id: '',
340
+ selectProps: {},
341
+ };
342
+
366
343
  export default DateInput;