@telus-uds/components-web 2.42.0 → 2.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,12 +1,29 @@
1
1
  # Change Log - @telus-uds/components-web
2
2
 
3
- This log was last generated on Sat, 12 Oct 2024 00:31:05 GMT and should not be manually modified.
3
+ This log was last generated on Thu, 31 Oct 2024 05:02:44 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 2.43.0
8
+
9
+ Thu, 31 Oct 2024 05:02:44 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - `Breadcrumbs`: add expander item on xs viewport (guillermo.peitzner@telus.com)
14
+ - `Modal`: Enable `footerTopWidth` token for `Modal` component (jaime.tuyuc@telus.com)
15
+ - `Types`: Export BaseProviderProps and add FileUpload types (6854874+kyletsang@users.noreply.github.com)
16
+ - Bump @telus-uds/components-base to v1.97.0
17
+ - Bump @telus-uds/system-theme-tokens to v2.66.0
18
+
19
+ ### Patches
20
+
21
+ - `DatePicker`: calendar misalignment and static overlay behavior fixed when the component is inside a modal (35577399+JoshHC@users.noreply.github.com)
22
+ - `Table`: added null check for container during resizing (kristina.kirpichnikova@telus.com)
23
+
7
24
  ## 2.42.0
8
25
 
9
- Sat, 12 Oct 2024 00:31:05 GMT
26
+ Sat, 12 Oct 2024 00:40:49 GMT
10
27
 
11
28
  ### Minor changes
12
29
 
@@ -8,6 +8,7 @@ var _react = _interopRequireWildcard(require("react"));
8
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
9
  var _styledComponents = _interopRequireDefault(require("styled-components"));
10
10
  var _reactHelmetAsync = require("react-helmet-async");
11
+ var _lodash = require("lodash");
11
12
  var _componentsBase = require("@telus-uds/components-base");
12
13
  var _utils = require("../utils");
13
14
  var _Item = _interopRequireDefault(require("./Item/Item"));
@@ -79,10 +80,11 @@ const getItems = (items, params, concatenatePaths) => {
79
80
  } = item;
80
81
  return {
81
82
  breadcrumbName,
82
- href,
83
+ href: item.isExpander ? '#' : href,
83
84
  current: isLast,
84
85
  LinkRouter,
85
86
  linkRouterProps,
87
+ onPress: item.onPress,
86
88
  ...omitProps(selectProps(item))
87
89
  };
88
90
  });
@@ -97,6 +99,7 @@ const getStructuredData = (items, baseUrl) => {
97
99
  }
98
100
  }));
99
101
  };
102
+ const MAX_ITEMS_ON_XS_VIEWPORT = 4;
100
103
 
101
104
  /**
102
105
  * Display a hierarchy of links, commonly used for navigation.
@@ -138,7 +141,33 @@ const Breadcrumbs = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
138
141
  ...itemRest
139
142
  };
140
143
  }) : routes.filter(route => route.path && route.breadcrumbName);
141
- const items = getItems(activeRoutes, params, !children);
144
+ const [optionsHidden, setOptionsHidden] = _react.default.useState(false);
145
+ const [itemsToBeRendered, setItemsToBeRendered] = _react.default.useState([]);
146
+ const viewport = (0, _componentsBase.useViewport)();
147
+ _react.default.useEffect(() => {
148
+ if (optionsHidden) {
149
+ if (viewport !== 'xs' && !(0, _lodash.isEqual)(itemsToBeRendered, activeRoutes)) {
150
+ setItemsToBeRendered(activeRoutes);
151
+ }
152
+ return;
153
+ }
154
+ if (viewport === 'xs' && activeRoutes.length >= MAX_ITEMS_ON_XS_VIEWPORT) {
155
+ const newItems = [...activeRoutes.slice(0, 2), {
156
+ path: '#',
157
+ breadcrumbName: '...',
158
+ onPress: event => {
159
+ event.preventDefault();
160
+ setItemsToBeRendered(activeRoutes);
161
+ },
162
+ isExpander: true
163
+ }, activeRoutes[activeRoutes.length - 1]];
164
+ setItemsToBeRendered(newItems);
165
+ setOptionsHidden(true);
166
+ } else if (!(0, _lodash.isEqual)(itemsToBeRendered, activeRoutes)) {
167
+ setItemsToBeRendered(activeRoutes);
168
+ }
169
+ }, [viewport, activeRoutes, optionsHidden, itemsToBeRendered]);
170
+ const items = getItems(itemsToBeRendered, params, !children);
142
171
  const themeTokens = (0, _componentsBase.useThemeTokens)('Breadcrumbs', tokens, variant);
143
172
  const metadata = /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactHelmetAsync.HelmetProvider, {
144
173
  context: helmetContext,
@@ -168,6 +197,7 @@ const Breadcrumbs = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
168
197
  breadcrumbName,
169
198
  LinkRouter: ItemLinkRouter = LinkRouter,
170
199
  linkRouterProps: itemLinkRouterProps,
200
+ onPress,
171
201
  ...itemRest
172
202
  } = _ref4;
173
203
  return /*#__PURE__*/(0, _react.createElement)(_Item.default, {
@@ -184,7 +214,8 @@ const Breadcrumbs = /*#__PURE__*/_react.default.forwardRef((_ref2, ref) => {
184
214
  ...variant,
185
215
  size: 'micro'
186
216
  },
187
- LinkRouter: ItemLinkRouter
217
+ LinkRouter: ItemLinkRouter,
218
+ onPress: onPress
188
219
  }, breadcrumbName);
189
220
  })
190
221
  }), metadata]
@@ -86,6 +86,7 @@ const Item = /*#__PURE__*/_react.default.forwardRef((_ref8, ref) => {
86
86
  // `light` variant (shared with the `Link` component) is default by design
87
87
  LinkRouter,
88
88
  linkRouterProps,
89
+ onPress,
89
90
  ...rest
90
91
  } = _ref8;
91
92
  const {
@@ -132,6 +133,7 @@ const Item = /*#__PURE__*/_react.default.forwardRef((_ref8, ref) => {
132
133
  LinkRouter: LinkRouter,
133
134
  linkRouterProps: linkRouterProps,
134
135
  variant: variant,
136
+ onPress: onPress,
135
137
  children: children
136
138
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(IconContainer, {
137
139
  iconPadding: iconPadding,
@@ -169,7 +171,11 @@ Item.propTypes = {
169
171
  */
170
172
  variant: _propTypes.default.shape({
171
173
  inverse: _propTypes.default.bool
172
- })
174
+ }),
175
+ /**
176
+ * Function to be called when the Item is clicked.
177
+ */
178
+ onPress: _propTypes.default.func
173
179
  };
174
180
  var _default = Item;
175
181
  exports.default = _default;
@@ -124,25 +124,39 @@ const DatePicker = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
124
124
  left: 0,
125
125
  top: 0
126
126
  });
127
+ const datePickerRef = _react.default.useRef(null);
127
128
  (0, _componentsBase.useSafeLayoutEffect)(() => {
128
- const updateDimensions = () => {
129
- if (inline || !textInputRef.current) return;
129
+ const updateDatePickerPosition = () => {
130
+ if (inline || !(textInputRef !== null && textInputRef !== void 0 && textInputRef.current)) return;
130
131
  const {
131
132
  left,
132
133
  top
133
134
  } = textInputRef.current.getBoundingClientRect();
134
135
  const inputTop = top + window.scrollY;
136
+ const inputLeft = left + window.scrollX;
135
137
  setDatePickerPosition({
136
- left,
137
- top: inputTop + textInputRef.current.offsetHeight
138
+ top: inputTop + textInputRef.current.offsetHeight,
139
+ left: inputLeft
138
140
  });
139
141
  };
140
- const throttledUpdateDimensions = (0, _lodash.throttle)(updateDimensions, 100, {
142
+ const throttledUpdate = (0, _lodash.throttle)(updateDatePickerPosition, 100, {
141
143
  leading: false
142
144
  });
143
- throttledUpdateDimensions();
144
- window.addEventListener('resize', throttledUpdateDimensions);
145
- return () => window.removeEventListener('resize', throttledUpdateDimensions);
145
+
146
+ // Initial call to set the position
147
+ updateDatePickerPosition();
148
+
149
+ // Register event listeners
150
+ window.addEventListener('resize', throttledUpdate);
151
+ window.addEventListener('scroll', updateDatePickerPosition, {
152
+ capture: true
153
+ });
154
+ return () => {
155
+ window.removeEventListener('resize', throttledUpdate);
156
+ window.removeEventListener('scroll', updateDatePickerPosition, {
157
+ capture: true
158
+ });
159
+ };
146
160
  }, []);
147
161
  const [isFocused, setIsFocused] = _react.default.useState(false);
148
162
  const [isClickedInside, setIsClickedInside] = _react.default.useState(false);
@@ -369,6 +383,7 @@ const DatePicker = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
369
383
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(PortalPositionedContainer, {
370
384
  top: datePickerPosition.top,
371
385
  left: datePickerPosition.left,
386
+ ref: datePickerRef,
372
387
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CalendarContainer.default, {
373
388
  ...selectProps(rest),
374
389
  daySize: daySize,
@@ -66,8 +66,9 @@ const Table = _ref2 => {
66
66
  const [tableWidth, setTableWidth] = _react.default.useState(0);
67
67
  (0, _componentsBase.useSafeLayoutEffect)(() => {
68
68
  const updateDimensions = () => {
69
- const containerClientWidth = containerRef.current.clientWidth;
70
- const responsiveTableWidth = fullWidth ? containerClientWidth : tableRef.current.clientWidth;
69
+ var _containerRef$current, _tableRef$current;
70
+ const containerClientWidth = (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.clientWidth;
71
+ const responsiveTableWidth = fullWidth ? containerClientWidth : (_tableRef$current = tableRef.current) === null || _tableRef$current === void 0 ? void 0 : _tableRef$current.clientWidth;
71
72
  setContainerWidth(containerClientWidth);
72
73
  setTableWidth(responsiveTableWidth);
73
74
  };
@@ -2,7 +2,8 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import styled from 'styled-components';
4
4
  import { Helmet, HelmetProvider } from 'react-helmet-async';
5
- import { componentPropType, selectSystemProps, unpackFragment, withLinkRouter, getTokensPropType, useThemeTokens } from '@telus-uds/components-base';
5
+ import { isEqual } from 'lodash';
6
+ import { componentPropType, selectSystemProps, unpackFragment, withLinkRouter, getTokensPropType, useThemeTokens, useViewport } from '@telus-uds/components-base';
6
7
  import { htmlAttrs } from '../utils';
7
8
  import Item from './Item/Item';
8
9
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -72,10 +73,11 @@ const getItems = (items, params, concatenatePaths) => {
72
73
  } = item;
73
74
  return {
74
75
  breadcrumbName,
75
- href,
76
+ href: item.isExpander ? '#' : href,
76
77
  current: isLast,
77
78
  LinkRouter,
78
79
  linkRouterProps,
80
+ onPress: item.onPress,
79
81
  ...omitProps(selectProps(item))
80
82
  };
81
83
  });
@@ -90,6 +92,7 @@ const getStructuredData = (items, baseUrl) => {
90
92
  }
91
93
  }));
92
94
  };
95
+ const MAX_ITEMS_ON_XS_VIEWPORT = 4;
93
96
 
94
97
  /**
95
98
  * Display a hierarchy of links, commonly used for navigation.
@@ -131,7 +134,33 @@ const Breadcrumbs = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
131
134
  ...itemRest
132
135
  };
133
136
  }) : routes.filter(route => route.path && route.breadcrumbName);
134
- const items = getItems(activeRoutes, params, !children);
137
+ const [optionsHidden, setOptionsHidden] = React.useState(false);
138
+ const [itemsToBeRendered, setItemsToBeRendered] = React.useState([]);
139
+ const viewport = useViewport();
140
+ React.useEffect(() => {
141
+ if (optionsHidden) {
142
+ if (viewport !== 'xs' && !isEqual(itemsToBeRendered, activeRoutes)) {
143
+ setItemsToBeRendered(activeRoutes);
144
+ }
145
+ return;
146
+ }
147
+ if (viewport === 'xs' && activeRoutes.length >= MAX_ITEMS_ON_XS_VIEWPORT) {
148
+ const newItems = [...activeRoutes.slice(0, 2), {
149
+ path: '#',
150
+ breadcrumbName: '...',
151
+ onPress: event => {
152
+ event.preventDefault();
153
+ setItemsToBeRendered(activeRoutes);
154
+ },
155
+ isExpander: true
156
+ }, activeRoutes[activeRoutes.length - 1]];
157
+ setItemsToBeRendered(newItems);
158
+ setOptionsHidden(true);
159
+ } else if (!isEqual(itemsToBeRendered, activeRoutes)) {
160
+ setItemsToBeRendered(activeRoutes);
161
+ }
162
+ }, [viewport, activeRoutes, optionsHidden, itemsToBeRendered]);
163
+ const items = getItems(itemsToBeRendered, params, !children);
135
164
  const themeTokens = useThemeTokens('Breadcrumbs', tokens, variant);
136
165
  const metadata = /*#__PURE__*/_jsx(HelmetProvider, {
137
166
  context: helmetContext,
@@ -161,6 +190,7 @@ const Breadcrumbs = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
161
190
  breadcrumbName,
162
191
  LinkRouter: ItemLinkRouter = LinkRouter,
163
192
  linkRouterProps: itemLinkRouterProps,
193
+ onPress,
164
194
  ...itemRest
165
195
  } = _ref4;
166
196
  return /*#__PURE__*/_createElement(Item, {
@@ -177,7 +207,8 @@ const Breadcrumbs = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
177
207
  ...variant,
178
208
  size: 'micro'
179
209
  },
180
- LinkRouter: ItemLinkRouter
210
+ LinkRouter: ItemLinkRouter,
211
+ onPress: onPress
181
212
  }, breadcrumbName);
182
213
  })
183
214
  }), metadata]
@@ -81,6 +81,7 @@ const Item = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
81
81
  // `light` variant (shared with the `Link` component) is default by design
82
82
  LinkRouter,
83
83
  linkRouterProps,
84
+ onPress,
84
85
  ...rest
85
86
  } = _ref8;
86
87
  const {
@@ -127,6 +128,7 @@ const Item = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
127
128
  LinkRouter: LinkRouter,
128
129
  linkRouterProps: linkRouterProps,
129
130
  variant: variant,
131
+ onPress: onPress,
130
132
  children: children
131
133
  }), /*#__PURE__*/_jsx(IconContainer, {
132
134
  iconPadding: iconPadding,
@@ -164,6 +166,10 @@ Item.propTypes = {
164
166
  */
165
167
  variant: PropTypes.shape({
166
168
  inverse: PropTypes.bool
167
- })
169
+ }),
170
+ /**
171
+ * Function to be called when the Item is clicked.
172
+ */
173
+ onPress: PropTypes.func
168
174
  };
169
175
  export default Item;
@@ -119,25 +119,39 @@ const DatePicker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
119
119
  left: 0,
120
120
  top: 0
121
121
  });
122
+ const datePickerRef = React.useRef(null);
122
123
  useSafeLayoutEffect(() => {
123
- const updateDimensions = () => {
124
- if (inline || !textInputRef.current) return;
124
+ const updateDatePickerPosition = () => {
125
+ if (inline || !(textInputRef !== null && textInputRef !== void 0 && textInputRef.current)) return;
125
126
  const {
126
127
  left,
127
128
  top
128
129
  } = textInputRef.current.getBoundingClientRect();
129
130
  const inputTop = top + window.scrollY;
131
+ const inputLeft = left + window.scrollX;
130
132
  setDatePickerPosition({
131
- left,
132
- top: inputTop + textInputRef.current.offsetHeight
133
+ top: inputTop + textInputRef.current.offsetHeight,
134
+ left: inputLeft
133
135
  });
134
136
  };
135
- const throttledUpdateDimensions = throttle(updateDimensions, 100, {
137
+ const throttledUpdate = throttle(updateDatePickerPosition, 100, {
136
138
  leading: false
137
139
  });
138
- throttledUpdateDimensions();
139
- window.addEventListener('resize', throttledUpdateDimensions);
140
- return () => window.removeEventListener('resize', throttledUpdateDimensions);
140
+
141
+ // Initial call to set the position
142
+ updateDatePickerPosition();
143
+
144
+ // Register event listeners
145
+ window.addEventListener('resize', throttledUpdate);
146
+ window.addEventListener('scroll', updateDatePickerPosition, {
147
+ capture: true
148
+ });
149
+ return () => {
150
+ window.removeEventListener('resize', throttledUpdate);
151
+ window.removeEventListener('scroll', updateDatePickerPosition, {
152
+ capture: true
153
+ });
154
+ };
141
155
  }, []);
142
156
  const [isFocused, setIsFocused] = React.useState(false);
143
157
  const [isClickedInside, setIsClickedInside] = React.useState(false);
@@ -364,6 +378,7 @@ const DatePicker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
364
378
  children: /*#__PURE__*/_jsx(PortalPositionedContainer, {
365
379
  top: datePickerPosition.top,
366
380
  left: datePickerPosition.left,
381
+ ref: datePickerRef,
367
382
  children: /*#__PURE__*/_jsx(CalendarContainer, {
368
383
  ...selectProps(rest),
369
384
  daySize: daySize,
@@ -58,8 +58,9 @@ const Table = _ref2 => {
58
58
  const [tableWidth, setTableWidth] = React.useState(0);
59
59
  useSafeLayoutEffect(() => {
60
60
  const updateDimensions = () => {
61
- const containerClientWidth = containerRef.current.clientWidth;
62
- const responsiveTableWidth = fullWidth ? containerClientWidth : tableRef.current.clientWidth;
61
+ var _containerRef$current, _tableRef$current;
62
+ const containerClientWidth = (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.clientWidth;
63
+ const responsiveTableWidth = fullWidth ? containerClientWidth : (_tableRef$current = tableRef.current) === null || _tableRef$current === void 0 ? void 0 : _tableRef$current.clientWidth;
63
64
  setContainerWidth(containerClientWidth);
64
65
  setTableWidth(responsiveTableWidth);
65
66
  };
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  ],
6
6
  "dependencies": {
7
7
  "@gorhom/portal": "^1.0.14",
8
- "@telus-uds/components-base": "1.96.0",
8
+ "@telus-uds/components-base": "1.97.0",
9
9
  "@telus-uds/system-constants": "^1.3.0",
10
10
  "fscreen": "^1.2.0",
11
11
  "lodash.omit": "^4.5.0",
@@ -13,7 +13,7 @@
13
13
  "react-dates": "^21.8.0",
14
14
  "react-helmet-async": "^1.3.0",
15
15
  "react-moment-proptypes": "^1.8.1",
16
- "@telus-uds/system-theme-tokens": "^2.65.0",
16
+ "@telus-uds/system-theme-tokens": "^2.66.0",
17
17
  "prop-types": "^15.7.2",
18
18
  "lodash.throttle": "^4.1.1",
19
19
  "react-youtube": "^10.1.0",
@@ -83,5 +83,5 @@
83
83
  "skip": true
84
84
  },
85
85
  "types": "types/index.d.ts",
86
- "version": "2.42.0"
86
+ "version": "2.43.0"
87
87
  }
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
3
3
  import styled from 'styled-components'
4
4
 
5
5
  import { Helmet, HelmetProvider } from 'react-helmet-async'
6
+ import { isEqual } from 'lodash'
6
7
 
7
8
  import {
8
9
  componentPropType,
@@ -10,7 +11,8 @@ import {
10
11
  unpackFragment,
11
12
  withLinkRouter,
12
13
  getTokensPropType,
13
- useThemeTokens
14
+ useThemeTokens,
15
+ useViewport
14
16
  } from '@telus-uds/components-base'
15
17
  import { htmlAttrs } from '../utils'
16
18
  import Item from './Item/Item'
@@ -79,10 +81,11 @@ const getItems = (items, params, concatenatePaths) => {
79
81
  const { LinkRouter, linkRouterProps } = item
80
82
  return {
81
83
  breadcrumbName,
82
- href,
84
+ href: item.isExpander ? '#' : href,
83
85
  current: isLast,
84
86
  LinkRouter,
85
87
  linkRouterProps,
88
+ onPress: item.onPress,
86
89
  ...omitProps(selectProps(item))
87
90
  }
88
91
  })
@@ -99,6 +102,8 @@ const getStructuredData = (items, baseUrl) => {
99
102
  }))
100
103
  }
101
104
 
105
+ const MAX_ITEMS_ON_XS_VIEWPORT = 4
106
+
102
107
  /**
103
108
  * Display a hierarchy of links, commonly used for navigation.
104
109
  */
@@ -139,7 +144,40 @@ const Breadcrumbs = React.forwardRef(
139
144
  )
140
145
  : routes.filter((route) => route.path && route.breadcrumbName)
141
146
 
142
- const items = getItems(activeRoutes, params, !children)
147
+ const [optionsHidden, setOptionsHidden] = React.useState(false)
148
+ const [itemsToBeRendered, setItemsToBeRendered] = React.useState([])
149
+
150
+ const viewport = useViewport()
151
+
152
+ React.useEffect(() => {
153
+ if (optionsHidden) {
154
+ if (viewport !== 'xs' && !isEqual(itemsToBeRendered, activeRoutes)) {
155
+ setItemsToBeRendered(activeRoutes)
156
+ }
157
+ return
158
+ }
159
+ if (viewport === 'xs' && activeRoutes.length >= MAX_ITEMS_ON_XS_VIEWPORT) {
160
+ const newItems = [
161
+ ...activeRoutes.slice(0, 2),
162
+ {
163
+ path: '#',
164
+ breadcrumbName: '...',
165
+ onPress: (event) => {
166
+ event.preventDefault()
167
+ setItemsToBeRendered(activeRoutes)
168
+ },
169
+ isExpander: true
170
+ },
171
+ activeRoutes[activeRoutes.length - 1]
172
+ ]
173
+ setItemsToBeRendered(newItems)
174
+ setOptionsHidden(true)
175
+ } else if (!isEqual(itemsToBeRendered, activeRoutes)) {
176
+ setItemsToBeRendered(activeRoutes)
177
+ }
178
+ }, [viewport, activeRoutes, optionsHidden, itemsToBeRendered])
179
+
180
+ const items = getItems(itemsToBeRendered, params, !children)
143
181
  const themeTokens = useThemeTokens('Breadcrumbs', tokens, variant)
144
182
 
145
183
  const metadata = (
@@ -168,6 +206,7 @@ const Breadcrumbs = React.forwardRef(
168
206
  breadcrumbName,
169
207
  LinkRouter: ItemLinkRouter = LinkRouter,
170
208
  linkRouterProps: itemLinkRouterProps,
209
+ onPress,
171
210
  ...itemRest
172
211
  }) => {
173
212
  return (
@@ -180,6 +219,7 @@ const Breadcrumbs = React.forwardRef(
180
219
  linkRouterProps={{ ...linkRouterProps, ...itemLinkRouterProps }}
181
220
  variant={{ ...variant, size: 'micro' }}
182
221
  LinkRouter={ItemLinkRouter}
222
+ onPress={onPress}
183
223
  >
184
224
  {breadcrumbName}
185
225
  </Item>
@@ -40,6 +40,7 @@ const Item = React.forwardRef(
40
40
  variant = { light: true }, // `light` variant (shared with the `Link` component) is default by design
41
41
  LinkRouter,
42
42
  linkRouterProps,
43
+ onPress,
43
44
  ...rest
44
45
  },
45
46
  ref
@@ -89,6 +90,7 @@ const Item = React.forwardRef(
89
90
  LinkRouter={LinkRouter}
90
91
  linkRouterProps={linkRouterProps}
91
92
  variant={variant}
93
+ onPress={onPress}
92
94
  >
93
95
  {children}
94
96
  </Link>
@@ -129,7 +131,11 @@ Item.propTypes = {
129
131
  /**
130
132
  * Variant to render.
131
133
  */
132
- variant: PropTypes.shape({ inverse: PropTypes.bool })
134
+ variant: PropTypes.shape({ inverse: PropTypes.bool }),
135
+ /**
136
+ * Function to be called when the Item is clicked.
137
+ */
138
+ onPress: PropTypes.func
133
139
  }
134
140
 
135
141
  export default Item
@@ -111,21 +111,33 @@ const DatePicker = React.forwardRef(
111
111
  const textInputRef = React.useRef()
112
112
  const prevButtonRef = React.useRef()
113
113
  const [datePickerPosition, setDatePickerPosition] = React.useState({ left: 0, top: 0 })
114
+ const datePickerRef = React.useRef(null)
114
115
 
115
116
  useSafeLayoutEffect(() => {
116
- const updateDimensions = () => {
117
- if (inline || !textInputRef.current) return
117
+ const updateDatePickerPosition = () => {
118
+ if (inline || !textInputRef?.current) return
118
119
  const { left, top } = textInputRef.current.getBoundingClientRect()
119
120
  const inputTop = top + window.scrollY
121
+ const inputLeft = left + window.scrollX
120
122
  setDatePickerPosition({
121
- left,
122
- top: inputTop + textInputRef.current.offsetHeight
123
+ top: inputTop + textInputRef.current.offsetHeight,
124
+ left: inputLeft
123
125
  })
124
126
  }
125
- const throttledUpdateDimensions = throttle(updateDimensions, 100, { leading: false })
126
- throttledUpdateDimensions()
127
- window.addEventListener('resize', throttledUpdateDimensions)
128
- return () => window.removeEventListener('resize', throttledUpdateDimensions)
127
+
128
+ const throttledUpdate = throttle(updateDatePickerPosition, 100, { leading: false })
129
+
130
+ // Initial call to set the position
131
+ updateDatePickerPosition()
132
+
133
+ // Register event listeners
134
+ window.addEventListener('resize', throttledUpdate)
135
+ window.addEventListener('scroll', updateDatePickerPosition, { capture: true })
136
+
137
+ return () => {
138
+ window.removeEventListener('resize', throttledUpdate)
139
+ window.removeEventListener('scroll', updateDatePickerPosition, { capture: true })
140
+ }
129
141
  }, [])
130
142
 
131
143
  const [isFocused, setIsFocused] = React.useState(false)
@@ -373,6 +385,7 @@ const DatePicker = React.forwardRef(
373
385
  <PortalPositionedContainer
374
386
  top={datePickerPosition.top}
375
387
  left={datePickerPosition.left}
388
+ ref={datePickerRef}
376
389
  >
377
390
  <CalendarContainer
378
391
  {...selectProps(rest)}
@@ -60,8 +60,8 @@ const Table = ({
60
60
 
61
61
  useSafeLayoutEffect(() => {
62
62
  const updateDimensions = () => {
63
- const containerClientWidth = containerRef.current.clientWidth
64
- const responsiveTableWidth = fullWidth ? containerClientWidth : tableRef.current.clientWidth
63
+ const containerClientWidth = containerRef.current?.clientWidth
64
+ const responsiveTableWidth = fullWidth ? containerClientWidth : tableRef.current?.clientWidth
65
65
  setContainerWidth(containerClientWidth)
66
66
  setTableWidth(responsiveTableWidth)
67
67
  }
@@ -1,22 +1,22 @@
1
1
  import type { ComponentType } from 'react'
2
2
 
3
- declare interface ThemeMetadata {
3
+ export interface ThemeMetadata {
4
4
  themeTokensVersion: string
5
5
  name: string
6
6
  }
7
7
 
8
- declare interface DefaultTheme {
8
+ export interface Theme {
9
9
  metadata: ThemeMetadata
10
10
  }
11
11
 
12
- declare interface ThemeOptions {
12
+ export interface ThemeOptions {
13
13
  forceAbsoluteFontSizing?: boolean
14
14
  forceZIndex?: boolean
15
15
  }
16
16
 
17
17
  export interface BaseProviderProps {
18
18
  themeOptions?: ThemeOptions
19
- defaultTheme: DefaultTheme
19
+ defaultTheme: Theme
20
20
  children: React.ReactNode
21
21
  }
22
22
 
@@ -0,0 +1,41 @@
1
+ // TODO: Duplicate of the one in components-base. TS module resolution doesn't seem to be working from web -> base.
2
+ import type { ComponentType } from 'react'
3
+
4
+ export interface FileUploadTokens {
5
+ buttonBackgroundColor?: string
6
+ buttonBorderColor?: string
7
+ buttonBorderRadius?: number
8
+ buttonBorderWidth?: string
9
+ buttonTextColor?: string
10
+ buttonHeight?: string
11
+ buttonMinWidth?: string
12
+ buttonWidth?: string
13
+ notificationBackgroundColor?: string
14
+ notificationBorderColor?: string
15
+ notificationBorderRadius?: number
16
+ notificationTextColor?: string
17
+ notificationDismissButtonGap?: string
18
+ notificationDismissIcon?: string
19
+ notificationDismissIconColor?: string
20
+ notificationIcon?: string
21
+ notificationIconColor?: string
22
+ notificationIconGap?: string
23
+ notificationIconSize?: number
24
+ }
25
+
26
+ export interface FileUploadProps {
27
+ tokens?: FileUploadTokens
28
+ variant?: Record<string, any>
29
+ copy?: 'en' | 'fr'
30
+ fileTypes?: string[]
31
+ allowMultipleFiles?: boolean
32
+ maxFileSize?: number
33
+ maxFilesCount?: number
34
+ onUpload?: (files: any) => void
35
+ onDelete?: (file: any) => void
36
+ documentPicker?: Record<string, any>
37
+ }
38
+
39
+ declare const FileUpload: ComponentType<FileUploadProps>
40
+
41
+ export default FileUpload
package/types/index.d.ts CHANGED
@@ -8,6 +8,9 @@ export type { AutocompleteProps, AutocompleteItem } from './Autocomplete'
8
8
  export { default as Badge } from './Badge'
9
9
  export type { BadgeProps } from './Badge'
10
10
 
11
+ export { default as BaseProvider } from './BaseProvider'
12
+ export type { BaseProviderProps, ThemeOptions, Theme, ThemeMetadata } from './BaseProvider'
13
+
11
14
  export { default as BlockQuote } from './BlockQuote'
12
15
  export type { BlockQuoteProps } from './BlockQuote'
13
16
 
@@ -35,6 +38,10 @@ export type { DatePickerProps } from './DatePicker'
35
38
 
36
39
  declare const Disclaimer: ComponentType<Props>
37
40
  declare const ExpandCollapseMini: ComponentType<Props>
41
+
42
+ export { default as FileUpload } from './FileUpload'
43
+ export type { FileUploadProps, FileUploadTokens } from './FileUpload'
44
+
38
45
  declare const Footnote: ComponentType<Props> & {
39
46
  Link: ComponentType<Props>
40
47
  }
@@ -115,7 +122,7 @@ declare const Pagination: ComponentType<Props> & {
115
122
 
116
123
  export { default as QuantitySelector } from './QuantitySelector'
117
124
  export type { QuantitySelectorProps } from './QuantitySelector'
118
- export { default as BaseProvider } from './BaseProvider'
125
+
119
126
  declare const QuickLinks: ComponentType<Props> & {
120
127
  Item: ComponentType<Props>
121
128
  }