@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.
@@ -2,9 +2,13 @@ import React from 'react';
2
2
  import { useCarousel } from '../CarouselContext';
3
3
  import StepTracker from '../../StepTracker';
4
4
  import StackView from '../../StackView';
5
+ import { variantProp } from '../../utils';
5
6
  import { jsx as _jsx } from "react/jsx-runtime";
6
7
 
7
- const CarouselStepTracker = () => {
8
+ const CarouselStepTracker = _ref => {
9
+ let {
10
+ variant
11
+ } = _ref;
8
12
  const {
9
13
  activeIndex,
10
14
  totalItems,
@@ -34,9 +38,13 @@ const CarouselStepTracker = () => {
34
38
  stepLabel: getCopyWithPlaceholders('stepLabel'),
35
39
  stepTrackerLabel: getCopyWithPlaceholders('stepTrackerLabel')
36
40
  },
37
- tokens: stepTrackerTokens
41
+ tokens: stepTrackerTokens,
42
+ variant: variant
38
43
  })
39
44
  });
40
45
  };
41
46
 
47
+ CarouselStepTracker.propTypes = {
48
+ variant: variantProp.propType
49
+ };
42
50
  export default CarouselStepTracker;
@@ -0,0 +1,112 @@
1
+ import React, { forwardRef } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import View from "react-native-web/dist/exports/View";
4
+ import StyleSheet from "react-native-web/dist/exports/StyleSheet";
5
+ import { Portal } from '@gorhom/portal';
6
+ import { copyPropTypes, getTokensPropType, selectTokens, useCopy, variantProp } from '../utils';
7
+ import { useViewport } from '../ViewportProvider';
8
+ import { useThemeTokens } from '../ThemeProvider';
9
+ import dictionary from './dictionary';
10
+ import Card from '../Card';
11
+ import IconButton from '../IconButton';
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { jsxs as _jsxs } from "react/jsx-runtime";
14
+ import { Fragment as _Fragment } from "react/jsx-runtime";
15
+ const staticStyles = StyleSheet.create({
16
+ positioner: {
17
+ flex: 1,
18
+ // Grow to maxWidth when possible, shrink when not possible
19
+ position: 'absolute',
20
+ height: 330,
21
+ paddingTop: 5,
22
+ zIndex: 10000 // Position on top of all the other overlays, including backdrops and modals
23
+
24
+ },
25
+ closeButtonContainer: {
26
+ position: 'absolute',
27
+ top: 0,
28
+ right: 0,
29
+ zIndex: 1
30
+ }
31
+ });
32
+
33
+ const selectCloseButtonContainerStyles = _ref => {
34
+ let {
35
+ paddingRight,
36
+ paddingTop
37
+ } = _ref;
38
+ return {
39
+ paddingRight,
40
+ paddingTop
41
+ };
42
+ };
43
+
44
+ const selectPaddingContainerStyles = _ref2 => {
45
+ let {
46
+ paddingTop,
47
+ paddingLeft,
48
+ paddingRight
49
+ } = _ref2;
50
+ return {
51
+ paddingBottom: 35,
52
+ paddingTop,
53
+ paddingLeft,
54
+ paddingRight
55
+ };
56
+ };
57
+
58
+ const ModalOverlay = /*#__PURE__*/forwardRef((_ref3, ref) => {
59
+ let {
60
+ children,
61
+ tokens,
62
+ variant,
63
+ copy,
64
+ onClose
65
+ } = _ref3;
66
+ const viewport = useViewport();
67
+ const themeTokens = useThemeTokens('Modal', tokens, variant, {
68
+ viewport,
69
+ maxWidth: false
70
+ });
71
+ const {
72
+ closeIcon: CloseIconComponent,
73
+ maxWidth
74
+ } = themeTokens;
75
+ const getCopy = useCopy({
76
+ dictionary,
77
+ copy
78
+ });
79
+ const closeLabel = getCopy('closeButton');
80
+ return /*#__PURE__*/_jsx(_Fragment, {
81
+ children: /*#__PURE__*/_jsx(Portal, {
82
+ ref: ref,
83
+ children: /*#__PURE__*/_jsx(View, {
84
+ style: [{
85
+ minWidth: maxWidth
86
+ }, staticStyles.positioner],
87
+ children: /*#__PURE__*/_jsxs(Card, {
88
+ tokens: selectPaddingContainerStyles(themeTokens),
89
+ children: [/*#__PURE__*/_jsx(View, {
90
+ style: [staticStyles.closeButtonContainer, selectCloseButtonContainerStyles(themeTokens)],
91
+ children: /*#__PURE__*/_jsx(IconButton, {
92
+ onPress: onClose,
93
+ icon: CloseIconComponent,
94
+ accessibilityRole: "button",
95
+ accessibilityLabel: closeLabel,
96
+ tokens: selectTokens('IconButton', themeTokens, 'close')
97
+ })
98
+ }), children]
99
+ })
100
+ })
101
+ })
102
+ });
103
+ });
104
+ ModalOverlay.displayName = 'ModalOverlay';
105
+ ModalOverlay.propTypes = {
106
+ children: PropTypes.node.isRequired,
107
+ variant: variantProp.propType,
108
+ tokens: getTokensPropType('Modal'),
109
+ copy: copyPropTypes,
110
+ onClose: PropTypes.func
111
+ };
112
+ export default ModalOverlay;
@@ -1,6 +1,6 @@
1
1
  import React, { forwardRef, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { useThemeTokensCallback } from '../ThemeProvider';
3
+ import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider';
4
4
  import { containUniqueFields, getTokensPropType, getPressHandlersWithArgs, selectTokens, useCopy, useMultipleInputValues, variantProp } from '../utils';
5
5
  import dictionary from './dictionary';
6
6
  import Box from '../Box';
@@ -8,21 +8,47 @@ import { Button, ButtonDropdown } from '../Button';
8
8
  import { CheckboxGroup } from '../Checkbox';
9
9
  import Divider from '../Divider';
10
10
  import FlexGrid from '../FlexGrid';
11
- import Modal from '../Modal';
12
11
  import Spacer from '../Spacer';
13
12
  import StackView from '../StackView';
14
13
  import Typography from '../Typography';
15
14
  import { TextButton } from '../Link';
15
+ import ModalOverlay from './ModalOverlay';
16
16
  import { jsx as _jsx } from "react/jsx-runtime";
17
- import { jsxs as _jsxs } from "react/jsx-runtime";
18
17
  import { Fragment as _Fragment } from "react/jsx-runtime";
18
+ import { jsxs as _jsxs } from "react/jsx-runtime";
19
19
  const {
20
20
  Col,
21
21
  Row
22
22
  } = FlexGrid;
23
- const MultiSelectFilter = /*#__PURE__*/forwardRef((_ref, ref) => {
23
+
24
+ const selectSubTitleTokens = _ref => {
25
+ let {
26
+ subtitleColor
27
+ } = _ref;
28
+ return {
29
+ color: subtitleColor
30
+ };
31
+ };
32
+
33
+ const selectDividerToknes = _ref2 => {
34
+ let {
35
+ dividerColor,
36
+ width,
37
+ decorative = true,
38
+ weight = 'thin'
39
+ } = _ref2;
40
+ return {
41
+ color: dividerColor,
42
+ width,
43
+ decorative,
44
+ weight
45
+ };
46
+ };
47
+
48
+ const MultiSelectFilter = /*#__PURE__*/forwardRef((_ref3, ref) => {
24
49
  let {
25
50
  label,
51
+ subtitle,
26
52
  id = label,
27
53
  variant,
28
54
  tokens,
@@ -36,7 +62,7 @@ const MultiSelectFilter = /*#__PURE__*/forwardRef((_ref, ref) => {
36
62
  inactive = false,
37
63
  rowLimit = 12,
38
64
  ...rest
39
- } = _ref;
65
+ } = _ref3;
40
66
  const {
41
67
  currentValues,
42
68
  setValues
@@ -47,6 +73,7 @@ const MultiSelectFilter = /*#__PURE__*/forwardRef((_ref, ref) => {
47
73
  onChange,
48
74
  readOnly
49
75
  });
76
+ const themeTokens = useThemeTokens('ButtonDropdown', tokens, variant);
50
77
  const getItemTokens = useThemeTokensCallback('ButtonDropdown', tokens, variant);
51
78
 
52
79
  const getButtonTokens = buttonState => selectTokens('Button', getItemTokens(buttonState));
@@ -74,7 +101,7 @@ const MultiSelectFilter = /*#__PURE__*/forwardRef((_ref, ref) => {
74
101
 
75
102
  const handleChange = event => {
76
103
  if (pressHandlers.onPress) pressHandlers === null || pressHandlers === void 0 ? void 0 : pressHandlers.onPress(event);
77
- setIsOpen(true);
104
+ setIsOpen(!isOpen);
78
105
  };
79
106
 
80
107
  const onApply = e => {
@@ -83,12 +110,20 @@ const MultiSelectFilter = /*#__PURE__*/forwardRef((_ref, ref) => {
83
110
  };
84
111
 
85
112
  return /*#__PURE__*/_jsxs(_Fragment, {
86
- children: [/*#__PURE__*/_jsxs(Modal, {
87
- isOpen: isOpen,
88
- onClose: () => setIsOpen(false),
113
+ children: [/*#__PURE__*/_jsx(ButtonDropdown, {
114
+ ref: ref,
115
+ ...pressHandlers,
116
+ value: isOpen,
117
+ selected: isSelected,
118
+ label: label,
119
+ onChange: handleChange,
120
+ tokens: getButtonTokens,
121
+ inactive: inactive
122
+ }, id), isOpen && /*#__PURE__*/_jsxs(ModalOverlay, {
89
123
  variant: {
90
124
  width: colSize > 1 ? 'size576' : 's'
91
125
  },
126
+ onClose: () => setIsOpen(false),
92
127
  children: [/*#__PURE__*/_jsx(Row, {
93
128
  children: /*#__PURE__*/_jsx(Typography, {
94
129
  variant: {
@@ -96,10 +131,20 @@ const MultiSelectFilter = /*#__PURE__*/forwardRef((_ref, ref) => {
96
131
  },
97
132
  children: getCopy('filterByLabel').replace(/%\{filterCategory\}/g, label.toLowerCase())
98
133
  })
134
+ }), subtitle && /*#__PURE__*/_jsxs(_Fragment, {
135
+ children: [/*#__PURE__*/_jsx(Spacer, {
136
+ space: 5
137
+ }), /*#__PURE__*/_jsx(Row, {
138
+ children: /*#__PURE__*/_jsx(Typography, {
139
+ variant: {
140
+ size: 'h5'
141
+ },
142
+ tokens: selectSubTitleTokens(themeTokens),
143
+ children: subtitle
144
+ })
145
+ })]
99
146
  }), /*#__PURE__*/_jsx(Spacer, {
100
147
  space: 4
101
- }), /*#__PURE__*/_jsx(Spacer, {
102
- space: 1
103
148
  }), /*#__PURE__*/_jsx(Box, {
104
149
  scroll: true,
105
150
  children: /*#__PURE__*/_jsx(Row, {
@@ -116,12 +161,9 @@ const MultiSelectFilter = /*#__PURE__*/forwardRef((_ref, ref) => {
116
161
  }, i))
117
162
  })
118
163
  }), /*#__PURE__*/_jsx(Divider, {
119
- variant: {
120
- width: 'full',
121
- color: 'E3E6E8',
122
- decorative: true,
123
- weight: 'thin'
124
- },
164
+ variant: selectDividerToknes({ ...themeTokens,
165
+ width: 'full'
166
+ }),
125
167
  space: 4
126
168
  }), /*#__PURE__*/_jsx(Row, {
127
169
  children: /*#__PURE__*/_jsxs(StackView, {
@@ -145,16 +187,7 @@ const MultiSelectFilter = /*#__PURE__*/forwardRef((_ref, ref) => {
145
187
  })]
146
188
  })
147
189
  })]
148
- }), /*#__PURE__*/_jsx(ButtonDropdown, {
149
- ref: ref,
150
- ...pressHandlers,
151
- value: isOpen,
152
- selected: isSelected,
153
- label: label,
154
- onChange: handleChange,
155
- tokens: getButtonTokens,
156
- inactive: inactive
157
- }, id)]
190
+ })]
158
191
  });
159
192
  });
160
193
  MultiSelectFilter.displayName = 'MultiSelectFilter';
@@ -164,6 +197,11 @@ MultiSelectFilter.propTypes = {
164
197
  */
165
198
  label: PropTypes.string.isRequired,
166
199
 
200
+ /**
201
+ * The text for the subtitle
202
+ */
203
+ subtitle: PropTypes.string,
204
+
167
205
  /**
168
206
  * An optional unique string may be provided to identify the ButtonDropdown.
169
207
  * If not provided, the label is used.
@@ -71,17 +71,41 @@ const Typography = /*#__PURE__*/forwardRef((_ref2, ref) => {
71
71
  ...getA11yPropsFromHtmlTag(tag, accessibilityRole),
72
72
  ...selectContainerProps(rest)
73
73
  };
74
+
75
+ const resetTagStyling = child => {
76
+ if (typeof child === 'object' && ((child === null || child === void 0 ? void 0 : child.type) === 'sub' || (child === null || child === void 0 ? void 0 : child.type) === 'sup')) {
77
+ var _child$props;
78
+
79
+ const sanitizedChild = /*#__PURE__*/React.cloneElement(child, {
80
+ style: { ...(child === null || child === void 0 ? void 0 : (_child$props = child.props) === null || _child$props === void 0 ? void 0 : _child$props.style),
81
+ lineHeight: 0
82
+ }
83
+ });
84
+ return sanitizedChild;
85
+ }
86
+
87
+ return child;
88
+ };
89
+
90
+ const sanitizeChildren = () => {
91
+ if (Array.isArray(children)) {
92
+ return children.map(resetTagStyling);
93
+ }
94
+
95
+ return resetTagStyling(children);
96
+ };
97
+
74
98
  return block ? /*#__PURE__*/_jsx(View, {
75
99
  ref: ref,
76
100
  ...containerProps,
77
101
  children: /*#__PURE__*/_jsx(Text, { ...resolvedTextProps,
78
- children: children
102
+ children: sanitizeChildren(children)
79
103
  })
80
104
  }) : /*#__PURE__*/_jsx(Text, {
81
105
  ref: ref,
82
106
  ...containerProps,
83
107
  ...resolvedTextProps,
84
- children: children
108
+ children: sanitizeChildren(children)
85
109
  });
86
110
  });
87
111
  Typography.displayName = 'Typography';
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "@floating-ui/react-native": "^0.8.1",
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@telus-uds/system-constants": "^1.2.0",
14
- "@telus-uds/system-theme-tokens": "^2.9.0",
14
+ "@telus-uds/system-theme-tokens": "^2.10.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.24.2"
75
+ "version": "1.26.0"
76
76
  }
@@ -174,7 +174,7 @@ const ButtonBase = forwardRef(
174
174
  ref
175
175
  ) => {
176
176
  const { onPress, ...rest } = clickProps.toPressProps(rawRest)
177
- const extraButtonState = { inactive, selected }
177
+ const extraButtonState = { inactive, selected, iconPosition }
178
178
  const resolveButtonTokens = (pressableState) =>
179
179
  resolvePressableTokens(tokens, pressableState, extraButtonState)
180
180
 
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import { View, Animated, PanResponder, StyleSheet, Platform } from 'react-native'
2
+ import { View, Animated, PanResponder, StyleSheet, Platform, Dimensions } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
4
  import { useThemeTokens } from '../ThemeProvider'
5
5
  import { useViewport } from '../ViewportProvider'
@@ -145,6 +145,7 @@ const Carousel = React.forwardRef(
145
145
  children,
146
146
  itemLabel = 'item',
147
147
  previousNextNavigationPosition = 'inside',
148
+ stepTrackerVariant,
148
149
  previousNextIconSize = 'default',
149
150
  minDistanceToCapture = 5,
150
151
  minDistanceForAction = 0.2,
@@ -160,7 +161,7 @@ const Carousel = React.forwardRef(
160
161
  panelNavigation = thumbnails ? (
161
162
  <CarouselThumbnailNavigation thumbnails={thumbnails} />
162
163
  ) : (
163
- <CarouselStepTracker />
164
+ <CarouselStepTracker variant={stepTrackerVariant} />
164
165
  ),
165
166
  tag = 'ul',
166
167
  accessibilityRole,
@@ -220,6 +221,7 @@ const Carousel = React.forwardRef(
220
221
  y: 0,
221
222
  width: 0
222
223
  })
224
+
223
225
  const [previousNextNavigationButtonWidth, setPreviousNextNavigationButtonWidth] =
224
226
  React.useState(0)
225
227
  const firstFocusRef = React.useRef(null)
@@ -382,6 +384,14 @@ const Carousel = React.forwardRef(
382
384
  }
383
385
  }, [pan.x, pan.y])
384
386
 
387
+ React.useEffect(() => {
388
+ const subscription = Dimensions.addEventListener('change', () => {
389
+ updateOffset()
390
+ })
391
+
392
+ return () => subscription?.remove()
393
+ })
394
+
385
395
  const goToNext = React.useCallback(() => {
386
396
  goToNeighboring()
387
397
  }, [goToNeighboring])
@@ -563,6 +573,10 @@ Carousel.propTypes = {
563
573
  ...selectedSystemPropTypes,
564
574
  tokens: getTokensPropType('Carousel'),
565
575
  variant: variantProp.propType,
576
+ /**
577
+ * Prop related to StepTracker Variants
578
+ */
579
+ stepTrackerVariant: variantProp.propType,
566
580
  /**
567
581
  * Slides to render in Carousel. Wrap individual slides in `Carousel.Item`
568
582
  */
@@ -2,8 +2,9 @@ import React from 'react'
2
2
  import { useCarousel } from '../CarouselContext'
3
3
  import StepTracker from '../../StepTracker'
4
4
  import StackView from '../../StackView'
5
+ import { variantProp } from '../../utils'
5
6
 
6
- const CarouselStepTracker = () => {
7
+ const CarouselStepTracker = ({ variant }) => {
7
8
  const { activeIndex, totalItems, getCopyWithPlaceholders, themeTokens } = useCarousel()
8
9
  const stackViewTokens = {
9
10
  justifyContent: 'center'
@@ -28,9 +29,14 @@ const CarouselStepTracker = () => {
28
29
  stepTrackerLabel: getCopyWithPlaceholders('stepTrackerLabel')
29
30
  }}
30
31
  tokens={stepTrackerTokens}
32
+ variant={variant}
31
33
  />
32
34
  </StackView>
33
35
  )
34
36
  }
35
37
 
38
+ CarouselStepTracker.propTypes = {
39
+ variant: variantProp.propType
40
+ }
41
+
36
42
  export default CarouselStepTracker
@@ -0,0 +1,86 @@
1
+ import React, { forwardRef } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { View, StyleSheet } from 'react-native-web'
4
+ import { Portal } from '@gorhom/portal'
5
+ import { copyPropTypes, getTokensPropType, selectTokens, useCopy, variantProp } from '../utils'
6
+ import { useViewport } from '../ViewportProvider'
7
+ import { useThemeTokens } from '../ThemeProvider'
8
+ import dictionary from './dictionary'
9
+
10
+ import Card from '../Card'
11
+ import IconButton from '../IconButton'
12
+
13
+ const staticStyles = StyleSheet.create({
14
+ positioner: {
15
+ flex: 1, // Grow to maxWidth when possible, shrink when not possible
16
+ position: 'absolute',
17
+ height: 330,
18
+ paddingTop: 5,
19
+ zIndex: 10000 // Position on top of all the other overlays, including backdrops and modals
20
+ },
21
+ closeButtonContainer: {
22
+ position: 'absolute',
23
+ top: 0,
24
+ right: 0,
25
+ zIndex: 1
26
+ }
27
+ })
28
+
29
+ const selectCloseButtonContainerStyles = ({ paddingRight, paddingTop }) => ({
30
+ paddingRight,
31
+ paddingTop
32
+ })
33
+
34
+ const selectPaddingContainerStyles = ({ paddingTop, paddingLeft, paddingRight }) => ({
35
+ paddingBottom: 35,
36
+ paddingTop,
37
+ paddingLeft,
38
+ paddingRight
39
+ })
40
+
41
+ const ModalOverlay = forwardRef(({ children, tokens, variant, copy, onClose }, ref) => {
42
+ const viewport = useViewport()
43
+ const themeTokens = useThemeTokens('Modal', tokens, variant, { viewport, maxWidth: false })
44
+
45
+ const { closeIcon: CloseIconComponent, maxWidth } = themeTokens
46
+
47
+ const getCopy = useCopy({ dictionary, copy })
48
+ const closeLabel = getCopy('closeButton')
49
+
50
+ return (
51
+ <>
52
+ <Portal ref={ref}>
53
+ <View style={[{ minWidth: maxWidth }, staticStyles.positioner]}>
54
+ <Card tokens={selectPaddingContainerStyles(themeTokens)}>
55
+ <View
56
+ style={[
57
+ staticStyles.closeButtonContainer,
58
+ selectCloseButtonContainerStyles(themeTokens)
59
+ ]}
60
+ >
61
+ <IconButton
62
+ onPress={onClose}
63
+ icon={CloseIconComponent}
64
+ accessibilityRole="button"
65
+ accessibilityLabel={closeLabel}
66
+ tokens={selectTokens('IconButton', themeTokens, 'close')}
67
+ />
68
+ </View>
69
+ {children}
70
+ </Card>
71
+ </View>
72
+ </Portal>
73
+ </>
74
+ )
75
+ })
76
+ ModalOverlay.displayName = 'ModalOverlay'
77
+
78
+ ModalOverlay.propTypes = {
79
+ children: PropTypes.node.isRequired,
80
+ variant: variantProp.propType,
81
+ tokens: getTokensPropType('Modal'),
82
+ copy: copyPropTypes,
83
+ onClose: PropTypes.func
84
+ }
85
+
86
+ export default ModalOverlay