@telus-uds/components-base 1.24.2 → 1.26.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 +44 -2
- package/component-docs.json +55 -1
- package/lib/Button/ButtonBase.js +2 -1
- package/lib/Carousel/Carousel.js +19 -1
- package/lib/Carousel/CarouselStepTracker/CarouselStepTracker.js +11 -2
- package/lib/MultiSelectFilter/ModalOverlay.js +136 -0
- package/lib/MultiSelectFilter/MultiSelectFilter.js +64 -26
- package/lib/Typography/Typography.js +27 -2
- package/lib-module/Button/ButtonBase.js +2 -1
- package/lib-module/Carousel/Carousel.js +16 -1
- package/lib-module/Carousel/CarouselStepTracker/CarouselStepTracker.js +10 -2
- package/lib-module/MultiSelectFilter/ModalOverlay.js +112 -0
- package/lib-module/MultiSelectFilter/MultiSelectFilter.js +65 -27
- package/lib-module/Typography/Typography.js +26 -2
- package/package.json +2 -2
- package/src/Button/ButtonBase.jsx +1 -1
- package/src/Carousel/Carousel.jsx +16 -2
- package/src/Carousel/CarouselStepTracker/CarouselStepTracker.jsx +7 -1
- package/src/MultiSelectFilter/ModalOverlay.jsx +86 -0
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +73 -49
- package/src/Typography/Typography.jsx +26 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { forwardRef, useState } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
|
-
import { useThemeTokensCallback } from '../ThemeProvider'
|
|
4
|
+
import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider'
|
|
5
5
|
import {
|
|
6
6
|
containUniqueFields,
|
|
7
7
|
getTokensPropType,
|
|
@@ -18,18 +18,30 @@ import { Button, ButtonDropdown } from '../Button'
|
|
|
18
18
|
import { CheckboxGroup } from '../Checkbox'
|
|
19
19
|
import Divider from '../Divider'
|
|
20
20
|
import FlexGrid from '../FlexGrid'
|
|
21
|
-
import Modal from '../Modal'
|
|
22
21
|
import Spacer from '../Spacer'
|
|
23
22
|
import StackView from '../StackView'
|
|
24
23
|
import Typography from '../Typography'
|
|
25
24
|
import { TextButton } from '../Link'
|
|
25
|
+
import ModalOverlay from './ModalOverlay'
|
|
26
26
|
|
|
27
27
|
const { Col, Row } = FlexGrid
|
|
28
28
|
|
|
29
|
+
const selectSubTitleTokens = ({ subtitleColor }) => ({
|
|
30
|
+
color: subtitleColor
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const selectDividerToknes = ({ dividerColor, width, decorative = true, weight = 'thin' }) => ({
|
|
34
|
+
color: dividerColor,
|
|
35
|
+
width,
|
|
36
|
+
decorative,
|
|
37
|
+
weight
|
|
38
|
+
})
|
|
39
|
+
|
|
29
40
|
const MultiSelectFilter = forwardRef(
|
|
30
41
|
(
|
|
31
42
|
{
|
|
32
43
|
label,
|
|
44
|
+
subtitle,
|
|
33
45
|
id = label,
|
|
34
46
|
variant,
|
|
35
47
|
tokens,
|
|
@@ -54,6 +66,7 @@ const MultiSelectFilter = forwardRef(
|
|
|
54
66
|
readOnly
|
|
55
67
|
})
|
|
56
68
|
|
|
69
|
+
const themeTokens = useThemeTokens('ButtonDropdown', tokens, variant)
|
|
57
70
|
const getItemTokens = useThemeTokensCallback('ButtonDropdown', tokens, variant)
|
|
58
71
|
const getButtonTokens = (buttonState) => selectTokens('Button', getItemTokens(buttonState))
|
|
59
72
|
const getCopy = useCopy({ dictionary, copy })
|
|
@@ -74,7 +87,7 @@ const MultiSelectFilter = forwardRef(
|
|
|
74
87
|
|
|
75
88
|
const handleChange = (event) => {
|
|
76
89
|
if (pressHandlers.onPress) pressHandlers?.onPress(event)
|
|
77
|
-
setIsOpen(
|
|
90
|
+
setIsOpen(!isOpen)
|
|
78
91
|
}
|
|
79
92
|
|
|
80
93
|
const onApply = (e) => {
|
|
@@ -84,52 +97,6 @@ const MultiSelectFilter = forwardRef(
|
|
|
84
97
|
|
|
85
98
|
return (
|
|
86
99
|
<>
|
|
87
|
-
<Modal
|
|
88
|
-
isOpen={isOpen}
|
|
89
|
-
onClose={() => setIsOpen(false)}
|
|
90
|
-
variant={{ width: colSize > 1 ? 'size576' : 's' }}
|
|
91
|
-
>
|
|
92
|
-
<Row>
|
|
93
|
-
<Typography variant={{ size: 'h4' }}>
|
|
94
|
-
{getCopy('filterByLabel').replace(/%\{filterCategory\}/g, label.toLowerCase())}
|
|
95
|
-
</Typography>
|
|
96
|
-
</Row>
|
|
97
|
-
<Spacer space={4} />
|
|
98
|
-
<Spacer space={1} />
|
|
99
|
-
<Box scroll={true}>
|
|
100
|
-
<Row distribute="between">
|
|
101
|
-
{[...Array(colSize).keys()].map((i) => (
|
|
102
|
-
<Col xs={12 / colSize} key={i}>
|
|
103
|
-
<CheckboxGroup
|
|
104
|
-
items={items.slice(i * rowLimit, (i + 1) * rowLimit)}
|
|
105
|
-
checkedIds={checkedIds}
|
|
106
|
-
onChange={(e) => setCheckedIds(e, i)}
|
|
107
|
-
/>
|
|
108
|
-
<Spacer size={4} />
|
|
109
|
-
</Col>
|
|
110
|
-
))}
|
|
111
|
-
</Row>
|
|
112
|
-
</Box>
|
|
113
|
-
<Divider
|
|
114
|
-
variant={{ width: 'full', color: 'E3E6E8', decorative: true, weight: 'thin' }}
|
|
115
|
-
space={4}
|
|
116
|
-
/>
|
|
117
|
-
<Row>
|
|
118
|
-
<StackView direction="row" space={3} tokens={{ alignItems: 'center' }}>
|
|
119
|
-
<Button
|
|
120
|
-
onPress={() => onApply(checkedIds)}
|
|
121
|
-
variant={{ size: 'small', priority: 'high' }}
|
|
122
|
-
>
|
|
123
|
-
{getCopy('applyButtonLabel')}
|
|
124
|
-
</Button>
|
|
125
|
-
<Box>
|
|
126
|
-
<TextButton onPress={() => setCheckedIds([])}>
|
|
127
|
-
{getCopy('clearButtonLabel')}
|
|
128
|
-
</TextButton>
|
|
129
|
-
</Box>
|
|
130
|
-
</StackView>
|
|
131
|
-
</Row>
|
|
132
|
-
</Modal>
|
|
133
100
|
<ButtonDropdown
|
|
134
101
|
ref={ref}
|
|
135
102
|
key={id}
|
|
@@ -141,6 +108,59 @@ const MultiSelectFilter = forwardRef(
|
|
|
141
108
|
tokens={getButtonTokens}
|
|
142
109
|
inactive={inactive}
|
|
143
110
|
/>
|
|
111
|
+
{isOpen && (
|
|
112
|
+
<ModalOverlay
|
|
113
|
+
variant={{ width: colSize > 1 ? 'size576' : 's' }}
|
|
114
|
+
onClose={() => setIsOpen(false)}
|
|
115
|
+
>
|
|
116
|
+
<Row>
|
|
117
|
+
<Typography variant={{ size: 'h4' }}>
|
|
118
|
+
{getCopy('filterByLabel').replace(/%\{filterCategory\}/g, label.toLowerCase())}
|
|
119
|
+
</Typography>
|
|
120
|
+
</Row>
|
|
121
|
+
{subtitle && (
|
|
122
|
+
<>
|
|
123
|
+
<Spacer space={5} />
|
|
124
|
+
<Row>
|
|
125
|
+
<Typography variant={{ size: 'h5' }} tokens={selectSubTitleTokens(themeTokens)}>
|
|
126
|
+
{subtitle}
|
|
127
|
+
</Typography>
|
|
128
|
+
</Row>
|
|
129
|
+
</>
|
|
130
|
+
)}
|
|
131
|
+
<Spacer space={4} />
|
|
132
|
+
<Box scroll={true}>
|
|
133
|
+
<Row distribute="between">
|
|
134
|
+
{[...Array(colSize).keys()].map((i) => (
|
|
135
|
+
<Col xs={12 / colSize} key={i}>
|
|
136
|
+
<CheckboxGroup
|
|
137
|
+
items={items.slice(i * rowLimit, (i + 1) * rowLimit)}
|
|
138
|
+
checkedIds={checkedIds}
|
|
139
|
+
onChange={(e) => setCheckedIds(e, i)}
|
|
140
|
+
/>
|
|
141
|
+
<Spacer size={4} />
|
|
142
|
+
</Col>
|
|
143
|
+
))}
|
|
144
|
+
</Row>
|
|
145
|
+
</Box>
|
|
146
|
+
<Divider variant={selectDividerToknes({ ...themeTokens, width: 'full' })} space={4} />
|
|
147
|
+
<Row>
|
|
148
|
+
<StackView direction="row" space={3} tokens={{ alignItems: 'center' }}>
|
|
149
|
+
<Button
|
|
150
|
+
onPress={() => onApply(checkedIds)}
|
|
151
|
+
variant={{ size: 'small', priority: 'high' }}
|
|
152
|
+
>
|
|
153
|
+
{getCopy('applyButtonLabel')}
|
|
154
|
+
</Button>
|
|
155
|
+
<Box>
|
|
156
|
+
<TextButton onPress={() => setCheckedIds([])}>
|
|
157
|
+
{getCopy('clearButtonLabel')}
|
|
158
|
+
</TextButton>
|
|
159
|
+
</Box>
|
|
160
|
+
</StackView>
|
|
161
|
+
</Row>
|
|
162
|
+
</ModalOverlay>
|
|
163
|
+
)}
|
|
144
164
|
</>
|
|
145
165
|
)
|
|
146
166
|
}
|
|
@@ -152,6 +172,10 @@ MultiSelectFilter.propTypes = {
|
|
|
152
172
|
* The text displayed to the user in a ButtonDropdown.
|
|
153
173
|
*/
|
|
154
174
|
label: PropTypes.string.isRequired,
|
|
175
|
+
/**
|
|
176
|
+
* The text for the subtitle
|
|
177
|
+
*/
|
|
178
|
+
subtitle: PropTypes.string,
|
|
155
179
|
/**
|
|
156
180
|
* An optional unique string may be provided to identify the ButtonDropdown.
|
|
157
181
|
* If not provided, the label is used.
|
|
@@ -60,6 +60,7 @@ const Typography = forwardRef(
|
|
|
60
60
|
const viewport = useViewport()
|
|
61
61
|
const themeTokens = useThemeTokens('Typography', tokens, variant, { viewport })
|
|
62
62
|
const { themeOptions } = useTheme()
|
|
63
|
+
|
|
63
64
|
const resolvedTextProps = {
|
|
64
65
|
...selectTextProps(rest),
|
|
65
66
|
style: selectTextStyles(
|
|
@@ -76,13 +77,36 @@ const Typography = forwardRef(
|
|
|
76
77
|
...selectContainerProps(rest)
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
const resetTagStyling = (child) => {
|
|
81
|
+
if (typeof child === 'object' && (child?.type === 'sub' || child?.type === 'sup')) {
|
|
82
|
+
const sanitizedChild = React.cloneElement(child, {
|
|
83
|
+
style: {
|
|
84
|
+
...child?.props?.style,
|
|
85
|
+
lineHeight: 0
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
return sanitizedChild
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return child
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const sanitizeChildren = () => {
|
|
96
|
+
if (Array.isArray(children)) {
|
|
97
|
+
return children.map(resetTagStyling)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return resetTagStyling(children)
|
|
101
|
+
}
|
|
102
|
+
|
|
79
103
|
return block ? (
|
|
80
104
|
<View ref={ref} {...containerProps}>
|
|
81
|
-
<Text {...resolvedTextProps}>{children}</Text>
|
|
105
|
+
<Text {...resolvedTextProps}>{sanitizeChildren(children)}</Text>
|
|
82
106
|
</View>
|
|
83
107
|
) : (
|
|
84
108
|
<Text ref={ref} {...containerProps} {...resolvedTextProps}>
|
|
85
|
-
{children}
|
|
109
|
+
{sanitizeChildren(children)}
|
|
86
110
|
</Text>
|
|
87
111
|
)
|
|
88
112
|
}
|