@telus-uds/components-base 3.12.2 → 3.13.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 +20 -2
- package/lib/cjs/Button/ButtonDropdown.js +105 -12
- package/lib/cjs/ExpandCollapse/ExpandCollapse.js +3 -1
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMini.js +1 -1
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMiniControl.js +30 -6
- package/lib/cjs/FlexGrid/FlexGrid.js +54 -5
- package/lib/cjs/Icon/Icon.js +3 -1
- package/lib/cjs/InputLabel/InputLabel.js +1 -1
- package/lib/cjs/InputSupports/InputSupports.js +1 -1
- package/lib/cjs/Notification/Notification.js +27 -8
- package/lib/cjs/utils/props/inputSupportsProps.js +1 -1
- package/lib/esm/Button/ButtonDropdown.js +107 -14
- package/lib/esm/ExpandCollapse/ExpandCollapse.js +4 -2
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMini.js +2 -2
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMiniControl.js +30 -6
- package/lib/esm/FlexGrid/FlexGrid.js +55 -6
- package/lib/esm/Icon/Icon.js +3 -1
- package/lib/esm/InputLabel/InputLabel.js +1 -1
- package/lib/esm/InputSupports/InputSupports.js +1 -1
- package/lib/esm/Notification/Notification.js +27 -8
- package/lib/esm/utils/props/inputSupportsProps.js +1 -1
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/Button/ButtonDropdown.jsx +109 -16
- package/src/ExpandCollapse/ExpandCollapse.jsx +5 -2
- package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +2 -2
- package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +39 -9
- package/src/FlexGrid/FlexGrid.jsx +62 -6
- package/src/Icon/Icon.jsx +3 -1
- package/src/InputLabel/InputLabel.jsx +1 -1
- package/src/InputSupports/InputSupports.jsx +1 -1
- package/src/Notification/Notification.jsx +58 -9
- package/src/utils/props/inputSupportsProps.js +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
|
-
import { Platform, Text, View } from 'react-native'
|
|
3
|
+
import { Platform, StyleSheet, Text, View } from 'react-native'
|
|
4
4
|
import buttonPropTypes, { textAndA11yText } from './propTypes'
|
|
5
5
|
import ButtonBase from './ButtonBase'
|
|
6
|
-
import { useThemeTokensCallback } from '../ThemeProvider'
|
|
6
|
+
import { applyTextStyles, useThemeTokensCallback } from '../ThemeProvider'
|
|
7
7
|
import {
|
|
8
8
|
a11yProps,
|
|
9
9
|
getTokensPropType,
|
|
@@ -13,9 +13,10 @@ import {
|
|
|
13
13
|
useInputValue
|
|
14
14
|
} from '../utils'
|
|
15
15
|
import Icon from '../Icon'
|
|
16
|
-
import { getStackedContent } from '../StackView'
|
|
17
16
|
import { getPressHandlersWithArgs } from '../utils/pressability'
|
|
18
17
|
|
|
18
|
+
const FULL_WIDTH_STYLE = 'full'
|
|
19
|
+
|
|
19
20
|
const selectIconTokens = ({
|
|
20
21
|
icon,
|
|
21
22
|
iconPosition,
|
|
@@ -50,6 +51,44 @@ const selectIconTokens = ({
|
|
|
50
51
|
}
|
|
51
52
|
})
|
|
52
53
|
|
|
54
|
+
const selectDescriptionTextStyles = (tokens) => ({
|
|
55
|
+
...applyTextStyles({
|
|
56
|
+
fontName: tokens?.descriptionFontName,
|
|
57
|
+
fontSize: tokens?.descriptionFontSize,
|
|
58
|
+
fontWeight: tokens?.descriptionFontWeight,
|
|
59
|
+
fontColor: tokens?.color
|
|
60
|
+
}),
|
|
61
|
+
paddingBottom: tokens?.descriptionTextPaddingBottom
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const selectLeadIconTokens = (tokens) => ({
|
|
65
|
+
color: tokens?.leadIconColor,
|
|
66
|
+
backgroundColor: tokens?.leadIconBackgroundColor,
|
|
67
|
+
size: tokens?.leadIconSize,
|
|
68
|
+
borderRadius: tokens?.leadIconBorderRadius,
|
|
69
|
+
padding: tokens?.leadIconPadding
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const selectLeadIconContainerStyles = (tokens) => ({
|
|
73
|
+
paddingTop: tokens?.leadIconContainerPaddingTop,
|
|
74
|
+
paddingBottom: tokens?.leadIconContainerPaddingBottom,
|
|
75
|
+
paddingLeft: tokens?.leadIconContainerPaddingLeft,
|
|
76
|
+
paddingRight: tokens?.leadIconContainerPaddingRight
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const selectTextContainerStyles = (tokens) => ({
|
|
80
|
+
paddingLeft: tokens?.textPaddingLeft,
|
|
81
|
+
paddingRight: tokens?.textPaddingRight
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const selectStackedContentStyles = (tokens, iconPosition, isFullWidth) => ({
|
|
85
|
+
...staticStyles.stackedContent,
|
|
86
|
+
gap: tokens?.iconSpace,
|
|
87
|
+
flexDirection: iconPosition === 'left' ? 'row' : 'row-reverse',
|
|
88
|
+
...(Platform.OS === 'web' && { flex: 1 }),
|
|
89
|
+
...(isFullWidth && { justifyContent: 'space-between', flex: 1 })
|
|
90
|
+
})
|
|
91
|
+
|
|
53
92
|
const ButtonDropdown = React.forwardRef(
|
|
54
93
|
(
|
|
55
94
|
{
|
|
@@ -63,10 +102,14 @@ const ButtonDropdown = React.forwardRef(
|
|
|
63
102
|
readOnly = false,
|
|
64
103
|
children = null,
|
|
65
104
|
accessibilityRole = 'radio',
|
|
105
|
+
description,
|
|
106
|
+
singleOption,
|
|
66
107
|
...props
|
|
67
108
|
},
|
|
68
109
|
ref
|
|
69
110
|
) => {
|
|
111
|
+
const isFullWidth = variant?.width === FULL_WIDTH_STYLE
|
|
112
|
+
|
|
70
113
|
const { currentValue: isOpen, setValue: setIsOpen } = useInputValue(
|
|
71
114
|
{
|
|
72
115
|
value,
|
|
@@ -85,7 +128,11 @@ const ButtonDropdown = React.forwardRef(
|
|
|
85
128
|
|
|
86
129
|
const getTokens = useThemeTokensCallback('ButtonDropdown', tokens, extraState)
|
|
87
130
|
|
|
88
|
-
const getButtonTokens = (buttonState) =>
|
|
131
|
+
const getButtonTokens = (buttonState) => ({
|
|
132
|
+
...selectTokens('Button', getTokens(buttonState)),
|
|
133
|
+
iconSpace: props?.icon ? getTokens(buttonState)?.iconSpace : 0,
|
|
134
|
+
...(isFullWidth && { width: 'full' })
|
|
135
|
+
})
|
|
89
136
|
|
|
90
137
|
// Pass an object of relevant component state as first argument for any passed-in press handlers
|
|
91
138
|
const pressHandlers = getPressHandlersWithArgs(props, [{ label, open: isOpen }])
|
|
@@ -103,7 +150,7 @@ const ButtonDropdown = React.forwardRef(
|
|
|
103
150
|
{...pressHandlers}
|
|
104
151
|
onPress={handlePress}
|
|
105
152
|
tokens={getButtonTokens}
|
|
106
|
-
inactive={inactive}
|
|
153
|
+
inactive={singleOption || inactive}
|
|
107
154
|
icon={() => null}
|
|
108
155
|
accessibilityRole={accessibilityRole}
|
|
109
156
|
{...props}
|
|
@@ -116,31 +163,50 @@ const ButtonDropdown = React.forwardRef(
|
|
|
116
163
|
// - Token sets: https://github.com/telus/universal-design-system/issues/782
|
|
117
164
|
|
|
118
165
|
const itemTokens = getTokens(buttonState)
|
|
166
|
+
const leadIcon = itemTokens?.leadIcon
|
|
119
167
|
|
|
120
168
|
const {
|
|
121
169
|
iconTokens,
|
|
122
170
|
iconPosition,
|
|
123
|
-
iconSpace,
|
|
124
171
|
iconWrapperStyle,
|
|
125
172
|
icon: IconComponent
|
|
126
173
|
} = selectIconTokens(itemTokens)
|
|
127
174
|
|
|
128
|
-
const iconContent =
|
|
129
|
-
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
|
|
175
|
+
const iconContent =
|
|
176
|
+
IconComponent && !singleOption ? (
|
|
177
|
+
<View style={iconWrapperStyle}>
|
|
178
|
+
<Icon icon={IconComponent} tokens={iconTokens} />
|
|
179
|
+
</View>
|
|
180
|
+
) : null
|
|
133
181
|
|
|
134
182
|
const childrenContent = () =>
|
|
135
183
|
typeof children === 'function'
|
|
136
184
|
? children({ ...resolvePressableState(buttonState, extraState), textStyles })
|
|
137
185
|
: children
|
|
138
186
|
|
|
139
|
-
const content = children ?
|
|
187
|
+
const content = children ? (
|
|
188
|
+
childrenContent()
|
|
189
|
+
) : (
|
|
190
|
+
<View style={staticStyles.contentContainer}>
|
|
191
|
+
{leadIcon && (
|
|
192
|
+
<View style={selectLeadIconContainerStyles(itemTokens)}>
|
|
193
|
+
<Icon icon={leadIcon} tokens={selectLeadIconTokens(itemTokens)} />
|
|
194
|
+
</View>
|
|
195
|
+
)}
|
|
196
|
+
<View style={[staticStyles.textContainer, selectTextContainerStyles(itemTokens)]}>
|
|
197
|
+
<Text style={textStyles}>{label}</Text>
|
|
198
|
+
{description && (
|
|
199
|
+
<Text style={selectDescriptionTextStyles(itemTokens)}>{description}</Text>
|
|
200
|
+
)}
|
|
201
|
+
</View>
|
|
202
|
+
</View>
|
|
203
|
+
)
|
|
140
204
|
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
|
|
205
|
+
return (
|
|
206
|
+
<View style={selectStackedContentStyles(itemTokens, iconPosition, isFullWidth)}>
|
|
207
|
+
{iconContent}
|
|
208
|
+
{content}
|
|
209
|
+
</View>
|
|
144
210
|
)
|
|
145
211
|
}}
|
|
146
212
|
</ButtonBase>
|
|
@@ -176,7 +242,34 @@ ButtonDropdown.propTypes = {
|
|
|
176
242
|
/**
|
|
177
243
|
* By default, `ButtonDropdown` is treated by accessibility tools as a radio button.
|
|
178
244
|
*/
|
|
179
|
-
accessibilityRole: PropTypes.string
|
|
245
|
+
accessibilityRole: PropTypes.string,
|
|
246
|
+
/**
|
|
247
|
+
* The description of ButtonDropdown.
|
|
248
|
+
*/
|
|
249
|
+
description: PropTypes.string,
|
|
250
|
+
/**
|
|
251
|
+
* Use this prop to render the ButtonDropdown as display only without any interaction when there is only one option.
|
|
252
|
+
*/
|
|
253
|
+
singleOption: PropTypes.bool
|
|
180
254
|
}
|
|
181
255
|
|
|
256
|
+
const staticStyles = StyleSheet.create({
|
|
257
|
+
textContainer: {
|
|
258
|
+
alignItems: 'flex-start',
|
|
259
|
+
flexShrink: 1,
|
|
260
|
+
...(Platform.OS === 'web' && { flex: 1 })
|
|
261
|
+
},
|
|
262
|
+
contentContainer: {
|
|
263
|
+
flexDirection: 'row',
|
|
264
|
+
alignContent: 'center',
|
|
265
|
+
alignItems: 'center',
|
|
266
|
+
...(Platform.OS === 'web' && { flex: 1 }),
|
|
267
|
+
flexShrink: 1
|
|
268
|
+
},
|
|
269
|
+
stackedContent: {
|
|
270
|
+
flexDirection: 'row',
|
|
271
|
+
alignItems: 'center'
|
|
272
|
+
}
|
|
273
|
+
})
|
|
274
|
+
|
|
182
275
|
export default ButtonDropdown
|
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
useMultipleInputValues,
|
|
11
11
|
variantProp,
|
|
12
12
|
viewProps,
|
|
13
|
-
contentfulProps
|
|
13
|
+
contentfulProps,
|
|
14
|
+
useUniqueId
|
|
14
15
|
} from '../utils'
|
|
15
16
|
|
|
16
17
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
@@ -36,6 +37,8 @@ function selectBorderStyles(tokens) {
|
|
|
36
37
|
*/
|
|
37
38
|
const ExpandCollapse = React.forwardRef(
|
|
38
39
|
({ children, tokens, variant, maxOpen, open, initialOpen, onChange, dataSet, ...rest }, ref) => {
|
|
40
|
+
const instanceId = useUniqueId('ExpandCollapse')
|
|
41
|
+
|
|
39
42
|
const {
|
|
40
43
|
currentValues: openIds,
|
|
41
44
|
toggleOneValue: onToggle,
|
|
@@ -54,7 +57,7 @@ const ExpandCollapse = React.forwardRef(
|
|
|
54
57
|
<View style={staticStyles.container} ref={ref} {...selectProps(rest)} dataSet={dataSet}>
|
|
55
58
|
<View style={selectBorderStyles(themeTokens)}>
|
|
56
59
|
{typeof children === 'function'
|
|
57
|
-
? children({ openIds, onToggle, resetValues, setValues, unsetValues })
|
|
60
|
+
? children({ openIds, onToggle, resetValues, setValues, unsetValues, instanceId })
|
|
58
61
|
: children}
|
|
59
62
|
</View>
|
|
60
63
|
</View>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import ExpandCollapse from '../ExpandCollapse'
|
|
4
|
-
import { getTokensPropType, selectSystemProps, contentfulProps } from '../utils'
|
|
4
|
+
import { getTokensPropType, selectSystemProps, contentfulProps, useUniqueId } from '../utils'
|
|
5
5
|
import { variantProp } from '../utils/props'
|
|
6
6
|
import ExpandCollapseMiniControl from './ExpandCollapseMiniControl'
|
|
7
7
|
|
|
@@ -12,7 +12,7 @@ const ExpandCollapseMini = React.forwardRef(
|
|
|
12
12
|
{ children, onToggle = () => {}, tokens = {}, nativeID, initialOpen = false, dataSet, ...rest },
|
|
13
13
|
ref
|
|
14
14
|
) => {
|
|
15
|
-
const expandCollapeMiniPanelId = 'ExpandCollapseMiniPanel'
|
|
15
|
+
const expandCollapeMiniPanelId = useUniqueId('ExpandCollapseMiniPanel')
|
|
16
16
|
const handleChange = (openPanels, event) => {
|
|
17
17
|
if (typeof onToggle === 'function') {
|
|
18
18
|
const isOpen = openPanels.length > 0
|
|
@@ -42,10 +42,15 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
42
42
|
pressed
|
|
43
43
|
}
|
|
44
44
|
)
|
|
45
|
-
const {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
const { fontSize, lineHeight, iconSize, icon } = useThemeTokens(
|
|
46
|
+
'ExpandCollapseMiniControl',
|
|
47
|
+
tokens,
|
|
48
|
+
variant,
|
|
49
|
+
{
|
|
50
|
+
expanded,
|
|
51
|
+
focus
|
|
52
|
+
}
|
|
53
|
+
)
|
|
49
54
|
|
|
50
55
|
// Choose hover styles when any part of Control is hoverred
|
|
51
56
|
const appearance = { ...variant, hover }
|
|
@@ -54,16 +59,39 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
54
59
|
const { hover: linkHover } = linkState || {}
|
|
55
60
|
const isHovered = hover || linkHover
|
|
56
61
|
|
|
62
|
+
const iconBaselineOffset = 0
|
|
63
|
+
const hoverTranslateY = 4
|
|
64
|
+
|
|
65
|
+
// Calculate baseline alignment to vertically center icon with text
|
|
66
|
+
// This combines font and icon metrics with adjustments for visual balance
|
|
67
|
+
const fontBaseline = fontSize / hoverTranslateY // Quarter of font size - adjusts for text's visual center point
|
|
68
|
+
const iconBaseline = iconSize / hoverTranslateY // Quarter of icon size - adjusts for icon's visual center point
|
|
69
|
+
const staticOffset = hoverTranslateY // Fixed downward adjustment to fine-tune vertical alignment
|
|
70
|
+
const sizeCompensation = -Math.abs(iconSize - fontSize) // Compensates when icon and text sizes differ significantly
|
|
71
|
+
|
|
72
|
+
const baselineAlignment = fontBaseline + iconBaseline - staticOffset + sizeCompensation
|
|
73
|
+
|
|
57
74
|
if (Platform.OS !== 'web') {
|
|
58
|
-
|
|
75
|
+
// For native platforms, use baseline alignment with optional offset
|
|
76
|
+
return { iconTranslateY: baselineAlignment + iconBaselineOffset }
|
|
59
77
|
}
|
|
60
78
|
|
|
61
79
|
if (isHovered) {
|
|
62
|
-
//
|
|
63
|
-
|
|
80
|
+
// Apply animation offset to the baseline-aligned position
|
|
81
|
+
// When expanded: move icon UP (1.3 the hover distance for clear movement)
|
|
82
|
+
// When collapsed: move icon DOWN (single hover distance)
|
|
83
|
+
const hoverMovementDistance = 1.3
|
|
84
|
+
const animationOffset = expanded
|
|
85
|
+
? -(hoverTranslateY * hoverMovementDistance)
|
|
86
|
+
: hoverTranslateY
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
iconTranslateY: baselineAlignment + iconBaselineOffset + animationOffset
|
|
90
|
+
}
|
|
64
91
|
}
|
|
65
92
|
|
|
66
|
-
|
|
93
|
+
// Default state uses baseline alignment with optional offset
|
|
94
|
+
return { iconTranslateY: baselineAlignment + iconBaselineOffset }
|
|
67
95
|
}
|
|
68
96
|
|
|
69
97
|
return (
|
|
@@ -73,7 +101,9 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
73
101
|
iconPosition={iconPosition}
|
|
74
102
|
tokens={(linkState) => ({
|
|
75
103
|
...linkTokens,
|
|
76
|
-
...getTokens(linkState)
|
|
104
|
+
...getTokens(linkState),
|
|
105
|
+
iconSize,
|
|
106
|
+
blockLineHeight: lineHeight
|
|
77
107
|
})}
|
|
78
108
|
ref={ref}
|
|
79
109
|
{...presentationOnly}
|
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
selectSystemProps,
|
|
11
11
|
BaseView,
|
|
12
12
|
StyleSheet,
|
|
13
|
-
createMediaQueryStyles
|
|
13
|
+
createMediaQueryStyles,
|
|
14
|
+
useResponsiveProp
|
|
14
15
|
} from '../utils'
|
|
15
16
|
import Row from './Row'
|
|
16
17
|
import Col from './Col'
|
|
@@ -21,6 +22,37 @@ import { useViewport } from '../ViewportProvider'
|
|
|
21
22
|
|
|
22
23
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
23
24
|
|
|
25
|
+
const CONTENT_MAX_WIDTH = 'max'
|
|
26
|
+
const CONTENT_FULL_WIDTH = 'full'
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Resolves the maximum width for content based on the provided value and responsive width.
|
|
30
|
+
*
|
|
31
|
+
* @param {number|string|null|undefined} contentMinWidthValue - The minimum width value for the content.
|
|
32
|
+
* Can be a number (pixels), a string constant (e.g., CONTENT_FULL_WIDTH, CONTENT_MAX_WIDTH), or null/undefined.
|
|
33
|
+
* @param {number|string} responsiveWidth - The responsive width to use when contentMinWidthValue is CONTENT_MAX_WIDTH.
|
|
34
|
+
* @returns {number|string|null} The resolved maximum width value, which can be a number, a string (e.g., '100%'), or null.
|
|
35
|
+
*/
|
|
36
|
+
const resolveContentMaxWidth = (contentMinWidthValue, responsiveWidth) => {
|
|
37
|
+
if (!contentMinWidthValue) {
|
|
38
|
+
return null
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (contentMinWidthValue === CONTENT_FULL_WIDTH) {
|
|
42
|
+
return '100%'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (Number.isFinite(contentMinWidthValue)) {
|
|
46
|
+
return contentMinWidthValue
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (contentMinWidthValue === CONTENT_MAX_WIDTH) {
|
|
50
|
+
return responsiveWidth
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return contentMinWidthValue
|
|
54
|
+
}
|
|
55
|
+
|
|
24
56
|
/**
|
|
25
57
|
* A mobile-first flexbox grid.
|
|
26
58
|
*/
|
|
@@ -40,6 +72,7 @@ const FlexGrid = React.forwardRef(
|
|
|
40
72
|
accessibilityRole,
|
|
41
73
|
children,
|
|
42
74
|
dataSet,
|
|
75
|
+
contentMinWidth,
|
|
43
76
|
...rest
|
|
44
77
|
},
|
|
45
78
|
ref
|
|
@@ -47,30 +80,36 @@ const FlexGrid = React.forwardRef(
|
|
|
47
80
|
const reverseLevel = applyInheritance([xsReverse, smReverse, mdReverse, lgReverse, xlReverse])
|
|
48
81
|
const viewport = useViewport()
|
|
49
82
|
const {
|
|
83
|
+
themeOptions,
|
|
50
84
|
themeOptions: { enableMediaQueryStyleSheet }
|
|
51
85
|
} = useTheme()
|
|
52
86
|
|
|
53
87
|
let flexgridStyles
|
|
54
88
|
let mediaIds
|
|
55
89
|
|
|
90
|
+
const contentMinWidthValue = useResponsiveProp(contentMinWidth)
|
|
91
|
+
const responsiveWidth = useResponsiveProp(themeOptions?.contentMaxWidth)
|
|
92
|
+
const maxWidth = resolveContentMaxWidth(contentMinWidthValue, responsiveWidth)
|
|
93
|
+
|
|
56
94
|
const stylesByViewport = {
|
|
57
95
|
xs: {
|
|
96
|
+
maxWidth: limitWidth ? viewports.map.get('sm') : maxWidth,
|
|
58
97
|
flexDirection: reverseLevel[0] ? 'column-reverse' : 'column'
|
|
59
98
|
},
|
|
60
99
|
sm: {
|
|
61
|
-
maxWidth: limitWidth
|
|
100
|
+
maxWidth: limitWidth ? viewports.map.get('sm') : maxWidth,
|
|
62
101
|
flexDirection: reverseLevel[1] ? 'column-reverse' : 'column'
|
|
63
102
|
},
|
|
64
103
|
md: {
|
|
65
|
-
maxWidth: limitWidth
|
|
104
|
+
maxWidth: limitWidth ? viewports.map.get('md') : maxWidth,
|
|
66
105
|
flexDirection: reverseLevel[2] ? 'column-reverse' : 'column'
|
|
67
106
|
},
|
|
68
107
|
lg: {
|
|
69
|
-
maxWidth: limitWidth
|
|
108
|
+
maxWidth: limitWidth ? viewports.map.get('lg') : maxWidth,
|
|
70
109
|
flexDirection: reverseLevel[3] ? 'column-reverse' : 'column'
|
|
71
110
|
},
|
|
72
111
|
xl: {
|
|
73
|
-
maxWidth: limitWidth
|
|
112
|
+
maxWidth: limitWidth ? viewports.map.get('xl') : maxWidth,
|
|
74
113
|
flexDirection: reverseLevel[4] ? 'column-reverse' : 'column'
|
|
75
114
|
}
|
|
76
115
|
}
|
|
@@ -162,7 +201,24 @@ FlexGrid.propTypes = {
|
|
|
162
201
|
/**
|
|
163
202
|
* The rows and columns of the Grid. Will typically be `FlexGrid.Row` and `FlexGrid.Col` components.
|
|
164
203
|
*/
|
|
165
|
-
children: PropTypes.node.isRequired
|
|
204
|
+
children: PropTypes.node.isRequired,
|
|
205
|
+
/**
|
|
206
|
+
* The minimum width of the content in the FlexGrid.
|
|
207
|
+
* This prop accepts responsive values for different viewports. If a number is provided,
|
|
208
|
+
* it will be the max content width for the desired viewport.
|
|
209
|
+
* - `xs`: 'max' | 'full' | <number>
|
|
210
|
+
* - `sm`: 'max' | 'full' | <number>
|
|
211
|
+
* - `md`: 'max' | 'full' | <number>
|
|
212
|
+
* - `lg`: 'max' | 'full' | <number>
|
|
213
|
+
* - `xl`: 'max' | 'full' | <number>
|
|
214
|
+
*/
|
|
215
|
+
contentMinWidth: PropTypes.shape({
|
|
216
|
+
xl: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
217
|
+
lg: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
218
|
+
md: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
219
|
+
sm: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number]),
|
|
220
|
+
xs: PropTypes.oneOfType([PropTypes.oneOf(['max', 'full']), PropTypes.number])
|
|
221
|
+
})
|
|
166
222
|
}
|
|
167
223
|
|
|
168
224
|
FlexGrid.Row = Row
|
package/src/Icon/Icon.jsx
CHANGED
|
@@ -38,7 +38,9 @@ const Icon = React.forwardRef(
|
|
|
38
38
|
width: themeTokens.size + themeTokens.width * 2, // sets the diameter of the circle which is the size of the icon plus twice the general padding established to obtain a perfect circle
|
|
39
39
|
height: themeTokens.size + themeTokens.width * 2
|
|
40
40
|
}
|
|
41
|
-
: {
|
|
41
|
+
: {
|
|
42
|
+
padding: themeTokens.padding
|
|
43
|
+
}
|
|
42
44
|
|
|
43
45
|
const getIconContentForMobile = () => {
|
|
44
46
|
if (Object.keys(paddingStyles).length) {
|
|
@@ -161,7 +161,7 @@ InputLabel.propTypes = {
|
|
|
161
161
|
/**
|
|
162
162
|
* Content of an optional `Tooltip`. If set, a tooltip button will be shown next to the label.
|
|
163
163
|
*/
|
|
164
|
-
tooltip: PropTypes.oneOfType([tooltipPropTypes, PropTypes.string]),
|
|
164
|
+
tooltip: PropTypes.oneOfType([PropTypes.shape(tooltipPropTypes), PropTypes.string]),
|
|
165
165
|
/**
|
|
166
166
|
* Current number of characterts of an input text.
|
|
167
167
|
*/
|
|
@@ -121,7 +121,7 @@ InputSupports.propTypes = {
|
|
|
121
121
|
* 1. `tooltip` as a string - The content of the tooltip.
|
|
122
122
|
* 2. `tooltip` as an object - Tooltip component props to be passed.
|
|
123
123
|
*/
|
|
124
|
-
tooltip: PropTypes.oneOfType([tooltipPropTypes, PropTypes.string]),
|
|
124
|
+
tooltip: PropTypes.oneOfType([PropTypes.shape(tooltipPropTypes), PropTypes.string]),
|
|
125
125
|
/**
|
|
126
126
|
* Use to visually mark an input as valid or invalid.
|
|
127
127
|
*/
|
|
@@ -26,6 +26,8 @@ import useCopy from '../utils/useCopy'
|
|
|
26
26
|
import dictionary from './dictionary'
|
|
27
27
|
import { useViewport } from '../ViewportProvider'
|
|
28
28
|
|
|
29
|
+
const CONTENT_MAX_WIDTH = 'max'
|
|
30
|
+
|
|
29
31
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
30
32
|
|
|
31
33
|
const selectContainerStyles = (tokens) => ({ ...tokens })
|
|
@@ -65,8 +67,14 @@ const selectDismissButtonContainerStyles = ({ dismissButtonGap }) => ({
|
|
|
65
67
|
placeContent: 'start'
|
|
66
68
|
})
|
|
67
69
|
|
|
68
|
-
const selectContentContainerStyle = (
|
|
69
|
-
|
|
70
|
+
const selectContentContainerStyle = (
|
|
71
|
+
themeTokens,
|
|
72
|
+
maxWidth,
|
|
73
|
+
system,
|
|
74
|
+
viewport,
|
|
75
|
+
useContentMaxWidth
|
|
76
|
+
) => ({
|
|
77
|
+
maxWidth: system && (useContentMaxWidth || viewport === 'xl') ? maxWidth : '100%',
|
|
70
78
|
width: '100%',
|
|
71
79
|
paddingRight: themeTokens?.containerPaddingRight,
|
|
72
80
|
paddingLeft: themeTokens?.containerPaddingLeft
|
|
@@ -79,7 +87,8 @@ const getMediaQueryStyles = (
|
|
|
79
87
|
mediaIdsRef,
|
|
80
88
|
dismissible,
|
|
81
89
|
viewport,
|
|
82
|
-
system
|
|
90
|
+
system,
|
|
91
|
+
useContentMaxWidth
|
|
83
92
|
) => {
|
|
84
93
|
const transformedSelectContainerStyles = Object.entries(themeTokens).reduce(
|
|
85
94
|
(acc, [vp, viewportTokens]) => {
|
|
@@ -100,7 +109,7 @@ const getMediaQueryStyles = (
|
|
|
100
109
|
const transformedSelectContentContainerStyles = Object.entries(themeTokens).reduce(
|
|
101
110
|
(acc, [vp, viewportTokens]) => {
|
|
102
111
|
acc[vp] = {
|
|
103
|
-
...selectContentContainerStyle(viewportTokens, maxWidth, system, vp),
|
|
112
|
+
...selectContentContainerStyle(viewportTokens, maxWidth, system, vp, useContentMaxWidth),
|
|
104
113
|
flexDirection: 'row',
|
|
105
114
|
flexShrink: 1,
|
|
106
115
|
justifyContent: 'space-between',
|
|
@@ -169,7 +178,15 @@ const getMediaQueryStyles = (
|
|
|
169
178
|
}
|
|
170
179
|
}
|
|
171
180
|
|
|
172
|
-
const getDefaultStyles = (
|
|
181
|
+
const getDefaultStyles = (
|
|
182
|
+
themeTokens,
|
|
183
|
+
themeOptions,
|
|
184
|
+
maxWidth,
|
|
185
|
+
dismissible,
|
|
186
|
+
viewport,
|
|
187
|
+
system,
|
|
188
|
+
useContentMaxWidth
|
|
189
|
+
) => ({
|
|
173
190
|
containerStyles: {
|
|
174
191
|
container: {
|
|
175
192
|
flexDirection: 'column',
|
|
@@ -181,7 +198,7 @@ const getDefaultStyles = (themeTokens, themeOptions, maxWidth, dismissible, view
|
|
|
181
198
|
flexDirection: 'row',
|
|
182
199
|
flexShrink: 1,
|
|
183
200
|
justifyContent: 'space-between',
|
|
184
|
-
...selectContentContainerStyle(themeTokens, maxWidth, system, viewport),
|
|
201
|
+
...selectContentContainerStyle(themeTokens, maxWidth, system, viewport, useContentMaxWidth),
|
|
185
202
|
...(system && { alignSelf: 'center' })
|
|
186
203
|
}
|
|
187
204
|
},
|
|
@@ -251,7 +268,20 @@ const getDefaultStyles = (themeTokens, themeOptions, maxWidth, dismissible, view
|
|
|
251
268
|
* Show system notifications at the top of the page, below the navigation, and expands the full-width of the viewport
|
|
252
269
|
*/
|
|
253
270
|
const Notification = React.forwardRef(
|
|
254
|
-
(
|
|
271
|
+
(
|
|
272
|
+
{
|
|
273
|
+
children,
|
|
274
|
+
system,
|
|
275
|
+
dismissible,
|
|
276
|
+
copy = 'en',
|
|
277
|
+
tokens,
|
|
278
|
+
variant,
|
|
279
|
+
onDismiss,
|
|
280
|
+
contentMinWidth,
|
|
281
|
+
...rest
|
|
282
|
+
},
|
|
283
|
+
ref
|
|
284
|
+
) => {
|
|
255
285
|
const [isDismissed, setIsDismissed] = React.useState(false)
|
|
256
286
|
const viewport = useViewport()
|
|
257
287
|
const getCopy = useCopy({ dictionary, copy })
|
|
@@ -266,6 +296,7 @@ const Notification = React.forwardRef(
|
|
|
266
296
|
system: isSystemEnabled,
|
|
267
297
|
viewport
|
|
268
298
|
})
|
|
299
|
+
const useContentMaxWidth = useResponsiveProp(contentMinWidth) === CONTENT_MAX_WIDTH
|
|
269
300
|
const maxWidth = useResponsiveProp(
|
|
270
301
|
themeOptions?.contentMaxWidth,
|
|
271
302
|
viewports.map.get(viewports.xl)
|
|
@@ -300,7 +331,8 @@ const Notification = React.forwardRef(
|
|
|
300
331
|
mediaIdsRef,
|
|
301
332
|
dismissible,
|
|
302
333
|
viewport,
|
|
303
|
-
isSystemEnabled
|
|
334
|
+
isSystemEnabled,
|
|
335
|
+
useContentMaxWidth
|
|
304
336
|
)
|
|
305
337
|
} else {
|
|
306
338
|
notificationComponentRef.current = getDefaultStyles(
|
|
@@ -309,7 +341,8 @@ const Notification = React.forwardRef(
|
|
|
309
341
|
maxWidth,
|
|
310
342
|
dismissible,
|
|
311
343
|
viewport,
|
|
312
|
-
isSystemEnabled
|
|
344
|
+
isSystemEnabled,
|
|
345
|
+
useContentMaxWidth
|
|
313
346
|
)
|
|
314
347
|
}
|
|
315
348
|
|
|
@@ -434,6 +467,22 @@ Notification.propTypes = {
|
|
|
434
467
|
* Callback function called when the dismiss button is clicked
|
|
435
468
|
*/
|
|
436
469
|
onDismiss: PropTypes.func,
|
|
470
|
+
/**
|
|
471
|
+
* The minimum width of the content in the Notification when using the system variant.
|
|
472
|
+
* This prop accepts responsive values for different viewports.
|
|
473
|
+
* - `xs`: 'max' | 'full'
|
|
474
|
+
* - `sm`: 'max' | 'full'
|
|
475
|
+
* - `md`: 'max' | 'full'
|
|
476
|
+
* - `lg`: 'max' | 'full'
|
|
477
|
+
* - `xl`: 'max' | 'full'
|
|
478
|
+
*/
|
|
479
|
+
contentMinWidth: PropTypes.shape({
|
|
480
|
+
xl: PropTypes.oneOf(['max', 'full']),
|
|
481
|
+
lg: PropTypes.oneOf(['max', 'full']),
|
|
482
|
+
md: PropTypes.oneOf(['max', 'full']),
|
|
483
|
+
sm: PropTypes.oneOf(['max', 'full']),
|
|
484
|
+
xs: PropTypes.oneOf(['max', 'full'])
|
|
485
|
+
}),
|
|
437
486
|
tokens: getTokensPropType('Notification'),
|
|
438
487
|
variant: variantProp.propType
|
|
439
488
|
}
|
|
@@ -38,7 +38,7 @@ export default {
|
|
|
38
38
|
* 1. `tooltip` as a string - The content of the tooltip.
|
|
39
39
|
* 2. `tooltip` as an object - Tooltip component props to be passed.
|
|
40
40
|
*/
|
|
41
|
-
tooltip: PropTypes.oneOfType([tooltipPropTypes, PropTypes.string]),
|
|
41
|
+
tooltip: PropTypes.oneOfType([PropTypes.shape(tooltipPropTypes), PropTypes.string]),
|
|
42
42
|
/**
|
|
43
43
|
* Use to visually mark an input as valid or invalid.
|
|
44
44
|
*/
|