@telus-uds/components-base 1.53.0 → 1.55.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +32 -2
  2. package/component-docs.json +278 -74
  3. package/lib/Button/ButtonBase.js +17 -5
  4. package/lib/Carousel/CarouselStepTracker/CarouselStepTracker.js +6 -2
  5. package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +9 -8
  6. package/lib/Carousel/CarouselThumbnail.js +53 -26
  7. package/lib/Carousel/CarouselThumbnailNavigation.js +15 -6
  8. package/lib/ExpandCollapse/Panel.js +65 -8
  9. package/lib/IconButton/IconButton.js +41 -7
  10. package/lib/Modal/Modal.js +9 -3
  11. package/lib/SkipLink/SkipLink.js +19 -15
  12. package/lib/ThemeProvider/utils/styles.js +18 -2
  13. package/lib/TooltipButton/TooltipButton.js +7 -3
  14. package/lib/Typography/Typography.js +11 -2
  15. package/lib-module/Button/ButtonBase.js +17 -5
  16. package/lib-module/Carousel/CarouselStepTracker/CarouselStepTracker.js +6 -2
  17. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +9 -8
  18. package/lib-module/Carousel/CarouselThumbnail.js +51 -27
  19. package/lib-module/Carousel/CarouselThumbnailNavigation.js +13 -6
  20. package/lib-module/ExpandCollapse/Panel.js +64 -8
  21. package/lib-module/IconButton/IconButton.js +41 -7
  22. package/lib-module/Modal/Modal.js +8 -3
  23. package/lib-module/SkipLink/SkipLink.js +19 -15
  24. package/lib-module/ThemeProvider/utils/styles.js +19 -2
  25. package/lib-module/TooltipButton/TooltipButton.js +7 -3
  26. package/lib-module/Typography/Typography.js +10 -2
  27. package/package.json +3 -3
  28. package/src/Button/ButtonBase.jsx +11 -1
  29. package/src/Carousel/CarouselStepTracker/CarouselStepTracker.jsx +10 -2
  30. package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +5 -5
  31. package/src/Carousel/CarouselThumbnail.jsx +31 -25
  32. package/src/Carousel/CarouselThumbnailNavigation.jsx +8 -3
  33. package/src/ExpandCollapse/Panel.jsx +55 -8
  34. package/src/IconButton/IconButton.jsx +50 -6
  35. package/src/Modal/Modal.jsx +8 -3
  36. package/src/SkipLink/SkipLink.jsx +12 -12
  37. package/src/ThemeProvider/utils/styles.js +29 -2
  38. package/src/TooltipButton/TooltipButton.jsx +14 -2
  39. package/src/Typography/Typography.jsx +7 -2
@@ -54,7 +54,10 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
54
54
  ...rest
55
55
  } = _ref2;
56
56
  const viewport = useViewport();
57
- const themeTokens = useThemeTokens('Typography', tokens, variant, {
57
+ const {
58
+ superScriptFontSize,
59
+ ...themeTokens
60
+ } = useThemeTokens('Typography', tokens, variant, {
58
61
  viewport
59
62
  });
60
63
  const {
@@ -77,8 +80,13 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
77
80
  if (typeof child === 'object' && ((child === null || child === void 0 ? void 0 : child.type) === 'sub' || (child === null || child === void 0 ? void 0 : child.type) === 'sup')) {
78
81
  var _child$props;
79
82
 
83
+ const childStyles = (child === null || child === void 0 ? void 0 : (_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.style) || {};
84
+ const supFontSize = childStyles.fontSize ?? superScriptFontSize;
80
85
  const sanitizedChild = /*#__PURE__*/React.cloneElement(child, {
81
- style: { ...(child === null || child === void 0 ? void 0 : (_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.style),
86
+ style: { ...childStyles,
87
+ ...(supFontSize ? {
88
+ fontSize: supFontSize
89
+ } : {}),
82
90
  lineHeight: 0
83
91
  }
84
92
  });
package/package.json CHANGED
@@ -10,8 +10,8 @@
10
10
  "@floating-ui/react-dom": "^1.0.1",
11
11
  "@floating-ui/react-native": "^0.8.1",
12
12
  "@gorhom/portal": "^1.0.14",
13
- "@telus-uds/system-constants": "^1.2.1",
14
- "@telus-uds/system-theme-tokens": "^2.36.0",
13
+ "@telus-uds/system-constants": "^1.3.0",
14
+ "@telus-uds/system-theme-tokens": "^2.38.0",
15
15
  "airbnb-prop-types": "^2.16.0",
16
16
  "lodash.debounce": "^4.0.8",
17
17
  "lodash.merge": "^4.6.2",
@@ -72,5 +72,5 @@
72
72
  "standard-engine": {
73
73
  "skip": true
74
74
  },
75
- "version": "1.53.0"
75
+ "version": "1.55.0"
76
76
  }
@@ -173,6 +173,13 @@ const selectWebOnlyStyles = (inactive, themeTokens, { accessibilityRole }) => {
173
173
  })
174
174
  }
175
175
 
176
+ const selectButtonStyles = ({ textAlign }) => {
177
+ return {
178
+ flexDirection: 'row',
179
+ justifyContent: textAlign
180
+ }
181
+ }
182
+
176
183
  const selectItemIconTokens = ({ color, iconColor, iconSize }) => ({
177
184
  size: iconSize,
178
185
  color: iconColor || color
@@ -237,6 +244,8 @@ const ButtonBase = forwardRef(
237
244
  const stretchStyles = themeTokens.width ? staticStyles.stretch : staticStyles.align
238
245
  const IconComponent = icon || themeTokens.icon
239
246
 
247
+ const rowStyles = selectButtonStyles(themeTokens)
248
+
240
249
  return (
241
250
  <View
242
251
  id={id}
@@ -249,7 +258,8 @@ const ButtonBase = forwardRef(
249
258
  web: {
250
259
  maxWidth: '100%', // ensure overflowing content wraps
251
260
  // TODO: https://github.com/telus/universal-design-system/issues/487
252
- transition: 'background-color 200ms, border-color 200ms'
261
+ transition: 'background-color 200ms, border-color 200ms',
262
+ ...rowStyles
253
263
  }
254
264
  })
255
265
  ]}
@@ -5,18 +5,26 @@ import StackView from '../../StackView'
5
5
  import { variantProp } from '../../utils'
6
6
 
7
7
  const CarouselStepTracker = ({ variant }) => {
8
- const { activeIndex, totalItems, getCopyWithPlaceholders, themeTokens } = useCarousel()
8
+ const {
9
+ activeIndex,
10
+ totalItems,
11
+ getCopyWithPlaceholders,
12
+ themeTokens: { stepTrackerCurrentBackgroundColor, ...themeTokens }
13
+ } = useCarousel()
9
14
  const stackViewTokens = {
10
15
  justifyContent: 'center'
11
16
  }
17
+
12
18
  const stepTrackerTokens = {
13
19
  showStepLabel: false,
14
20
  showStepTrackerLabel: true,
15
- knobCompletedBackgroundColor: 'none',
21
+ // TODO: StepTracker 'isComplete'/'isCurrent' is incorrect, see line StepTracker/Step.jsx line 63, refactor incorrect values and remove this
22
+ knobCompletedBackgroundColor: stepTrackerCurrentBackgroundColor ?? 'none',
16
23
  connectorCompletedColor: 'none',
17
24
  connectorColor: 'none',
18
25
  containerPaddingTop: themeTokens.spaceBetweenSlideAndPanelNavigation
19
26
  }
27
+
20
28
  const steps = Array.from(Array(totalItems)).map((_, index) => String(index))
21
29
  return (
22
30
  <StackView direction="row" tokens={stackViewTokens}>
@@ -17,11 +17,6 @@ const CarouselTabsPanel = forwardRef(({ items }, ref) => {
17
17
  const firstTabRef = useRef()
18
18
  const [isInverse, setIsInverse] = useState(false)
19
19
 
20
- // TODO: figure out a better cross-brand way to specify subcomponent variants.
21
- // For now, this picks an Allium variant, and does nothing in brands that lack it.
22
- // See similar comment in Carousel and https://github.com/telus/universal-design-system/issues/1549
23
- const dividerVariant = { decorative: true }
24
-
25
20
  const lastTabSelected = activeIndex === items.length - 1
26
21
 
27
22
  // Get current select tab style
@@ -30,6 +25,11 @@ const CarouselTabsPanel = forwardRef(({ items }, ref) => {
30
25
  setIsInverse(selectedVariantIsInverse?.inverse)
31
26
  }, [items, activeIndex])
32
27
 
28
+ // TODO: figure out a better cross-brand way to specify subcomponent variants.
29
+ // For now, this picks an Allium variant, and does nothing in brands that lack it.
30
+ // See similar comment in Carousel and https://github.com/telus/universal-design-system/issues/1549
31
+ const dividerVariant = { decorative: true, inverse: isInverse }
32
+
33
33
  return (
34
34
  <View style={selectTabPanelStyle()}>
35
35
  <StackView direction="row" space={3} divider={{ variant: dividerVariant }} ref={ref}>
@@ -2,14 +2,25 @@ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import { Pressable, Image } from 'react-native'
4
4
  import { useCarousel } from './CarouselContext'
5
+ import { useThemeTokensCallback } from '../ThemeProvider'
6
+ import { useViewport } from '../ViewportProvider'
7
+
8
+ const selectPressableTokens = ({ borderColor, borderRadius, borderWidth, margin, padding }) => ({
9
+ borderColor,
10
+ borderRadius,
11
+ borderWidth,
12
+ margin,
13
+ padding
14
+ })
5
15
 
6
16
  /**
7
17
  * `Carousel.Thumbnail` is used to wrap the content of an individual slide and is suppsoed to be the
8
18
  * only top-level component passed to the `Carousel`
9
19
  */
10
20
  const CarouselThumbnail = ({ accessibilityLabel, alt, index, src }) => {
11
- const { activeIndex, itemLabel, totalItems, getCopyWithPlaceholders, goTo, themeTokens } =
12
- useCarousel()
21
+ const { activeIndex, itemLabel, totalItems, getCopyWithPlaceholders, goTo } = useCarousel()
22
+ const getThumbnailTokens = useThemeTokensCallback('CarouselThumbnail')
23
+ const viewport = useViewport()
13
24
  const thumbnailTitle =
14
25
  alt ??
15
26
  getCopyWithPlaceholders('stepTrackerLabel')
@@ -21,32 +32,17 @@ const CarouselThumbnail = ({ accessibilityLabel, alt, index, src }) => {
21
32
  // Allow using the spacebar for navigation
22
33
  if (event?.key === ' ') goTo(index)
23
34
  }
24
- const {
25
- thumbnailBorderColor,
26
- thumbnailBorderRadius,
27
- thumbnailBorderWidth,
28
- thumbnailMargin,
29
- thumbnailPadding,
30
- thumbnailSelectedBorderColor,
31
- thumbnailSelectedBorderWidth,
32
- thumbnailSize
33
- } = themeTokens
35
+ const { borderWidth, padding, selectedBorderColor, selectedBorderWidth, size } =
36
+ getThumbnailTokens({ viewport })
34
37
  const styles = {
35
- pressable: {
36
- borderColor: thumbnailBorderColor,
37
- borderRadius: thumbnailBorderRadius,
38
- borderWidth: thumbnailBorderWidth,
39
- margin: thumbnailMargin,
40
- padding: thumbnailPadding
41
- },
42
38
  image: {
43
- height: thumbnailSize,
44
- width: thumbnailSize
39
+ height: size,
40
+ width: size
45
41
  },
46
42
  selected: {
47
- borderColor: thumbnailSelectedBorderColor,
48
- borderWidth: thumbnailSelectedBorderWidth,
49
- padding: thumbnailPadding - thumbnailSelectedBorderWidth + thumbnailBorderWidth
43
+ borderColor: selectedBorderColor,
44
+ borderWidth: selectedBorderWidth,
45
+ padding: padding - selectedBorderWidth + borderWidth
50
46
  }
51
47
  }
52
48
 
@@ -55,7 +51,17 @@ const CarouselThumbnail = ({ accessibilityLabel, alt, index, src }) => {
55
51
  key={src}
56
52
  onKeyDown={handleKeyDown}
57
53
  onPress={handlePress}
58
- style={[styles.pressable, index === activeIndex && styles.selected]}
54
+ style={({ hovered, pressed, focused }) => {
55
+ const pressableStyles = selectPressableTokens(
56
+ getThumbnailTokens({
57
+ hover: hovered,
58
+ pressed,
59
+ focus: focused
60
+ })
61
+ )
62
+
63
+ return [pressableStyles, index === activeIndex && styles.selected]
64
+ }}
59
65
  >
60
66
  <Image
61
67
  accessibilityIgnoresInvertColors
@@ -4,19 +4,24 @@ import { View } from 'react-native'
4
4
  import { useCarousel } from './CarouselContext'
5
5
  import CarouselThumbnail from './CarouselThumbnail'
6
6
  import { StackWrap } from '../StackView'
7
+ import { useThemeTokens } from '../ThemeProvider'
8
+ import { useViewport } from '../ViewportProvider'
7
9
 
8
10
  const CarouselThumbnailNavigation = forwardRef(({ thumbnails = [] }, ref) => {
9
- const { totalItems, themeTokens } = useCarousel()
11
+ const viewport = useViewport()
12
+ const { alignItems } = useThemeTokens('CarouselThumbnail', {}, { viewport })
13
+ const { totalItems } = useCarousel()
10
14
  if (thumbnails.length !== totalItems) {
11
15
  throw new Error('Thumbnail set provided does not match the number of slides in the carousel')
12
16
  }
13
- const { thumbnailContainerPaddingTop, thumbnailMargin } = themeTokens
17
+ const { containerPaddingTop: thumbnailContainerPaddingTop, margin: thumbnailMargin } =
18
+ useThemeTokens('CarouselThumbnail')
14
19
  const stackWrapTokens = {
15
20
  justifyContent: 'flex-start'
16
21
  }
17
22
  const containerStyles = {
18
23
  justifyContent: 'center',
19
- alignItems: 'center',
24
+ alignItems,
20
25
  paddingTop: thumbnailContainerPaddingTop - thumbnailMargin
21
26
  }
22
27
 
@@ -1,5 +1,5 @@
1
1
  import React, { forwardRef, useState } from 'react'
2
- import { Animated, Platform, View } from 'react-native'
2
+ import { Animated, Platform, View, Text } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
4
  import ABBPropTypes from 'airbnb-prop-types'
5
5
 
@@ -26,7 +26,42 @@ const selectContainerStyles = ({
26
26
  paddingLeft: contentPaddingLeft,
27
27
  paddingRight: contentPaddingRight,
28
28
  paddingTop: contentPaddingTop,
29
- paddingBottom: contentPaddingBottom
29
+ paddingBottom: contentPaddingBottom,
30
+ flex: 1
31
+ })
32
+ const selectTextStyles = ({
33
+ contentPanelFontSize,
34
+ contentPanelFontName,
35
+ contentPanelFontColor,
36
+ contentPanelFontWeight,
37
+ contentPanelLineHeight
38
+ }) => ({
39
+ fontSize: contentPanelFontSize,
40
+ fontFamily: `${contentPanelFontName}${contentPanelFontWeight}normal`,
41
+ lineHeight: contentPanelFontSize * contentPanelLineHeight,
42
+ color: contentPanelFontColor
43
+ })
44
+ const selectContentPanelStyles = ({
45
+ contentPanelBackgroundColor,
46
+ contentPanelPaddingTop,
47
+ contentPanelPaddingBottom,
48
+ contentPanelPaddingLeft,
49
+ contentPanelPaddingRight,
50
+ contentPanelBorderWidth,
51
+ contentPanelBorderColor,
52
+ borderRadius,
53
+ marginBottom
54
+ }) => ({
55
+ backgroundColor: contentPanelBackgroundColor,
56
+ paddingTop: contentPanelPaddingTop,
57
+ paddingBottom: contentPanelPaddingBottom,
58
+ paddingLeft: contentPanelPaddingLeft,
59
+ paddingRight: contentPanelPaddingRight,
60
+ borderWidth: contentPanelBorderWidth,
61
+ borderColor: contentPanelBorderColor,
62
+ borderStyle: 'solid',
63
+ borderRadius,
64
+ marginBottom
30
65
  })
31
66
 
32
67
  /**
@@ -52,6 +87,7 @@ const ExpandCollapsePanel = forwardRef(
52
87
  tokens,
53
88
  variant,
54
89
  controlRef,
90
+ content,
55
91
  ...rest
56
92
  },
57
93
  ref
@@ -90,8 +126,15 @@ const ExpandCollapsePanel = forwardRef(
90
126
  })
91
127
 
92
128
  const focusabilityProps = isExpanded ? {} : a11yProps.nonFocusableProps
93
-
94
- return (
129
+ return content ? (
130
+ <View style={selectContentPanelStyles(themeTokens)}>
131
+ {typeof children === 'string' ? (
132
+ <Text style={selectTextStyles(themeTokens)}>{children}</Text>
133
+ ) : (
134
+ children
135
+ )}
136
+ </View>
137
+ ) : (
95
138
  <View ref={ref} style={themeTokens}>
96
139
  <ExpandCollapseControl
97
140
  {...selectedProps}
@@ -140,7 +183,7 @@ ExpandCollapsePanel.propTypes = {
140
183
  * Function to call on pressing the panel's control, which should open or close the panel.
141
184
  * If Panel is a direct child of `ExpandCollapse`, this prop will be provided by the ExpandCollapse parent.
142
185
  */
143
- onToggle: PropTypes.func.isRequired,
186
+ onToggle: PropTypes.func,
144
187
  /**
145
188
  * Optional function to call on pressing the panel's control, in addition to opening or closing the panel.
146
189
  */
@@ -151,9 +194,9 @@ ExpandCollapsePanel.propTypes = {
151
194
  */
152
195
  children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
153
196
  /**
154
- * The content inside the always-visible control element that opens and closes the ExpandCollapse when pressed.
197
+ * The content inside the control element that opens and closes the ExpandCollapse when pressed.
155
198
  */
156
- control: ExpandCollapseControl.propTypes.children.isRequired,
199
+ control: ExpandCollapseControl.propTypes.children,
157
200
  /**
158
201
  * Optional theme token overrides that may be passed to the ExpandCollapseControl element.
159
202
  */
@@ -161,7 +204,11 @@ ExpandCollapsePanel.propTypes = {
161
204
  /**
162
205
  * An optional ref to be attached to the control
163
206
  */
164
- controlRef: ABBPropTypes.ref()
207
+ controlRef: ABBPropTypes.ref(),
208
+ /**
209
+ * A boolean prop to determine if the panel is a content panel or not. If true, the panel will not have a control
210
+ */
211
+ content: PropTypes.bool
165
212
  }
166
213
 
167
214
  export default ExpandCollapsePanel
@@ -22,27 +22,71 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, vie
22
22
 
23
23
  const selectOuterStyle = ({
24
24
  backgroundColor,
25
- borderRadius,
26
25
  outerBorderWidth,
27
26
  outerBorderColor,
28
27
  outerBorderGap,
28
+ borderRadius,
29
+ borderTopLeftRadius,
30
+ borderTopRightRadius,
31
+ borderBottomLeftRadius,
32
+ borderBottomRightRadius,
29
33
  shadow
30
34
  }) => [
31
35
  {
32
36
  backgroundColor,
33
37
  ...applyShadowToken(shadow),
34
- ...applyOuterBorder({ borderRadius, outerBorderWidth, outerBorderColor, outerBorderGap }),
38
+ ...applyOuterBorder({
39
+ borderRadius,
40
+ borderTopLeftRadius,
41
+ borderTopRightRadius,
42
+ borderBottomLeftRadius,
43
+ borderBottomRightRadius,
44
+ outerBorderWidth,
45
+ outerBorderColor,
46
+ outerBorderGap
47
+ }),
35
48
  ...Platform.select({ web: { outline: 'none', display: 'inline-flex' } })
36
49
  },
37
50
  staticStyles.outer
38
51
  ]
39
52
 
40
- const selectInnerStyle = ({ borderColor, borderWidth = 0, borderRadius, padding = 0 }) => ({
53
+ const calculatePadding = (padding, borderWidth) => padding && Math.max(0, padding - borderWidth) // Stable size as border changes
54
+
55
+ const selectInnerStyle = ({
56
+ borderColor,
57
+ borderWidth,
58
+ borderTopLeftRadius,
59
+ borderTopRightRadius,
60
+ borderBottomLeftRadius,
61
+ borderBottomRightRadius,
62
+ borderRadius,
63
+ padding = 0,
64
+ borderTopWidth,
65
+ borderRightWidth,
66
+ borderBottomWidth,
67
+ borderLeftWidth,
68
+ paddingLeft,
69
+ paddingRight,
70
+ paddingTop,
71
+ paddingBottom
72
+ }) => ({
41
73
  // Inner borders animate with the icon and should be treated like a themable feature of the icon
42
74
  borderColor,
43
75
  borderRadius,
44
76
  borderWidth,
45
- padding: Math.max(0, padding - borderWidth) // Stable size as border changes
77
+ borderTopLeftRadius,
78
+ borderTopRightRadius,
79
+ borderBottomLeftRadius,
80
+ borderBottomRightRadius,
81
+ borderTopWidth,
82
+ borderRightWidth,
83
+ borderBottomWidth,
84
+ borderLeftWidth,
85
+ padding: calculatePadding(padding, borderWidth),
86
+ paddingLeft: calculatePadding(paddingLeft, borderLeftWidth),
87
+ paddingRight: calculatePadding(paddingRight, borderRightWidth),
88
+ paddingTop: calculatePadding(paddingTop, borderTopWidth),
89
+ paddingBottom: calculatePadding(paddingBottom, borderBottomWidth)
46
90
  })
47
91
 
48
92
  /**
@@ -90,7 +134,7 @@ const IconButton = forwardRef(
90
134
  return (
91
135
  <View style={selectInnerStyle(themeTokens)}>
92
136
  <Icon
93
- icon={IconComponent}
137
+ icon={IconComponent || themeTokens.icon}
94
138
  title={selectedProps.accessibilityLabel}
95
139
  tokens={selectTokens('Icon', themeTokens, 'icon')}
96
140
  variant={variant}
@@ -111,7 +155,7 @@ IconButton.propTypes = {
111
155
  /**
112
156
  * Defines the icon to be rendered
113
157
  */
114
- icon: PropTypes.elementType.isRequired,
158
+ icon: PropTypes.elementType,
115
159
  /**
116
160
  * URL to navigate to when the `Iconbutton` is pressed
117
161
  */
@@ -3,6 +3,7 @@ import {
3
3
  StyleSheet,
4
4
  TouchableWithoutFeedback,
5
5
  View,
6
+ ScrollView,
6
7
  Modal as NativeModal,
7
8
  Platform
8
9
  } from 'react-native'
@@ -114,7 +115,7 @@ const Modal = forwardRef(
114
115
 
115
116
  return (
116
117
  <NativeModal transparent {...selectProps(rest)}>
117
- <View style={[staticStyles.positioningContainer]} ref={modalRef}>
118
+ <ScrollView contentContainerStyle={[staticStyles.positioningContainer]} ref={modalRef}>
118
119
  <View
119
120
  style={[staticStyles.sizingContainer, selectContainerStyles(themeTokens)]}
120
121
  pointerEvents="box-none" // don't capture backdrop press events
@@ -149,7 +150,7 @@ const Modal = forwardRef(
149
150
  <TouchableWithoutFeedback onPress={handleClose}>
150
151
  <View style={[staticStyles.backdrop, selectBackdropStyles(themeTokens)]} />
151
152
  </TouchableWithoutFeedback>
152
- </View>
153
+ </ScrollView>
153
154
  </NativeModal>
154
155
  )
155
156
  }
@@ -210,7 +211,11 @@ const staticStyles = StyleSheet.create({
210
211
  },
211
212
  modal: {
212
213
  maxHeight: '100%', // so that the modal can expand vertically up to the sizing container's height (exclusive of its vertical padding)
213
- overflow: 'auto'
214
+ ...Platform.select({
215
+ web: {
216
+ overflow: 'auto'
217
+ }
218
+ })
214
219
  },
215
220
  closeButtonContainer: {
216
221
  position: 'absolute',
@@ -37,8 +37,12 @@ const selectStyles = ({
37
37
  borderRadius
38
38
  })
39
39
 
40
- const selectTextStyles = ({ color }) => ({
41
- color
40
+ const selectTextStyles = ({ color, textLine, fontName, fontSize, fontWeight, lineHeight }) => ({
41
+ color,
42
+ textDecorationLine: textLine,
43
+ fontFamily: `${fontName}${fontWeight}normal`,
44
+ lineHeight: fontSize * lineHeight,
45
+ fontSize
42
46
  })
43
47
 
44
48
  /**
@@ -100,9 +104,6 @@ const SkipLink = forwardRef(({ tokens, variant, href, children, ...rawRest }, re
100
104
  const { onPress, ...rest } = clickProps.toPressProps(rawRest)
101
105
 
102
106
  const getTokens = useThemeTokensCallback('SkipLink', tokens, variant)
103
- const defaultTokens = getTokens()
104
-
105
- const resolveLinkTokens = (pressState) => resolvePressableTokens(defaultTokens, pressState)
106
107
 
107
108
  const handlePress = (event) => {
108
109
  if (typeof onPress === 'function') onPress(event)
@@ -115,18 +116,17 @@ const SkipLink = forwardRef(({ tokens, variant, href, children, ...rawRest }, re
115
116
  accessibilityRole="link"
116
117
  onPress={handlePress}
117
118
  href={href}
118
- style={({ focused: focus }) => {
119
- const themeTokens = getTokens({ focus })
119
+ style={(pressableState) => {
120
+ const themeTokens = resolvePressableTokens(getTokens, pressableState)
120
121
  const skipLinkStyle = selectStyles(themeTokens)
121
-
122
- return [staticStyles.absolute, skipLinkStyle, !focus && staticStyles.hidden]
122
+ const { focused } = pressableState
123
+ return [staticStyles.absolute, skipLinkStyle, !focused && staticStyles.hidden]
123
124
  }}
124
125
  {...selectProps(rest)}
125
126
  >
126
- {(pressState) => {
127
- const themeTokens = resolveLinkTokens(pressState)
127
+ {(pressableState) => {
128
+ const themeTokens = resolvePressableTokens(getTokens, pressableState)
128
129
  const textStyles = selectTextStyles(themeTokens)
129
-
130
130
  return <Text style={[textStyles, staticStyles.baseline]}>{children}</Text>
131
131
  }}
132
132
  </Pressable>
@@ -147,6 +147,13 @@ export function verticalAlignRow(verticalAlign, reverse = false) {
147
147
  }
148
148
  }
149
149
 
150
+ const calculateBorderRadius = (borderRadius, outerBorderGap, outerBorderWidth) => {
151
+ if (borderRadius) {
152
+ return borderRadius + outerBorderGap + outerBorderWidth
153
+ }
154
+
155
+ return null
156
+ }
150
157
  /**
151
158
  * Use on an outer container to create an outer border with an optional gap around it
152
159
  * that matches the border radius of any inner border.
@@ -155,11 +162,31 @@ export const applyOuterBorder = ({
155
162
  outerBorderColor,
156
163
  outerBorderWidth = 0,
157
164
  outerBorderGap = 0,
158
- borderRadius = 0
165
+ borderRadius,
166
+ borderTopLeftRadius,
167
+ borderTopRightRadius,
168
+ borderBottomLeftRadius,
169
+ borderBottomRightRadius
159
170
  }) => ({
160
171
  margin: 0 - outerBorderWidth - outerBorderGap,
161
172
  padding: outerBorderGap,
162
- borderRadius: borderRadius + outerBorderGap + outerBorderWidth,
173
+ borderRadius: calculateBorderRadius(borderRadius, outerBorderGap, outerBorderWidth),
174
+ borderTopLeftRadius: calculateBorderRadius(borderTopLeftRadius, outerBorderGap, outerBorderWidth),
175
+ borderTopRightRadius: calculateBorderRadius(
176
+ borderTopRightRadius,
177
+ outerBorderGap,
178
+ outerBorderWidth
179
+ ),
180
+ borderBottomLeftRadius: calculateBorderRadius(
181
+ borderBottomLeftRadius,
182
+ outerBorderGap,
183
+ outerBorderWidth
184
+ ),
185
+ borderBottomRightRadius: calculateBorderRadius(
186
+ borderBottomRightRadius,
187
+ outerBorderGap,
188
+ outerBorderWidth
189
+ ),
163
190
  borderWidth: outerBorderWidth,
164
191
  borderColor: outerBorderColor
165
192
  })
@@ -7,7 +7,11 @@ import Icon from '../Icon'
7
7
 
8
8
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
9
9
 
10
- const selectInnerContainerStyles = ({ borderRadius, width }) => ({ borderRadius, width })
10
+ const selectInnerContainerStyles = ({ borderRadius, width, backgroundColor }) => ({
11
+ borderRadius,
12
+ width,
13
+ backgroundColor
14
+ })
11
15
 
12
16
  const selectIconTokens = ({ iconSize, iconColor, iconScale = 1 }) => ({
13
17
  size: iconSize,
@@ -26,7 +30,15 @@ const TooltipButton = ({ pressableState, tokens, variant, ...rest }) => {
26
30
  const { icon: IconComponent } = themeTokens
27
31
 
28
32
  return (
29
- <View style={applyOuterBorder(themeTokens)} {...selectProps(rest)}>
33
+ <View
34
+ style={[
35
+ applyOuterBorder(themeTokens),
36
+ themeTokens.outerBorderWidth && {
37
+ margin: -themeTokens.outerBorderWidth
38
+ }
39
+ ]}
40
+ {...selectProps(rest)}
41
+ >
30
42
  <View style={selectInnerContainerStyles(themeTokens)}>
31
43
  {IconComponent && <Icon icon={IconComponent} tokens={selectIconTokens(themeTokens)} />}
32
44
  </View>
@@ -59,7 +59,9 @@ const Typography = forwardRef(
59
59
  ref
60
60
  ) => {
61
61
  const viewport = useViewport()
62
- const themeTokens = useThemeTokens('Typography', tokens, variant, { viewport })
62
+ const { superScriptFontSize, ...themeTokens } = useThemeTokens('Typography', tokens, variant, {
63
+ viewport
64
+ })
63
65
  const { themeOptions } = useTheme()
64
66
 
65
67
  const resolvedTextProps = {
@@ -80,9 +82,12 @@ const Typography = forwardRef(
80
82
 
81
83
  const resetTagStyling = (child) => {
82
84
  if (typeof child === 'object' && (child?.type === 'sub' || child?.type === 'sup')) {
85
+ const childStyles = child?.props?.style || {}
86
+ const supFontSize = childStyles.fontSize ?? superScriptFontSize
83
87
  const sanitizedChild = React.cloneElement(child, {
84
88
  style: {
85
- ...child?.props?.style,
89
+ ...childStyles,
90
+ ...(supFontSize ? { fontSize: supFontSize } : {}),
86
91
  lineHeight: 0
87
92
  }
88
93
  })