@telus-uds/components-base 2.3.0 → 2.4.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 +21 -2
- package/lib/InputLabel/InputLabel.js +36 -2
- package/lib/InputSupports/InputSupports.js +31 -8
- package/lib/InputSupports/dictionary.js +12 -0
- package/lib/InputSupports/useInputSupports.js +12 -3
- package/lib/Link/LinkBase.js +17 -15
- package/lib/Modal/Modal.js +2 -2
- package/lib/MultiSelectFilter/MultiSelectFilter.js +54 -41
- package/lib/Notification/Notification.js +7 -3
- package/lib/Search/Search.js +39 -8
- package/lib/Select/Picker.native.js +8 -4
- package/lib/Select/constants.js +4 -2
- package/lib/TextInput/TextArea.js +7 -6
- package/lib/TextInput/TextInput.js +7 -6
- package/lib/TextInput/TextInputBase.js +48 -14
- package/lib/utils/props/inputSupportsProps.js +15 -3
- package/package.json +2 -2
- package/src/InputLabel/InputLabel.jsx +39 -2
- package/src/InputSupports/InputSupports.jsx +33 -7
- package/src/InputSupports/dictionary.js +12 -0
- package/src/InputSupports/useInputSupports.js +24 -3
- package/src/Link/LinkBase.jsx +17 -15
- package/src/Modal/Modal.jsx +1 -1
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +55 -27
- package/src/Notification/Notification.jsx +9 -3
- package/src/Search/Search.jsx +52 -24
- package/src/Select/Picker.native.jsx +10 -4
- package/src/Select/constants.js +4 -1
- package/src/TextInput/TextArea.jsx +12 -5
- package/src/TextInput/TextInput.jsx +13 -6
- package/src/TextInput/TextInputBase.jsx +57 -10
- package/src/utils/props/inputSupportsProps.js +15 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
1
|
# Change Log - @telus-uds/components-base
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Fri, 10 Jan 2025 21:41:25 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 2.4.0
|
|
8
|
+
|
|
9
|
+
Fri, 10 Jan 2025 21:41:25 GMT
|
|
10
|
+
|
|
11
|
+
### Minor changes
|
|
12
|
+
|
|
13
|
+
- `Search`: `showLeftIcon` prop added to display the update icon in the left side for the component. (35577399+JoshHC@users.noreply.github.com)
|
|
14
|
+
- `MultiSelectFilter`: add label and button icon tokens (kristina.kirpichnikova@telus.com)
|
|
15
|
+
- Bump @telus-uds/system-theme-tokens to v3.3.0
|
|
16
|
+
|
|
17
|
+
### Patches
|
|
18
|
+
|
|
19
|
+
- `Link`: add missing outer border tokens for mobile devices (guillermo.peitzner@telus.com)
|
|
20
|
+
- `Modal`: add fallback to avoid error when pressing Tab (Mauricio.BatresMontejo@telus.com)
|
|
21
|
+
- `Select`: fix Option not appearing in component when selected on iOS largest text sizes (sergio.ramirez@telus.com)
|
|
22
|
+
- `InputLabel`: add character count to support InputText and TextArea (Mauricio.BatresMontejo@telus.com)
|
|
23
|
+
- `Notification`: add system style variant retrocompatibility (guillermo.peitzner@telus.com)
|
|
24
|
+
- `InputLabel`: static styles of the label modified to fix hint and tooltip misalignment (35577399+JoshHC@users.noreply.github.com)
|
|
25
|
+
|
|
7
26
|
## 2.3.0
|
|
8
27
|
|
|
9
|
-
Thu, 19 Dec 2024
|
|
28
|
+
Thu, 19 Dec 2024 05:02:20 GMT
|
|
10
29
|
|
|
11
30
|
### Minor changes
|
|
12
31
|
|
|
@@ -49,6 +49,8 @@ const InputLabel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
49
49
|
tooltip,
|
|
50
50
|
tokens,
|
|
51
51
|
variant,
|
|
52
|
+
characterCount,
|
|
53
|
+
maxCharacterAllowed,
|
|
52
54
|
...rest
|
|
53
55
|
} = _ref3;
|
|
54
56
|
const themeTokens = useThemeTokens('InputLabel', tokens, variant);
|
|
@@ -81,11 +83,26 @@ const InputLabel = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
81
83
|
content: tooltip,
|
|
82
84
|
copy: copy
|
|
83
85
|
})
|
|
86
|
+
}), maxCharacterAllowed && isHintInline && /*#__PURE__*/_jsxs(Text, {
|
|
87
|
+
style: [selectHintStyles({
|
|
88
|
+
...themeTokens
|
|
89
|
+
}), staticStyles.characterCountlabel],
|
|
90
|
+
children: [characterCount, "/", maxCharacterAllowed]
|
|
84
91
|
})]
|
|
85
|
-
}), hint && !isHintInline && /*#__PURE__*/_jsx(Text, {
|
|
92
|
+
}), hint && !maxCharacterAllowed && !isHintInline && /*#__PURE__*/_jsx(Text, {
|
|
86
93
|
style: [selectHintStyles(themeTokens), staticStyles.hintBelow],
|
|
87
94
|
nativeID: hintId,
|
|
88
95
|
children: hint
|
|
96
|
+
}), hint && maxCharacterAllowed && !isHintInline && /*#__PURE__*/_jsxs(View, {
|
|
97
|
+
style: staticStyles.container,
|
|
98
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
99
|
+
style: [selectHintStyles(themeTokens), staticStyles.flexHintBelow],
|
|
100
|
+
nativeID: hintId,
|
|
101
|
+
children: hint
|
|
102
|
+
}), /*#__PURE__*/_jsxs(Text, {
|
|
103
|
+
style: [selectHintStyles(themeTokens), staticStyles.characterCountlabel],
|
|
104
|
+
children: [characterCount, "/", maxCharacterAllowed]
|
|
105
|
+
})]
|
|
89
106
|
})]
|
|
90
107
|
});
|
|
91
108
|
});
|
|
@@ -120,6 +137,14 @@ InputLabel.propTypes = {
|
|
|
120
137
|
* Content of an optional `Tooltip`. If set, a tooltip button will be shown next to the label.
|
|
121
138
|
*/
|
|
122
139
|
tooltip: PropTypes.string,
|
|
140
|
+
/**
|
|
141
|
+
* Current number of characterts of an input text.
|
|
142
|
+
*/
|
|
143
|
+
characterCount: PropTypes.number,
|
|
144
|
+
/**
|
|
145
|
+
* Max number of characters that allows an input text.
|
|
146
|
+
*/
|
|
147
|
+
maxCharacterAllowed: PropTypes.number,
|
|
123
148
|
tokens: getTokensPropType('InputLabel'),
|
|
124
149
|
variant: variantProp.propType
|
|
125
150
|
};
|
|
@@ -129,13 +154,22 @@ const staticStyles = StyleSheet.create({
|
|
|
129
154
|
flexShrink: 1,
|
|
130
155
|
flexDirection: 'row'
|
|
131
156
|
},
|
|
157
|
+
characterCountlabel: {
|
|
158
|
+
marginLeft: 'auto',
|
|
159
|
+
marginTop: 'auto'
|
|
160
|
+
},
|
|
132
161
|
label: {
|
|
133
|
-
flexShrink: 1
|
|
162
|
+
flexShrink: 1,
|
|
163
|
+
alignSelf: 'center'
|
|
134
164
|
},
|
|
135
165
|
hintBelow: {
|
|
136
166
|
flexBasis: '100%',
|
|
137
167
|
flexShrink: 0
|
|
138
168
|
},
|
|
169
|
+
flexHintBelow: {
|
|
170
|
+
flexBasis: '100%',
|
|
171
|
+
flexShrink: 1
|
|
172
|
+
},
|
|
139
173
|
tooltipAlign: {
|
|
140
174
|
alignSelf: 'center',
|
|
141
175
|
justifyContent: 'center'
|
|
@@ -5,7 +5,8 @@ import Feedback from '../Feedback';
|
|
|
5
5
|
import StackView from '../StackView';
|
|
6
6
|
import { useThemeTokens } from '../ThemeProvider';
|
|
7
7
|
import useInputSupports from './useInputSupports';
|
|
8
|
-
import { getTokensPropType } from '../utils';
|
|
8
|
+
import { getTokensPropType, useCopy } from '../utils';
|
|
9
|
+
import dictionary from './dictionary';
|
|
9
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
11
|
const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
11
12
|
let {
|
|
@@ -19,11 +20,19 @@ const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
19
20
|
feedbackProps = {},
|
|
20
21
|
tooltip,
|
|
21
22
|
validation,
|
|
23
|
+
maxCharacterAllowed,
|
|
24
|
+
inputValue,
|
|
22
25
|
nativeID
|
|
23
26
|
} = _ref;
|
|
24
27
|
const {
|
|
25
28
|
space
|
|
26
29
|
} = useThemeTokens('InputSupports');
|
|
30
|
+
const getCopy = useCopy({
|
|
31
|
+
dictionary,
|
|
32
|
+
copy
|
|
33
|
+
});
|
|
34
|
+
const maxCharsReachedErrorMessage = (inputValue === null || inputValue === void 0 ? void 0 : inputValue.length) > maxCharacterAllowed ? getCopy('maxCharsMessage').replace(/%\{charCount\}/g, maxCharacterAllowed) : '';
|
|
35
|
+
const feedbackValidation = (inputValue === null || inputValue === void 0 ? void 0 : inputValue.length) > maxCharacterAllowed ? 'error' : validation;
|
|
27
36
|
const {
|
|
28
37
|
inputId,
|
|
29
38
|
hintId,
|
|
@@ -34,7 +43,10 @@ const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
34
43
|
hint,
|
|
35
44
|
label,
|
|
36
45
|
validation,
|
|
37
|
-
nativeID
|
|
46
|
+
nativeID,
|
|
47
|
+
copy,
|
|
48
|
+
maxCharacterAllowed,
|
|
49
|
+
charactersCount: maxCharacterAllowed - (inputValue === null || inputValue === void 0 ? void 0 : inputValue.length)
|
|
38
50
|
});
|
|
39
51
|
return /*#__PURE__*/_jsxs(StackView, {
|
|
40
52
|
space: space,
|
|
@@ -46,14 +58,17 @@ const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
46
58
|
hintPosition: hintPosition,
|
|
47
59
|
hintId: hintId,
|
|
48
60
|
tooltip: tooltip,
|
|
49
|
-
forId: inputId
|
|
61
|
+
forId: inputId,
|
|
62
|
+
characterCount: inputValue === null || inputValue === void 0 ? void 0 : inputValue.length,
|
|
63
|
+
maxCharacterAllowed: maxCharacterAllowed
|
|
50
64
|
}), typeof children === 'function' ? children({
|
|
51
65
|
inputId,
|
|
52
|
-
...a11yProps
|
|
53
|
-
|
|
66
|
+
...a11yProps,
|
|
67
|
+
validation: feedbackValidation
|
|
68
|
+
}) : children, feedback || maxCharsReachedErrorMessage ? /*#__PURE__*/_jsx(Feedback, {
|
|
54
69
|
id: feedbackId,
|
|
55
|
-
title: feedback,
|
|
56
|
-
validation:
|
|
70
|
+
title: feedback || maxCharsReachedErrorMessage,
|
|
71
|
+
validation: feedbackValidation,
|
|
57
72
|
tokens: feedbackTokens,
|
|
58
73
|
variant: {
|
|
59
74
|
icon: feedbackProps.showFeedbackIcon
|
|
@@ -105,6 +120,14 @@ InputSupports.propTypes = {
|
|
|
105
120
|
/**
|
|
106
121
|
* ID for DOM element on web
|
|
107
122
|
*/
|
|
108
|
-
nativeID: PropTypes.string
|
|
123
|
+
nativeID: PropTypes.string,
|
|
124
|
+
/**
|
|
125
|
+
* The text value of a TextArea or TextInput
|
|
126
|
+
*/
|
|
127
|
+
inputValue: PropTypes.string,
|
|
128
|
+
/**
|
|
129
|
+
* Max number of characters that allows an input text.
|
|
130
|
+
*/
|
|
131
|
+
maxCharacterAllowed: PropTypes.number
|
|
109
132
|
};
|
|
110
133
|
export default InputSupports;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
en: {
|
|
3
|
+
maxCharacters: 'Maximum %{charCount} characters',
|
|
4
|
+
charactersRemaining: '%{charCount} characters remaining',
|
|
5
|
+
maxCharsMessage: 'Must not exceed %{charCount} characters'
|
|
6
|
+
},
|
|
7
|
+
fr: {
|
|
8
|
+
maxCharacters: '%{charCount} caractères maximum',
|
|
9
|
+
charactersRemaining: '%{charCount} caractères restants',
|
|
10
|
+
maxCharsMessage: 'Ne doit pas dépasser %{charCount} caractères'
|
|
11
|
+
}
|
|
12
|
+
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import useUniqueId from '../utils/useUniqueId';
|
|
2
|
+
import { useCopy } from '../utils';
|
|
3
|
+
import dictionary from './dictionary';
|
|
2
4
|
const joinDefined = array => array.filter(item => item !== undefined).join(' ');
|
|
3
5
|
const useInputSupports = _ref => {
|
|
4
6
|
let {
|
|
@@ -6,19 +8,26 @@ const useInputSupports = _ref => {
|
|
|
6
8
|
feedback,
|
|
7
9
|
validation,
|
|
8
10
|
hint,
|
|
9
|
-
nativeID
|
|
11
|
+
nativeID,
|
|
12
|
+
copy,
|
|
13
|
+
maxCharacterAllowed,
|
|
14
|
+
charactersCount
|
|
10
15
|
} = _ref;
|
|
16
|
+
const getCopy = useCopy({
|
|
17
|
+
dictionary,
|
|
18
|
+
copy
|
|
19
|
+
});
|
|
11
20
|
const hasValidationError = validation === 'error';
|
|
12
21
|
const inputId = useUniqueId('input');
|
|
13
22
|
const hintId = useUniqueId('input-hint');
|
|
14
23
|
const feedbackId = useUniqueId('input-feedback');
|
|
15
24
|
const a11yProps = {
|
|
16
25
|
accessibilityLabel: label,
|
|
17
|
-
accessibilityHint: joinDefined([!hasValidationError && feedback, hint]),
|
|
26
|
+
accessibilityHint: joinDefined([!hasValidationError && feedback, hint, maxCharacterAllowed ? getCopy('maxCharacters').replace(/%\{charCount\}/g, maxCharacterAllowed) : undefined]),
|
|
18
27
|
// native only -> replaced with describedBy on web
|
|
19
28
|
accessibilityDescribedBy: joinDefined([!hasValidationError && feedback && feedbackId,
|
|
20
29
|
// feedback receives a11yRole=alert on error, so there's no need to include it here
|
|
21
|
-
hint && hintId]),
|
|
30
|
+
hint && hintId, charactersCount ? getCopy('charactersRemaining').replace(/%\{charCount\}/g, charactersCount) : undefined]),
|
|
22
31
|
accessibilityInvalid: hasValidationError
|
|
23
32
|
};
|
|
24
33
|
return {
|
package/lib/Link/LinkBase.js
CHANGED
|
@@ -19,20 +19,15 @@ const selectOuterBorderStyles = _ref => {
|
|
|
19
19
|
borderRadius,
|
|
20
20
|
outerBorderOutline
|
|
21
21
|
} = _ref;
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
outerBorderGap
|
|
32
|
-
}),
|
|
33
|
-
borderRadius
|
|
34
|
-
} : {}
|
|
35
|
-
);
|
|
22
|
+
return {
|
|
23
|
+
outline: outerBorderOutline,
|
|
24
|
+
...applyOuterBorder({
|
|
25
|
+
outerBorderColor,
|
|
26
|
+
outerBorderWidth,
|
|
27
|
+
outerBorderGap
|
|
28
|
+
}),
|
|
29
|
+
borderRadius
|
|
30
|
+
};
|
|
36
31
|
};
|
|
37
32
|
const selectTextStyles = _ref2 => {
|
|
38
33
|
let {
|
|
@@ -182,7 +177,7 @@ const LinkBase = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
|
182
177
|
const themeTokens = resolveLinkTokens(linkState);
|
|
183
178
|
const outerBorderStyles = selectOuterBorderStyles(themeTokens);
|
|
184
179
|
const decorationStyles = selectDecorationStyles(themeTokens);
|
|
185
|
-
return [outerBorderStyles, blockLeftStyle, decorationStyles, hasIcon && staticStyles.rowContainer];
|
|
180
|
+
return [outerBorderStyles, staticStyles.outerBorderStyles, blockLeftStyle, decorationStyles, hasIcon && staticStyles.rowContainer];
|
|
186
181
|
},
|
|
187
182
|
children: linkState => {
|
|
188
183
|
const themeTokens = resolveLinkTokens(linkState);
|
|
@@ -264,6 +259,13 @@ const staticStyles = StyleSheet.create({
|
|
|
264
259
|
pointerEvents: 'none'
|
|
265
260
|
}
|
|
266
261
|
})
|
|
262
|
+
},
|
|
263
|
+
outerBorderStyles: {
|
|
264
|
+
...(Platform.OS !== 'web' && {
|
|
265
|
+
margin: 0,
|
|
266
|
+
marginHorizontal: 2,
|
|
267
|
+
padding: 0
|
|
268
|
+
})
|
|
267
269
|
}
|
|
268
270
|
});
|
|
269
271
|
export default withLinkRouter(LinkBase);
|
package/lib/Modal/Modal.js
CHANGED
|
@@ -148,11 +148,11 @@ const Modal = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
148
148
|
const manageFocus = React.useCallback(event => {
|
|
149
149
|
if (event.key === 'Tab') {
|
|
150
150
|
var _modalBodyRef$current;
|
|
151
|
-
const focusableElements = Array.from(modalBodyRef === null || modalBodyRef === void 0 || (_modalBodyRef$current = modalBodyRef.current) === null || _modalBodyRef$current === void 0 ? void 0 : _modalBodyRef$current.querySelectorAll(`
|
|
151
|
+
const focusableElements = Array.from((modalBodyRef === null || modalBodyRef === void 0 || (_modalBodyRef$current = modalBodyRef.current) === null || _modalBodyRef$current === void 0 ? void 0 : _modalBodyRef$current.querySelectorAll(`
|
|
152
152
|
a[href], button, textarea, input, select,
|
|
153
153
|
[tabindex]:not([tabindex="-1"]),
|
|
154
154
|
[contenteditable="true"]
|
|
155
|
-
`));
|
|
155
|
+
`)) || []);
|
|
156
156
|
const firstElement = focusableElements[0];
|
|
157
157
|
const lastElement = focusableElements[focusableElements.length - 1];
|
|
158
158
|
if (event.shiftKey && document.activeElement === firstElement) {
|
|
@@ -25,30 +25,14 @@ const {
|
|
|
25
25
|
Col,
|
|
26
26
|
Row
|
|
27
27
|
} = FlexGrid;
|
|
28
|
-
const
|
|
29
|
-
let {
|
|
30
|
-
subtitleColor
|
|
31
|
-
} = _ref;
|
|
32
|
-
return {
|
|
33
|
-
color: subtitleColor
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
const selectDividerTokens = _ref2 => {
|
|
37
|
-
let {
|
|
38
|
-
dividerColor
|
|
39
|
-
} = _ref2;
|
|
40
|
-
return {
|
|
41
|
-
color: dividerColor
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
const selectHeaderTokens = _ref3 => {
|
|
28
|
+
const selectHeaderTokens = _ref => {
|
|
45
29
|
let {
|
|
46
30
|
contentMarginLeft,
|
|
47
31
|
contentMarginRight,
|
|
48
32
|
contentMarginTop,
|
|
49
33
|
contentPaddingLeft,
|
|
50
34
|
contentPaddingRight
|
|
51
|
-
} =
|
|
35
|
+
} = _ref;
|
|
52
36
|
return {
|
|
53
37
|
marginLeft: contentMarginLeft,
|
|
54
38
|
marginRight: contentMarginRight,
|
|
@@ -58,14 +42,14 @@ const selectHeaderTokens = _ref3 => {
|
|
|
58
42
|
flexGrow: 1
|
|
59
43
|
};
|
|
60
44
|
};
|
|
61
|
-
const selectControlsTokens =
|
|
45
|
+
const selectControlsTokens = _ref2 => {
|
|
62
46
|
let {
|
|
63
47
|
contentMarginBottom,
|
|
64
48
|
contentMarginLeft,
|
|
65
49
|
contentMarginRight,
|
|
66
50
|
contentPaddingLeft,
|
|
67
51
|
contentPaddingRight
|
|
68
|
-
} =
|
|
52
|
+
} = _ref2;
|
|
69
53
|
return {
|
|
70
54
|
marginBottom: contentMarginBottom,
|
|
71
55
|
marginLeft: contentMarginLeft,
|
|
@@ -80,7 +64,7 @@ const selectContainerStyle = (windowHeight, windowWidth) => ({
|
|
|
80
64
|
});
|
|
81
65
|
const TOTAL_COLUMNS = 12;
|
|
82
66
|
const MAX_ITEMS_THRESHOLD = 12;
|
|
83
|
-
const MultiSelectFilter = /*#__PURE__*/React.forwardRef((
|
|
67
|
+
const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
84
68
|
let {
|
|
85
69
|
label,
|
|
86
70
|
subtitle,
|
|
@@ -102,7 +86,7 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
102
86
|
rowLimit = 12,
|
|
103
87
|
dictionary = defaultDictionary,
|
|
104
88
|
...rest
|
|
105
|
-
} =
|
|
89
|
+
} = _ref3;
|
|
106
90
|
const viewport = useViewport();
|
|
107
91
|
const {
|
|
108
92
|
currentValues,
|
|
@@ -117,23 +101,6 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
117
101
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
118
102
|
const [checkedIds, setCheckedIds] = React.useState(currentValues ?? []);
|
|
119
103
|
const [maxWidth, setMaxWidth] = React.useState(false);
|
|
120
|
-
const themeTokens = useThemeTokens('ButtonDropdown', tokens, variant);
|
|
121
|
-
const getItemTokens = useThemeTokensCallback('ButtonDropdown', tokens, variant);
|
|
122
|
-
const getButtonTokens = buttonState => selectTokens('Button', getItemTokens(buttonState));
|
|
123
|
-
const getCopy = useCopy({
|
|
124
|
-
dictionary,
|
|
125
|
-
copy
|
|
126
|
-
});
|
|
127
|
-
const colSizeNotMobile = items.length > rowLimit ? 2 : 1;
|
|
128
|
-
const colSize = viewport !== 'xs' ? colSizeNotMobile : 1;
|
|
129
|
-
const itemsLengthNotMobile = items.length > 24 ? items.length / 2 : rowLimit;
|
|
130
|
-
const isSelected = currentValues.length > 0;
|
|
131
|
-
const rowLength = viewport !== 'xs' ? itemsLengthNotMobile : items.length;
|
|
132
|
-
React.useEffect(() => {
|
|
133
|
-
if (colSize === 1) return setMaxWidth(false);
|
|
134
|
-
return colSize === 2 && setMaxWidth(true);
|
|
135
|
-
}, [colSize]);
|
|
136
|
-
React.useEffect(() => setCheckedIds(currentValues ?? []), [currentValues]);
|
|
137
104
|
const {
|
|
138
105
|
headerFontColor,
|
|
139
106
|
headerFontSize,
|
|
@@ -147,6 +114,20 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
147
114
|
subHeaderLineHeight,
|
|
148
115
|
minHeight,
|
|
149
116
|
minWidth,
|
|
117
|
+
labelFontName,
|
|
118
|
+
labelFontSize,
|
|
119
|
+
labelFontWeight,
|
|
120
|
+
labelColor,
|
|
121
|
+
labelLineHeight,
|
|
122
|
+
labelPaddingTop,
|
|
123
|
+
labelPaddingBottom,
|
|
124
|
+
labelPaddingLeft,
|
|
125
|
+
labelPaddingRight,
|
|
126
|
+
buttonBorderColor,
|
|
127
|
+
buttonIconSize,
|
|
128
|
+
buttonIconPadding,
|
|
129
|
+
subtitleColor,
|
|
130
|
+
dividerColor,
|
|
150
131
|
...restTokens
|
|
151
132
|
} = useThemeTokens('MultiSelectFilter', tokens, {
|
|
152
133
|
...variant,
|
|
@@ -155,6 +136,36 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
155
136
|
}, {
|
|
156
137
|
viewport
|
|
157
138
|
});
|
|
139
|
+
const dropdownTokens = {
|
|
140
|
+
borderColor: buttonBorderColor,
|
|
141
|
+
iconSize: buttonIconSize,
|
|
142
|
+
iconPadding: buttonIconPadding,
|
|
143
|
+
lineHeight: labelLineHeight,
|
|
144
|
+
fontName: labelFontName,
|
|
145
|
+
fontSize: labelFontSize,
|
|
146
|
+
fontWeight: labelFontWeight,
|
|
147
|
+
color: labelColor,
|
|
148
|
+
paddingTop: labelPaddingTop,
|
|
149
|
+
paddingBottom: labelPaddingBottom,
|
|
150
|
+
paddingLeft: labelPaddingLeft,
|
|
151
|
+
paddingRight: labelPaddingRight
|
|
152
|
+
};
|
|
153
|
+
const getButtonDropdownTokens = useThemeTokensCallback('ButtonDropdown', dropdownTokens, variant);
|
|
154
|
+
const getButtonTokens = buttonState => selectTokens('ButtonDropdown', getButtonDropdownTokens(buttonState));
|
|
155
|
+
const getCopy = useCopy({
|
|
156
|
+
dictionary,
|
|
157
|
+
copy
|
|
158
|
+
});
|
|
159
|
+
const colSizeNotMobile = items.length > rowLimit ? 2 : 1;
|
|
160
|
+
const colSize = viewport !== 'xs' ? colSizeNotMobile : 1;
|
|
161
|
+
const itemsLengthNotMobile = items.length > 24 ? items.length / 2 : rowLimit;
|
|
162
|
+
const isSelected = currentValues.length > 0;
|
|
163
|
+
const rowLength = viewport !== 'xs' ? itemsLengthNotMobile : items.length;
|
|
164
|
+
React.useEffect(() => {
|
|
165
|
+
if (colSize === 1) return setMaxWidth(false);
|
|
166
|
+
return colSize === 2 && setMaxWidth(true);
|
|
167
|
+
}, [colSize]);
|
|
168
|
+
React.useEffect(() => setCheckedIds(currentValues ?? []), [currentValues]);
|
|
158
169
|
const uniqueFields = ['id', 'label'];
|
|
159
170
|
if (!containUniqueFields(items, uniqueFields)) {
|
|
160
171
|
throw new Error(`MultiSelectFilter items must have unique ${uniqueFields.join(', ')}`);
|
|
@@ -213,7 +224,7 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
213
224
|
const subeHeaderStyles = applyTextStyles({
|
|
214
225
|
fontSize: subHeaderFontSize,
|
|
215
226
|
fontWeight: subHeaderFontWeight,
|
|
216
|
-
fontColor:
|
|
227
|
+
fontColor: subtitleColor
|
|
217
228
|
});
|
|
218
229
|
const {
|
|
219
230
|
overlaidPosition,
|
|
@@ -299,7 +310,9 @@ const MultiSelectFilter = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
|
299
310
|
});
|
|
300
311
|
const controlsContent = /*#__PURE__*/_jsxs(_Fragment, {
|
|
301
312
|
children: [isScrolling ? /*#__PURE__*/_jsx(Divider, {
|
|
302
|
-
tokens:
|
|
313
|
+
tokens: {
|
|
314
|
+
color: dividerColor
|
|
315
|
+
},
|
|
303
316
|
space: 4
|
|
304
317
|
}) : /*#__PURE__*/_jsx(Spacer, {
|
|
305
318
|
space: 4
|
|
@@ -274,6 +274,7 @@ const getDefaultStyles = (themeTokens, themeOptions, maxWidth, dismissible, view
|
|
|
274
274
|
* Show system notifications at the top of the page, below the navigation, and expands the full-width of the viewport
|
|
275
275
|
*/
|
|
276
276
|
const Notification = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
277
|
+
var _variant$style;
|
|
277
278
|
let {
|
|
278
279
|
children,
|
|
279
280
|
system,
|
|
@@ -290,6 +291,9 @@ const Notification = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
|
290
291
|
dictionary,
|
|
291
292
|
copy
|
|
292
293
|
});
|
|
294
|
+
|
|
295
|
+
// TODO: Remove this once the system style variant is deprecated
|
|
296
|
+
const isSystemEnabled = system || (variant === null || variant === void 0 || (_variant$style = variant.style) === null || _variant$style === void 0 ? void 0 : _variant$style.includes('system'));
|
|
293
297
|
const {
|
|
294
298
|
themeOptions
|
|
295
299
|
} = useTheme();
|
|
@@ -298,7 +302,7 @@ const Notification = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
|
298
302
|
} = themeOptions;
|
|
299
303
|
const useTokens = enableMediaQueryStyleSheet ? useResponsiveThemeTokens : useThemeTokens;
|
|
300
304
|
const themeTokens = useTokens('Notification', tokens, variant, {
|
|
301
|
-
system,
|
|
305
|
+
system: isSystemEnabled,
|
|
302
306
|
viewport
|
|
303
307
|
});
|
|
304
308
|
const maxWidth = useResponsiveProp(themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.contentMaxWidth);
|
|
@@ -323,9 +327,9 @@ const Notification = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
|
|
|
323
327
|
selectDismissIconPropsIds: {}
|
|
324
328
|
});
|
|
325
329
|
if (enableMediaQueryStyleSheet) {
|
|
326
|
-
notificationComponentRef.current = getMediaQueryStyles(themeTokens, themeOptions, mediaIdsRef, dismissible, viewport,
|
|
330
|
+
notificationComponentRef.current = getMediaQueryStyles(themeTokens, themeOptions, mediaIdsRef, dismissible, viewport, isSystemEnabled);
|
|
327
331
|
} else {
|
|
328
|
-
notificationComponentRef.current = getDefaultStyles(themeTokens, themeOptions, maxWidth, dismissible, viewport,
|
|
332
|
+
notificationComponentRef.current = getDefaultStyles(themeTokens, themeOptions, maxWidth, dismissible, viewport, isSystemEnabled);
|
|
329
333
|
}
|
|
330
334
|
if (isDismissed) {
|
|
331
335
|
return null;
|
package/lib/Search/Search.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import View from "react-native-web/dist/exports/View";
|
|
3
|
+
import Platform from "react-native-web/dist/exports/Platform";
|
|
3
4
|
import PropTypes from 'prop-types';
|
|
4
5
|
import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider';
|
|
5
6
|
import { a11yProps, getTokensPropType, selectSystemProps, selectTokens, useInputValue, useSpacingScale, textInputHandlerProps, textInputProps, variantProp, viewProps, contentfulProps } from '../utils';
|
|
@@ -7,6 +8,7 @@ import TextInputBase from '../TextInput/TextInputBase';
|
|
|
7
8
|
import ButtonBase from '../Button/ButtonBase';
|
|
8
9
|
import useCopy from '../utils/useCopy';
|
|
9
10
|
import dictionary from './dictionary';
|
|
11
|
+
import Icon from '../Icon';
|
|
10
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
13
|
const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([a11yProps, viewProps, contentfulProps]);
|
|
12
14
|
const [selectInputProps, selectedInputPropTypes] = selectSystemProps([textInputHandlerProps, textInputProps]);
|
|
@@ -33,7 +35,7 @@ const selectInputTokens = _ref => {
|
|
|
33
35
|
paddingRight: paddingWithButtons
|
|
34
36
|
};
|
|
35
37
|
};
|
|
36
|
-
const selectButtonTokens = tokens => selectTokens('
|
|
38
|
+
const selectButtonTokens = tokens => selectTokens('SearchButton', tokens);
|
|
37
39
|
const selectIconTokens = _ref2 => {
|
|
38
40
|
let {
|
|
39
41
|
iconSize,
|
|
@@ -44,6 +46,26 @@ const selectIconTokens = _ref2 => {
|
|
|
44
46
|
size: iconSize
|
|
45
47
|
};
|
|
46
48
|
};
|
|
49
|
+
const selectBorderTokens = _ref3 => {
|
|
50
|
+
let {
|
|
51
|
+
borderWidth,
|
|
52
|
+
mobileBorderWidth,
|
|
53
|
+
...tokens
|
|
54
|
+
} = _ref3;
|
|
55
|
+
return {
|
|
56
|
+
borderWidth: Platform.OS === 'web' ? borderWidth : mobileBorderWidth,
|
|
57
|
+
...tokens
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
const modifyButtonTokens = tokens => {
|
|
61
|
+
const modifiedTokens = {
|
|
62
|
+
...tokens
|
|
63
|
+
};
|
|
64
|
+
if (Platform.OS !== 'web') {
|
|
65
|
+
modifiedTokens.backgroundColor = tokens.mobileBackgroundColor;
|
|
66
|
+
}
|
|
67
|
+
return modifiedTokens;
|
|
68
|
+
};
|
|
47
69
|
|
|
48
70
|
/**
|
|
49
71
|
* The `Search` component is a combination of a `TextInput` and 2 different kinds of custom buttons.
|
|
@@ -58,7 +80,7 @@ const selectIconTokens = _ref2 => {
|
|
|
58
80
|
* Use the following props to supply additional accessibility labels for the input - `accessibilityLabel`,
|
|
59
81
|
* clear button - `clearButtonAccessibilityLabel`, and submit button - `submitButtonAccessibilityLabel`.
|
|
60
82
|
*/
|
|
61
|
-
const Search = /*#__PURE__*/React.forwardRef((
|
|
83
|
+
const Search = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
62
84
|
let {
|
|
63
85
|
initialValue,
|
|
64
86
|
value,
|
|
@@ -73,9 +95,10 @@ const Search = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
73
95
|
tokens,
|
|
74
96
|
variant,
|
|
75
97
|
nativeSubmitBtnID,
|
|
98
|
+
searchIconPosition = 'right',
|
|
76
99
|
dataSet,
|
|
77
100
|
...rest
|
|
78
|
-
} =
|
|
101
|
+
} = _ref4;
|
|
79
102
|
const {
|
|
80
103
|
currentValue = '',
|
|
81
104
|
setValue
|
|
@@ -139,8 +162,8 @@ const Search = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
139
162
|
testID: testID,
|
|
140
163
|
...selectInputProps(rest),
|
|
141
164
|
ref: ref,
|
|
142
|
-
tokens:
|
|
143
|
-
searchTokens: getThemeTokens(
|
|
165
|
+
tokens: pressableStates => selectInputTokens({
|
|
166
|
+
searchTokens: selectBorderTokens(getThemeTokens(pressableStates)),
|
|
144
167
|
buttonTokens,
|
|
145
168
|
buttonsGapSize,
|
|
146
169
|
isEmpty
|
|
@@ -155,16 +178,17 @@ const Search = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
155
178
|
onSubmitEditing: handleSubmit,
|
|
156
179
|
onFocus: handleFocus,
|
|
157
180
|
accessibilityLabel: a11yLabelText,
|
|
181
|
+
direction: searchIconPosition,
|
|
158
182
|
buttons: [ClearButtonIcon && !isEmpty && /*#__PURE__*/_jsx(ButtonBase, {
|
|
159
183
|
accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
|
|
160
184
|
accessibilityRole: "button",
|
|
161
185
|
inactive: inactive,
|
|
162
186
|
onPress: handleClear,
|
|
163
|
-
tokens:
|
|
187
|
+
tokens: pressableStates => modifyButtonTokens(selectButtonTokens(getButtonTokens(pressableStates))),
|
|
164
188
|
children: buttonState => /*#__PURE__*/_jsx(ClearButtonIcon, {
|
|
165
189
|
...selectIconTokens(getButtonTokens(buttonState))
|
|
166
190
|
})
|
|
167
|
-
}, "clear"), SubmitButtonIcon && /*#__PURE__*/_jsx(ButtonBase, {
|
|
191
|
+
}, "clear"), SubmitButtonIcon && (searchIconPosition === 'right' ? /*#__PURE__*/_jsx(ButtonBase, {
|
|
168
192
|
accessibilityLabel: getCopy('submitButtonAccessibilityLabel'),
|
|
169
193
|
accessibilityRole: "button",
|
|
170
194
|
inactive: inactive,
|
|
@@ -180,7 +204,14 @@ const Search = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
180
204
|
priority: 'high'
|
|
181
205
|
}))
|
|
182
206
|
})
|
|
183
|
-
}, "submit")
|
|
207
|
+
}, "submit-right") : /*#__PURE__*/_jsx(Icon, {
|
|
208
|
+
icon: SubmitButtonIcon,
|
|
209
|
+
testID: "iconLeft",
|
|
210
|
+
tokens: {
|
|
211
|
+
color: themeTokens.iconLeftColor,
|
|
212
|
+
size: themeTokens.iconLeftSize
|
|
213
|
+
}
|
|
214
|
+
}, "submitIcon"))]
|
|
184
215
|
})
|
|
185
216
|
});
|
|
186
217
|
});
|
|
@@ -5,7 +5,7 @@ import Platform from "react-native-web/dist/exports/Platform";
|
|
|
5
5
|
import NativePicker from 'react-native-picker-select';
|
|
6
6
|
import { a11yProps, componentPropType } from '../utils';
|
|
7
7
|
import Group from './Group';
|
|
8
|
-
import {
|
|
8
|
+
import { ANDROID_HORIZONTAL_PADDING_OFFSET, ANDROID_DEFAULT_PADDING, ALLOW_FONT_SCALING, ADJUSTS_FONT_SIZE_TO_FIT, MAX_FONT_SIZE_MULTIPLIER } from './constants';
|
|
9
9
|
|
|
10
10
|
// Styling of the native input is very limited, most of the styles have to be applied to an additional View
|
|
11
11
|
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
@@ -34,8 +34,7 @@ const selectAndroidContainerStyles = _ref2 => {
|
|
|
34
34
|
paddingLeft: paddingLeft > ANDROID_HORIZONTAL_PADDING_OFFSET ? paddingLeft - ANDROID_HORIZONTAL_PADDING_OFFSET : ANDROID_DEFAULT_PADDING,
|
|
35
35
|
paddingRight: paddingRight > ANDROID_HORIZONTAL_PADDING_OFFSET ? paddingRight - ANDROID_HORIZONTAL_PADDING_OFFSET : ANDROID_DEFAULT_PADDING,
|
|
36
36
|
paddingBottom: ANDROID_DEFAULT_PADDING,
|
|
37
|
-
paddingTop: ANDROID_DEFAULT_PADDING
|
|
38
|
-
height: rest.height + ANDROID_HEIGHT_OFFSET
|
|
37
|
+
paddingTop: ANDROID_DEFAULT_PADDING
|
|
39
38
|
};
|
|
40
39
|
};
|
|
41
40
|
const Picker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
@@ -94,7 +93,12 @@ const Picker = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
94
93
|
inputIOS: style,
|
|
95
94
|
inputAndroid: selectAndroidInputStyles(style)
|
|
96
95
|
},
|
|
97
|
-
placeholder: placeholder !== undefined ? placeholder : {}
|
|
96
|
+
placeholder: placeholder !== undefined ? placeholder : {},
|
|
97
|
+
textInputProps: {
|
|
98
|
+
allowFontScaling: ALLOW_FONT_SCALING,
|
|
99
|
+
adjustFontSizeToFit: ADJUSTS_FONT_SIZE_TO_FIT,
|
|
100
|
+
maxFontSizeMultiplier: MAX_FONT_SIZE_MULTIPLIER
|
|
101
|
+
}
|
|
98
102
|
});
|
|
99
103
|
return /*#__PURE__*/_jsx(_Fragment, {
|
|
100
104
|
children: Platform.OS === 'android' ? /*#__PURE__*/_jsx(View, {
|
package/lib/Select/constants.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Because Android
|
|
2
2
|
export const ANDROID_VALIDATION_ICON_CONTAINER_OFFSET = 5;
|
|
3
|
-
export const ANDROID_HEIGHT_OFFSET = 12;
|
|
4
3
|
export const ANDROID_HORIZONTAL_PADDING_OFFSET = 8;
|
|
5
|
-
export const ANDROID_DEFAULT_PADDING = 0;
|
|
4
|
+
export const ANDROID_DEFAULT_PADDING = 0;
|
|
5
|
+
export const ALLOW_FONT_SCALING = true;
|
|
6
|
+
export const ADJUSTS_FONT_SIZE_TO_FIT = true;
|
|
7
|
+
export const MAX_FONT_SIZE_MULTIPLIER = 3;
|