@telus-uds/components-base 1.13.0 → 1.14.2

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 CHANGED
@@ -1,12 +1,42 @@
1
1
  # Change Log - @telus-uds/components-base
2
2
 
3
- This log was last generated on Fri, 12 Aug 2022 20:14:48 GMT and should not be manually modified.
3
+ This log was last generated on Tue, 23 Aug 2022 19:30:28 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 1.14.2
8
+
9
+ Tue, 23 Aug 2022 19:30:28 GMT
10
+
11
+ ### Patches
12
+
13
+ - fix: remove extra icons from pagination (ruslan.bredikhin@nearform.com)
14
+ - Bump @telus-uds/system-theme-tokens to v2.4.0
15
+
16
+ ## 1.14.1
17
+
18
+ Wed, 17 Aug 2022 20:50:59 GMT
19
+
20
+ ### Patches
21
+
22
+ - Bump @telus-uds/system-theme-tokens to v2.3.0
23
+
24
+ ## 1.14.0
25
+
26
+ Wed, 17 Aug 2022 18:45:01 GMT
27
+
28
+ ### Minor changes
29
+
30
+ - Base notification component improvements (tiagohldb@gmail.com)
31
+ - Allowing icons to the button component (tiagohldb@gmail.com)
32
+
33
+ ### Patches
34
+
35
+ - fix(propTypes): fix PropTypes for icons (carlos.jeronimo@telus.com)
36
+
7
37
  ## 1.13.0
8
38
 
9
- Fri, 12 Aug 2022 20:14:48 GMT
39
+ Fri, 12 Aug 2022 20:17:12 GMT
10
40
 
11
41
  ### Minor changes
12
42
 
@@ -29,6 +29,9 @@
29
29
  "paddingBottom": "size",
30
30
  "width": "size",
31
31
  "minWidth": "size",
32
+ "iconSize": "size",
33
+ "iconSpace": "integer",
34
+ "icon": "icon",
32
35
  "outerBorderColor": "color",
33
36
  "outerBorderWidth": "border",
34
37
  "outerBorderGap": "size",
@@ -1154,6 +1157,16 @@
1154
1157
  true
1155
1158
  ],
1156
1159
  "type": "state"
1160
+ },
1161
+ "width": {
1162
+ "description": "The width of the modal",
1163
+ "values": [
1164
+ "s",
1165
+ "m",
1166
+ "l",
1167
+ "xl"
1168
+ ],
1169
+ "type": "state"
1157
1170
  }
1158
1171
  },
1159
1172
  "Notification": {
@@ -4696,7 +4709,7 @@
4696
4709
  },
4697
4710
  "icon": {
4698
4711
  "type": {
4699
- "name": "func"
4712
+ "name": "elementType"
4700
4713
  },
4701
4714
  "required": false,
4702
4715
  "description": "Renders side item icon"
@@ -4867,7 +4880,7 @@
4867
4880
  },
4868
4881
  "icon": {
4869
4882
  "type": {
4870
- "name": "func"
4883
+ "name": "elementType"
4871
4884
  },
4872
4885
  "required": false,
4873
4886
  "description": "Renders side item icon"
@@ -4960,7 +4973,7 @@
4960
4973
  },
4961
4974
  "icon": {
4962
4975
  "type": {
4963
- "name": "func"
4976
+ "name": "elementType"
4964
4977
  },
4965
4978
  "required": false,
4966
4979
  "description": "Renders side item icon"
@@ -8152,6 +8165,9 @@
8152
8165
  "paddingBottom": "size",
8153
8166
  "width": "size",
8154
8167
  "minWidth": "size",
8168
+ "iconSize": "size",
8169
+ "iconSpace": "integer",
8170
+ "icon": "icon",
8155
8171
  "outerBorderColor": "color",
8156
8172
  "outerBorderWidth": "border",
8157
8173
  "outerBorderGap": "size",
@@ -8190,6 +8206,59 @@
8190
8206
  "required": false,
8191
8207
  "description": "Function called when the button is pressed. Required unless the button has a href."
8192
8208
  },
8209
+ "iconProps": {
8210
+ "type": {
8211
+ "name": "exact",
8212
+ "value": {
8213
+ "variant": {
8214
+ "name": "custom",
8215
+ "raw": "variantProp.propType",
8216
+ "required": false
8217
+ },
8218
+ "tokens": {
8219
+ "name": "custom",
8220
+ "raw": "getTokensPropType('Icon')",
8221
+ "required": false
8222
+ },
8223
+ "accessibilityLabel": {
8224
+ "name": "string",
8225
+ "description": "Descriptive label used in web SVG title tag for accessibility",
8226
+ "required": false
8227
+ },
8228
+ "scalesWithText": {
8229
+ "name": "bool",
8230
+ "description": "controls whether the icon size should be proportionate to any accessibility-related font scaling.",
8231
+ "required": false
8232
+ }
8233
+ }
8234
+ },
8235
+ "required": false,
8236
+ "description": "Optional variant that may be passed down to the link's icon if there is one"
8237
+ },
8238
+ "iconPosition": {
8239
+ "type": {
8240
+ "name": "enum",
8241
+ "value": [
8242
+ {
8243
+ "value": "'left'",
8244
+ "computed": false
8245
+ },
8246
+ {
8247
+ "value": "'right'",
8248
+ "computed": false
8249
+ }
8250
+ ]
8251
+ },
8252
+ "required": false,
8253
+ "description": "When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of the button."
8254
+ },
8255
+ "icon": {
8256
+ "type": {
8257
+ "name": "func"
8258
+ },
8259
+ "required": false,
8260
+ "description": "A function component for an SVG icon to render inside the link. Inherits size and color from\nthe link and any Typography the link is nested inside."
8261
+ },
8193
8262
  "variant": {
8194
8263
  "type": {
8195
8264
  "name": "objectOf",
@@ -8485,6 +8554,9 @@
8485
8554
  "paddingBottom": "size",
8486
8555
  "width": "size",
8487
8556
  "minWidth": "size",
8557
+ "iconSize": "size",
8558
+ "iconSpace": "integer",
8559
+ "icon": "icon",
8488
8560
  "outerBorderColor": "color",
8489
8561
  "outerBorderWidth": "border",
8490
8562
  "outerBorderGap": "size",
@@ -8523,6 +8595,59 @@
8523
8595
  "required": false,
8524
8596
  "description": "Function called when the button is pressed. Required unless the button has a href."
8525
8597
  },
8598
+ "iconProps": {
8599
+ "type": {
8600
+ "name": "exact",
8601
+ "value": {
8602
+ "variant": {
8603
+ "name": "custom",
8604
+ "raw": "variantProp.propType",
8605
+ "required": false
8606
+ },
8607
+ "tokens": {
8608
+ "name": "custom",
8609
+ "raw": "getTokensPropType('Icon')",
8610
+ "required": false
8611
+ },
8612
+ "accessibilityLabel": {
8613
+ "name": "string",
8614
+ "description": "Descriptive label used in web SVG title tag for accessibility",
8615
+ "required": false
8616
+ },
8617
+ "scalesWithText": {
8618
+ "name": "bool",
8619
+ "description": "controls whether the icon size should be proportionate to any accessibility-related font scaling.",
8620
+ "required": false
8621
+ }
8622
+ }
8623
+ },
8624
+ "required": false,
8625
+ "description": "Optional variant that may be passed down to the link's icon if there is one"
8626
+ },
8627
+ "iconPosition": {
8628
+ "type": {
8629
+ "name": "enum",
8630
+ "value": [
8631
+ {
8632
+ "value": "'left'",
8633
+ "computed": false
8634
+ },
8635
+ {
8636
+ "value": "'right'",
8637
+ "computed": false
8638
+ }
8639
+ ]
8640
+ },
8641
+ "required": false,
8642
+ "description": "When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of the button."
8643
+ },
8644
+ "icon": {
8645
+ "type": {
8646
+ "name": "func"
8647
+ },
8648
+ "required": false,
8649
+ "description": "A function component for an SVG icon to render inside the link. Inherits size and color from\nthe link and any Typography the link is nested inside."
8650
+ },
8526
8651
  "variant": {
8527
8652
  "type": {
8528
8653
  "name": "objectOf",
@@ -9968,7 +10093,7 @@
9968
10093
  },
9969
10094
  "icon": {
9970
10095
  "type": {
9971
- "name": "func"
10096
+ "name": "elementType"
9972
10097
  },
9973
10098
  "required": false,
9974
10099
  "description": "A valid UDS icon component imported from a UDS palette."
@@ -10215,7 +10340,7 @@
10215
10340
  },
10216
10341
  "icon": {
10217
10342
  "type": {
10218
- "name": "func"
10343
+ "name": "elementType"
10219
10344
  },
10220
10345
  "required": false,
10221
10346
  "description": "A function component for an SVG icon to render inside the link. Inherits size and color from\nthe link and any Typography the link is nested inside."
@@ -23,6 +23,8 @@ var _propTypes2 = _interopRequireDefault(require("./propTypes"));
23
23
 
24
24
  var _utils = require("../utils");
25
25
 
26
+ var _Icon = require("../Icon");
27
+
26
28
  var _jsxRuntime = require("react/jsx-runtime");
27
29
 
28
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -190,7 +192,18 @@ const selectWebOnlyStyles = (inactive, themeTokens, _ref7) => {
190
192
  });
191
193
  };
192
194
 
193
- const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref8, ref) => {
195
+ const selectItemIconTokens = _ref8 => {
196
+ let {
197
+ color,
198
+ iconSize
199
+ } = _ref8;
200
+ return {
201
+ size: iconSize,
202
+ color
203
+ };
204
+ };
205
+
206
+ const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref9, ref) => {
194
207
  let {
195
208
  id,
196
209
  href,
@@ -201,8 +214,11 @@ const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref8, ref) => {
201
214
  // alias for inactive
202
215
  inactive = disabled,
203
216
  selected = false,
217
+ icon,
218
+ iconPosition = icon ? 'left' : undefined,
219
+ iconProps,
204
220
  ...rawRest
205
- } = _ref8;
221
+ } = _ref9;
206
222
 
207
223
  const {
208
224
  onPress,
@@ -241,10 +257,15 @@ const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref8, ref) => {
241
257
  const themeTokens = resolveButtonTokens(pressableState);
242
258
  const containerStyles = selectInnerContainerStyles(themeTokens);
243
259
  const borderStyles = selectBorderStyles(themeTokens);
244
- const textStyles = [selectTextStyles(themeTokens, themeOptions), staticStyles.text]; // If the container has a width set, fill it instead of sizing from content.
260
+ const textStyles = [selectTextStyles(themeTokens, themeOptions), staticStyles.text];
261
+ const iconTokens = selectItemIconTokens(themeTokens);
262
+ const {
263
+ iconSpace
264
+ } = themeTokens; // If the container has a width set, fill it instead of sizing from content.
245
265
  // If in future we support text alignments other than center, add here.
246
266
 
247
267
  const stretchStyles = themeTokens.width ? staticStyles.stretch : staticStyles.align;
268
+ const IconComponent = icon || themeTokens.icon;
248
269
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
249
270
  id: id,
250
271
  style: [containerStyles, borderStyles, stretchStyles, staticStyles.row, _Platform.default.select({
@@ -255,10 +276,18 @@ const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref8, ref) => {
255
276
  transition: 'background-color 200ms, border-color 200ms'
256
277
  }
257
278
  })],
258
- children: (0, _utils.wrapStringsInText)(typeof children === 'function' ? children({ ...(0, _utils.resolvePressableState)(pressableState, extraButtonState),
259
- textStyles
260
- }) : children, {
261
- style: textStyles
279
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.IconText, {
280
+ icon: IconComponent,
281
+ iconPosition: iconPosition,
282
+ space: iconSpace,
283
+ iconProps: { ...iconProps,
284
+ tokens: iconTokens
285
+ },
286
+ children: (0, _utils.wrapStringsInText)(typeof children === 'function' ? children({ ...(0, _utils.resolvePressableState)(pressableState, extraButtonState),
287
+ textStyles
288
+ }) : children, {
289
+ style: textStyles
290
+ })
262
291
  })
263
292
  });
264
293
  }
@@ -13,6 +13,8 @@ var _props = require("../utils/props");
13
13
 
14
14
  var _A11yText = _interopRequireDefault(require("../A11yText"));
15
15
 
16
+ var _Icon = require("../Icon");
17
+
16
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
19
 
18
20
  const textAndA11yText = _airbnbPropTypes.default.childrenOf(_propTypes.default.oneOfType([_airbnbPropTypes.default.elementType(_A11yText.default), _propTypes.default.string]));
@@ -46,6 +48,22 @@ const buttonPropTypes = {
46
48
  * Function called when the button is pressed. Required unless the button has a href.
47
49
  */
48
50
  onPress: _propTypes.default.func,
51
+
52
+ /**
53
+ * Optional variant that may be passed down to the link's icon if there is one
54
+ */
55
+ iconProps: _propTypes.default.exact(_Icon.iconComponentPropTypes),
56
+
57
+ /**
58
+ * When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of the button.
59
+ */
60
+ iconPosition: _propTypes.default.oneOf(['left', 'right']),
61
+
62
+ /**
63
+ * A function component for an SVG icon to render inside the link. Inherits size and color from
64
+ * the link and any Typography the link is nested inside.
65
+ */
66
+ icon: _propTypes.default.func,
49
67
  variant: _props.variantProp.propType
50
68
  };
51
69
  var _default = buttonPropTypes;
@@ -86,7 +86,7 @@ IconText.propTypes = {
86
86
  /**
87
87
  * A valid UDS icon component imported from a UDS palette.
88
88
  */
89
- icon: _propTypes.default.func,
89
+ icon: _propTypes.default.elementType,
90
90
 
91
91
  /**
92
92
  * Props that will be passed to the icon component. By default the icon's `scalesWithText`
@@ -245,7 +245,7 @@ LinkBase.propTypes = { ...selectedSystemPropTypes,
245
245
  * A function component for an SVG icon to render inside the link. Inherits size and color from
246
246
  * the link and any Typography the link is nested inside.
247
247
  */
248
- icon: _propTypes.default.func,
248
+ icon: _propTypes.default.elementType,
249
249
 
250
250
  /**
251
251
  * When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of Link.
@@ -246,7 +246,7 @@ ListItem.propTypes = { ...selectedSystemPropTypes,
246
246
  /**
247
247
  * Renders side item icon
248
248
  */
249
- icon: _propTypes.default.func,
249
+ icon: _propTypes.default.elementType,
250
250
 
251
251
  /**
252
252
  * Will set display icon color
@@ -79,6 +79,10 @@ const selectDismissButtonContainerStyles = _ref4 => {
79
79
  paddingLeft: dismissButtonGap
80
80
  };
81
81
  };
82
+
83
+ const selectContentContainerStyle = maxWidth => ({
84
+ width: maxWidth || '100%'
85
+ });
82
86
  /**
83
87
  * A banner that highlights important messages:
84
88
  * - Status message to show there is an error or outage of services
@@ -153,6 +157,7 @@ const Notification = /*#__PURE__*/(0, _react.forwardRef)((_ref5, ref) => {
153
157
  const {
154
158
  themeOptions
155
159
  } = (0, _ThemeProvider.useTheme)();
160
+ const contentMaxWidth = (0, _utils.useResponsiveProp)(themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.contentMaxWidth);
156
161
 
157
162
  if (isDismissed) {
158
163
  return null;
@@ -172,30 +177,33 @@ const Notification = /*#__PURE__*/(0, _react.forwardRef)((_ref5, ref) => {
172
177
  const onDismissPress = () => setIsDismissed(true); // TODO: replace the dismiss button with IconButton when implemented (https://github.com/telus/universal-design-system/issues/281)
173
178
 
174
179
 
175
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
180
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
176
181
  ref: ref,
177
182
  style: [staticStyles.container, selectContainerStyles(themeTokens)],
178
183
  ...selectProps(rest),
179
- children: [IconComponent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
180
- style: selectIconContainerStyles(themeTokens),
181
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(IconComponent, { ...selectIconProps(themeTokens)
182
- })
183
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
184
- style: staticStyles.contentContainer,
185
- children: content && typeof content === 'function' ? content({
186
- textStyles,
187
- variant
188
- }) : content
189
- }), dismissible && DismissIconComponent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
190
- style: selectDismissButtonContainerStyles(themeTokens),
191
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ButtonBase.default, {
192
- onPress: onDismissPress,
193
- accessibilityRole: "button",
194
- accessibilityLabel: getCopy('dismiss'),
195
- children: () => /*#__PURE__*/(0, _jsxRuntime.jsx)(DismissIconComponent, { ...selectDismissIconProps(themeTokens)
184
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
185
+ style: [staticStyles.content, selectContentContainerStyle(contentMaxWidth)],
186
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
187
+ style: staticStyles.contentContainer,
188
+ children: [IconComponent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
189
+ style: selectIconContainerStyles(themeTokens),
190
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(IconComponent, { ...selectIconProps(themeTokens)
191
+ })
192
+ }), content && typeof content === 'function' ? content({
193
+ textStyles,
194
+ variant
195
+ }) : content]
196
+ }), dismissible && DismissIconComponent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
197
+ style: selectDismissButtonContainerStyles(themeTokens),
198
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ButtonBase.default, {
199
+ onPress: onDismissPress,
200
+ accessibilityRole: "button",
201
+ accessibilityLabel: getCopy('dismiss'),
202
+ children: () => /*#__PURE__*/(0, _jsxRuntime.jsx)(DismissIconComponent, { ...selectDismissIconProps(themeTokens)
203
+ })
196
204
  })
197
- })
198
- })]
205
+ })]
206
+ })
199
207
  });
200
208
  });
201
209
  Notification.displayName = 'Notification';
@@ -230,9 +238,16 @@ exports.default = _default;
230
238
 
231
239
  const staticStyles = _StyleSheet.default.create({
232
240
  container: {
233
- flexDirection: 'row'
241
+ flexDirection: 'row',
242
+ justifyContent: 'center'
234
243
  },
235
244
  contentContainer: {
236
- flex: 1
245
+ flexDirection: 'row',
246
+ flexShrink: 1
247
+ },
248
+ content: {
249
+ flexDirection: 'row',
250
+ flexShrink: 1,
251
+ justifyContent: 'space-between'
237
252
  }
238
253
  });
@@ -33,12 +33,22 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
33
33
 
34
34
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
35
35
 
36
- const selectIconTokens = (_ref, direction) => {
36
+ // We need to drop the icon here since it gets rendered via children and not
37
+ // `ButtonBase` in order to tap into the state of the button
38
+ const selectButtonTokens = _ref => {
39
+ let {
40
+ icon: _,
41
+ ...rest
42
+ } = _ref;
43
+ return (0, _utils.selectTokens)('Button', rest);
44
+ };
45
+
46
+ const selectIconTokens = (_ref2, direction) => {
37
47
  let {
38
48
  color,
39
49
  iconSize,
40
50
  iconDisplace
41
- } = _ref;
51
+ } = _ref2;
42
52
  return {
43
53
  color,
44
54
  size: iconSize,
@@ -50,7 +60,7 @@ const directionToSide = {
50
60
  previous: 'left',
51
61
  next: 'right'
52
62
  };
53
- const SideButton = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
63
+ const SideButton = /*#__PURE__*/(0, _react.forwardRef)((_ref3, ref) => {
54
64
  let {
55
65
  direction = 'previous',
56
66
  onPress,
@@ -59,7 +69,7 @@ const SideButton = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
59
69
  variant,
60
70
  tokens,
61
71
  ...props
62
- } = _ref2;
72
+ } = _ref3;
63
73
  const viewport = (0, _ViewportProvider.useViewport)();
64
74
  const buttonVariant = {
65
75
  direction,
@@ -75,7 +85,7 @@ const SideButton = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
75
85
  icon
76
86
  } = getTokens(tokens, buttonVariant);
77
87
 
78
- const getButtonTokens = buttonState => (0, _utils.selectTokens)('Button', getTokens(buttonState));
88
+ const getButtonTokens = buttonState => selectButtonTokens(getTokens(buttonState));
79
89
 
80
90
  const getIconTokens = buttonState => selectIconTokens(getTokens(buttonState), direction);
81
91
 
@@ -101,11 +111,11 @@ const SideButton = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
101
111
  ref: ref,
102
112
  ...buttonProps,
103
113
  tokens: getButtonTokens,
104
- children: _ref3 => {
114
+ children: _ref4 => {
105
115
  let {
106
116
  textStyles,
107
117
  ...buttonState
108
- } = _ref3;
118
+ } = _ref4;
109
119
  const iconProps = {
110
120
  tokens: getIconTokens(buttonState)
111
121
  };
@@ -7,6 +7,7 @@ import Platform from "react-native-web/dist/exports/Platform";
7
7
  import { applyTextStyles, applyShadowToken, applyOuterBorder, useTheme } from '../ThemeProvider';
8
8
  import buttonPropTypes from './propTypes';
9
9
  import { a11yProps, clickProps, focusHandlerProps, getCursorStyle, linkProps, resolvePressableState, resolvePressableTokens, selectSystemProps, viewProps, wrapStringsInText, withLinkRouter } from '../utils';
10
+ import { IconText } from '../Icon';
10
11
  import { jsx as _jsx } from "react/jsx-runtime";
11
12
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, linkProps, viewProps]);
12
13
 
@@ -167,7 +168,18 @@ const selectWebOnlyStyles = (inactive, themeTokens, _ref7) => {
167
168
  });
168
169
  };
169
170
 
170
- const ButtonBase = /*#__PURE__*/forwardRef((_ref8, ref) => {
171
+ const selectItemIconTokens = _ref8 => {
172
+ let {
173
+ color,
174
+ iconSize
175
+ } = _ref8;
176
+ return {
177
+ size: iconSize,
178
+ color
179
+ };
180
+ };
181
+
182
+ const ButtonBase = /*#__PURE__*/forwardRef((_ref9, ref) => {
171
183
  let {
172
184
  id,
173
185
  href,
@@ -178,8 +190,11 @@ const ButtonBase = /*#__PURE__*/forwardRef((_ref8, ref) => {
178
190
  // alias for inactive
179
191
  inactive = disabled,
180
192
  selected = false,
193
+ icon,
194
+ iconPosition = icon ? 'left' : undefined,
195
+ iconProps,
181
196
  ...rawRest
182
- } = _ref8;
197
+ } = _ref9;
183
198
  const {
184
199
  onPress,
185
200
  ...rest
@@ -216,10 +231,15 @@ const ButtonBase = /*#__PURE__*/forwardRef((_ref8, ref) => {
216
231
  const themeTokens = resolveButtonTokens(pressableState);
217
232
  const containerStyles = selectInnerContainerStyles(themeTokens);
218
233
  const borderStyles = selectBorderStyles(themeTokens);
219
- const textStyles = [selectTextStyles(themeTokens, themeOptions), staticStyles.text]; // If the container has a width set, fill it instead of sizing from content.
234
+ const textStyles = [selectTextStyles(themeTokens, themeOptions), staticStyles.text];
235
+ const iconTokens = selectItemIconTokens(themeTokens);
236
+ const {
237
+ iconSpace
238
+ } = themeTokens; // If the container has a width set, fill it instead of sizing from content.
220
239
  // If in future we support text alignments other than center, add here.
221
240
 
222
241
  const stretchStyles = themeTokens.width ? staticStyles.stretch : staticStyles.align;
242
+ const IconComponent = icon || themeTokens.icon;
223
243
  return /*#__PURE__*/_jsx(View, {
224
244
  id: id,
225
245
  style: [containerStyles, borderStyles, stretchStyles, staticStyles.row, Platform.select({
@@ -230,10 +250,18 @@ const ButtonBase = /*#__PURE__*/forwardRef((_ref8, ref) => {
230
250
  transition: 'background-color 200ms, border-color 200ms'
231
251
  }
232
252
  })],
233
- children: wrapStringsInText(typeof children === 'function' ? children({ ...resolvePressableState(pressableState, extraButtonState),
234
- textStyles
235
- }) : children, {
236
- style: textStyles
253
+ children: /*#__PURE__*/_jsx(IconText, {
254
+ icon: IconComponent,
255
+ iconPosition: iconPosition,
256
+ space: iconSpace,
257
+ iconProps: { ...iconProps,
258
+ tokens: iconTokens
259
+ },
260
+ children: wrapStringsInText(typeof children === 'function' ? children({ ...resolvePressableState(pressableState, extraButtonState),
261
+ textStyles
262
+ }) : children, {
263
+ style: textStyles
264
+ })
237
265
  })
238
266
  });
239
267
  }
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
2
2
  import ABBPropTypes from 'airbnb-prop-types';
3
3
  import { variantProp, getTokensPropType } from '../utils/props';
4
4
  import A11yText from '../A11yText';
5
+ import { iconComponentPropTypes } from '../Icon';
5
6
  export const textAndA11yText = ABBPropTypes.childrenOf(PropTypes.oneOfType([ABBPropTypes.elementType(A11yText), PropTypes.string]));
6
7
  const buttonPropTypes = {
7
8
  tokens: getTokensPropType('Button'),
@@ -31,6 +32,22 @@ const buttonPropTypes = {
31
32
  * Function called when the button is pressed. Required unless the button has a href.
32
33
  */
33
34
  onPress: PropTypes.func,
35
+
36
+ /**
37
+ * Optional variant that may be passed down to the link's icon if there is one
38
+ */
39
+ iconProps: PropTypes.exact(iconComponentPropTypes),
40
+
41
+ /**
42
+ * When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of the button.
43
+ */
44
+ iconPosition: PropTypes.oneOf(['left', 'right']),
45
+
46
+ /**
47
+ * A function component for an SVG icon to render inside the link. Inherits size and color from
48
+ * the link and any Typography the link is nested inside.
49
+ */
50
+ icon: PropTypes.func,
34
51
  variant: variantProp.propType
35
52
  };
36
53
  export default buttonPropTypes;
@@ -68,7 +68,7 @@ IconText.propTypes = {
68
68
  /**
69
69
  * A valid UDS icon component imported from a UDS palette.
70
70
  */
71
- icon: PropTypes.func,
71
+ icon: PropTypes.elementType,
72
72
 
73
73
  /**
74
74
  * Props that will be passed to the icon component. By default the icon's `scalesWithText`
@@ -217,7 +217,7 @@ LinkBase.propTypes = { ...selectedSystemPropTypes,
217
217
  * A function component for an SVG icon to render inside the link. Inherits size and color from
218
218
  * the link and any Typography the link is nested inside.
219
219
  */
220
- icon: PropTypes.func,
220
+ icon: PropTypes.elementType,
221
221
 
222
222
  /**
223
223
  * When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of Link.
@@ -225,7 +225,7 @@ ListItem.propTypes = { ...selectedSystemPropTypes,
225
225
  /**
226
226
  * Renders side item icon
227
227
  */
228
- icon: PropTypes.func,
228
+ icon: PropTypes.elementType,
229
229
 
230
230
  /**
231
231
  * Will set display icon color
@@ -3,7 +3,7 @@ import StyleSheet from "react-native-web/dist/exports/StyleSheet";
3
3
  import View from "react-native-web/dist/exports/View";
4
4
  import PropTypes from 'prop-types';
5
5
  import { applyTextStyles, useTheme, useThemeTokens } from '../ThemeProvider';
6
- import { a11yProps, getTokensPropType, selectSystemProps, selectTokens, variantProp, viewProps, wrapStringsInText } from '../utils';
6
+ import { a11yProps, getTokensPropType, selectSystemProps, selectTokens, variantProp, viewProps, wrapStringsInText, useResponsiveProp } from '../utils';
7
7
  import ButtonBase from '../Button/ButtonBase';
8
8
  import useCopy from '../utils/useCopy';
9
9
  import dictionary from './dictionary';
@@ -57,6 +57,10 @@ const selectDismissButtonContainerStyles = _ref4 => {
57
57
  paddingLeft: dismissButtonGap
58
58
  };
59
59
  };
60
+
61
+ const selectContentContainerStyle = maxWidth => ({
62
+ width: maxWidth || '100%'
63
+ });
60
64
  /**
61
65
  * A banner that highlights important messages:
62
66
  * - Status message to show there is an error or outage of services
@@ -131,6 +135,7 @@ const Notification = /*#__PURE__*/forwardRef((_ref5, ref) => {
131
135
  const {
132
136
  themeOptions
133
137
  } = useTheme();
138
+ const contentMaxWidth = useResponsiveProp(themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.contentMaxWidth);
134
139
 
135
140
  if (isDismissed) {
136
141
  return null;
@@ -150,30 +155,33 @@ const Notification = /*#__PURE__*/forwardRef((_ref5, ref) => {
150
155
  const onDismissPress = () => setIsDismissed(true); // TODO: replace the dismiss button with IconButton when implemented (https://github.com/telus/universal-design-system/issues/281)
151
156
 
152
157
 
153
- return /*#__PURE__*/_jsxs(View, {
158
+ return /*#__PURE__*/_jsx(View, {
154
159
  ref: ref,
155
160
  style: [staticStyles.container, selectContainerStyles(themeTokens)],
156
161
  ...selectProps(rest),
157
- children: [IconComponent && /*#__PURE__*/_jsx(View, {
158
- style: selectIconContainerStyles(themeTokens),
159
- children: /*#__PURE__*/_jsx(IconComponent, { ...selectIconProps(themeTokens)
160
- })
161
- }), /*#__PURE__*/_jsx(View, {
162
- style: staticStyles.contentContainer,
163
- children: content && typeof content === 'function' ? content({
164
- textStyles,
165
- variant
166
- }) : content
167
- }), dismissible && DismissIconComponent && /*#__PURE__*/_jsx(View, {
168
- style: selectDismissButtonContainerStyles(themeTokens),
169
- children: /*#__PURE__*/_jsx(ButtonBase, {
170
- onPress: onDismissPress,
171
- accessibilityRole: "button",
172
- accessibilityLabel: getCopy('dismiss'),
173
- children: () => /*#__PURE__*/_jsx(DismissIconComponent, { ...selectDismissIconProps(themeTokens)
162
+ children: /*#__PURE__*/_jsxs(View, {
163
+ style: [staticStyles.content, selectContentContainerStyle(contentMaxWidth)],
164
+ children: [/*#__PURE__*/_jsxs(View, {
165
+ style: staticStyles.contentContainer,
166
+ children: [IconComponent && /*#__PURE__*/_jsx(View, {
167
+ style: selectIconContainerStyles(themeTokens),
168
+ children: /*#__PURE__*/_jsx(IconComponent, { ...selectIconProps(themeTokens)
169
+ })
170
+ }), content && typeof content === 'function' ? content({
171
+ textStyles,
172
+ variant
173
+ }) : content]
174
+ }), dismissible && DismissIconComponent && /*#__PURE__*/_jsx(View, {
175
+ style: selectDismissButtonContainerStyles(themeTokens),
176
+ children: /*#__PURE__*/_jsx(ButtonBase, {
177
+ onPress: onDismissPress,
178
+ accessibilityRole: "button",
179
+ accessibilityLabel: getCopy('dismiss'),
180
+ children: () => /*#__PURE__*/_jsx(DismissIconComponent, { ...selectDismissIconProps(themeTokens)
181
+ })
174
182
  })
175
- })
176
- })]
183
+ })]
184
+ })
177
185
  });
178
186
  });
179
187
  Notification.displayName = 'Notification';
@@ -206,9 +214,16 @@ Notification.propTypes = { ...selectedSystemPropTypes,
206
214
  export default Notification;
207
215
  const staticStyles = StyleSheet.create({
208
216
  container: {
209
- flexDirection: 'row'
217
+ flexDirection: 'row',
218
+ justifyContent: 'center'
210
219
  },
211
220
  contentContainer: {
212
- flex: 1
221
+ flexDirection: 'row',
222
+ flexShrink: 1
223
+ },
224
+ content: {
225
+ flexDirection: 'row',
226
+ flexShrink: 1,
227
+ justifyContent: 'space-between'
213
228
  }
214
229
  });
@@ -7,15 +7,25 @@ import { useThemeTokensCallback } from '../ThemeProvider';
7
7
  import { useViewport } from '../ViewportProvider';
8
8
  import { copyPropTypes, hrefAttrsProp, linkProps, selectTokens, withLinkRouter } from '../utils';
9
9
  import dictionary from './dictionary';
10
- import useCopy from '../utils/useCopy';
10
+ import useCopy from '../utils/useCopy'; // We need to drop the icon here since it gets rendered via children and not
11
+ // `ButtonBase` in order to tap into the state of the button
12
+
11
13
  import { jsx as _jsx } from "react/jsx-runtime";
12
14
 
13
- const selectIconTokens = (_ref, direction) => {
15
+ const selectButtonTokens = _ref => {
16
+ let {
17
+ icon: _,
18
+ ...rest
19
+ } = _ref;
20
+ return selectTokens('Button', rest);
21
+ };
22
+
23
+ const selectIconTokens = (_ref2, direction) => {
14
24
  let {
15
25
  color,
16
26
  iconSize,
17
27
  iconDisplace
18
- } = _ref;
28
+ } = _ref2;
19
29
  return {
20
30
  color,
21
31
  size: iconSize,
@@ -27,7 +37,7 @@ const directionToSide = {
27
37
  previous: 'left',
28
38
  next: 'right'
29
39
  };
30
- const SideButton = /*#__PURE__*/forwardRef((_ref2, ref) => {
40
+ const SideButton = /*#__PURE__*/forwardRef((_ref3, ref) => {
31
41
  let {
32
42
  direction = 'previous',
33
43
  onPress,
@@ -36,7 +46,7 @@ const SideButton = /*#__PURE__*/forwardRef((_ref2, ref) => {
36
46
  variant,
37
47
  tokens,
38
48
  ...props
39
- } = _ref2;
49
+ } = _ref3;
40
50
  const viewport = useViewport();
41
51
  const buttonVariant = {
42
52
  direction,
@@ -52,7 +62,7 @@ const SideButton = /*#__PURE__*/forwardRef((_ref2, ref) => {
52
62
  icon
53
63
  } = getTokens(tokens, buttonVariant);
54
64
 
55
- const getButtonTokens = buttonState => selectTokens('Button', getTokens(buttonState));
65
+ const getButtonTokens = buttonState => selectButtonTokens(getTokens(buttonState));
56
66
 
57
67
  const getIconTokens = buttonState => selectIconTokens(getTokens(buttonState), direction);
58
68
 
@@ -76,11 +86,11 @@ const SideButton = /*#__PURE__*/forwardRef((_ref2, ref) => {
76
86
  ref: ref,
77
87
  ...buttonProps,
78
88
  tokens: getButtonTokens,
79
- children: _ref3 => {
89
+ children: _ref4 => {
80
90
  let {
81
91
  textStyles,
82
92
  ...buttonState
83
- } = _ref3;
93
+ } = _ref4;
84
94
  const iconProps = {
85
95
  tokens: getIconTokens(buttonState)
86
96
  };
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "dependencies": {
10
10
  "airbnb-prop-types": "^2.16.0",
11
11
  "@telus-uds/system-constants": "^1.0.4",
12
- "@telus-uds/system-theme-tokens": "^2.2.0",
12
+ "@telus-uds/system-theme-tokens": "^2.4.0",
13
13
  "lodash.debounce": "^4.0.8",
14
14
  "lodash.merge": "^4.6.2",
15
15
  "prop-types": "^15.7.2",
@@ -71,5 +71,5 @@
71
71
  "standard-engine": {
72
72
  "skip": true
73
73
  },
74
- "version": "1.13.0"
74
+ "version": "1.14.2"
75
75
  }
@@ -17,6 +17,7 @@ import {
17
17
  wrapStringsInText,
18
18
  withLinkRouter
19
19
  } from '../utils'
20
+ import { IconText } from '../Icon'
20
21
 
21
22
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([
22
23
  a11yProps,
@@ -147,6 +148,11 @@ const selectWebOnlyStyles = (inactive, themeTokens, { accessibilityRole }) => {
147
148
  })
148
149
  }
149
150
 
151
+ const selectItemIconTokens = ({ color, iconSize }) => ({
152
+ size: iconSize,
153
+ color
154
+ })
155
+
150
156
  const ButtonBase = forwardRef(
151
157
  (
152
158
  {
@@ -158,6 +164,9 @@ const ButtonBase = forwardRef(
158
164
  disabled = false, // alias for inactive
159
165
  inactive = disabled,
160
166
  selected = false,
167
+ icon,
168
+ iconPosition = icon ? 'left' : undefined,
169
+ iconProps,
161
170
  ...rawRest
162
171
  },
163
172
  ref
@@ -195,10 +204,13 @@ const ButtonBase = forwardRef(
195
204
  const containerStyles = selectInnerContainerStyles(themeTokens)
196
205
  const borderStyles = selectBorderStyles(themeTokens)
197
206
  const textStyles = [selectTextStyles(themeTokens, themeOptions), staticStyles.text]
207
+ const iconTokens = selectItemIconTokens(themeTokens)
208
+ const { iconSpace } = themeTokens
198
209
 
199
210
  // If the container has a width set, fill it instead of sizing from content.
200
211
  // If in future we support text alignments other than center, add here.
201
212
  const stretchStyles = themeTokens.width ? staticStyles.stretch : staticStyles.align
213
+ const IconComponent = icon || themeTokens.icon
202
214
 
203
215
  return (
204
216
  <View
@@ -217,15 +229,22 @@ const ButtonBase = forwardRef(
217
229
  })
218
230
  ]}
219
231
  >
220
- {wrapStringsInText(
221
- typeof children === 'function'
222
- ? children({
223
- ...resolvePressableState(pressableState, extraButtonState),
224
- textStyles
225
- })
226
- : children,
227
- { style: textStyles }
228
- )}
232
+ <IconText
233
+ icon={IconComponent}
234
+ iconPosition={iconPosition}
235
+ space={iconSpace}
236
+ iconProps={{ ...iconProps, tokens: iconTokens }}
237
+ >
238
+ {wrapStringsInText(
239
+ typeof children === 'function'
240
+ ? children({
241
+ ...resolvePressableState(pressableState, extraButtonState),
242
+ textStyles
243
+ })
244
+ : children,
245
+ { style: textStyles }
246
+ )}
247
+ </IconText>
229
248
  </View>
230
249
  )
231
250
  }}
@@ -2,6 +2,7 @@ import PropTypes from 'prop-types'
2
2
  import ABBPropTypes from 'airbnb-prop-types'
3
3
  import { variantProp, getTokensPropType } from '../utils/props'
4
4
  import A11yText from '../A11yText'
5
+ import { iconComponentPropTypes } from '../Icon'
5
6
 
6
7
  export const textAndA11yText = ABBPropTypes.childrenOf(
7
8
  PropTypes.oneOfType([ABBPropTypes.elementType(A11yText), PropTypes.string])
@@ -31,6 +32,19 @@ const buttonPropTypes = {
31
32
  * Function called when the button is pressed. Required unless the button has a href.
32
33
  */
33
34
  onPress: PropTypes.func,
35
+ /**
36
+ * Optional variant that may be passed down to the link's icon if there is one
37
+ */
38
+ iconProps: PropTypes.exact(iconComponentPropTypes),
39
+ /**
40
+ * When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of the button.
41
+ */
42
+ iconPosition: PropTypes.oneOf(['left', 'right']),
43
+ /**
44
+ * A function component for an SVG icon to render inside the link. Inherits size and color from
45
+ * the link and any Typography the link is nested inside.
46
+ */
47
+ icon: PropTypes.func,
34
48
  variant: variantProp.propType
35
49
  }
36
50
  export default buttonPropTypes
@@ -52,7 +52,7 @@ IconText.propTypes = {
52
52
  /**
53
53
  * A valid UDS icon component imported from a UDS palette.
54
54
  */
55
- icon: PropTypes.func,
55
+ icon: PropTypes.elementType,
56
56
  /**
57
57
  * Props that will be passed to the icon component. By default the icon's `scalesWithText`
58
58
  * prop will be set as "true" so that the icon continues to match the size of the text
@@ -193,7 +193,7 @@ LinkBase.propTypes = {
193
193
  * A function component for an SVG icon to render inside the link. Inherits size and color from
194
194
  * the link and any Typography the link is nested inside.
195
195
  */
196
- icon: PropTypes.func,
196
+ icon: PropTypes.elementType,
197
197
  /**
198
198
  * When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of Link.
199
199
  */
@@ -180,7 +180,7 @@ ListItem.propTypes = {
180
180
  /**
181
181
  * Renders side item icon
182
182
  */
183
- icon: PropTypes.func,
183
+ icon: PropTypes.elementType,
184
184
  /**
185
185
  * Will set display icon color
186
186
  */
@@ -10,7 +10,8 @@ import {
10
10
  selectTokens,
11
11
  variantProp,
12
12
  viewProps,
13
- wrapStringsInText
13
+ wrapStringsInText,
14
+ useResponsiveProp
14
15
  } from '../utils'
15
16
  import ButtonBase from '../Button/ButtonBase'
16
17
  import useCopy from '../utils/useCopy'
@@ -41,6 +42,10 @@ const selectDismissButtonContainerStyles = ({ dismissButtonGap }) => ({
41
42
  paddingLeft: dismissButtonGap
42
43
  })
43
44
 
45
+ const selectContentContainerStyle = (maxWidth) => ({
46
+ width: maxWidth || '100%'
47
+ })
48
+
44
49
  /**
45
50
  * A banner that highlights important messages:
46
51
  * - Status message to show there is an error or outage of services
@@ -98,6 +103,7 @@ const Notification = forwardRef(
98
103
  const themeTokens = useThemeTokens('Notification', tokens, variant, { system })
99
104
  const getCopy = useCopy({ dictionary, copy })
100
105
  const { themeOptions } = useTheme()
106
+ const contentMaxWidth = useResponsiveProp(themeOptions?.contentMaxWidth)
101
107
 
102
108
  if (isDismissed) {
103
109
  return null
@@ -121,25 +127,27 @@ const Notification = forwardRef(
121
127
  style={[staticStyles.container, selectContainerStyles(themeTokens)]}
122
128
  {...selectProps(rest)}
123
129
  >
124
- {IconComponent && (
125
- <View style={selectIconContainerStyles(themeTokens)}>
126
- <IconComponent {...selectIconProps(themeTokens)} />
130
+ <View style={[staticStyles.content, selectContentContainerStyle(contentMaxWidth)]}>
131
+ <View style={staticStyles.contentContainer}>
132
+ {IconComponent && (
133
+ <View style={selectIconContainerStyles(themeTokens)}>
134
+ <IconComponent {...selectIconProps(themeTokens)} />
135
+ </View>
136
+ )}
137
+ {content && typeof content === 'function' ? content({ textStyles, variant }) : content}
127
138
  </View>
128
- )}
129
- <View style={staticStyles.contentContainer}>
130
- {content && typeof content === 'function' ? content({ textStyles, variant }) : content}
139
+ {dismissible && DismissIconComponent && (
140
+ <View style={selectDismissButtonContainerStyles(themeTokens)}>
141
+ <ButtonBase
142
+ onPress={onDismissPress}
143
+ accessibilityRole="button"
144
+ accessibilityLabel={getCopy('dismiss')}
145
+ >
146
+ {() => <DismissIconComponent {...selectDismissIconProps(themeTokens)} />}
147
+ </ButtonBase>
148
+ </View>
149
+ )}
131
150
  </View>
132
- {dismissible && DismissIconComponent && (
133
- <View style={selectDismissButtonContainerStyles(themeTokens)}>
134
- <ButtonBase
135
- onPress={onDismissPress}
136
- accessibilityRole="button"
137
- accessibilityLabel={getCopy('dismiss')}
138
- >
139
- {() => <DismissIconComponent {...selectDismissIconProps(themeTokens)} />}
140
- </ButtonBase>
141
- </View>
142
- )}
143
151
  </View>
144
152
  )
145
153
  }
@@ -175,9 +183,16 @@ export default Notification
175
183
 
176
184
  const staticStyles = StyleSheet.create({
177
185
  container: {
178
- flexDirection: 'row'
186
+ flexDirection: 'row',
187
+ justifyContent: 'center'
179
188
  },
180
189
  contentContainer: {
181
- flex: 1
190
+ flexDirection: 'row',
191
+ flexShrink: 1
192
+ },
193
+ content: {
194
+ flexDirection: 'row',
195
+ flexShrink: 1,
196
+ justifyContent: 'space-between'
182
197
  }
183
198
  })
@@ -12,6 +12,9 @@ import { copyPropTypes, hrefAttrsProp, linkProps, selectTokens, withLinkRouter }
12
12
  import dictionary from './dictionary'
13
13
  import useCopy from '../utils/useCopy'
14
14
 
15
+ // We need to drop the icon here since it gets rendered via children and not
16
+ // `ButtonBase` in order to tap into the state of the button
17
+ const selectButtonTokens = ({ icon: _, ...rest }) => selectTokens('Button', rest)
15
18
  const selectIconTokens = ({ color, iconSize, iconDisplace }, direction) => {
16
19
  return {
17
20
  color,
@@ -35,7 +38,7 @@ const SideButton = forwardRef(
35
38
 
36
39
  const { icon } = getTokens(tokens, buttonVariant)
37
40
 
38
- const getButtonTokens = (buttonState) => selectTokens('Button', getTokens(buttonState))
41
+ const getButtonTokens = (buttonState) => selectButtonTokens(getTokens(buttonState))
39
42
  const getIconTokens = (buttonState) => selectIconTokens(getTokens(buttonState), direction)
40
43
 
41
44
  const label = direction === 'previous' ? getCopy('previousText') : getCopy('nextText')