@telus-uds/components-base 2.4.0 → 2.5.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 +15 -2
- package/lib/A11yInfoProvider/index.js +2 -2
- package/lib/Autocomplete/Autocomplete.js +22 -32
- package/lib/Autocomplete/Suggestions.js +1 -1
- package/lib/BaseProvider/HydrationContext.js +1 -2
- package/lib/BaseProvider/index.js +1 -2
- package/lib/Button/ButtonDropdown.js +1 -1
- package/lib/Card/Card.js +12 -13
- package/lib/Card/CardBase.js +1 -1
- package/lib/Card/PressableCardBase.js +1 -1
- package/lib/CardGroup/CardGroup.js +3 -3
- package/lib/Carousel/Carousel.js +5 -6
- package/lib/Carousel/CarouselStepTracker/CarouselStepTracker.js +3 -0
- package/lib/Carousel/CarouselTabs/CarouselTabs.js +1 -2
- package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +1 -1
- package/lib/Carousel/CarouselTabs/CarouselTabsPanelItem.js +1 -1
- package/lib/Carousel/CarouselThumbnail.js +1 -1
- package/lib/Checkbox/Checkbox.js +1 -1
- package/lib/ColourToggle/ColourToggle.js +1 -1
- package/lib/ExpandCollapseMini/ExpandCollapseMini.js +77 -0
- package/lib/ExpandCollapseMini/ExpandCollapseMiniControl.js +126 -0
- package/lib/ExpandCollapseMini/index.js +2 -0
- package/lib/Footnote/Footnote.js +4 -4
- package/lib/HorizontalScroll/HorizontalScroll.js +1 -2
- package/lib/Icon/Icon.js +1 -1
- package/lib/Icon/IconText.js +2 -3
- package/lib/IconButton/IconButton.js +1 -2
- package/lib/InputSupports/InputSupports.js +4 -4
- package/lib/Link/LinkBase.js +8 -3
- package/lib/List/List.js +1 -2
- package/lib/List/ListItemContent.js +1 -1
- package/lib/Listbox/Listbox.js +5 -8
- package/lib/Listbox/PressableItem.js +4 -4
- package/lib/Modal/Modal.js +4 -7
- package/lib/MultiSelectFilter/MultiSelectFilter.js +1 -1
- package/lib/Notification/Notification.js +10 -12
- package/lib/OrderedList/OrderedList.js +2 -3
- package/lib/Pagination/usePagination.js +1 -2
- package/lib/PriceLockup/utils/renderFootnoteContent.js +2 -2
- package/lib/PriceLockup/utils/renderFootnoteLinks.js +2 -2
- package/lib/PriceLockup/utils/renderPrice.js +2 -2
- package/lib/ProductCard/ProductCard.js +2 -3
- package/lib/Progress/ProgressBarBackground.js +2 -2
- package/lib/QuickLinksFeature/QuickLinksFeature.js +1 -2
- package/lib/Radio/Radio.js +1 -1
- package/lib/Search/Search.js +2 -3
- package/lib/Select/Picker.js +2 -2
- package/lib/StackView/StackWrap.js +1 -4
- package/lib/StackView/getStackedContent.js +1 -2
- package/lib/StepTracker/StepTracker.js +1 -2
- package/lib/TabBar/TabBar.js +1 -1
- package/lib/Tabs/Tabs.js +1 -1
- package/lib/Tabs/TabsItem.js +2 -2
- package/lib/TextInput/TextArea.js +1 -1
- package/lib/TextInput/TextInput.js +1 -1
- package/lib/TextInput/TextInputBase.js +10 -12
- package/lib/ThemeProvider/utils/theme-tokens.js +2 -4
- package/lib/Timeline/Timeline.js +1 -2
- package/lib/Tooltip/Tooltip.native.js +4 -4
- package/lib/Typography/Typography.js +4 -5
- package/lib/Validator/Validator.js +9 -14
- package/lib/ViewportProvider/useViewportListener.js +1 -1
- package/lib/index.js +1 -0
- package/lib/utils/children.js +2 -6
- package/lib/utils/input.js +1 -1
- package/lib/utils/props/componentPropType.js +1 -2
- package/lib/utils/props/selectSystemProps.js +2 -2
- package/lib/utils/ssr-media-query/create-stylesheet/create-stylesheet-mobile.js +1 -1
- package/lib/utils/ssr-media-query/create-stylesheet/index.js +2 -3
- package/lib/utils/ssr-media-query/utils/inject.js +3 -5
- package/lib/utils/useHash.js +1 -4
- package/lib/utils/useOverlaidPosition.js +25 -4
- package/lib/utils/useScrollBlocking.js +2 -4
- package/lib/utils/useSpacingScale.js +2 -2
- package/package.json +1 -1
- package/src/Carousel/CarouselStepTracker/CarouselStepTracker.jsx +3 -0
- package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +76 -0
- package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +119 -0
- package/src/ExpandCollapseMini/index.js +3 -0
- package/src/Link/LinkBase.jsx +8 -3
- package/src/index.js +1 -0
- package/src/utils/useOverlaidPosition.js +23 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import ExpandCollapse from '../ExpandCollapse'
|
|
4
|
+
import { getTokensPropType } from '../utils'
|
|
5
|
+
import ExpandCollapseMiniControl from './ExpandCollapseMiniControl'
|
|
6
|
+
|
|
7
|
+
const ExpandCollapseMini = React.forwardRef(
|
|
8
|
+
({ children, onToggle = () => {}, tokens = {}, nativeID, initialOpen = false, ...rest }, ref) => {
|
|
9
|
+
const expandCollapeMiniPanelId = 'ExpandCollapseMiniPanel'
|
|
10
|
+
const handleChange = (openPanels, event) => {
|
|
11
|
+
if (typeof onToggle === 'function') {
|
|
12
|
+
const isOpen = openPanels.length > 0
|
|
13
|
+
onToggle(event, isOpen)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<ExpandCollapse
|
|
19
|
+
onChange={handleChange}
|
|
20
|
+
tokens={tokens}
|
|
21
|
+
initialOpen={initialOpen ? [expandCollapeMiniPanelId] : []}
|
|
22
|
+
>
|
|
23
|
+
{(expandProps) => (
|
|
24
|
+
<ExpandCollapse.Panel
|
|
25
|
+
{...expandProps}
|
|
26
|
+
panelId={expandCollapeMiniPanelId}
|
|
27
|
+
variant={{ mini: true }}
|
|
28
|
+
controlTokens={{
|
|
29
|
+
// Remove unwanted look and feel from ExpandCollapse(background pressed, focus border and text underline)
|
|
30
|
+
icon: null,
|
|
31
|
+
borderColor: 'transparent',
|
|
32
|
+
textLine: 'none',
|
|
33
|
+
backgroundColor: 'transparent'
|
|
34
|
+
}}
|
|
35
|
+
// TODO refactor
|
|
36
|
+
// eslint-disable-next-line react/no-unstable-nested-components
|
|
37
|
+
control={(pressableState) => (
|
|
38
|
+
<ExpandCollapseMiniControl pressableState={pressableState} {...rest} />
|
|
39
|
+
)}
|
|
40
|
+
controlRef={ref}
|
|
41
|
+
nativeID={nativeID}
|
|
42
|
+
>
|
|
43
|
+
{children}
|
|
44
|
+
</ExpandCollapse.Panel>
|
|
45
|
+
)}
|
|
46
|
+
</ExpandCollapse>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
ExpandCollapseMini.displayName = 'ExpandCollapseMini'
|
|
51
|
+
|
|
52
|
+
ExpandCollapseMini.propTypes = {
|
|
53
|
+
...ExpandCollapseMiniControl.propTypes,
|
|
54
|
+
/**
|
|
55
|
+
* Function to call on pressing the panel's control, which should open or close the panel.
|
|
56
|
+
*/
|
|
57
|
+
onToggle: PropTypes.func,
|
|
58
|
+
/**
|
|
59
|
+
* ID for DOM element on web
|
|
60
|
+
*/
|
|
61
|
+
nativeID: PropTypes.string,
|
|
62
|
+
/**
|
|
63
|
+
* Children nodes that can be added
|
|
64
|
+
*/
|
|
65
|
+
children: PropTypes.node.isRequired,
|
|
66
|
+
/**
|
|
67
|
+
* Controls if the panel and the content is opened by default on the first load
|
|
68
|
+
*/
|
|
69
|
+
initialOpen: PropTypes.bool,
|
|
70
|
+
/**
|
|
71
|
+
* Optional variant object to override the default theme tokens
|
|
72
|
+
*/
|
|
73
|
+
tokens: getTokensPropType('ExpandCollapseMini')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export default ExpandCollapseMini
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import { Platform } from 'react-native'
|
|
4
|
+
import { Link } from '../Link'
|
|
5
|
+
import { useThemeTokens } from '../ThemeProvider'
|
|
6
|
+
import { htmlAttrs, viewProps, selectSystemProps } from '../utils'
|
|
7
|
+
|
|
8
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs, viewProps])
|
|
9
|
+
|
|
10
|
+
// The ExpandCollapseControl has all the appropriate role, a11y, press handling etc
|
|
11
|
+
// and a more appropriate press area, defer interaction handling to it.
|
|
12
|
+
const presentationOnly = {
|
|
13
|
+
accessibilityRole: null, // Treat as regular flow content with the Control
|
|
14
|
+
pointerEvents: 'none', // Stop RNW from stopping clicks from bubbling to Control
|
|
15
|
+
focusable: false // Stop RNW from setting tabIndex={0}: focus goes to Control only
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const selectLinkTokens = ({ color, textLine, lineHeight, fontSize }) => ({
|
|
19
|
+
color,
|
|
20
|
+
textLine,
|
|
21
|
+
blockLineHeight: lineHeight,
|
|
22
|
+
blockFontSize: fontSize
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const ExpandCollapseMiniControl = React.forwardRef(
|
|
26
|
+
(
|
|
27
|
+
{
|
|
28
|
+
pressableState,
|
|
29
|
+
collapseTitle,
|
|
30
|
+
expandTitle = collapseTitle,
|
|
31
|
+
iconPosition = 'right',
|
|
32
|
+
tokens,
|
|
33
|
+
variant = {},
|
|
34
|
+
...rest
|
|
35
|
+
},
|
|
36
|
+
ref
|
|
37
|
+
) => {
|
|
38
|
+
const { expanded, hover, focus } = pressableState || {}
|
|
39
|
+
// we only want focus outline when focusing, if user is pressing we don't want the border.
|
|
40
|
+
const { outerBorderColor } = useThemeTokens(
|
|
41
|
+
'Link',
|
|
42
|
+
{},
|
|
43
|
+
{},
|
|
44
|
+
{ focus: Platform.OS !== 'web' ? expanded : focus }
|
|
45
|
+
)
|
|
46
|
+
const { size, icon, ...themeTokens } = useThemeTokens(
|
|
47
|
+
'ExpandCollapseMiniControl',
|
|
48
|
+
tokens,
|
|
49
|
+
variant,
|
|
50
|
+
{ expanded, focus }
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
// Choose hover styles when any part of Control is hoverred
|
|
54
|
+
const appearance = { ...variant, hover }
|
|
55
|
+
|
|
56
|
+
const getTokens = (linkState) => {
|
|
57
|
+
const { hover: linkHover } = linkState || {}
|
|
58
|
+
const isHovered = hover || linkHover
|
|
59
|
+
|
|
60
|
+
if (Platform.OS !== 'web') {
|
|
61
|
+
return { iconTranslateY: -1 }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (isHovered) {
|
|
65
|
+
// Include vertical icon animation on hover alongside built-in Link theme, the size is size4
|
|
66
|
+
return { iconTranslateY: (expanded ? -1 : 1) * size }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return {}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<Link
|
|
74
|
+
variant={appearance}
|
|
75
|
+
icon={icon}
|
|
76
|
+
iconPosition={iconPosition}
|
|
77
|
+
tokens={(linkState) => ({
|
|
78
|
+
...getTokens(linkState),
|
|
79
|
+
...selectLinkTokens(themeTokens),
|
|
80
|
+
outerBorderColor
|
|
81
|
+
})}
|
|
82
|
+
ref={ref}
|
|
83
|
+
{...presentationOnly}
|
|
84
|
+
{...selectProps(rest)}
|
|
85
|
+
>
|
|
86
|
+
{expanded ? expandTitle : collapseTitle}
|
|
87
|
+
</Link>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
ExpandCollapseMiniControl.displayName = 'ExpandCollapseMiniControl'
|
|
93
|
+
|
|
94
|
+
ExpandCollapseMiniControl.propTypes = {
|
|
95
|
+
...selectedSystemPropTypes,
|
|
96
|
+
...Link.propTypes,
|
|
97
|
+
/**
|
|
98
|
+
* Optional function to call on pressing the panel's control, in addition to opening or closing the panel
|
|
99
|
+
*/
|
|
100
|
+
onPress: PropTypes.func,
|
|
101
|
+
/**
|
|
102
|
+
* ExpandCollapseMiniControl title when expanded
|
|
103
|
+
*/
|
|
104
|
+
expandTitle: PropTypes.string.isRequired,
|
|
105
|
+
/**
|
|
106
|
+
* ExpandCollapseMiniControl title when collapsed
|
|
107
|
+
*/
|
|
108
|
+
collapseTitle: PropTypes.string.isRequired,
|
|
109
|
+
/**
|
|
110
|
+
* React Native's `Pressable`'s state object
|
|
111
|
+
*/
|
|
112
|
+
pressableState: PropTypes.object,
|
|
113
|
+
/**
|
|
114
|
+
* Optional variant object to override the default theme tokens
|
|
115
|
+
*/
|
|
116
|
+
variant: PropTypes.object
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export default ExpandCollapseMiniControl
|
package/src/Link/LinkBase.jsx
CHANGED
|
@@ -81,18 +81,19 @@ const selectDecorationStyles = ({ color, textLine, textLineStyle, alignSelf }) =
|
|
|
81
81
|
})
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
-
const selectIconTokens = ({ color, iconSize, blockFontSize, iconTranslateX }) => {
|
|
84
|
+
const selectIconTokens = ({ color, iconSize, blockFontSize, iconTranslateX, iconTranslateY }) => {
|
|
85
85
|
/**
|
|
86
86
|
* These calculations were carried out using a set of linear equations to calculate that the
|
|
87
87
|
* position of the icon "->"" is aligned to the first line of the tooltip text.
|
|
88
88
|
* The base equation is: X/4 + Y/4 - 4 - |X - Y| = Z
|
|
89
89
|
* where X = blockFontSize, Y = iconSize and Z = translateY
|
|
90
90
|
*/
|
|
91
|
-
const translateY =
|
|
91
|
+
const translateY =
|
|
92
|
+
iconTranslateY ?? blockFontSize / 4 + iconSize / 4 - 4 - Math.abs(iconSize - blockFontSize)
|
|
92
93
|
return {
|
|
93
94
|
color,
|
|
94
95
|
translateX: iconTranslateX,
|
|
95
|
-
translateY
|
|
96
|
+
translateY,
|
|
96
97
|
size: iconSize
|
|
97
98
|
}
|
|
98
99
|
}
|
|
@@ -274,6 +275,10 @@ const staticStyles = StyleSheet.create({
|
|
|
274
275
|
margin: 0,
|
|
275
276
|
marginHorizontal: 2,
|
|
276
277
|
padding: 0
|
|
278
|
+
}),
|
|
279
|
+
...(Platform.OS === 'android' && {
|
|
280
|
+
paddingHorizontal: 2,
|
|
281
|
+
paddingTop: 2
|
|
277
282
|
})
|
|
278
283
|
}
|
|
279
284
|
})
|
package/src/index.js
CHANGED
|
@@ -18,6 +18,7 @@ export { default as ColourToggle } from './ColourToggle'
|
|
|
18
18
|
export { default as DownloadApp } from './DownloadApp'
|
|
19
19
|
export { default as Divider } from './Divider'
|
|
20
20
|
export { default as ExpandCollapse, Accordion } from './ExpandCollapse'
|
|
21
|
+
export { default as ExpandCollapseMini } from './ExpandCollapseMini'
|
|
21
22
|
export { default as Feedback } from './Feedback'
|
|
22
23
|
export { default as Fieldset } from './Fieldset'
|
|
23
24
|
export { default as FlexGrid } from './FlexGrid'
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
2
2
|
import { Dimensions, Platform } from 'react-native'
|
|
3
|
+
import debounce from 'lodash.debounce'
|
|
4
|
+
|
|
5
|
+
const DEBOUNCE_DELAY = 100
|
|
3
6
|
|
|
4
7
|
const adjustHorizontalToFit = (initialOffset, windowWidth, sourceWidth) => {
|
|
5
8
|
const offset = Math.max(0, initialOffset)
|
|
@@ -200,6 +203,26 @@ const useOverlaidPosition = ({
|
|
|
200
203
|
return unsubscribe
|
|
201
204
|
}, [readyToShow])
|
|
202
205
|
|
|
206
|
+
useEffect(() => {
|
|
207
|
+
if (Platform.OS !== 'web') {
|
|
208
|
+
return undefined
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const handleScroll = debounce(() => {
|
|
212
|
+
sourceRef.current?.measureInWindow((x, y, width, height) => {
|
|
213
|
+
setWindowDimensions(window)
|
|
214
|
+
setSourceLayout({ x, y, width, height })
|
|
215
|
+
})
|
|
216
|
+
}, DEBOUNCE_DELAY)
|
|
217
|
+
|
|
218
|
+
window.addEventListener('scroll', handleScroll)
|
|
219
|
+
|
|
220
|
+
return () => {
|
|
221
|
+
window.removeEventListener('scroll', handleScroll)
|
|
222
|
+
handleScroll.cancel()
|
|
223
|
+
}
|
|
224
|
+
}, [sourceRef])
|
|
225
|
+
|
|
203
226
|
const isReady = Boolean(isShown && sourceLayout && windowDimensions && targetDimensions)
|
|
204
227
|
|
|
205
228
|
const overlaidPosition = isReady
|