@telus-uds/components-web 2.32.2 → 2.33.1
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 +27 -2
- package/lib/Breadcrumbs/Breadcrumbs.js +9 -15
- package/lib/Breadcrumbs/Item/Item.js +2 -1
- package/lib/DatePicker/DatePicker.js +3 -2
- package/lib/NavigationBar/NavigationBar.js +26 -3
- package/lib/NavigationBar/NavigationSubMenu.js +6 -3
- package/lib-module/Breadcrumbs/Breadcrumbs.js +9 -15
- package/lib-module/Breadcrumbs/Item/Item.js +2 -1
- package/lib-module/DatePicker/DatePicker.js +3 -2
- package/lib-module/NavigationBar/NavigationBar.js +27 -4
- package/lib-module/NavigationBar/NavigationSubMenu.js +6 -3
- package/package.json +3 -3
- package/src/Breadcrumbs/Breadcrumbs.jsx +1 -2
- package/src/Breadcrumbs/Item/Item.jsx +2 -1
- package/src/DatePicker/DatePicker.jsx +3 -2
- package/src/NavigationBar/NavigationBar.jsx +43 -4
- package/src/NavigationBar/NavigationSubMenu.jsx +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,37 @@
|
|
|
1
1
|
# Change Log - @telus-uds/components-web
|
|
2
2
|
|
|
3
|
-
This log was last generated on Wed,
|
|
3
|
+
This log was last generated on Wed, 24 Apr 2024 16:28:55 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 2.33.1
|
|
8
|
+
|
|
9
|
+
Wed, 24 Apr 2024 16:28:55 GMT
|
|
10
|
+
|
|
11
|
+
### Patches
|
|
12
|
+
|
|
13
|
+
- DatePicker visual inconsistency fixed: when the selected date was outside the actual month, the date was highlighted in the calendar but the calendar still appeared in the actual month instead of the correct month. (35577399+JoshHC@users.noreply.github.com)
|
|
14
|
+
- vertical position fixed for the calendar in datepicker when scrolling (35577399+JoshHC@users.noreply.github.com)
|
|
15
|
+
- `NavigationSubMenu:` fix proptype (guillermo.peitzner@telus.com)
|
|
16
|
+
- `NavigationBar:` close menus when clicking outside the component (guillermo.peitzner@telus.com)
|
|
17
|
+
- Bump @telus-uds/components-base to v1.83.0
|
|
18
|
+
|
|
19
|
+
## 2.33.0
|
|
20
|
+
|
|
21
|
+
Fri, 05 Apr 2024 17:16:24 GMT
|
|
22
|
+
|
|
23
|
+
### Minor changes
|
|
24
|
+
|
|
25
|
+
- Bump @telus-uds/components-base to v1.82.0
|
|
26
|
+
- Bump @telus-uds/system-theme-tokens to v2.54.0
|
|
27
|
+
|
|
28
|
+
### Patches
|
|
29
|
+
|
|
30
|
+
- `Breadcrumbs`: fix text wrapping error (guillermo.peitzner@telus.com)
|
|
31
|
+
|
|
7
32
|
## 2.32.2
|
|
8
33
|
|
|
9
|
-
Wed, 27 Mar 2024 21:
|
|
34
|
+
Wed, 27 Mar 2024 21:13:10 GMT
|
|
10
35
|
|
|
11
36
|
### Patches
|
|
12
37
|
|
|
@@ -27,15 +27,9 @@ const StyledList = /*#__PURE__*/_styledComponents.default.ol.withConfig({
|
|
|
27
27
|
listStylePosition: 'inside',
|
|
28
28
|
margin: 0,
|
|
29
29
|
padding: 0,
|
|
30
|
-
alignItems: 'baseline'
|
|
31
|
-
height: _ref => {
|
|
32
|
-
let {
|
|
33
|
-
iconContainerSize
|
|
34
|
-
} = _ref;
|
|
35
|
-
return `${iconContainerSize}px`;
|
|
36
|
-
}
|
|
30
|
+
alignItems: 'baseline'
|
|
37
31
|
});
|
|
38
|
-
const omitProps =
|
|
32
|
+
const omitProps = _ref => {
|
|
39
33
|
let {
|
|
40
34
|
current,
|
|
41
35
|
path,
|
|
@@ -44,7 +38,7 @@ const omitProps = _ref2 => {
|
|
|
44
38
|
childRoutes,
|
|
45
39
|
component,
|
|
46
40
|
...props
|
|
47
|
-
} =
|
|
41
|
+
} = _ref;
|
|
48
42
|
return props;
|
|
49
43
|
};
|
|
50
44
|
const getBreadcrumbName = (item, params) => {
|
|
@@ -107,7 +101,7 @@ const getStructuredData = (items, baseUrl) => {
|
|
|
107
101
|
/**
|
|
108
102
|
* Display a hierarchy of links, commonly used for navigation.
|
|
109
103
|
*/
|
|
110
|
-
const Breadcrumbs =
|
|
104
|
+
const Breadcrumbs = _ref2 => {
|
|
111
105
|
let {
|
|
112
106
|
baseUrl,
|
|
113
107
|
children,
|
|
@@ -118,7 +112,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
118
112
|
variant,
|
|
119
113
|
LinkRouter,
|
|
120
114
|
...rest
|
|
121
|
-
} =
|
|
115
|
+
} = _ref2;
|
|
122
116
|
// React Helmet can cause a memory leak in SSR if not properly configured.
|
|
123
117
|
// Only run it in SSR if theme options tells us to.
|
|
124
118
|
/* const {
|
|
@@ -128,7 +122,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
128
122
|
// const isSSR = typeof window === 'undefined' || isHydrating
|
|
129
123
|
// const hasMetadata = isSSR ? enableHelmetSSR : true
|
|
130
124
|
const helmetContext = {};
|
|
131
|
-
const activeRoutes = children ? _react.default.Children.map((0, _componentsBase.unpackFragment)(children),
|
|
125
|
+
const activeRoutes = children ? _react.default.Children.map((0, _componentsBase.unpackFragment)(children), _ref3 => {
|
|
132
126
|
let {
|
|
133
127
|
props: {
|
|
134
128
|
href,
|
|
@@ -136,7 +130,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
136
130
|
...itemRest
|
|
137
131
|
},
|
|
138
132
|
ref
|
|
139
|
-
} =
|
|
133
|
+
} = _ref3;
|
|
140
134
|
return {
|
|
141
135
|
path: href,
|
|
142
136
|
breadcrumbName,
|
|
@@ -166,7 +160,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
166
160
|
...selectProps(rest),
|
|
167
161
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(StyledList, {
|
|
168
162
|
iconContainerSize: themeTokens.iconContainerSize,
|
|
169
|
-
children: items.map(
|
|
163
|
+
children: items.map(_ref4 => {
|
|
170
164
|
let {
|
|
171
165
|
href,
|
|
172
166
|
current,
|
|
@@ -174,7 +168,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
174
168
|
LinkRouter: ItemLinkRouter = LinkRouter,
|
|
175
169
|
linkRouterProps: itemLinkRouterProps,
|
|
176
170
|
...itemRest
|
|
177
|
-
} =
|
|
171
|
+
} = _ref4;
|
|
178
172
|
return /*#__PURE__*/(0, _react.createElement)(_Item.default, {
|
|
179
173
|
...itemRest,
|
|
180
174
|
current: current,
|
|
@@ -37,7 +37,8 @@ const StyledItemContainer = /*#__PURE__*/_styledComponents.default.li.withConfig
|
|
|
37
37
|
iconContainerSize
|
|
38
38
|
} = _ref3;
|
|
39
39
|
return `${iconContainerSize}px`;
|
|
40
|
-
}
|
|
40
|
+
},
|
|
41
|
+
marginBottom: '8px'
|
|
41
42
|
});
|
|
42
43
|
const IconContainer = /*#__PURE__*/_styledComponents.default.span.withConfig({
|
|
43
44
|
displayName: "Item__IconContainer",
|
|
@@ -131,9 +131,10 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref3, ref) => {
|
|
|
131
131
|
left,
|
|
132
132
|
top
|
|
133
133
|
} = textInputRef.current.getBoundingClientRect();
|
|
134
|
+
const inputTop = top + window.scrollY;
|
|
134
135
|
setDatePickerPosition({
|
|
135
136
|
left,
|
|
136
|
-
top:
|
|
137
|
+
top: inputTop + textInputRef.current.offsetHeight
|
|
137
138
|
});
|
|
138
139
|
};
|
|
139
140
|
const throttledUpdateDimensions = (0, _lodash.throttle)(updateDimensions, 100, {
|
|
@@ -308,7 +309,7 @@ const DatePicker = /*#__PURE__*/(0, _react.forwardRef)((_ref3, ref) => {
|
|
|
308
309
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DayPickerSingleDateController.default, {
|
|
309
310
|
date: inputDate,
|
|
310
311
|
onDateChange: onChange,
|
|
311
|
-
focused: isFocused,
|
|
312
|
+
focused: inputDate ?? isFocused,
|
|
312
313
|
onFocusChange: onFocusChange,
|
|
313
314
|
numberOfMonths: 1,
|
|
314
315
|
hideKeyboardShortcutsPanel: true,
|
|
@@ -70,27 +70,49 @@ const NavigationBar = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
|
70
70
|
setOpenSubMenuId(null);
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
|
+
const navRefDefault = (0, _react.useRef)(null);
|
|
74
|
+
const navRef = ref ?? navRefDefault;
|
|
75
|
+
const itemsRef = (0, _react.useRef)(null);
|
|
76
|
+
|
|
77
|
+
// Close the submenu when the user clicks outside the navigation bar
|
|
78
|
+
const handleMouseDown = (0, _react.useCallback)(event => {
|
|
79
|
+
if (navRef.current && itemsRef.current) {
|
|
80
|
+
// Get the bounding rectangles of the navigation bar and the items container
|
|
81
|
+
const navRect = navRef.current.getBoundingClientRect();
|
|
82
|
+
const itemsRect = itemsRef.current.getBoundingClientRect();
|
|
83
|
+
|
|
84
|
+
// Check if the click was outside the navigation bar and the items container
|
|
85
|
+
const isOutsideNav = event.clientX < navRect.left || event.clientX > navRect.right || event.clientY < navRect.top || event.clientY > navRect.bottom;
|
|
86
|
+
const isOutsideItems = event.clientX < itemsRect.left || event.clientX > itemsRect.right || event.clientY < itemsRect.top || event.clientY > itemsRect.bottom;
|
|
87
|
+
if (isOutsideNav && isOutsideItems) {
|
|
88
|
+
setOpenSubMenuId(null);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}, [navRef, itemsRef, setOpenSubMenuId]);
|
|
73
92
|
|
|
74
|
-
// Add listeners for mouse clicks outside and for ESCAPE key presses
|
|
75
93
|
// TODO: create a custom hook for that and use here and in the Footnote
|
|
76
94
|
(0, _react.useEffect)(() => {
|
|
95
|
+
// Add listeners for mouse clicks outside and for key presses
|
|
96
|
+
document.addEventListener('mousedown', handleMouseDown);
|
|
77
97
|
if (openSubMenuId !== null) {
|
|
78
98
|
window.addEventListener('click', handleSubMenuClose);
|
|
79
99
|
window.addEventListener('keydown', handleSubMenuClose);
|
|
80
100
|
window.addEventListener('touchstart', handleSubMenuClose);
|
|
81
101
|
}
|
|
82
102
|
return () => {
|
|
103
|
+
// Remove listeners when the component is unmounted
|
|
104
|
+
document.removeEventListener('mousedown', handleMouseDown);
|
|
83
105
|
if (openSubMenuId !== null) {
|
|
84
106
|
window.removeEventListener('click', handleSubMenuClose);
|
|
85
107
|
window.removeEventListener('keydown', handleSubMenuClose);
|
|
86
108
|
window.removeEventListener('touchstart', handleSubMenuClose);
|
|
87
109
|
}
|
|
88
110
|
};
|
|
89
|
-
}, [openSubMenuId]);
|
|
111
|
+
}, [openSubMenuId, handleMouseDown]);
|
|
90
112
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_componentsBase.StackView, {
|
|
91
113
|
accessibilityRole: accessibilityRole,
|
|
92
114
|
direction: direction,
|
|
93
|
-
ref:
|
|
115
|
+
ref: navRef,
|
|
94
116
|
space: 2,
|
|
95
117
|
tokens: {
|
|
96
118
|
alignItems: direction === 'column' ? 'flex-start' : 'center',
|
|
@@ -142,6 +164,7 @@ const NavigationBar = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
|
142
164
|
},
|
|
143
165
|
items: nestedItems,
|
|
144
166
|
selected: itemId === selectedId,
|
|
167
|
+
itemsContainerRef: itemsRef,
|
|
145
168
|
...itemRest,
|
|
146
169
|
...(nestedItems && {
|
|
147
170
|
isOpen
|
|
@@ -29,7 +29,8 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
29
29
|
items = [],
|
|
30
30
|
openOverlayRef,
|
|
31
31
|
LinkRouter,
|
|
32
|
-
linkRouterProps
|
|
32
|
+
linkRouterProps,
|
|
33
|
+
itemsContainerRef
|
|
33
34
|
} = _ref;
|
|
34
35
|
const focusTrapRef = (0, _react.useRef)();
|
|
35
36
|
const maxWidth = 289; // Slightly over 288 of nav item to account for subpixel rounding
|
|
@@ -131,7 +132,8 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
131
132
|
parentRef: sourceRef,
|
|
132
133
|
selectedId: selectedId,
|
|
133
134
|
LinkRouter: LinkRouter,
|
|
134
|
-
linkRouterProps: linkRouterProps
|
|
135
|
+
linkRouterProps: linkRouterProps,
|
|
136
|
+
ref: itemsContainerRef
|
|
135
137
|
})
|
|
136
138
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
137
139
|
// This catches and shifts focus to other interactive elements.
|
|
@@ -156,7 +158,8 @@ NavigationSubMenu.propTypes = {
|
|
|
156
158
|
items: _propTypes.default.array,
|
|
157
159
|
openOverlayRef: _propTypes.default.object,
|
|
158
160
|
LinkRouter: _propTypes.default.elementType,
|
|
159
|
-
linkRouterProps: _propTypes.default.object
|
|
161
|
+
linkRouterProps: _propTypes.default.object,
|
|
162
|
+
itemsContainerRef: _propTypes.default.object
|
|
160
163
|
};
|
|
161
164
|
var _default = NavigationSubMenu;
|
|
162
165
|
exports.default = _default;
|
|
@@ -20,15 +20,9 @@ const StyledList = /*#__PURE__*/styled.ol.withConfig({
|
|
|
20
20
|
listStylePosition: 'inside',
|
|
21
21
|
margin: 0,
|
|
22
22
|
padding: 0,
|
|
23
|
-
alignItems: 'baseline'
|
|
24
|
-
height: _ref => {
|
|
25
|
-
let {
|
|
26
|
-
iconContainerSize
|
|
27
|
-
} = _ref;
|
|
28
|
-
return `${iconContainerSize}px`;
|
|
29
|
-
}
|
|
23
|
+
alignItems: 'baseline'
|
|
30
24
|
});
|
|
31
|
-
const omitProps =
|
|
25
|
+
const omitProps = _ref => {
|
|
32
26
|
let {
|
|
33
27
|
current,
|
|
34
28
|
path,
|
|
@@ -37,7 +31,7 @@ const omitProps = _ref2 => {
|
|
|
37
31
|
childRoutes,
|
|
38
32
|
component,
|
|
39
33
|
...props
|
|
40
|
-
} =
|
|
34
|
+
} = _ref;
|
|
41
35
|
return props;
|
|
42
36
|
};
|
|
43
37
|
const getBreadcrumbName = (item, params) => {
|
|
@@ -100,7 +94,7 @@ const getStructuredData = (items, baseUrl) => {
|
|
|
100
94
|
/**
|
|
101
95
|
* Display a hierarchy of links, commonly used for navigation.
|
|
102
96
|
*/
|
|
103
|
-
const Breadcrumbs =
|
|
97
|
+
const Breadcrumbs = _ref2 => {
|
|
104
98
|
let {
|
|
105
99
|
baseUrl,
|
|
106
100
|
children,
|
|
@@ -111,7 +105,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
111
105
|
variant,
|
|
112
106
|
LinkRouter,
|
|
113
107
|
...rest
|
|
114
|
-
} =
|
|
108
|
+
} = _ref2;
|
|
115
109
|
// React Helmet can cause a memory leak in SSR if not properly configured.
|
|
116
110
|
// Only run it in SSR if theme options tells us to.
|
|
117
111
|
/* const {
|
|
@@ -121,7 +115,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
121
115
|
// const isSSR = typeof window === 'undefined' || isHydrating
|
|
122
116
|
// const hasMetadata = isSSR ? enableHelmetSSR : true
|
|
123
117
|
const helmetContext = {};
|
|
124
|
-
const activeRoutes = children ? React.Children.map(unpackFragment(children),
|
|
118
|
+
const activeRoutes = children ? React.Children.map(unpackFragment(children), _ref3 => {
|
|
125
119
|
let {
|
|
126
120
|
props: {
|
|
127
121
|
href,
|
|
@@ -129,7 +123,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
129
123
|
...itemRest
|
|
130
124
|
},
|
|
131
125
|
ref
|
|
132
|
-
} =
|
|
126
|
+
} = _ref3;
|
|
133
127
|
return {
|
|
134
128
|
path: href,
|
|
135
129
|
breadcrumbName,
|
|
@@ -159,7 +153,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
159
153
|
...selectProps(rest),
|
|
160
154
|
children: [/*#__PURE__*/_jsx(StyledList, {
|
|
161
155
|
iconContainerSize: themeTokens.iconContainerSize,
|
|
162
|
-
children: items.map(
|
|
156
|
+
children: items.map(_ref4 => {
|
|
163
157
|
let {
|
|
164
158
|
href,
|
|
165
159
|
current,
|
|
@@ -167,7 +161,7 @@ const Breadcrumbs = _ref3 => {
|
|
|
167
161
|
LinkRouter: ItemLinkRouter = LinkRouter,
|
|
168
162
|
linkRouterProps: itemLinkRouterProps,
|
|
169
163
|
...itemRest
|
|
170
|
-
} =
|
|
164
|
+
} = _ref4;
|
|
171
165
|
return /*#__PURE__*/_createElement(Item, {
|
|
172
166
|
...itemRest,
|
|
173
167
|
current: current,
|
|
@@ -30,7 +30,8 @@ const StyledItemContainer = /*#__PURE__*/styled.li.withConfig({
|
|
|
30
30
|
iconContainerSize
|
|
31
31
|
} = _ref3;
|
|
32
32
|
return `${iconContainerSize}px`;
|
|
33
|
-
}
|
|
33
|
+
},
|
|
34
|
+
marginBottom: '8px'
|
|
34
35
|
});
|
|
35
36
|
const IconContainer = /*#__PURE__*/styled.span.withConfig({
|
|
36
37
|
displayName: "Item__IconContainer",
|
|
@@ -124,9 +124,10 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref3, ref) => {
|
|
|
124
124
|
left,
|
|
125
125
|
top
|
|
126
126
|
} = textInputRef.current.getBoundingClientRect();
|
|
127
|
+
const inputTop = top + window.scrollY;
|
|
127
128
|
setDatePickerPosition({
|
|
128
129
|
left,
|
|
129
|
-
top:
|
|
130
|
+
top: inputTop + textInputRef.current.offsetHeight
|
|
130
131
|
});
|
|
131
132
|
};
|
|
132
133
|
const throttledUpdateDimensions = throttle(updateDimensions, 100, {
|
|
@@ -301,7 +302,7 @@ const DatePicker = /*#__PURE__*/forwardRef((_ref3, ref) => {
|
|
|
301
302
|
children: /*#__PURE__*/_jsx(DayPickerSingleDateController, {
|
|
302
303
|
date: inputDate,
|
|
303
304
|
onDateChange: onChange,
|
|
304
|
-
focused: isFocused,
|
|
305
|
+
focused: inputDate ?? isFocused,
|
|
305
306
|
onFocusChange: onFocusChange,
|
|
306
307
|
numberOfMonths: 1,
|
|
307
308
|
hideKeyboardShortcutsPanel: true,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var _withLinkRouter$propT, _withLinkRouter$propT2, _withLinkRouter$propT3, _withLinkRouter$propT4;
|
|
2
|
-
import React, { forwardRef, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import React, { forwardRef, useEffect, useRef, useState, useCallback } from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { selectSystemProps, StackView, Typography, useResponsiveProp, withLinkRouter, getTokensPropType } from '@telus-uds/components-base';
|
|
5
5
|
import styled from 'styled-components';
|
|
@@ -62,27 +62,49 @@ const NavigationBar = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
62
62
|
setOpenSubMenuId(null);
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
|
+
const navRefDefault = useRef(null);
|
|
66
|
+
const navRef = ref ?? navRefDefault;
|
|
67
|
+
const itemsRef = useRef(null);
|
|
68
|
+
|
|
69
|
+
// Close the submenu when the user clicks outside the navigation bar
|
|
70
|
+
const handleMouseDown = useCallback(event => {
|
|
71
|
+
if (navRef.current && itemsRef.current) {
|
|
72
|
+
// Get the bounding rectangles of the navigation bar and the items container
|
|
73
|
+
const navRect = navRef.current.getBoundingClientRect();
|
|
74
|
+
const itemsRect = itemsRef.current.getBoundingClientRect();
|
|
75
|
+
|
|
76
|
+
// Check if the click was outside the navigation bar and the items container
|
|
77
|
+
const isOutsideNav = event.clientX < navRect.left || event.clientX > navRect.right || event.clientY < navRect.top || event.clientY > navRect.bottom;
|
|
78
|
+
const isOutsideItems = event.clientX < itemsRect.left || event.clientX > itemsRect.right || event.clientY < itemsRect.top || event.clientY > itemsRect.bottom;
|
|
79
|
+
if (isOutsideNav && isOutsideItems) {
|
|
80
|
+
setOpenSubMenuId(null);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, [navRef, itemsRef, setOpenSubMenuId]);
|
|
65
84
|
|
|
66
|
-
// Add listeners for mouse clicks outside and for ESCAPE key presses
|
|
67
85
|
// TODO: create a custom hook for that and use here and in the Footnote
|
|
68
86
|
useEffect(() => {
|
|
87
|
+
// Add listeners for mouse clicks outside and for key presses
|
|
88
|
+
document.addEventListener('mousedown', handleMouseDown);
|
|
69
89
|
if (openSubMenuId !== null) {
|
|
70
90
|
window.addEventListener('click', handleSubMenuClose);
|
|
71
91
|
window.addEventListener('keydown', handleSubMenuClose);
|
|
72
92
|
window.addEventListener('touchstart', handleSubMenuClose);
|
|
73
93
|
}
|
|
74
94
|
return () => {
|
|
95
|
+
// Remove listeners when the component is unmounted
|
|
96
|
+
document.removeEventListener('mousedown', handleMouseDown);
|
|
75
97
|
if (openSubMenuId !== null) {
|
|
76
98
|
window.removeEventListener('click', handleSubMenuClose);
|
|
77
99
|
window.removeEventListener('keydown', handleSubMenuClose);
|
|
78
100
|
window.removeEventListener('touchstart', handleSubMenuClose);
|
|
79
101
|
}
|
|
80
102
|
};
|
|
81
|
-
}, [openSubMenuId]);
|
|
103
|
+
}, [openSubMenuId, handleMouseDown]);
|
|
82
104
|
return /*#__PURE__*/_jsxs(StackView, {
|
|
83
105
|
accessibilityRole: accessibilityRole,
|
|
84
106
|
direction: direction,
|
|
85
|
-
ref:
|
|
107
|
+
ref: navRef,
|
|
86
108
|
space: 2,
|
|
87
109
|
tokens: {
|
|
88
110
|
alignItems: direction === 'column' ? 'flex-start' : 'center',
|
|
@@ -134,6 +156,7 @@ const NavigationBar = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
134
156
|
},
|
|
135
157
|
items: nestedItems,
|
|
136
158
|
selected: itemId === selectedId,
|
|
159
|
+
itemsContainerRef: itemsRef,
|
|
137
160
|
...itemRest,
|
|
138
161
|
...(nestedItems && {
|
|
139
162
|
isOpen
|
|
@@ -24,7 +24,8 @@ const NavigationSubMenu = _ref => {
|
|
|
24
24
|
items = [],
|
|
25
25
|
openOverlayRef,
|
|
26
26
|
LinkRouter,
|
|
27
|
-
linkRouterProps
|
|
27
|
+
linkRouterProps,
|
|
28
|
+
itemsContainerRef
|
|
28
29
|
} = _ref;
|
|
29
30
|
const focusTrapRef = useRef();
|
|
30
31
|
const maxWidth = 289; // Slightly over 288 of nav item to account for subpixel rounding
|
|
@@ -126,7 +127,8 @@ const NavigationSubMenu = _ref => {
|
|
|
126
127
|
parentRef: sourceRef,
|
|
127
128
|
selectedId: selectedId,
|
|
128
129
|
LinkRouter: LinkRouter,
|
|
129
|
-
linkRouterProps: linkRouterProps
|
|
130
|
+
linkRouterProps: linkRouterProps,
|
|
131
|
+
ref: itemsContainerRef
|
|
130
132
|
})
|
|
131
133
|
}), /*#__PURE__*/_jsx("div", {
|
|
132
134
|
// This catches and shifts focus to other interactive elements.
|
|
@@ -151,6 +153,7 @@ NavigationSubMenu.propTypes = {
|
|
|
151
153
|
items: PropTypes.array,
|
|
152
154
|
openOverlayRef: PropTypes.object,
|
|
153
155
|
LinkRouter: PropTypes.elementType,
|
|
154
|
-
linkRouterProps: PropTypes.object
|
|
156
|
+
linkRouterProps: PropTypes.object,
|
|
157
|
+
itemsContainerRef: PropTypes.object
|
|
155
158
|
};
|
|
156
159
|
export default NavigationSubMenu;
|
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.
|
|
8
|
+
"@telus-uds/components-base": "1.83.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.
|
|
16
|
+
"@telus-uds/system-theme-tokens": "^2.54.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.
|
|
86
|
+
"version": "2.33.1"
|
|
87
87
|
}
|
|
@@ -17,7 +17,8 @@ const StyledItemContainer = styled.li({
|
|
|
17
17
|
display: 'flex',
|
|
18
18
|
paddingLeft: ({ listItemPadding }) => `${listItemPadding}px`,
|
|
19
19
|
lineHeight: ({ lineHeight, fontSize }) => `${Math.ceil(lineHeight * fontSize)}px`,
|
|
20
|
-
height: ({ iconContainerSize }) => `${iconContainerSize}px
|
|
20
|
+
height: ({ iconContainerSize }) => `${iconContainerSize}px`,
|
|
21
|
+
marginBottom: '8px'
|
|
21
22
|
})
|
|
22
23
|
|
|
23
24
|
const IconContainer = styled.span({
|
|
@@ -114,9 +114,10 @@ const DatePicker = forwardRef(
|
|
|
114
114
|
const updateDimensions = () => {
|
|
115
115
|
if (inline || !textInputRef.current) return
|
|
116
116
|
const { left, top } = textInputRef.current.getBoundingClientRect()
|
|
117
|
+
const inputTop = top + window.scrollY
|
|
117
118
|
setDatePickerPosition({
|
|
118
119
|
left,
|
|
119
|
-
top:
|
|
120
|
+
top: inputTop + textInputRef.current.offsetHeight
|
|
120
121
|
})
|
|
121
122
|
}
|
|
122
123
|
const throttledUpdateDimensions = throttle(updateDimensions, 100, { leading: false })
|
|
@@ -282,7 +283,7 @@ const DatePicker = forwardRef(
|
|
|
282
283
|
<DayPickerSingleDateController
|
|
283
284
|
date={inputDate}
|
|
284
285
|
onDateChange={onChange}
|
|
285
|
-
focused={isFocused}
|
|
286
|
+
focused={inputDate ?? isFocused}
|
|
286
287
|
onFocusChange={onFocusChange}
|
|
287
288
|
numberOfMonths={1}
|
|
288
289
|
hideKeyboardShortcutsPanel={true}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, useEffect, useRef, useState } from 'react'
|
|
1
|
+
import React, { forwardRef, useEffect, useRef, useState, useCallback } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import {
|
|
4
4
|
selectSystemProps,
|
|
@@ -69,28 +69,66 @@ const NavigationBar = forwardRef(
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
const navRefDefault = useRef(null)
|
|
73
|
+
const navRef = ref ?? navRefDefault
|
|
74
|
+
const itemsRef = useRef(null)
|
|
75
|
+
|
|
76
|
+
// Close the submenu when the user clicks outside the navigation bar
|
|
77
|
+
const handleMouseDown = useCallback(
|
|
78
|
+
(event) => {
|
|
79
|
+
if (navRef.current && itemsRef.current) {
|
|
80
|
+
// Get the bounding rectangles of the navigation bar and the items container
|
|
81
|
+
const navRect = navRef.current.getBoundingClientRect()
|
|
82
|
+
const itemsRect = itemsRef.current.getBoundingClientRect()
|
|
83
|
+
|
|
84
|
+
// Check if the click was outside the navigation bar and the items container
|
|
85
|
+
const isOutsideNav =
|
|
86
|
+
event.clientX < navRect.left ||
|
|
87
|
+
event.clientX > navRect.right ||
|
|
88
|
+
event.clientY < navRect.top ||
|
|
89
|
+
event.clientY > navRect.bottom
|
|
90
|
+
|
|
91
|
+
const isOutsideItems =
|
|
92
|
+
event.clientX < itemsRect.left ||
|
|
93
|
+
event.clientX > itemsRect.right ||
|
|
94
|
+
event.clientY < itemsRect.top ||
|
|
95
|
+
event.clientY > itemsRect.bottom
|
|
96
|
+
|
|
97
|
+
if (isOutsideNav && isOutsideItems) {
|
|
98
|
+
setOpenSubMenuId(null)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
[navRef, itemsRef, setOpenSubMenuId]
|
|
103
|
+
)
|
|
104
|
+
|
|
73
105
|
// TODO: create a custom hook for that and use here and in the Footnote
|
|
74
106
|
useEffect(() => {
|
|
107
|
+
// Add listeners for mouse clicks outside and for key presses
|
|
108
|
+
document.addEventListener('mousedown', handleMouseDown)
|
|
109
|
+
|
|
75
110
|
if (openSubMenuId !== null) {
|
|
76
111
|
window.addEventListener('click', handleSubMenuClose)
|
|
77
112
|
window.addEventListener('keydown', handleSubMenuClose)
|
|
78
113
|
window.addEventListener('touchstart', handleSubMenuClose)
|
|
79
114
|
}
|
|
80
115
|
return () => {
|
|
116
|
+
// Remove listeners when the component is unmounted
|
|
117
|
+
document.removeEventListener('mousedown', handleMouseDown)
|
|
118
|
+
|
|
81
119
|
if (openSubMenuId !== null) {
|
|
82
120
|
window.removeEventListener('click', handleSubMenuClose)
|
|
83
121
|
window.removeEventListener('keydown', handleSubMenuClose)
|
|
84
122
|
window.removeEventListener('touchstart', handleSubMenuClose)
|
|
85
123
|
}
|
|
86
124
|
}
|
|
87
|
-
}, [openSubMenuId])
|
|
125
|
+
}, [openSubMenuId, handleMouseDown])
|
|
88
126
|
|
|
89
127
|
return (
|
|
90
128
|
<StackView
|
|
91
129
|
accessibilityRole={accessibilityRole}
|
|
92
130
|
direction={direction}
|
|
93
|
-
ref={
|
|
131
|
+
ref={navRef}
|
|
94
132
|
space={2}
|
|
95
133
|
tokens={{
|
|
96
134
|
alignItems: direction === 'column' ? 'flex-start' : 'center',
|
|
@@ -145,6 +183,7 @@ const NavigationBar = forwardRef(
|
|
|
145
183
|
linkRouterProps={{ ...linkRouterProps, ...itemLinkRouterProps }}
|
|
146
184
|
items={nestedItems}
|
|
147
185
|
selected={itemId === selectedId}
|
|
186
|
+
itemsContainerRef={itemsRef}
|
|
148
187
|
{...itemRest}
|
|
149
188
|
{...(nestedItems && { isOpen })}
|
|
150
189
|
{...(nestedItems && isOpen && { openOverlayRef })}
|
|
@@ -20,7 +20,8 @@ const NavigationSubMenu = ({
|
|
|
20
20
|
items = [],
|
|
21
21
|
openOverlayRef,
|
|
22
22
|
LinkRouter,
|
|
23
|
-
linkRouterProps
|
|
23
|
+
linkRouterProps,
|
|
24
|
+
itemsContainerRef
|
|
24
25
|
}) => {
|
|
25
26
|
const focusTrapRef = useRef()
|
|
26
27
|
|
|
@@ -86,6 +87,7 @@ const NavigationSubMenu = ({
|
|
|
86
87
|
selectedId={selectedId}
|
|
87
88
|
LinkRouter={LinkRouter}
|
|
88
89
|
linkRouterProps={linkRouterProps}
|
|
90
|
+
ref={itemsContainerRef}
|
|
89
91
|
/>
|
|
90
92
|
</Listbox.Overlay>
|
|
91
93
|
<div
|
|
@@ -114,7 +116,8 @@ NavigationSubMenu.propTypes = {
|
|
|
114
116
|
items: PropTypes.array,
|
|
115
117
|
openOverlayRef: PropTypes.object,
|
|
116
118
|
LinkRouter: PropTypes.elementType,
|
|
117
|
-
linkRouterProps: PropTypes.object
|
|
119
|
+
linkRouterProps: PropTypes.object,
|
|
120
|
+
itemsContainerRef: PropTypes.object
|
|
118
121
|
}
|
|
119
122
|
|
|
120
123
|
export default NavigationSubMenu
|