@telus-uds/components-web 1.2.0 → 1.4.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 (140) hide show
  1. package/CHANGELOG.md +34 -2
  2. package/lib/Breadcrumbs/Breadcrumbs.js +247 -0
  3. package/lib/Breadcrumbs/Item/Item.js +165 -0
  4. package/lib/Breadcrumbs/index.js +15 -0
  5. package/lib/Callout/Callout.js +121 -0
  6. package/lib/Callout/index.js +13 -0
  7. package/lib/DatePicker/CalendarContainer.js +221 -0
  8. package/lib/DatePicker/DatePicker.js +329 -0
  9. package/lib/DatePicker/dictionary.js +134 -0
  10. package/lib/DatePicker/index.js +13 -0
  11. package/lib/DatePicker/reactDatesCss.js +12 -0
  12. package/lib/ExpandCollapseMini/ExpandCollapseMini.js +75 -0
  13. package/lib/ExpandCollapseMini/ExpandCollapseMiniControl.js +95 -0
  14. package/lib/ExpandCollapseMini/index.js +13 -0
  15. package/lib/Footnote/Footnote.js +571 -0
  16. package/lib/Footnote/FootnoteLink.js +149 -0
  17. package/lib/Footnote/dictionary.js +19 -0
  18. package/lib/Footnote/index.js +16 -0
  19. package/lib/OrderedList/Item.js +162 -0
  20. package/lib/OrderedList/ItemBase.js +42 -0
  21. package/lib/OrderedList/OrderedList.js +94 -0
  22. package/lib/OrderedList/OrderedListBase.js +68 -0
  23. package/lib/OrderedList/constants.js +9 -0
  24. package/lib/OrderedList/index.js +16 -0
  25. package/lib/PreviewCard/AuthorDate.js +64 -0
  26. package/lib/PreviewCard/PreviewCard.js +236 -0
  27. package/lib/PreviewCard/index.js +13 -0
  28. package/lib/PriceLockup/PriceLockup.js +237 -0
  29. package/lib/PriceLockup/index.js +13 -0
  30. package/lib/PriceLockup/tokens.js +131 -0
  31. package/lib/ResponsiveImage/ResponsiveImage.js +115 -0
  32. package/lib/ResponsiveImage/index.js +13 -0
  33. package/lib/Ribbon/Ribbon.js +0 -1
  34. package/lib/Span/Span.js +88 -0
  35. package/lib/Span/index.js +13 -0
  36. package/lib/index.js +91 -1
  37. package/lib/shared/FullBleedContent/FullBleedContent.js +121 -0
  38. package/lib/shared/FullBleedContent/getFullBleedBorderRadius.js +73 -0
  39. package/lib/shared/FullBleedContent/index.js +29 -0
  40. package/lib/shared/FullBleedContent/useFullBleedContentProps.js +73 -0
  41. package/lib/utils/index.js +32 -0
  42. package/lib/utils/logger.js +31 -0
  43. package/lib/utils/media.js +54 -0
  44. package/lib/utils/renderStructuredContent.js +89 -0
  45. package/lib/utils/useTypographyTheme.js +32 -0
  46. package/lib-module/Breadcrumbs/Breadcrumbs.js +228 -0
  47. package/lib-module/Breadcrumbs/Item/Item.js +141 -0
  48. package/lib-module/Breadcrumbs/index.js +1 -0
  49. package/lib-module/Callout/Callout.js +106 -0
  50. package/lib-module/Callout/index.js +2 -0
  51. package/lib-module/DatePicker/CalendarContainer.js +208 -0
  52. package/lib-module/DatePicker/DatePicker.js +302 -0
  53. package/lib-module/DatePicker/dictionary.js +127 -0
  54. package/lib-module/DatePicker/index.js +2 -0
  55. package/lib-module/DatePicker/reactDatesCss.js +3 -0
  56. package/lib-module/ExpandCollapseMini/ExpandCollapseMini.js +56 -0
  57. package/lib-module/ExpandCollapseMini/ExpandCollapseMiniControl.js +80 -0
  58. package/lib-module/ExpandCollapseMini/index.js +2 -0
  59. package/lib-module/Footnote/Footnote.js +541 -0
  60. package/lib-module/Footnote/FootnoteLink.js +130 -0
  61. package/lib-module/Footnote/dictionary.js +12 -0
  62. package/lib-module/Footnote/index.js +4 -0
  63. package/lib-module/OrderedList/Item.js +139 -0
  64. package/lib-module/OrderedList/ItemBase.js +28 -0
  65. package/lib-module/OrderedList/OrderedList.js +71 -0
  66. package/lib-module/OrderedList/OrderedListBase.js +48 -0
  67. package/lib-module/OrderedList/constants.js +2 -0
  68. package/lib-module/OrderedList/index.js +4 -0
  69. package/lib-module/PreviewCard/AuthorDate.js +53 -0
  70. package/lib-module/PreviewCard/PreviewCard.js +211 -0
  71. package/lib-module/PreviewCard/index.js +2 -0
  72. package/lib-module/PriceLockup/PriceLockup.js +213 -0
  73. package/lib-module/PriceLockup/index.js +2 -0
  74. package/lib-module/PriceLockup/tokens.js +120 -0
  75. package/lib-module/ResponsiveImage/ResponsiveImage.js +100 -0
  76. package/lib-module/ResponsiveImage/index.js +2 -0
  77. package/lib-module/Ribbon/Ribbon.js +1 -2
  78. package/lib-module/Span/Span.js +70 -0
  79. package/lib-module/Span/index.js +2 -0
  80. package/lib-module/index.js +10 -0
  81. package/lib-module/shared/FullBleedContent/FullBleedContent.js +106 -0
  82. package/lib-module/shared/FullBleedContent/getFullBleedBorderRadius.js +65 -0
  83. package/lib-module/shared/FullBleedContent/index.js +4 -0
  84. package/lib-module/shared/FullBleedContent/useFullBleedContentProps.js +65 -0
  85. package/lib-module/utils/index.js +5 -1
  86. package/lib-module/utils/logger.js +18 -0
  87. package/lib-module/utils/media.js +46 -0
  88. package/lib-module/utils/renderStructuredContent.js +77 -0
  89. package/lib-module/utils/useTypographyTheme.js +24 -0
  90. package/package.json +9 -4
  91. package/src/Breadcrumbs/Breadcrumbs.jsx +222 -0
  92. package/src/Breadcrumbs/Item/Item.jsx +127 -0
  93. package/src/Breadcrumbs/index.js +1 -0
  94. package/src/Callout/Callout.jsx +76 -0
  95. package/src/Callout/index.js +3 -0
  96. package/src/DatePicker/CalendarContainer.jsx +210 -0
  97. package/src/DatePicker/DatePicker.jsx +303 -0
  98. package/src/DatePicker/dictionary.js +92 -0
  99. package/src/DatePicker/index.js +3 -0
  100. package/src/DatePicker/reactDatesCss.js +892 -0
  101. package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +48 -0
  102. package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +67 -0
  103. package/src/ExpandCollapseMini/index.js +3 -0
  104. package/src/Footnote/Footnote.jsx +468 -0
  105. package/src/Footnote/FootnoteLink.jsx +120 -0
  106. package/src/Footnote/dictionary.js +12 -0
  107. package/src/Footnote/index.js +6 -0
  108. package/src/OrderedList/Item.jsx +121 -0
  109. package/src/OrderedList/ItemBase.jsx +18 -0
  110. package/src/OrderedList/OrderedList.jsx +61 -0
  111. package/src/OrderedList/OrderedListBase.jsx +38 -0
  112. package/src/OrderedList/constants.js +2 -0
  113. package/src/OrderedList/index.js +6 -0
  114. package/src/PreviewCard/AuthorDate.jsx +31 -0
  115. package/src/PreviewCard/PreviewCard.jsx +201 -0
  116. package/src/PreviewCard/index.js +3 -0
  117. package/src/PriceLockup/PriceLockup.jsx +210 -0
  118. package/src/PriceLockup/index.js +3 -0
  119. package/src/PriceLockup/tokens.js +58 -0
  120. package/src/ResponsiveImage/ResponsiveImage.jsx +77 -0
  121. package/src/ResponsiveImage/index.js +3 -0
  122. package/src/Ribbon/Ribbon.jsx +0 -1
  123. package/src/Span/Span.jsx +66 -0
  124. package/src/Span/index.js +3 -0
  125. package/src/index.js +10 -0
  126. package/src/shared/FullBleedContent/FullBleedContent.jsx +90 -0
  127. package/src/shared/FullBleedContent/getFullBleedBorderRadius.js +55 -0
  128. package/src/shared/FullBleedContent/index.js +6 -0
  129. package/src/shared/FullBleedContent/useFullBleedContentProps.js +63 -0
  130. package/src/utils/index.js +5 -1
  131. package/src/utils/logger.js +20 -0
  132. package/src/utils/media.js +40 -0
  133. package/src/utils/renderStructuredContent.jsx +73 -0
  134. package/src/utils/useTypographyTheme.js +14 -0
  135. package/types/Callout.d.ts +13 -0
  136. package/types/DatePicker.d.ts +21 -0
  137. package/types/Footnote.d.ts +21 -0
  138. package/types/FootnoteLink.d.ts +20 -0
  139. package/types/PriceLockup.d.ts +22 -0
  140. package/types/common.d.ts +14 -0
@@ -0,0 +1,571 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = _interopRequireWildcard(require("react"));
9
+
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+
12
+ var _styledComponents = _interopRequireWildcard(require("styled-components"));
13
+
14
+ var _componentsBase = require("@telus-uds/components-base");
15
+
16
+ var _Close = _interopRequireDefault(require("../../__fixtures__/icons/Close"));
17
+
18
+ var _OrderedListBase = _interopRequireDefault(require("../OrderedList/OrderedListBase"));
19
+
20
+ var _utils = require("../utils");
21
+
22
+ var _dictionary = _interopRequireDefault(require("./dictionary"));
23
+
24
+ var _jsxRuntime = require("react/jsx-runtime");
25
+
26
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
+
28
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
29
+
30
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
31
+
32
+ const [selectProps, selectedSystemPropTypes] = (0, _componentsBase.selectSystemProps)([_utils.htmlAttrs]);
33
+ const GlobalBodyScrollLock = /*#__PURE__*/(0, _styledComponents.createGlobalStyle)({
34
+ 'html, body': (0, _utils.media)().until('md').css({
35
+ overflow: 'hidden'
36
+ })
37
+ });
38
+
39
+ const StyledFootnote = /*#__PURE__*/_styledComponents.default.div.withConfig({
40
+ displayName: "Footnote__StyledFootnote",
41
+ componentId: "components-web__sc-1563bo5-0"
42
+ })(_ref => {
43
+ let {
44
+ footnoteBackground,
45
+ isVisible,
46
+ footnoteBorderTop
47
+ } = _ref;
48
+ return {
49
+ position: 'fixed',
50
+ overflowY: 'scroll',
51
+ top: 0,
52
+ left: 0,
53
+ height: '100vh',
54
+ width: '100vw',
55
+ backgroundColor: footnoteBackground,
56
+ display: 'block',
57
+ boxShadow: '0 0 16px 0 rgba(0, 0, 0, 0.1)',
58
+ transform: 'translateY(100%)',
59
+ transition: 'transform 500ms ease-out',
60
+ '@media() (prefers-reduced-motion: reduce)': {
61
+ transition: 'none'
62
+ },
63
+ zIndex: 99999,
64
+ visibility: isVisible ? 'visible' : 'hidden',
65
+ ...(0, _utils.media)().from('md').css({
66
+ top: 'auto',
67
+ bottom: 0,
68
+ height: 'auto',
69
+ maxHeight: '50vh',
70
+ borderTop: footnoteBorderTop
71
+ })
72
+ };
73
+ }, _ref2 => {
74
+ let {
75
+ isOpen
76
+ } = _ref2;
77
+
78
+ if (isOpen) {
79
+ return {
80
+ transform: 'translateY(0)'
81
+ };
82
+ }
83
+
84
+ return {};
85
+ });
86
+
87
+ const StyledFootnoteHeader = /*#__PURE__*/_styledComponents.default.div.withConfig({
88
+ displayName: "Footnote__StyledFootnoteHeader",
89
+ componentId: "components-web__sc-1563bo5-1"
90
+ })({
91
+ position: 'relative',
92
+ width: '100%'
93
+ });
94
+
95
+ const StyledHeader = /*#__PURE__*/_styledComponents.default.div.withConfig({
96
+ displayName: "Footnote__StyledHeader",
97
+ componentId: "components-web__sc-1563bo5-2"
98
+ })(_ref3 => {
99
+ let {
100
+ headerMargin
101
+ } = _ref3;
102
+ return {
103
+ alignItems: 'center',
104
+ display: 'flex',
105
+ flexDirection: 'row',
106
+ justifyContent: 'space-between',
107
+ margin: headerMargin
108
+ };
109
+ });
110
+
111
+ const StyledFootnoteBody = /*#__PURE__*/_styledComponents.default.div.withConfig({
112
+ displayName: "Footnote__StyledFootnoteBody",
113
+ componentId: "components-web__sc-1563bo5-3"
114
+ })({
115
+ overflow: 'auto',
116
+ transition: 'height 300ms ease-out, opacity 200ms ease-out',
117
+ transform: 'translateZ(0)',
118
+ '@media() (prefers-reduced-motion: reduce)': {
119
+ transition: 'height 1ms ease-out, opacity 1ms ease-out'
120
+ }
121
+ }, _ref4 => {
122
+ let {
123
+ footnoteBodyBackground,
124
+ footnoteBodyPadding
125
+ } = _ref4;
126
+ return {
127
+ backgroundColor: footnoteBodyBackground,
128
+ padding: footnoteBodyPadding
129
+ };
130
+ }, _ref5 => {
131
+ let {
132
+ headerHeight
133
+ } = _ref5;
134
+ return {
135
+ maxHeight: `calc(100vh - ${headerHeight}px)`,
136
+ ...(0, _utils.media)().from('md').css({
137
+ maxHeight: `calc(50vh - ${headerHeight}px)`
138
+ })
139
+ };
140
+ }, _ref6 => {
141
+ let {
142
+ bodyHeight,
143
+ isTextVisible
144
+ } = _ref6;
145
+ return {
146
+ height: bodyHeight,
147
+ opacity: isTextVisible ? 1 : 0
148
+ };
149
+ });
150
+
151
+ const List = /*#__PURE__*/(0, _styledComponents.default)(_OrderedListBase.default).withConfig({
152
+ displayName: "Footnote__List",
153
+ componentId: "components-web__sc-1563bo5-4"
154
+ })(_ref7 => {
155
+ let {
156
+ listPaddingLeft
157
+ } = _ref7;
158
+ return {
159
+ listStylePosition: 'outside',
160
+ paddingLeft: listPaddingLeft
161
+ };
162
+ });
163
+ const ListItem = /*#__PURE__*/(0, _styledComponents.default)(_OrderedListBase.default.Item).withConfig({
164
+ displayName: "Footnote__ListItem",
165
+ componentId: "components-web__sc-1563bo5-5"
166
+ })(_ref8 => {
167
+ let {
168
+ listItemMarkerFontSize,
169
+ listItemMarkerLineHeight,
170
+ listItemColor,
171
+ listItemFontSize,
172
+ listItemLineHeight,
173
+ listItemPaddingLeft
174
+ } = _ref8;
175
+ return {
176
+ display: 'list-item',
177
+ '&::marker': {
178
+ fontFamily: 'HelveticaNow400normal',
179
+ fontSize: listItemMarkerFontSize,
180
+ lineHeight: listItemMarkerLineHeight,
181
+ textAlign: 'end !important'
182
+ },
183
+ color: listItemColor,
184
+ fontFamily: 'HelveticaNow400normal',
185
+ fontSize: listItemFontSize,
186
+ lineHeight: listItemLineHeight,
187
+ paddingLeft: listItemPaddingLeft
188
+ };
189
+ });
190
+
191
+ const CloseButton = /*#__PURE__*/_styledComponents.default.button.withConfig({
192
+ displayName: "Footnote__CloseButton",
193
+ componentId: "components-web__sc-1563bo5-6"
194
+ })(_ref9 => {
195
+ let {
196
+ closeButtonBorder,
197
+ closeButtonHeight,
198
+ closeButtonMargin,
199
+ closeButtonWidth
200
+ } = _ref9;
201
+ return {
202
+ alignItems: 'center',
203
+ borderRadius: '50%',
204
+ cursor: 'pointer',
205
+ display: 'flex',
206
+ justifyContent: 'center',
207
+ border: closeButtonBorder,
208
+ height: closeButtonHeight,
209
+ margin: closeButtonMargin,
210
+ width: closeButtonWidth
211
+ };
212
+ });
213
+
214
+ const ContentContainer = /*#__PURE__*/_styledComponents.default.div.withConfig({
215
+ displayName: "Footnote__ContentContainer",
216
+ componentId: "components-web__sc-1563bo5-7"
217
+ })({
218
+ 'margin-left': 'auto',
219
+ 'margin-right': 'auto',
220
+ left: 0,
221
+ right: 0
222
+ }, _ref10 => {
223
+ let {
224
+ maxWidth
225
+ } = _ref10;
226
+ return {
227
+ width: maxWidth
228
+ };
229
+ });
230
+
231
+ const usePrevious = value => {
232
+ const ref = (0, _react.useRef)();
233
+ (0, _react.useEffect)(() => {
234
+ ref.current = value;
235
+ });
236
+
237
+ if (ref.current) {
238
+ return ref.current;
239
+ }
240
+
241
+ return {};
242
+ };
243
+ /**
244
+ * Use `Footnote` to display a single legal content.
245
+ *
246
+ * ## Usage Criteria
247
+ *
248
+ * - Use `Footnote` to display a single legal statement
249
+ * - Display on top of all UI, including other sticky elements such as Cart Summary
250
+ * - Dismiss by clicking on the close button, clicking anywhere outside of the `Footnote`, or by pressing the ESC key
251
+ * - Responsive display based on breakpoints
252
+ * - Use copy to set language, ‘en’ for English or ‘fr’ for French
253
+ *
254
+ * ## Accessibility requirements
255
+ *
256
+ * - Only one instance of `Footnote` should display at a time
257
+ * - Place `Footnote` as the last element in the body or main
258
+ * - When `Footnote` is open, the inert prop must be set on all children of body excluding the Footnote
259
+ * - When `Footnote` is closed, focus must return to the initiating element
260
+ */
261
+
262
+
263
+ const Footnote = props => {
264
+ var _theme$themeOptions;
265
+
266
+ const {
267
+ copy,
268
+ number,
269
+ content,
270
+ onClose,
271
+ isOpen,
272
+ tokens,
273
+ variant = {},
274
+ ...rest
275
+ } = props;
276
+ const {
277
+ footnoteBackground,
278
+ footnoteBorderTopSizeMd,
279
+ footnoteBorderColorMd,
280
+ headerMargin,
281
+ footnoteBodyBackground,
282
+ footnoteBodyPaddingLeft,
283
+ footnoteBodyPaddingRight,
284
+ footnoteBodyPaddingTop,
285
+ footnoteBodyPaddingBottom,
286
+ listPaddingLeft,
287
+ listItemMarkerFontSize,
288
+ listItemMarkerLineHeight,
289
+ listItemColor,
290
+ listItemFontSize,
291
+ listItemLineHeight,
292
+ listItemPaddingLeft,
293
+ closeButtonBorderSize,
294
+ closeButtonBorderColor,
295
+ closeButtonHeight,
296
+ closeButtonMarginTop,
297
+ closeButtonMarginLeft,
298
+ closeButtonMarginRight,
299
+ closeButtonMarginBottom,
300
+ closeButtonWidth,
301
+ closeButtonIconSize
302
+ } = (0, _componentsBase.useThemeTokens)('Footnote', tokens, variant);
303
+ const footnoteRef = (0, _react.useRef)(null);
304
+ const headerRef = (0, _react.useRef)(null);
305
+ const bodyRef = (0, _react.useRef)(null);
306
+ const listRef = (0, _react.useRef)(null);
307
+ const headingRef = (0, _react.useRef)(null);
308
+ const [data, setData] = (0, _react.useState)({
309
+ content: null,
310
+ number: null
311
+ });
312
+ const [headerHeight, setHeaderHeight] = (0, _react.useState)('auto');
313
+ const [bodyHeight, setBodyHeight] = (0, _react.useState)('auto');
314
+ const [isVisible, setIsVisible] = (0, _react.useState)(false);
315
+ const [isTextVisible, setIsTextVisible] = (0, _react.useState)(true);
316
+ const getCopy = (0, _componentsBase.useCopy)({
317
+ dictionary: _dictionary.default,
318
+ copy
319
+ });
320
+ const prevProps = usePrevious(props);
321
+ const theme = (0, _componentsBase.useTheme)();
322
+ const maxWidth = (0, _componentsBase.useResponsiveProp)((_theme$themeOptions = theme.themeOptions) === null || _theme$themeOptions === void 0 ? void 0 : _theme$themeOptions.contentMaxWidth);
323
+ const closeFootnote = (0, _react.useCallback)((event, options) => {
324
+ onClose(event, options);
325
+ }, [onClose]); // Listen for ESCAPE, close button clicks, and clicks outside of the Footnote. Call onClose.
326
+
327
+ const handleClose = (0, _react.useCallback)(event => {
328
+ var _footnoteRef$current, _footnoteRef$current2;
329
+
330
+ if (event.type === 'keydown') {
331
+ if (event.key === 'Escape' || event.key === 27) {
332
+ closeFootnote(event, {
333
+ returnFocus: true
334
+ });
335
+ }
336
+ } else if ((event.type === 'click' || event.type === 'mousedown') && footnoteRef !== null && footnoteRef !== void 0 && footnoteRef.current && event.target && !(footnoteRef !== null && footnoteRef !== void 0 && (_footnoteRef$current = footnoteRef.current) !== null && _footnoteRef$current !== void 0 && _footnoteRef$current.contains(event.target)) && event.target.getAttribute('data-tds-id') !== 'footnote-link') {
337
+ closeFootnote(event, {
338
+ returnFocus: false
339
+ });
340
+ } else if (event.type === 'touchstart' && footnoteRef !== null && footnoteRef !== void 0 && footnoteRef.current && event.touches[0].target && !(footnoteRef !== null && footnoteRef !== void 0 && (_footnoteRef$current2 = footnoteRef.current) !== null && _footnoteRef$current2 !== void 0 && _footnoteRef$current2.contains(event.touches[0].target)) && event.touches[0].target.getAttribute('data-tds-id') !== 'footnote-link') {
341
+ closeFootnote(event, {
342
+ returnFocus: false
343
+ });
344
+ }
345
+ }, [closeFootnote]);
346
+
347
+ const saveCurrentHeight = () => {
348
+ const oldHeight = listRef.current.offsetHeight;
349
+ setBodyHeight(oldHeight);
350
+ };
351
+
352
+ const focusHeading = () => {
353
+ if (Boolean(content) && isVisible && headingRef && headingRef.current !== null) {
354
+ headingRef.current.focus();
355
+ }
356
+ };
357
+
358
+ const handleStyledFootnoteTransitionEnd = event => {
359
+ if (event.propertyName === 'transform' && !isOpen) {
360
+ setIsVisible(false);
361
+ } else {
362
+ focusHeading();
363
+ }
364
+ };
365
+
366
+ const handleTransitionEnd = event => {
367
+ event.persist();
368
+
369
+ if (event.propertyName === 'opacity' && !isTextVisible) {
370
+ setData({
371
+ content,
372
+ number
373
+ });
374
+
375
+ if (bodyHeight !== listRef.current.offsetHeight) {
376
+ // Set new height
377
+ setBodyHeight(listRef.current.offsetHeight);
378
+ } else {
379
+ setIsTextVisible(true);
380
+ }
381
+ } else {
382
+ setBodyHeight(listRef.current.offsetHeight);
383
+ }
384
+
385
+ if (event.propertyName === 'height' && !isTextVisible) {
386
+ setIsTextVisible(true);
387
+ }
388
+ };
389
+
390
+ const resetFootnote = () => {
391
+ // Reset footnote state if closed
392
+ if (!isOpen) {
393
+ setBodyHeight('auto');
394
+ setIsTextVisible(true);
395
+ }
396
+ }; // Set height of header on mount
397
+
398
+
399
+ (0, _react.useEffect)(() => {
400
+ var _headerRef$current;
401
+
402
+ setHeaderHeight((_headerRef$current = headerRef.current) === null || _headerRef$current === void 0 ? void 0 : _headerRef$current.offsetHeight);
403
+ }, []);
404
+
405
+ const preventDefault = event => {
406
+ if (!bodyRef.current.contains(event.touches[0].target)) {
407
+ event.preventDefault();
408
+ }
409
+ }; // Add listeners for mouse clicks outside of Footnote and for ESCAPE key presses
410
+
411
+
412
+ (0, _react.useEffect)(() => {
413
+ if (isOpen) {
414
+ setIsVisible(true);
415
+ document.addEventListener('mousedown', handleClose);
416
+ window.addEventListener('click', handleClose);
417
+ window.addEventListener('keydown', handleClose);
418
+ window.addEventListener('touchstart', handleClose);
419
+ window.addEventListener('touchmove', preventDefault, {
420
+ passive: false
421
+ });
422
+ }
423
+
424
+ return () => {
425
+ if (isOpen) {
426
+ document.addEventListener('mousedown', handleClose);
427
+ window.removeEventListener('click', handleClose);
428
+ window.removeEventListener('keydown', handleClose);
429
+ window.removeEventListener('touchstart', handleClose);
430
+ window.removeEventListener('touchmove', preventDefault);
431
+ }
432
+ };
433
+ }, [handleClose, isOpen]); // Set data if opening a new footnote
434
+
435
+ (0, _react.useEffect)(() => {
436
+ if (isOpen && !prevProps.isOpen) {
437
+ setData({
438
+ content,
439
+ number
440
+ });
441
+ }
442
+ }, [isOpen, prevProps.isOpen, content, number]);
443
+ (0, _react.useEffect)(() => {
444
+ if (isOpen && prevProps.isOpen && number !== prevProps.number) {
445
+ saveCurrentHeight();
446
+ setIsTextVisible(false);
447
+ }
448
+ }, [number, isOpen, prevProps.isOpen, prevProps.number]); // Reset footnote on close
449
+
450
+ (0, _react.useEffect)(resetFootnote, [isOpen]);
451
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Portal, {
452
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", { ...selectProps(rest),
453
+ children: [isOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(GlobalBodyScrollLock, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledFootnote, {
454
+ ref: footnoteRef,
455
+ isOpen: isOpen,
456
+ isVisible: isVisible,
457
+ onTransitionEnd: handleStyledFootnoteTransitionEnd,
458
+ tabIndex: 0,
459
+ footnoteBackground: footnoteBackground,
460
+ footnoteBorderTop: `${footnoteBorderTopSizeMd}px solid ${footnoteBorderColorMd}`,
461
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(ContentContainer, {
462
+ maxWidth: maxWidth,
463
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(StyledFootnoteHeader, {
464
+ ref: headerRef,
465
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(StyledHeader, {
466
+ ref: headingRef,
467
+ headerMargin: headerMargin,
468
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Typography, {
469
+ block: true,
470
+ heading: true,
471
+ tabIndex: -1,
472
+ variant: {
473
+ size: 'h4'
474
+ },
475
+ children: getCopy('heading')
476
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(CloseButton, {
477
+ closeButtonBorder: `${closeButtonBorderSize}px solid ${closeButtonBorderColor}`,
478
+ closeButtonWidth: `${closeButtonWidth}px`,
479
+ closeButtonHeight: `${closeButtonHeight}px`,
480
+ closeButtonMargin: `${closeButtonMarginTop}px ${closeButtonMarginRight}px ${closeButtonMarginBottom}px ${closeButtonMarginLeft}px`,
481
+ onClick: event => {
482
+ closeFootnote(event, {
483
+ returnFocus: true
484
+ });
485
+ },
486
+ "aria-label": getCopy('close'),
487
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Icon, {
488
+ icon: _Close.default,
489
+ tokens: {
490
+ size: `${closeButtonIconSize}px`
491
+ }
492
+ })
493
+ })]
494
+ })
495
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(StyledFootnoteBody, {
496
+ ref: bodyRef,
497
+ bodyHeight: bodyHeight,
498
+ headerHeight: headerHeight,
499
+ isTextVisible: isTextVisible,
500
+ onTransitionEnd: handleTransitionEnd,
501
+ maxWidth: theme.contentMaxWidth,
502
+ footnoteBodyBackground: footnoteBodyBackground,
503
+ footnoteBodyPadding: `${footnoteBodyPaddingTop}px ${footnoteBodyPaddingRight}px ${footnoteBodyPaddingBottom}px ${footnoteBodyPaddingLeft}px`,
504
+ children: data.number && data.content && /*#__PURE__*/(0, _jsxRuntime.jsx)(List, {
505
+ start: data.number,
506
+ ref: listRef,
507
+ listPaddingLeft: listPaddingLeft,
508
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ListItem, {
509
+ listItemMarkerFontSize: listItemMarkerFontSize,
510
+ listItemMarkerLineHeight: listItemMarkerLineHeight,
511
+ listItemColor: listItemColor,
512
+ listItemFontSize: listItemFontSize,
513
+ listItemLineHeight: listItemLineHeight,
514
+ listItemPaddingLeft: listItemPaddingLeft,
515
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_componentsBase.Typography, {
516
+ children: (0, _utils.renderStructuredContent)(data.content)
517
+ })
518
+ })
519
+ })
520
+ })]
521
+ })
522
+ })]
523
+ })
524
+ });
525
+ };
526
+
527
+ const copyShape = _propTypes.default.shape({
528
+ close: _propTypes.default.string.isRequired,
529
+ heading: _propTypes.default.string.isRequired
530
+ });
531
+
532
+ Footnote.propTypes = { ...selectedSystemPropTypes,
533
+
534
+ /**
535
+ * The content.
536
+ */
537
+ content: _propTypes.default.string,
538
+
539
+ /**
540
+ * Use the `copy` prop to either select provided English or French copy by passing 'en' or 'fr' respectively.
541
+ * To provide your own, pass a JSON object with the keys `heading` and `close`.
542
+ */
543
+ copy: _propTypes.default.oneOfType([_propTypes.default.oneOf(['en', 'fr']), copyShape]),
544
+
545
+ /**
546
+ * A boolean flag used hide or show the `Footnote`. Set to `true` to open the `Footnote`.
547
+ */
548
+ isOpen: _propTypes.default.bool,
549
+
550
+ /**
551
+ * The number, must match the number of the `FootnoteLink` that initiated the `Footnote`.
552
+ */
553
+ number: _propTypes.default.number,
554
+
555
+ /**
556
+ * A callback function to handle the closing of the footnote.
557
+ *
558
+ * @param {SyntheticEvent} event The React `SyntheticEvent`
559
+ * @param {Object} options Custom options
560
+ * @param {boolean} options.returnFocus Should the `Footnote` return focus on close
561
+ */
562
+ onClose: _propTypes.default.func.isRequired
563
+ };
564
+ Footnote.defaultProps = {
565
+ isOpen: false,
566
+ number: undefined,
567
+ content: undefined,
568
+ copy: 'en'
569
+ };
570
+ var _default = Footnote;
571
+ exports.default = _default;