@telus-uds/components-web 2.41.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.
@@ -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,
@@ -47,11 +47,14 @@ const StyledItemBase = /*#__PURE__*/styled(ItemBase).withConfig({
47
47
  counterIncrement: OL_COUNTER_NAME,
48
48
  '::before': {
49
49
  content: `counter(${OL_COUNTER_NAME})'.'`,
50
- display: 'inline-flex',
50
+ display: 'inline-block',
51
51
  color: itemColor || itemTextColor,
52
52
  width: itemBulletContainerWidth,
53
53
  paddingRight: listGutter,
54
- justifyContent: itemBulletTextAlign,
54
+ textAlign: itemBulletTextAlign,
55
+ flexShrink: 0,
56
+ whiteSpace: 'nowrap',
57
+ overflow: 'hidden',
55
58
  ...applyTextStyles({
56
59
  fontWeight: itemFontWeight,
57
60
  fontSize: itemFontSize,
@@ -69,7 +72,9 @@ const ItemContent = /*#__PURE__*/styled.div.withConfig({
69
72
  displayName: "Item__ItemContent",
70
73
  componentId: "components-web__sc-7jzwcq-1"
71
74
  })({
72
- flex: 1
75
+ display: 'flex',
76
+ flexDirection: 'column',
77
+ gap: 5
73
78
  });
74
79
  const Item = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
75
80
  let {
@@ -116,7 +121,9 @@ const Item = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
116
121
  ...themeTokens,
117
122
  children: itemContent
118
123
  })]
119
- }) : itemContent
124
+ }) : /*#__PURE__*/_jsx(ItemContent, {
125
+ children: itemContent
126
+ })
120
127
  });
121
128
  });
122
129
  Item.displayName = 'OrderedListItem';
@@ -12,64 +12,69 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs]);
12
12
  const PriceLockupContainer = /*#__PURE__*/styled.div.withConfig({
13
13
  displayName: "PriceLockup__PriceLockupContainer",
14
14
  componentId: "components-web__sc-1x6duay-0"
15
- })(["display:flex;flex-direction:column;width:fit-content;"]);
15
+ })(["align-items:", ";display:flex;flex-direction:column;width:fit-content;"], _ref => {
16
+ let {
17
+ alignItemsText
18
+ } = _ref;
19
+ return alignItemsText;
20
+ });
16
21
  const PriceContainer = /*#__PURE__*/styled.div.withConfig({
17
22
  displayName: "PriceLockup__PriceContainer",
18
23
  componentId: "components-web__sc-1x6duay-1"
19
- })(["display:flex;margin-bottom:", ";"], _ref => {
24
+ })(["display:flex;margin-bottom:", ";"], _ref2 => {
20
25
  let {
21
26
  priceMarginBottom
22
- } = _ref;
27
+ } = _ref2;
23
28
  return priceMarginBottom;
24
29
  });
25
30
  const FootnoteContainer = /*#__PURE__*/styled.div.withConfig({
26
31
  displayName: "PriceLockup__FootnoteContainer",
27
32
  componentId: "components-web__sc-1x6duay-2"
28
- })(["display:flex;margin-top:", ";gap:", ";"], _ref2 => {
33
+ })(["display:flex;margin-top:", ";gap:", ";"], _ref3 => {
29
34
  let {
30
35
  footnoteMarginTop
31
- } = _ref2;
36
+ } = _ref3;
32
37
  return footnoteMarginTop;
33
- }, _ref3 => {
38
+ }, _ref4 => {
34
39
  let {
35
40
  footnoteGap
36
- } = _ref3;
41
+ } = _ref4;
37
42
  return footnoteGap;
38
43
  });
39
44
  const BottomTextContainer = /*#__PURE__*/styled.div.withConfig({
40
45
  displayName: "PriceLockup__BottomTextContainer",
41
46
  componentId: "components-web__sc-1x6duay-3"
42
- })(["margin-top:", ";"], _ref4 => {
47
+ })(["margin-top:", ";"], _ref5 => {
43
48
  let {
44
49
  bottomTextMarginTop
45
- } = _ref4;
50
+ } = _ref5;
46
51
  return bottomTextMarginTop;
47
52
  });
48
53
  const BottomLinksContainer = /*#__PURE__*/styled.div.withConfig({
49
54
  displayName: "PriceLockup__BottomLinksContainer",
50
55
  componentId: "components-web__sc-1x6duay-4"
51
- })(["align-self:center;margin-left:", ";"], _ref5 => {
56
+ })(["align-self:center;margin-left:", ";"], _ref6 => {
52
57
  let {
53
58
  bottomLinksMarginLeft
54
- } = _ref5;
59
+ } = _ref6;
55
60
  return bottomLinksMarginLeft;
56
61
  });
57
62
  const TopTextContainer = /*#__PURE__*/styled.div.withConfig({
58
63
  displayName: "PriceLockup__TopTextContainer",
59
64
  componentId: "components-web__sc-1x6duay-5"
60
- })(["margin-bottom:", ";"], _ref6 => {
65
+ })(["margin-bottom:", ";"], _ref7 => {
61
66
  let {
62
67
  topTextMarginBottom
63
- } = _ref6;
68
+ } = _ref7;
64
69
  return topTextMarginBottom;
65
70
  });
66
71
  const PriceTextContainer = /*#__PURE__*/styled.div.withConfig({
67
72
  displayName: "PriceLockup__PriceTextContainer",
68
73
  componentId: "components-web__sc-1x6duay-6"
69
- })(["display:flex;flex-direction:", ";"], _ref7 => {
74
+ })(["display:flex;flex-direction:", ";"], _ref8 => {
70
75
  let {
71
76
  ratePosition
72
- } = _ref7;
77
+ } = _ref8;
73
78
  return ratePosition === 'bottom' ? 'column' : 'row';
74
79
  });
75
80
  const RateContainer = /*#__PURE__*/styled.div.withConfig({
@@ -79,38 +84,38 @@ const RateContainer = /*#__PURE__*/styled.div.withConfig({
79
84
  const RateTextContainer = /*#__PURE__*/styled.div.withConfig({
80
85
  displayName: "PriceLockup__RateTextContainer",
81
86
  componentId: "components-web__sc-1x6duay-8"
82
- })(["align-self:", ";"], _ref8 => {
87
+ })(["align-self:", ";"], _ref9 => {
83
88
  let {
84
89
  ratePosition
85
- } = _ref8;
90
+ } = _ref9;
86
91
  return ratePosition === 'bottom' ? 'flex-start' : 'flex-end';
87
92
  });
88
93
  const StrikeThroughContainer = /*#__PURE__*/styled.div.withConfig({
89
94
  displayName: "PriceLockup__StrikeThroughContainer",
90
95
  componentId: "components-web__sc-1x6duay-9"
91
- })(["display:flex;position:relative;align-items:center;::before{content:'';width:100%;top:", ";height:", ";background:", ";position:absolute;}"], _ref9 => {
96
+ })(["display:flex;position:relative;align-items:center;::before{content:'';width:100%;top:", ";height:", ";background:", ";position:absolute;}"], _ref10 => {
92
97
  let {
93
98
  strikeThroughPosition
94
- } = _ref9;
99
+ } = _ref10;
95
100
  return `${strikeThroughPosition}px`;
96
- }, _ref10 => {
101
+ }, _ref11 => {
97
102
  let {
98
103
  strikeThroughHeight
99
- } = _ref10;
104
+ } = _ref11;
100
105
  return `${strikeThroughHeight}px`;
101
- }, _ref11 => {
106
+ }, _ref12 => {
102
107
  let {
103
108
  strikeThroughColor
104
- } = _ref11;
109
+ } = _ref12;
105
110
  return strikeThroughColor;
106
111
  });
107
- const selectFootnoteLinkStyles = _ref12 => {
112
+ const selectFootnoteLinkStyles = _ref13 => {
108
113
  let {
109
114
  footnoteLinkColor,
110
115
  footnoteLinkFontName,
111
116
  footnoteLinkFontWeight,
112
117
  footnoteLinkLineHeight
113
- } = _ref12;
118
+ } = _ref13;
114
119
  return {
115
120
  color: footnoteLinkColor,
116
121
  fontName: footnoteLinkFontName,
@@ -118,19 +123,19 @@ const selectFootnoteLinkStyles = _ref12 => {
118
123
  lineHeight: footnoteLinkLineHeight
119
124
  };
120
125
  };
121
- const selectStrikeThroughTokens = _ref13 => {
126
+ const selectStrikeThroughTokens = _ref14 => {
122
127
  let {
123
128
  strikeThroughPosition,
124
129
  strikeThroughHeight,
125
130
  strikeThroughColor
126
- } = _ref13;
131
+ } = _ref14;
127
132
  return {
128
133
  strikeThroughHeight,
129
134
  strikeThroughPosition,
130
135
  strikeThroughColor
131
136
  };
132
137
  };
133
- const PriceLockup = /*#__PURE__*/React.forwardRef((_ref14, ref) => {
138
+ const PriceLockup = /*#__PURE__*/React.forwardRef((_ref15, ref) => {
134
139
  let {
135
140
  size = 'medium',
136
141
  signDirection = 'left',
@@ -147,7 +152,7 @@ const PriceLockup = /*#__PURE__*/React.forwardRef((_ref14, ref) => {
147
152
  tokens: priceLockupTokens,
148
153
  variant = {},
149
154
  ...rest
150
- } = _ref14;
155
+ } = _ref15;
151
156
  const viewport = useViewport();
152
157
  const {
153
158
  footnoteMarginTop,
@@ -159,6 +164,7 @@ const PriceLockup = /*#__PURE__*/React.forwardRef((_ref14, ref) => {
159
164
  fontColor,
160
165
  dividerColor,
161
166
  footnoteLinkFontSize,
167
+ alignItemsText,
162
168
  ...themeTokens
163
169
  } = useThemeTokens('PriceLockup', priceLockupTokens, {
164
170
  ...variant,
@@ -252,6 +258,7 @@ const PriceLockup = /*#__PURE__*/React.forwardRef((_ref14, ref) => {
252
258
  }
253
259
  return /*#__PURE__*/_jsxs(PriceLockupContainer, {
254
260
  ...selectProps(rest),
261
+ alignItemsText: alignItemsText,
255
262
  ref: ref,
256
263
  children: [topText && /*#__PURE__*/_jsx(TopTextContainer, {
257
264
  topTextMarginBottom: `${topTextMarginBottom}px`,
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { getTokensPropType, Progress, selectSystemProps, useThemeTokens, a11yProps, viewProps, variantProp } from '@telus-uds/components-base';
3
+ import { getTokensPropType, Progress, selectSystemProps, useThemeTokens, a11yProps, viewProps, variantProp, applyShadowToken } from '@telus-uds/components-base';
4
4
  import styled from 'styled-components';
5
5
 
6
6
  // Passes React Native-oriented system props through UDS Progress
@@ -16,20 +16,20 @@ const Gradient = /*#__PURE__*/styled.div.attrs({
16
16
  componentId: "components-web__sc-1vmzyq5-0"
17
17
  })(_ref => {
18
18
  let {
19
- percentage,
20
19
  gradient: {
21
20
  angle,
22
21
  stops,
23
22
  type
24
- }
23
+ },
24
+ borderRadius,
25
+ shadow
25
26
  } = _ref;
26
27
  return {
27
28
  height: '100%',
28
- // As per the design specs, we need to have the gradient expanding to 100% and being
29
- // revealed by bar width, so we need to stretch it beyond the parent (progress element)
30
- // to the full length of the progress bar
31
- width: `${100 * 100 / percentage}%`,
32
- background: `${type}-gradient(${angle}deg, ${stops[0].color}, ${stops[1].color})`
29
+ width: '100%',
30
+ background: `${type}-gradient(${angle}deg, ${stops[0].color}, ${stops[1].color})`,
31
+ borderRadius,
32
+ ...applyShadowToken(shadow)
33
33
  };
34
34
  });
35
35
 
@@ -60,8 +60,7 @@ const ProgressBar = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
60
60
  ref: ref,
61
61
  ...selectedProps,
62
62
  children: themeTokens.gradient && /*#__PURE__*/_jsx(Gradient, {
63
- ...themeTokens,
64
- percentage: percentage
63
+ ...themeTokens
65
64
  })
66
65
  });
67
66
  });
@@ -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
  };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import styled from 'styled-components';
4
- import { Box, Divider, selectSystemProps, Typography, useCopy, useThemeTokens, useViewport, getTokensPropType } from '@telus-uds/components-base';
4
+ import { Box, Divider, selectSystemProps, Typography, useCopy, useThemeTokens, useViewport, getTokensPropType, useTheme, useResponsiveThemeTokens, createMediaQueryStyles, StyleSheet } from '@telus-uds/components-base';
5
5
  import ExpandCollapse from './ExpandCollapse';
6
6
  import OrderedListBase from '../OrderedList/OrderedListBase';
7
7
  import { htmlAttrs, media, renderStructuredContent } from '../utils';
@@ -116,9 +116,60 @@ const TermsAndConditions = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
116
116
  const hasIndexedContent = indexedContent.length > 0;
117
117
  const hasNonIndexedContent = nonIndexedContent.length > 0;
118
118
  const viewport = useViewport();
119
- const themeTokens = useThemeTokens('TermsAndConditions', tokens, variant, {
119
+ const {
120
+ themeOptions
121
+ } = useTheme();
122
+ const {
123
+ enableMediaQueryStyleSheet
124
+ } = themeOptions;
125
+ const useTokens = enableMediaQueryStyleSheet ? useResponsiveThemeTokens : useThemeTokens;
126
+ const themeTokens = useTokens('TermsAndConditions', tokens, variant, !enableMediaQueryStyleSheet && {
120
127
  viewport
121
128
  });
129
+ let listItemStyles;
130
+ let listItemMediaIds;
131
+ let nonIndexedContentStyles;
132
+ let nonIndexedContentMediaIds;
133
+ if (enableMediaQueryStyleSheet) {
134
+ const {
135
+ transformedListItemThemeTokens,
136
+ transformedNonIndexedContentThemeTokens
137
+ } = Object.entries(themeTokens).reduce((acc, _ref7) => {
138
+ let [vp, viewportTokens] = _ref7;
139
+ acc.transformedListItemThemeTokens[vp] = {
140
+ marginLeft: viewportTokens.listMarginLeft
141
+ };
142
+ acc.transformedNonIndexedContentThemeTokens[vp] = {
143
+ paddingLeft: viewportTokens.titlePaddingLeft
144
+ };
145
+ return acc;
146
+ }, {
147
+ transformedListItemThemeTokens: {},
148
+ transformedNonIndexedContentThemeTokens: {}
149
+ });
150
+ const listItemMediaQueryStyles = createMediaQueryStyles(transformedListItemThemeTokens);
151
+ const nonIndexedContentMediaQueryStyles = createMediaQueryStyles(transformedNonIndexedContentThemeTokens);
152
+ const {
153
+ ids,
154
+ styles
155
+ } = StyleSheet.create({
156
+ listItem: {
157
+ ...themeTokens[viewport],
158
+ ...listItemMediaQueryStyles
159
+ },
160
+ nonIndexedContent: {
161
+ ...themeTokens[viewport],
162
+ ...nonIndexedContentMediaQueryStyles
163
+ }
164
+ });
165
+ listItemStyles = styles.listItem;
166
+ listItemMediaIds = ids.listItem;
167
+ nonIndexedContentStyles = styles.nonIndexedContent;
168
+ nonIndexedContentMediaIds = ids.nonIndexedContent;
169
+ } else {
170
+ listItemStyles = themeTokens;
171
+ nonIndexedContentStyles = themeTokens;
172
+ }
122
173
  return /*#__PURE__*/_jsxs("div", {
123
174
  ...selectProps(rest),
124
175
  children: [/*#__PURE__*/_jsx(Divider, {
@@ -139,13 +190,15 @@ const TermsAndConditions = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
139
190
  /*#__PURE__*/
140
191
  // eslint-disable-next-line react/no-array-index-key
141
192
  _jsx(ListItem, {
142
- tokens: themeTokens,
193
+ tokens: listItemStyles,
194
+ media: listItemMediaIds,
143
195
  children: renderStructuredContent(contentItem)
144
196
  }, idx))
145
197
  }), hasNonIndexedContent && /*#__PURE__*/_jsxs(Box, {
146
198
  between: 3,
147
199
  children: [/*#__PURE__*/_jsx(NonIndexedContentTitle, {
148
- tokens: themeTokens,
200
+ tokens: nonIndexedContentStyles,
201
+ media: nonIndexedContentMediaIds,
149
202
  children: /*#__PURE__*/_jsx(Typography, {
150
203
  block: true,
151
204
  heading: true,
@@ -163,7 +216,8 @@ const TermsAndConditions = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
163
216
  /*#__PURE__*/
164
217
  // eslint-disable-next-line react/no-array-index-key
165
218
  _jsx(ListItem, {
166
- tokens: themeTokens,
219
+ tokens: listItemStyles,
220
+ media: listItemMediaIds,
167
221
  children: renderStructuredContent(contentItem)
168
222
  }, idx))
169
223
  })]
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.95.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.64.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.41.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)}