@transferwise/components 46.12.0 → 46.14.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.
Files changed (136) hide show
  1. package/build/index.esm.js +193 -352
  2. package/build/index.esm.js.map +1 -1
  3. package/build/index.js +166 -325
  4. package/build/index.js.map +1 -1
  5. package/build/main.css +6 -82
  6. package/build/styles/decision/Decision.css +6 -82
  7. package/build/styles/main.css +6 -82
  8. package/build/types/body/Body.d.ts +1 -1
  9. package/build/types/common/commonProps.d.ts +1 -1
  10. package/build/types/common/commonProps.d.ts.map +1 -1
  11. package/build/types/common/dateUtils/getDayNames/getDayNames.d.ts +1 -1
  12. package/build/types/common/dateUtils/getDayNames/getDayNames.d.ts.map +1 -1
  13. package/build/types/common/dateUtils/getDayNames/index.d.ts +1 -1
  14. package/build/types/common/dateUtils/getDayNames/index.d.ts.map +1 -1
  15. package/build/types/common/dateUtils/getMonthNames/getMonthNames.d.ts +1 -1
  16. package/build/types/common/dateUtils/getMonthNames/getMonthNames.d.ts.map +1 -1
  17. package/build/types/common/dateUtils/getMonthNames/index.d.ts +1 -1
  18. package/build/types/common/dateUtils/getMonthNames/index.d.ts.map +1 -1
  19. package/build/types/common/dateUtils/index.d.ts +6 -6
  20. package/build/types/common/dateUtils/index.d.ts.map +1 -1
  21. package/build/types/common/dateUtils/isDateValid/index.d.ts +1 -1
  22. package/build/types/common/dateUtils/isDateValid/index.d.ts.map +1 -1
  23. package/build/types/common/dateUtils/isDateValid/isDateValid.d.ts +2 -2
  24. package/build/types/common/dateUtils/isDateValid/isDateValid.d.ts.map +1 -1
  25. package/build/types/common/dateUtils/isMonthAndYearFormat/index.d.ts +1 -1
  26. package/build/types/common/dateUtils/isMonthAndYearFormat/index.d.ts.map +1 -1
  27. package/build/types/common/dateUtils/isMonthAndYearFormat/isMonthAndYearFormat.d.ts +1 -1
  28. package/build/types/common/dateUtils/isMonthAndYearFormat/isMonthAndYearFormat.d.ts.map +1 -1
  29. package/build/types/common/dateUtils/isWithinRange/index.d.ts +1 -1
  30. package/build/types/common/dateUtils/isWithinRange/index.d.ts.map +1 -1
  31. package/build/types/common/dateUtils/isWithinRange/isWithinRange.d.ts +1 -1
  32. package/build/types/common/dateUtils/isWithinRange/isWithinRange.d.ts.map +1 -1
  33. package/build/types/common/dateUtils/moveToWithinRange/index.d.ts +1 -1
  34. package/build/types/common/dateUtils/moveToWithinRange/index.d.ts.map +1 -1
  35. package/build/types/common/dateUtils/moveToWithinRange/moveToWithinRange.d.ts +1 -1
  36. package/build/types/common/dateUtils/moveToWithinRange/moveToWithinRange.d.ts.map +1 -1
  37. package/build/types/common/panel/Panel.d.ts +1 -1
  38. package/build/types/common/responsivePanel/ResponsivePanel.d.ts +1 -1
  39. package/build/types/dateInput/DateInput.d.ts +30 -41
  40. package/build/types/dateInput/DateInput.d.ts.map +1 -1
  41. package/build/types/dateInput/DateInput.messages.d.ts +24 -33
  42. package/build/types/dateInput/DateInput.messages.d.ts.map +1 -1
  43. package/build/types/dateInput/index.d.ts +2 -2
  44. package/build/types/dateInput/index.d.ts.map +1 -1
  45. package/build/types/dateInput/utils/convertToLocalMidnight/convertToLocalMidnight.d.ts +1 -1
  46. package/build/types/dateInput/utils/convertToLocalMidnight/convertToLocalMidnight.d.ts.map +1 -1
  47. package/build/types/dateInput/utils/convertToLocalMidnight/index.d.ts +1 -1
  48. package/build/types/dateInput/utils/convertToLocalMidnight/index.d.ts.map +1 -1
  49. package/build/types/dateInput/utils/index.d.ts +1 -2
  50. package/build/types/dateInput/utils/index.d.ts.map +1 -1
  51. package/build/types/dateLookup/DateLookup.d.ts +1 -0
  52. package/build/types/dateLookup/DateLookup.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/drawer/Drawer.d.ts.map +1 -1
  59. package/build/types/index.d.ts +2 -0
  60. package/build/types/index.d.ts.map +1 -1
  61. package/build/types/modal/Modal.d.ts.map +1 -1
  62. package/build/types/popover/Popover.d.ts +1 -0
  63. package/build/types/popover/Popover.d.ts.map +1 -1
  64. package/build/types/promoCard/PromoCard.d.ts +1 -2
  65. package/build/types/promoCard/PromoCard.d.ts.map +1 -1
  66. package/build/types/select/searchBox/SearchBox.d.ts +1 -1
  67. package/package.json +1 -1
  68. package/src/common/commonProps.ts +1 -1
  69. package/src/common/dateUtils/getDayNames/getDayNames.spec.js +2 -2
  70. package/src/common/dateUtils/getDayNames/{getDayNames.js → getDayNames.ts} +5 -2
  71. package/src/common/dateUtils/getMonthNames/getMonthNames.spec.js +9 -8
  72. package/src/common/dateUtils/getMonthNames/{getMonthNames.js → getMonthNames.ts} +5 -3
  73. package/src/common/dateUtils/isDateValid/{isDateValid.spec.js → isDateValid.spec.ts} +1 -1
  74. package/src/common/dateUtils/isDateValid/isDateValid.ts +13 -0
  75. package/src/common/dateUtils/isMonthAndYearFormat/isMonthAndYearFormat.spec.js +3 -7
  76. package/src/common/dateUtils/isMonthAndYearFormat/{isMonthAndYearFormat.js → isMonthAndYearFormat.ts} +1 -1
  77. package/src/common/dateUtils/isWithinRange/{isWithinRange.spec.js → isWithinRange.spec.ts} +0 -10
  78. package/src/common/dateUtils/isWithinRange/{isWithinRange.js → isWithinRange.ts} +1 -1
  79. package/src/common/dateUtils/moveToWithinRange/{moveToWithinRange.js → moveToWithinRange.ts} +2 -2
  80. package/src/dateInput/DateInput.spec.js +7 -56
  81. package/src/dateInput/DateInput.story.tsx +11 -8
  82. package/src/dateInput/{DateInput.js → DateInput.tsx} +116 -123
  83. package/src/dateInput/index.ts +2 -0
  84. package/src/dateInput/utils/convertToLocalMidnight/{convertToLocalMidnight.js → convertToLocalMidnight.ts} +1 -1
  85. package/src/dateInput/utils/{index.js → index.ts} +0 -1
  86. package/src/dateLookup/DateLookup.js +12 -1
  87. package/src/dateLookup/DateLookup.testingLibrary.spec.js +12 -1
  88. package/src/dateLookup/dayCalendar/table/DayCalendarTable.js +1 -0
  89. package/src/decision/Decision.css +6 -82
  90. package/src/decision/Decision.less +3 -41
  91. package/src/decision/Decision.spec.js +56 -61
  92. package/src/decision/{Decision.story.js → Decision.story.tsx} +5 -5
  93. package/src/decision/Decision.tsx +133 -0
  94. package/src/decision/index.ts +1 -0
  95. package/src/drawer/Drawer.js +13 -2
  96. package/src/drawer/__snapshots__/Drawer.rtl.spec.js.snap +1 -0
  97. package/src/index.ts +2 -0
  98. package/src/main.css +6 -82
  99. package/src/modal/Modal.tsx +6 -3
  100. package/src/popover/Popover.js +7 -3
  101. package/src/popover/Popover.spec.js +16 -8
  102. package/src/popover/__snapshots__/Popover.spec.js.snap +0 -56
  103. package/src/promoCard/PromoCard.tsx +1 -2
  104. package/src/tile/Tile.js +1 -1
  105. package/build/types/dateInput/utils/explodeDate/explodeDate.d.ts +0 -6
  106. package/build/types/dateInput/utils/explodeDate/explodeDate.d.ts.map +0 -1
  107. package/build/types/dateInput/utils/explodeDate/index.d.ts +0 -2
  108. package/build/types/dateInput/utils/explodeDate/index.d.ts.map +0 -1
  109. package/build/types/decision/decisionEnums.d.ts +0 -9
  110. package/build/types/decision/decisionEnums.d.ts.map +0 -1
  111. package/build/types/sizeSwapper/SizeSwapper.d.ts +0 -3
  112. package/build/types/sizeSwapper/SizeSwapper.d.ts.map +0 -1
  113. package/build/types/sizeSwapper/index.d.ts +0 -2
  114. package/build/types/sizeSwapper/index.d.ts.map +0 -1
  115. package/src/common/dateUtils/isDateValid/isDateValid.js +0 -6
  116. package/src/dateInput/index.js +0 -3
  117. package/src/dateInput/utils/explodeDate/explodeDate.js +0 -7
  118. package/src/dateInput/utils/explodeDate/explodeDate.spec.js +0 -11
  119. package/src/dateInput/utils/explodeDate/index.js +0 -1
  120. package/src/decision/Decision.js +0 -148
  121. package/src/decision/decisionEnums.ts +0 -11
  122. package/src/decision/index.js +0 -2
  123. package/src/sizeSwapper/SizeSwapper.js +0 -69
  124. package/src/sizeSwapper/SizeSwapper.spec.js +0 -100
  125. package/src/sizeSwapper/SizeSwapper.story.js +0 -34
  126. package/src/sizeSwapper/index.js +0 -1
  127. /package/src/common/dateUtils/getDayNames/{index.js → index.ts} +0 -0
  128. /package/src/common/dateUtils/getMonthNames/{index.js → index.ts} +0 -0
  129. /package/src/common/dateUtils/{index.js → index.ts} +0 -0
  130. /package/src/common/dateUtils/isDateValid/{index.js → index.ts} +0 -0
  131. /package/src/common/dateUtils/isMonthAndYearFormat/{index.js → index.ts} +0 -0
  132. /package/src/common/dateUtils/isWithinRange/{index.js → index.ts} +0 -0
  133. /package/src/common/dateUtils/moveToWithinRange/{index.js → index.ts} +0 -0
  134. /package/src/dateInput/{DateInput.messages.js → DateInput.messages.ts} +0 -0
  135. /package/src/dateInput/utils/convertToLocalMidnight/{convertToLocalMidnight.spec.js → convertToLocalMidnight.spec.ts} +0 -0
  136. /package/src/dateInput/utils/convertToLocalMidnight/{index.js → index.ts} +0 -0
@@ -45,62 +45,6 @@ exports[`Popover on mobile renders when is open 1`] = `
45
45
  Open
46
46
  </button>
47
47
  </span>
48
- <div
49
- class="dimmer"
50
- >
51
- <div
52
- class="sliding-panel sliding-panel--open-bottom np-bottom-sheet np-popover__container"
53
- >
54
- <div
55
- class="np-bottom-sheet--top-bar"
56
- >
57
- <div
58
- class="np-bottom-sheet--handler"
59
- />
60
- <button
61
- aria-label="Close"
62
- class="np-close-button close btn-link text-no-decoration sr-only np-bottom-sheet--close-btn"
63
- type="button"
64
- >
65
- <span
66
- aria-hidden="true"
67
- class="tw-icon tw-icon-cross "
68
- data-testid="cross-icon"
69
- role="presentation"
70
- >
71
- <svg
72
- fill="currentColor"
73
- focusable="false"
74
- height="16"
75
- viewBox="0 0 24 24"
76
- width="16"
77
- >
78
- <path
79
- d="m19.629 5.915-1.2-1.2-6.257 6.257-6.258-6.257-1.2 1.2 6.258 6.257-6.258 6.257 1.2 1.2 6.258-6.257 6.257 6.257 1.2-1.2-6.258-6.257 6.258-6.257Z"
80
- />
81
- </svg>
82
- </span>
83
- </button>
84
- </div>
85
- <div
86
- class="np-bottom-sheet--content"
87
- style="max-height: calc(768px - 64px - 32px);"
88
- >
89
- <div
90
- aria-hidden="false"
91
- class="np-popover__content"
92
- role="dialog"
93
- >
94
- <h4
95
- class="np-text-title-body m-b-1"
96
- >
97
- title
98
- </h4>
99
- content
100
- </div>
101
- </div>
102
- </div>
103
- </div>
104
48
  </span>
105
49
  </div>
106
50
  `;
@@ -13,7 +13,6 @@ import { usePromoCardContext } from './PromoCardContext';
13
13
  import PromoCardIndicator, { PromoCardIndicatorProps } from './PromoCardIndicator';
14
14
 
15
15
  export type ReferenceType = React.Ref<HTMLInputElement>;
16
- export type LinkTarget = '_blank' | '_parent' | '_self' | '_top';
17
16
  export type RelatedTypes =
18
17
  | ''
19
18
  | 'alternate'
@@ -98,7 +97,7 @@ export interface PromoCardLinkProps extends PromoCardCommonProps, Omit<CardProps
98
97
  rel?: RelatedTypes;
99
98
 
100
99
  /** Optional prop to to display where the linked URL will show */
101
- target?: LinkTarget;
100
+ target?: React.HTMLAttributeAnchorTarget;
102
101
 
103
102
  /** Only applies to role="radio" or "checkbox" */
104
103
  defaultChecked?: never;
package/src/tile/Tile.js CHANGED
@@ -65,7 +65,7 @@ Tile.propTypes = {
65
65
  className: PropTypes.string,
66
66
  description: PropTypes.node,
67
67
  disabled: PropTypes.bool,
68
- href: PropTypes.string.isRequired,
68
+ href: PropTypes.string,
69
69
  target: PropTypes.oneOf(['_self', '_blank', '_parent', '_top']),
70
70
  /** Accepts only Avatar and images */
71
71
  media: PropTypes.node.isRequired,
@@ -1,6 +0,0 @@
1
- export function explodeDate(date: any): {
2
- year: any;
3
- month: any;
4
- day: any;
5
- };
6
- //# sourceMappingURL=explodeDate.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"explodeDate.d.ts","sourceRoot":"","sources":["../../../../../src/dateInput/utils/explodeDate/explodeDate.js"],"names":[],"mappings":"AAAO;;;;EAMN"}
@@ -1,2 +0,0 @@
1
- export { explodeDate } from "./explodeDate";
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/dateInput/utils/explodeDate/index.js"],"names":[],"mappings":""}
@@ -1,9 +0,0 @@
1
- export declare enum Presentation {
2
- LIST = "LIST",
3
- LIST_BLOCK = "LIST_BLOCK",
4
- LIST_BLOCK_GRID = "LIST_BLOCK_GRID"
5
- }
6
- export declare enum Type {
7
- NAVIGATION = "NAVIGATION"
8
- }
9
- //# sourceMappingURL=decisionEnums.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"decisionEnums.d.ts","sourceRoot":"","sources":["../../../src/decision/decisionEnums.ts"],"names":[],"mappings":"AACA,oBAAY,YAAY;IACtB,IAAI,SAAS;IACb,UAAU,eAAe;IACzB,eAAe,oBAAoB;CACpC;AAGD,oBAAY,IAAI;IACd,UAAU,eAAe;CAC1B"}
@@ -1,3 +0,0 @@
1
- export default SizeSwapper;
2
- declare const SizeSwapper: import("react").ForwardRefExoticComponent<import("react").RefAttributes<any>>;
3
- //# sourceMappingURL=SizeSwapper.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SizeSwapper.d.ts","sourceRoot":"","sources":["../../../src/sizeSwapper/SizeSwapper.js"],"names":[],"mappings":";AASA,yGAqCG"}
@@ -1,2 +0,0 @@
1
- export { default } from "./SizeSwapper";
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sizeSwapper/index.js"],"names":[],"mappings":""}
@@ -1,6 +0,0 @@
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,3 +0,0 @@
1
- import DateInput from './DateInput';
2
-
3
- export default DateInput;
@@ -1,7 +0,0 @@
1
- export const explodeDate = (date) => {
2
- const year = date.getFullYear();
3
- const month = date.getMonth();
4
- const day = date.getDate();
5
-
6
- return { year, month, day };
7
- };
@@ -1,11 +0,0 @@
1
- import { explodeDate } from '.';
2
-
3
- describe('explodeDate', () => {
4
- it('returns exploded model for valid format', () => {
5
- expect(explodeDate(new Date('1995-12-17T03:24:00'))).toStrictEqual({
6
- day: 17,
7
- month: 11,
8
- year: 1995,
9
- });
10
- });
11
- });
@@ -1 +0,0 @@
1
- export { explodeDate } from './explodeDate';
@@ -1,148 +0,0 @@
1
- import classNames from 'classnames';
2
- import PropTypes from 'prop-types';
3
-
4
- import { Size, Breakpoint } from '../common';
5
- import NavigationOption from '../navigationOption';
6
- import SizeSwapper from '../sizeSwapper';
7
- import Tile from '../tile';
8
-
9
- import { Presentation, Type } from './decisionEnums';
10
-
11
- const Decision = ({
12
- options,
13
- presentation,
14
- type,
15
- showMediaCircleInList,
16
- isContainerAligned,
17
- size,
18
- }) => {
19
- if (type === Type.NAVIGATION) {
20
- const { LIST_BLOCK, LIST_BLOCK_GRID } = Presentation;
21
- if (presentation === LIST_BLOCK || presentation === LIST_BLOCK_GRID) {
22
- const isSmall = size === Size.SMALL;
23
- const isGrid = presentation === LIST_BLOCK_GRID;
24
- const items = [
25
- {
26
- items: [],
27
- layout: SizeSwapper.Layout.COLUMN,
28
- },
29
- {
30
- items: [],
31
- breakpoint: isSmall ? Breakpoint.EXTRA_SMALL : Breakpoint.SMALL,
32
- wrap: isGrid,
33
- },
34
- ];
35
-
36
- options.forEach(
37
- ({ description, disabled, href, target, media: { block, list }, onClick, title }, key) => {
38
- items[0].items.push(
39
- <NavigationOption
40
- // eslint-disable-next-line react/no-array-index-key
41
- key={`nav-${key}`}
42
- complex={false}
43
- content={description}
44
- disabled={disabled}
45
- href={href}
46
- target={target}
47
- media={list}
48
- showMediaAtAllSizes
49
- showMediaCircle={showMediaCircleInList}
50
- isContainerAligned={isContainerAligned}
51
- title={title}
52
- onClick={onClick}
53
- />,
54
- );
55
- items[1].items.push(
56
- <Tile
57
- // eslint-disable-next-line react/no-array-index-key
58
- key={`tile-${key}`}
59
- className={classNames(`np-decision__tile${isSmall ? '--small' : ''}`, {
60
- 'np-decision__tile--fixed-width': isGrid,
61
- })}
62
- description={description}
63
- disabled={disabled}
64
- href={href}
65
- target={target}
66
- media={block}
67
- size={isSmall ? Size.SMALL : Size.MEDIUM}
68
- title={title}
69
- onClick={onClick}
70
- />,
71
- );
72
- },
73
- );
74
-
75
- return (
76
- <div
77
- className={classNames('np-decision', {
78
- 'np-decision--small': isSmall,
79
- 'np-decision--grid': isGrid,
80
- })}
81
- >
82
- <SizeSwapper items={items} />
83
- </div>
84
- );
85
- }
86
- // LIST
87
- return options.map(
88
- ({ title, description, disabled, href, target, media: { list }, onClick }, key) => (
89
- <NavigationOption
90
- // eslint-disable-next-line react/no-array-index-key
91
- key={`nav-${key}`}
92
- complex={false}
93
- content={description}
94
- disabled={disabled}
95
- href={href}
96
- target={target}
97
- media={list}
98
- showMediaAtAllSizes
99
- showMediaCircle={showMediaCircleInList}
100
- isContainerAligned={isContainerAligned}
101
- title={title}
102
- onClick={onClick}
103
- />
104
- ),
105
- );
106
- }
107
- return <></>;
108
- };
109
-
110
- Decision.propTypes = {
111
- /** A list of elements to be rendered */
112
- options: PropTypes.arrayOf(
113
- PropTypes.shape({
114
- description: PropTypes.node,
115
- disabled: PropTypes.bool,
116
- href: PropTypes.string,
117
- target: PropTypes.oneOf(['_self', '_blank', '_parent', '_top']),
118
- media: PropTypes.shape({
119
- block: PropTypes.node.isRequired,
120
- list: PropTypes.node.isRequired,
121
- }),
122
- onClick: PropTypes.func,
123
- title: PropTypes.node.isRequired,
124
- }),
125
- ).isRequired,
126
- /** Handles the display mode of the component */
127
- presentation: PropTypes.oneOf(['LIST', 'LIST_BLOCK', 'LIST_BLOCK_GRID']),
128
- /** Size currently affects only Tile dimension */
129
- size: PropTypes.oneOf(['sm', 'md']),
130
- /** Decide which kind of element type needs to be rendered ex: Navigation Options or in the future Radio or Checkbox Options */
131
- type: PropTypes.oneOf(['NAVIGATION']),
132
-
133
- /** Display media in a circle in list presentation */
134
- showMediaCircleInList: PropTypes.bool,
135
-
136
- /** Sets navigation options to be aligned with the parent container */
137
- isContainerAligned: PropTypes.bool,
138
- };
139
-
140
- Decision.defaultProps = {
141
- presentation: Presentation.LIST,
142
- size: Size.MEDIUM,
143
- type: Type.NAVIGATION,
144
- showMediaCircleInList: true,
145
- isContainerAligned: false,
146
- };
147
-
148
- export default Decision;
@@ -1,11 +0,0 @@
1
- // TODO: consider to move this enum into component file once we migrate it on TypeScript or replace with some common enum
2
- export enum Presentation {
3
- LIST = 'LIST',
4
- LIST_BLOCK = 'LIST_BLOCK',
5
- LIST_BLOCK_GRID = 'LIST_BLOCK_GRID',
6
- }
7
-
8
- // TODO: consider to move this enum into component file once we migrate it on TypeScript or replace with some common enum
9
- export enum Type {
10
- NAVIGATION = 'NAVIGATION',
11
- }
@@ -1,2 +0,0 @@
1
- export { Presentation as DecisionPresentation, Type as DecisionType } from './decisionEnums';
2
- export { default } from './Decision';
@@ -1,69 +0,0 @@
1
- import classNames from 'classnames';
2
- import PropTypes from 'prop-types';
3
- import { forwardRef, useRef } from 'react';
4
-
5
- import { Breakpoint } from '../common';
6
- import { useClientWidth } from '../common/hooks';
7
-
8
- const Layout = { COLUMN: 'COLUMN' };
9
-
10
- const SizeSwapper = forwardRef(({ items, inline }, reference) => {
11
- const parentReference = useRef(null);
12
- const [clientWidth] = useClientWidth({ ref: reference || parentReference });
13
-
14
- if (!items || items.length === 0) {
15
- return null;
16
- }
17
- // If all breakpoints are specified and clientWidth never > breakpoint itemsToRender can be undefined.
18
- // Do not use deconstruct here to get items and layout.
19
- let itemsToRender = [];
20
-
21
- if (clientWidth) {
22
- itemsToRender = items.filter(({ breakpoint = 0 }) => clientWidth >= breakpoint).pop();
23
- } else {
24
- // On SSR environments useClientWidth returns null because ref is undefined so we render
25
- // all elements by default.
26
- // If there's no SSR and on first Hydration only the right elements are going to be rendered.
27
- // If clientWidth is null or zero all elements render like a responsive technique would do.
28
- itemsToRender.items = items.map(({ items }) => Object.values(items));
29
- }
30
-
31
- // Always return parent container even if there are no items to display to
32
- // keep the ref on DOM and let clientWidth be calculated properly.
33
- return (
34
- <div
35
- ref={parentReference}
36
- className={classNames('np-size-swapper', {
37
- 'd-flex': !inline,
38
- 'd-inline-flex': inline,
39
- 'flex-column': itemsToRender && itemsToRender.layout === Layout.COLUMN,
40
- 'flex-wrap': itemsToRender && itemsToRender.wrap,
41
- })}
42
- style={{ visibility: clientWidth ? 'visible' : 'hidden' }}
43
- >
44
- {itemsToRender && itemsToRender.items}
45
- </div>
46
- );
47
- });
48
-
49
- SizeSwapper.Breakpoint = Breakpoint;
50
- SizeSwapper.Layout = Layout;
51
-
52
- SizeSwapper.propTypes = {
53
- inline: PropTypes.bool,
54
- /** List of items that will appear at the specified breakpoint and presented in row or columns depending on layout */
55
- items: PropTypes.arrayOf(
56
- PropTypes.shape({
57
- items: PropTypes.arrayOf(PropTypes.element),
58
- breakpoint: PropTypes.number,
59
- layout: PropTypes.oneOf([SizeSwapper.Layout.COLUMN]),
60
- wrap: PropTypes.bool,
61
- }),
62
- ).isRequired,
63
- };
64
-
65
- SizeSwapper.defaultProps = {
66
- inline: false,
67
- };
68
-
69
- export default SizeSwapper;
@@ -1,100 +0,0 @@
1
- import '@testing-library/jest-dom';
2
- import { Breakpoint } from '../common';
3
- import { render, fireEvent, screen } from '../test-utils';
4
-
5
- import SizeSwapper from '.';
6
-
7
- jest.mock('lodash.throttle', () => jest.fn((fn) => fn));
8
-
9
- describe('SizeSwapper', () => {
10
- const resetClientWidth = (width) => {
11
- Object.defineProperty(HTMLElement.prototype, 'clientWidth', {
12
- configurable: true,
13
- value: width,
14
- });
15
- };
16
- const breakpoints = [0, Breakpoint.EXTRA_SMALL];
17
-
18
- const items = breakpoints.map((bp) => ({
19
- items: [...new Array(2)].map((_, index) => (
20
- // eslint-disable-next-line react/no-array-index-key
21
- <div key={`${index}-${bp}`}>
22
- element-{index + 1}-{bp}
23
- </div>
24
- )),
25
- layout: SizeSwapper.Layout.COLUMN,
26
- breakpoint: bp,
27
- }));
28
-
29
- afterAll(() => {
30
- const originalClientWidth = Object.getOwnPropertyDescriptor(
31
- HTMLElement.prototype,
32
- 'clientWidth',
33
- );
34
-
35
- Object.defineProperty(HTMLElement.prototype, 'clientWidth', originalClientWidth);
36
- });
37
-
38
- it('renders all elements and hides sizeswapper if clientWidth is not defined', () => {
39
- const { container } = render(<SizeSwapper items={items} />);
40
-
41
- expect(screen.getByText('element-1-0')).toBeInTheDocument();
42
- expect(screen.getByText('element-2-0')).toBeInTheDocument();
43
- expect(screen.getByText(`element-1-${breakpoints[1]}`)).toBeInTheDocument();
44
- expect(screen.getByText(`element-2-${breakpoints[1]}`)).toBeInTheDocument();
45
-
46
- expect(container.querySelector('.np-size-swapper')).toHaveStyle(`visibility: hidden`);
47
- });
48
-
49
- it('changes visibility when clientWidth is set', () => {
50
- const { container } = render(<SizeSwapper items={items} />);
51
-
52
- expect(container.querySelector('.np-size-swapper')).toHaveStyle(`visibility: hidden`);
53
-
54
- resetClientWidth(breakpoints[1]);
55
- fireEvent(window, new Event('resize'));
56
-
57
- expect(container.querySelector('.np-size-swapper')).toHaveStyle(`visibility: visible`);
58
- });
59
-
60
- it('switches elements according to breakpoints', () => {
61
- render(<SizeSwapper items={items} />);
62
- resetClientWidth(breakpoints[1] - 1);
63
- fireEvent(window, new Event('resize'));
64
-
65
- expect(screen.getByText(`element-1-0`)).toBeInTheDocument();
66
- expect(screen.getByText(`element-2-0`)).toBeInTheDocument();
67
- expect(screen.queryByText(`element-1-${breakpoints[1]}`)).not.toBeInTheDocument();
68
- expect(screen.queryByText(`element-2-${breakpoints[1]}`)).not.toBeInTheDocument();
69
-
70
- // resetClientWidth(breakpoints[1]);
71
- // fireEvent(window, new Event('resize'));
72
-
73
- // expect(screen.queryByText(`element-1-${breakpoints[0]}`)).not.toBeInTheDocument();
74
- // expect(screen.queryByText(`element-2-${breakpoints[0]}`)).not.toBeInTheDocument();
75
- // expect(screen.getByText(`element-1-${breakpoints[1]}`)).toBeInTheDocument();
76
- // expect(screen.getByText(`element-2-${breakpoints[1]}`)).toBeInTheDocument();
77
- });
78
-
79
- describe('when ref is window', () => {
80
- it('switches elements according to breakpoints', () => {
81
- render(<SizeSwapper ref={window} items={items} />);
82
- global.innerWidth = breakpoints[1] - 1;
83
- fireEvent(window, new Event('resize'));
84
-
85
- expect(screen.getByText(`element-1-0`)).toBeInTheDocument();
86
- expect(screen.getByText(`element-2-0`)).toBeInTheDocument();
87
- expect(screen.queryByText(`element-1-${breakpoints[1]}`)).not.toBeInTheDocument();
88
- expect(screen.queryByText(`element-2-${breakpoints[1]}`)).not.toBeInTheDocument();
89
-
90
- [, global.innerWidth] = breakpoints;
91
-
92
- fireEvent(window, new Event('resize'));
93
-
94
- expect(screen.queryByText(`element-1-${breakpoints[0]}`)).not.toBeInTheDocument();
95
- expect(screen.queryByText(`element-2-${breakpoints[0]}`)).not.toBeInTheDocument();
96
- expect(screen.getByText(`element-1-${breakpoints[1]}`)).toBeInTheDocument();
97
- expect(screen.getByText(`element-2-${breakpoints[1]}`)).toBeInTheDocument();
98
- });
99
- });
100
- });
@@ -1,34 +0,0 @@
1
- import SizeSwapper from './SizeSwapper';
2
-
3
- export default {
4
- component: SizeSwapper,
5
- title: 'Internal/SizeSwapper',
6
- };
7
-
8
- export const Basic = () => {
9
- const breakpoints = [
10
- 0,
11
- SizeSwapper.Breakpoint.EXTRA_SMALL,
12
- SizeSwapper.Breakpoint.SMALL,
13
- SizeSwapper.Breakpoint.MEDIUM,
14
- SizeSwapper.Breakpoint.LARGE,
15
- SizeSwapper.Breakpoint.EXTRA_LARGE,
16
- ];
17
-
18
- const items = breakpoints.map((bp, key) => {
19
- const isColumn = (key + 1) % 2 === 0;
20
-
21
- return {
22
- items: [...new Array(4)].map((value, key2) => (
23
- // eslint-disable-next-line react/no-array-index-key
24
- <div key={`el-${key2}-${key}`} className="p-a-3 well m-x-2">
25
- Element shown from {bp}px {isColumn && `in ${SizeSwapper.Layout.COLUMN} mode`}
26
- </div>
27
- )),
28
- layout: isColumn ? SizeSwapper.Layout.COLUMN : null,
29
- breakpoint: bp,
30
- };
31
- });
32
-
33
- return <SizeSwapper items={items} />;
34
- };
@@ -1 +0,0 @@
1
- export { default } from './SizeSwapper';
File without changes