@telus-uds/components-base 1.82.0 → 1.83.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,25 @@
1
1
  # Change Log - @telus-uds/components-base
2
2
 
3
- This log was last generated on Fri, 05 Apr 2024 17:10:34 GMT and should not be manually modified.
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
+ ## 1.83.0
8
+
9
+ Wed, 24 Apr 2024 16:28:55 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - Radio: Allow React node along with string labels for label prop (35577399+JoshHC@users.noreply.github.com)
14
+ - `Listbox:` add ref prop (guillermo.peitzner@telus.com)
15
+
16
+ ### Patches
17
+
18
+ - Notification: fix justify-content not being reflected. (evander.owusu@telus.com)
19
+
7
20
  ## 1.82.0
8
21
 
9
- Fri, 05 Apr 2024 17:10:34 GMT
22
+ Fri, 05 Apr 2024 17:16:24 GMT
10
23
 
11
24
  ### Minor changes
12
25
 
@@ -27,7 +27,7 @@ const styles = _StyleSheet.default.create({
27
27
  }
28
28
  });
29
29
  const getInitialOpen = (items, selectedId) => items.filter(item => item.items && item.items.some(nestedItem => (nestedItem.id ?? nestedItem.label) === selectedId)).map(item => item.id ?? item.label);
30
- const Listbox = _ref => {
30
+ const Listbox = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
31
31
  let {
32
32
  items = [],
33
33
  firstItemRef = null,
@@ -106,6 +106,7 @@ const Listbox = _ref => {
106
106
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ExpandCollapse.default, {
107
107
  initialOpen: initialOpen,
108
108
  maxOpen: 1,
109
+ ref: ref,
109
110
  children: expandProps => /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
110
111
  style: [styles.list, {
111
112
  minHeight,
@@ -121,9 +122,9 @@ const Listbox = _ref => {
121
122
  const itemId = id ?? label;
122
123
 
123
124
  // Give the list of refs.
124
- const itemRef = ref => {
125
- itemRefs.current[index] = ref;
126
- return ref;
125
+ const itemRef = currentItemRef => {
126
+ itemRefs.current[index] = currentItemRef;
127
+ return currentItemRef;
127
128
  };
128
129
  return nestedItems ? /*#__PURE__*/(0, _react.createElement)(_ListboxGroup.default, {
129
130
  ...item,
@@ -148,7 +149,8 @@ const Listbox = _ref => {
148
149
  })
149
150
  })
150
151
  });
151
- };
152
+ });
153
+ Listbox.displayName = 'Listbox';
152
154
  Listbox.propTypes = {
153
155
  ..._utils.withLinkRouter.propTypes,
154
156
  tokens: (0, _utils.getTokensPropType)('Listbox'),
@@ -72,7 +72,7 @@ const selectDismissButtonContainerStyles = _ref4 => {
72
72
  };
73
73
  };
74
74
  const selectContentContainerStyle = maxWidth => ({
75
- width: maxWidth || '100%'
75
+ maxWidth: maxWidth || '100%'
76
76
  });
77
77
  const getMediaQueryStyles = (themeTokens, themeOptions, viewport, mediaIdsRef, dismissible) => {
78
78
  const transformedSelectContainerStyles = Object.entries(themeTokens).reduce((acc, _ref5) => {
@@ -248,7 +248,7 @@ Radio.propTypes = {
248
248
  /**
249
249
  * The label.
250
250
  */
251
- label: _propTypes.default.string,
251
+ label: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.node]),
252
252
  /**
253
253
  * Associate this radio button with a group (set as the name attribute).
254
254
  */
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react';
1
+ import React, { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import View from "react-native-web/dist/exports/View";
4
4
  import StyleSheet from "react-native-web/dist/exports/StyleSheet";
@@ -19,7 +19,7 @@ const styles = StyleSheet.create({
19
19
  }
20
20
  });
21
21
  const getInitialOpen = (items, selectedId) => items.filter(item => item.items && item.items.some(nestedItem => (nestedItem.id ?? nestedItem.label) === selectedId)).map(item => item.id ?? item.label);
22
- const Listbox = _ref => {
22
+ const Listbox = /*#__PURE__*/forwardRef((_ref, ref) => {
23
23
  let {
24
24
  items = [],
25
25
  firstItemRef = null,
@@ -98,6 +98,7 @@ const Listbox = _ref => {
98
98
  children: /*#__PURE__*/_jsx(ExpandCollapse, {
99
99
  initialOpen: initialOpen,
100
100
  maxOpen: 1,
101
+ ref: ref,
101
102
  children: expandProps => /*#__PURE__*/_jsx(View, {
102
103
  style: [styles.list, {
103
104
  minHeight,
@@ -113,9 +114,9 @@ const Listbox = _ref => {
113
114
  const itemId = id ?? label;
114
115
 
115
116
  // Give the list of refs.
116
- const itemRef = ref => {
117
- itemRefs.current[index] = ref;
118
- return ref;
117
+ const itemRef = currentItemRef => {
118
+ itemRefs.current[index] = currentItemRef;
119
+ return currentItemRef;
119
120
  };
120
121
  return nestedItems ? /*#__PURE__*/_createElement(ListboxGroup, {
121
122
  ...item,
@@ -140,7 +141,8 @@ const Listbox = _ref => {
140
141
  })
141
142
  })
142
143
  });
143
- };
144
+ });
145
+ Listbox.displayName = 'Listbox';
144
146
  Listbox.propTypes = {
145
147
  ...withLinkRouter.propTypes,
146
148
  tokens: getTokensPropType('Listbox'),
@@ -64,7 +64,7 @@ const selectDismissButtonContainerStyles = _ref4 => {
64
64
  };
65
65
  };
66
66
  const selectContentContainerStyle = maxWidth => ({
67
- width: maxWidth || '100%'
67
+ maxWidth: maxWidth || '100%'
68
68
  });
69
69
  const getMediaQueryStyles = (themeTokens, themeOptions, viewport, mediaIdsRef, dismissible) => {
70
70
  const transformedSelectContainerStyles = Object.entries(themeTokens).reduce((acc, _ref5) => {
@@ -240,7 +240,7 @@ Radio.propTypes = {
240
240
  /**
241
241
  * The label.
242
242
  */
243
- label: PropTypes.string,
243
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
244
244
  /**
245
245
  * Associate this radio button with a group (set as the name attribute).
246
246
  */
package/package.json CHANGED
@@ -85,6 +85,6 @@
85
85
  "standard-engine": {
86
86
  "skip": true
87
87
  },
88
- "version": "1.82.0",
88
+ "version": "1.83.0",
89
89
  "types": "types/index.d.ts"
90
90
  }
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react'
1
+ import React, { forwardRef, useCallback, useEffect, useRef, useState } from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { View, StyleSheet, Platform } from 'react-native'
4
4
  import { useThemeTokens } from '../ThemeProvider'
@@ -25,119 +25,126 @@ const getInitialOpen = (items, selectedId) =>
25
25
  )
26
26
  .map((item) => item.id ?? item.label)
27
27
 
28
- const Listbox = ({
29
- items = [],
30
- firstItemRef = null, // focus will be moved to this one once within the menu
31
- parentRef = null, // to return focus to after leaving the last menu item
32
- selectedId: defaultSelectedId,
33
- LinkRouter,
34
- itemRouterProps,
35
- onClose,
36
- variant,
37
- tokens
38
- }) => {
39
- const initialOpen = getInitialOpen(items, defaultSelectedId)
28
+ const Listbox = forwardRef(
29
+ (
30
+ {
31
+ items = [],
32
+ firstItemRef = null, // focus will be moved to this one once within the menu
33
+ parentRef = null, // to return focus to after leaving the last menu item
34
+ selectedId: defaultSelectedId,
35
+ LinkRouter,
36
+ itemRouterProps,
37
+ onClose,
38
+ variant,
39
+ tokens
40
+ },
41
+ ref
42
+ ) => {
43
+ const initialOpen = getInitialOpen(items, defaultSelectedId)
40
44
 
41
- const [selectedId, setSelectedId] = useState(defaultSelectedId)
45
+ const [selectedId, setSelectedId] = useState(defaultSelectedId)
42
46
 
43
- const { minHeight, minWidth } = useThemeTokens('Listbox', variant, tokens)
47
+ const { minHeight, minWidth } = useThemeTokens('Listbox', variant, tokens)
44
48
 
45
- // We need to keep track of each item's ref in order to be able to
46
- // focus on a specific item via keyboard navigation
47
- const itemRefs = useRef([])
48
- if (firstItemRef?.current) itemRefs.current[0] = firstItemRef.current
49
- const [focusedIndex, setFocusedIndex] = useState(0)
50
- const handleKeydown = useCallback(
51
- (event) => {
52
- const nextItemRef = itemRefs.current[focusedIndex + 1]
53
- const prevItemRef = itemRefs.current[focusedIndex - 1]
54
- if (event.key === 'ArrowUp' || (event.shiftKey && event.key === 'Tab')) {
55
- // Move the focus to the previous item or to the parent one if on the first
56
- if (prevItemRef) {
49
+ // We need to keep track of each item's ref in order to be able to
50
+ // focus on a specific item via keyboard navigation
51
+ const itemRefs = useRef([])
52
+ if (firstItemRef?.current) itemRefs.current[0] = firstItemRef.current
53
+ const [focusedIndex, setFocusedIndex] = useState(0)
54
+ const handleKeydown = useCallback(
55
+ (event) => {
56
+ const nextItemRef = itemRefs.current[focusedIndex + 1]
57
+ const prevItemRef = itemRefs.current[focusedIndex - 1]
58
+ if (event.key === 'ArrowUp' || (event.shiftKey && event.key === 'Tab')) {
59
+ // Move the focus to the previous item or to the parent one if on the first
60
+ if (prevItemRef) {
61
+ event.preventDefault()
62
+ prevItemRef.focus()
63
+ } else if (parentRef) parentRef.current?.focus()
64
+ setFocusedIndex(focusedIndex - 1)
65
+ } else if ((event.key === 'ArrowDown' || event.key === 'Tab') && nextItemRef) {
57
66
  event.preventDefault()
58
- prevItemRef.focus()
59
- } else if (parentRef) parentRef.current?.focus()
60
- setFocusedIndex(focusedIndex - 1)
61
- } else if ((event.key === 'ArrowDown' || event.key === 'Tab') && nextItemRef) {
62
- event.preventDefault()
63
- setFocusedIndex(focusedIndex + 1)
64
- nextItemRef.focus()
65
- } else if (event.key === 'Escape') {
66
- // Close the dropdown
67
- parentRef?.current?.click()
68
- // Return focus to the dropdown control after leaving the last item
69
- parentRef?.current?.focus()
70
- if (onClose) onClose(event)
71
- } else if (!nextItemRef && firstItemRef) {
72
- // If the last item is focused, move the focus to the first one
73
- event.preventDefault()
74
- setFocusedIndex(0)
75
- firstItemRef.current?.focus()
76
- }
77
- },
78
- [focusedIndex, onClose, parentRef, firstItemRef]
79
- )
67
+ setFocusedIndex(focusedIndex + 1)
68
+ nextItemRef.focus()
69
+ } else if (event.key === 'Escape') {
70
+ // Close the dropdown
71
+ parentRef?.current?.click()
72
+ // Return focus to the dropdown control after leaving the last item
73
+ parentRef?.current?.focus()
74
+ if (onClose) onClose(event)
75
+ } else if (!nextItemRef && firstItemRef) {
76
+ // If the last item is focused, move the focus to the first one
77
+ event.preventDefault()
78
+ setFocusedIndex(0)
79
+ firstItemRef.current?.focus()
80
+ }
81
+ },
82
+ [focusedIndex, onClose, parentRef, firstItemRef]
83
+ )
80
84
 
81
- // Add listeners for mouse clicks outside and for key presses
82
- useEffect(() => {
83
- if (Platform.OS === 'web') {
84
- window.addEventListener('click', onClose)
85
- window.addEventListener('keydown', handleKeydown)
86
- window.addEventListener('touchstart', onClose)
87
- return () => {
88
- window.removeEventListener('click', onClose)
89
- window.removeEventListener('keydown', handleKeydown)
90
- window.removeEventListener('touchstart', onClose)
85
+ // Add listeners for mouse clicks outside and for key presses
86
+ useEffect(() => {
87
+ if (Platform.OS === 'web') {
88
+ window.addEventListener('click', onClose)
89
+ window.addEventListener('keydown', handleKeydown)
90
+ window.addEventListener('touchstart', onClose)
91
+ return () => {
92
+ window.removeEventListener('click', onClose)
93
+ window.removeEventListener('keydown', handleKeydown)
94
+ window.removeEventListener('touchstart', onClose)
95
+ }
91
96
  }
92
- }
93
- return () => {}
94
- }, [onClose, handleKeydown])
97
+ return () => {}
98
+ }, [onClose, handleKeydown])
95
99
 
96
- return (
97
- <ListboxContext.Provider value={{ selectedId, setSelectedId }}>
98
- <ExpandCollapse initialOpen={initialOpen} maxOpen={1}>
99
- {(expandProps) => (
100
- <View style={[styles.list, { minHeight, minWidth }]} role="listbox">
101
- {items.map((item, index) => {
102
- const { id, label, items: nestedItems } = item
103
- const itemId = id ?? label
100
+ return (
101
+ <ListboxContext.Provider value={{ selectedId, setSelectedId }}>
102
+ <ExpandCollapse initialOpen={initialOpen} maxOpen={1} ref={ref}>
103
+ {(expandProps) => (
104
+ <View style={[styles.list, { minHeight, minWidth }]} role="listbox">
105
+ {items.map((item, index) => {
106
+ const { id, label, items: nestedItems } = item
107
+ const itemId = id ?? label
104
108
 
105
- // Give the list of refs.
106
- const itemRef = (ref) => {
107
- itemRefs.current[index] = ref
108
- return ref
109
- }
109
+ // Give the list of refs.
110
+ const itemRef = (currentItemRef) => {
111
+ itemRefs.current[index] = currentItemRef
112
+ return currentItemRef
113
+ }
110
114
 
111
- return nestedItems ? (
112
- <ListboxGroup
113
- {...item}
114
- expandProps={expandProps}
115
- LinkRouter={LinkRouter}
116
- itemRouterProps={itemRouterProps}
117
- prevItemRef={itemRefs.current[index - 1] ?? null}
118
- nextItemRef={itemRefs.current[index + 1] ?? null}
119
- ref={index === 0 ? firstItemRef : itemRef}
120
- key={itemId}
121
- />
122
- ) : (
123
- <ListboxItem
124
- {...item}
125
- key={itemId}
126
- id={itemId}
127
- LinkRouter={LinkRouter}
128
- itemRouterProps={itemRouterProps}
129
- prevItemRef={itemRefs.current[index - 1] ?? null}
130
- nextItemRef={itemRefs.current[index + 1] ?? null}
131
- ref={index === 0 ? firstItemRef : itemRef}
132
- />
133
- )
134
- })}
135
- </View>
136
- )}
137
- </ExpandCollapse>
138
- </ListboxContext.Provider>
139
- )
140
- }
115
+ return nestedItems ? (
116
+ <ListboxGroup
117
+ {...item}
118
+ expandProps={expandProps}
119
+ LinkRouter={LinkRouter}
120
+ itemRouterProps={itemRouterProps}
121
+ prevItemRef={itemRefs.current[index - 1] ?? null}
122
+ nextItemRef={itemRefs.current[index + 1] ?? null}
123
+ ref={index === 0 ? firstItemRef : itemRef}
124
+ key={itemId}
125
+ />
126
+ ) : (
127
+ <ListboxItem
128
+ {...item}
129
+ key={itemId}
130
+ id={itemId}
131
+ LinkRouter={LinkRouter}
132
+ itemRouterProps={itemRouterProps}
133
+ prevItemRef={itemRefs.current[index - 1] ?? null}
134
+ nextItemRef={itemRefs.current[index + 1] ?? null}
135
+ ref={index === 0 ? firstItemRef : itemRef}
136
+ />
137
+ )
138
+ })}
139
+ </View>
140
+ )}
141
+ </ExpandCollapse>
142
+ </ListboxContext.Provider>
143
+ )
144
+ }
145
+ )
146
+
147
+ Listbox.displayName = 'Listbox'
141
148
 
142
149
  Listbox.propTypes = {
143
150
  ...withLinkRouter.propTypes,
@@ -65,7 +65,7 @@ const selectDismissButtonContainerStyles = ({ dismissButtonGap }) => ({
65
65
  })
66
66
 
67
67
  const selectContentContainerStyle = (maxWidth) => ({
68
- width: maxWidth || '100%'
68
+ maxWidth: maxWidth || '100%'
69
69
  })
70
70
 
71
71
  const getMediaQueryStyles = (themeTokens, themeOptions, viewport, mediaIdsRef, dismissible) => {
@@ -247,7 +247,7 @@ Radio.propTypes = {
247
247
  /**
248
248
  * The label.
249
249
  */
250
- label: PropTypes.string,
250
+ label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
251
251
  /**
252
252
  * Associate this radio button with a group (set as the name attribute).
253
253
  */