@telus-uds/components-base 1.13.0 → 1.14.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 CHANGED
@@ -1,12 +1,25 @@
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 Wed, 17 Aug 2022 18:43:08 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 1.14.0
8
+
9
+ Wed, 17 Aug 2022 18:43:08 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - Base notification component improvements (tiagohldb@gmail.com)
14
+ - Allowing icons to the button component (tiagohldb@gmail.com)
15
+
16
+ ### Patches
17
+
18
+ - fix(propTypes): fix PropTypes for icons (carlos.jeronimo@telus.com)
19
+
7
20
  ## 1.13.0
8
21
 
9
- Fri, 12 Aug 2022 20:14:48 GMT
22
+ Fri, 12 Aug 2022 20:17:12 GMT
10
23
 
11
24
  ### Minor changes
12
25
 
@@ -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",
@@ -4696,7 +4699,7 @@
4696
4699
  },
4697
4700
  "icon": {
4698
4701
  "type": {
4699
- "name": "func"
4702
+ "name": "elementType"
4700
4703
  },
4701
4704
  "required": false,
4702
4705
  "description": "Renders side item icon"
@@ -4867,7 +4870,7 @@
4867
4870
  },
4868
4871
  "icon": {
4869
4872
  "type": {
4870
- "name": "func"
4873
+ "name": "elementType"
4871
4874
  },
4872
4875
  "required": false,
4873
4876
  "description": "Renders side item icon"
@@ -4960,7 +4963,7 @@
4960
4963
  },
4961
4964
  "icon": {
4962
4965
  "type": {
4963
- "name": "func"
4966
+ "name": "elementType"
4964
4967
  },
4965
4968
  "required": false,
4966
4969
  "description": "Renders side item icon"
@@ -8152,6 +8155,9 @@
8152
8155
  "paddingBottom": "size",
8153
8156
  "width": "size",
8154
8157
  "minWidth": "size",
8158
+ "iconSize": "size",
8159
+ "iconSpace": "integer",
8160
+ "icon": "icon",
8155
8161
  "outerBorderColor": "color",
8156
8162
  "outerBorderWidth": "border",
8157
8163
  "outerBorderGap": "size",
@@ -8190,6 +8196,59 @@
8190
8196
  "required": false,
8191
8197
  "description": "Function called when the button is pressed. Required unless the button has a href."
8192
8198
  },
8199
+ "iconProps": {
8200
+ "type": {
8201
+ "name": "exact",
8202
+ "value": {
8203
+ "variant": {
8204
+ "name": "custom",
8205
+ "raw": "variantProp.propType",
8206
+ "required": false
8207
+ },
8208
+ "tokens": {
8209
+ "name": "custom",
8210
+ "raw": "getTokensPropType('Icon')",
8211
+ "required": false
8212
+ },
8213
+ "accessibilityLabel": {
8214
+ "name": "string",
8215
+ "description": "Descriptive label used in web SVG title tag for accessibility",
8216
+ "required": false
8217
+ },
8218
+ "scalesWithText": {
8219
+ "name": "bool",
8220
+ "description": "controls whether the icon size should be proportionate to any accessibility-related font scaling.",
8221
+ "required": false
8222
+ }
8223
+ }
8224
+ },
8225
+ "required": false,
8226
+ "description": "Optional variant that may be passed down to the link's icon if there is one"
8227
+ },
8228
+ "iconPosition": {
8229
+ "type": {
8230
+ "name": "enum",
8231
+ "value": [
8232
+ {
8233
+ "value": "'left'",
8234
+ "computed": false
8235
+ },
8236
+ {
8237
+ "value": "'right'",
8238
+ "computed": false
8239
+ }
8240
+ ]
8241
+ },
8242
+ "required": false,
8243
+ "description": "When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of the button."
8244
+ },
8245
+ "icon": {
8246
+ "type": {
8247
+ "name": "func"
8248
+ },
8249
+ "required": false,
8250
+ "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."
8251
+ },
8193
8252
  "variant": {
8194
8253
  "type": {
8195
8254
  "name": "objectOf",
@@ -8485,6 +8544,9 @@
8485
8544
  "paddingBottom": "size",
8486
8545
  "width": "size",
8487
8546
  "minWidth": "size",
8547
+ "iconSize": "size",
8548
+ "iconSpace": "integer",
8549
+ "icon": "icon",
8488
8550
  "outerBorderColor": "color",
8489
8551
  "outerBorderWidth": "border",
8490
8552
  "outerBorderGap": "size",
@@ -8523,6 +8585,59 @@
8523
8585
  "required": false,
8524
8586
  "description": "Function called when the button is pressed. Required unless the button has a href."
8525
8587
  },
8588
+ "iconProps": {
8589
+ "type": {
8590
+ "name": "exact",
8591
+ "value": {
8592
+ "variant": {
8593
+ "name": "custom",
8594
+ "raw": "variantProp.propType",
8595
+ "required": false
8596
+ },
8597
+ "tokens": {
8598
+ "name": "custom",
8599
+ "raw": "getTokensPropType('Icon')",
8600
+ "required": false
8601
+ },
8602
+ "accessibilityLabel": {
8603
+ "name": "string",
8604
+ "description": "Descriptive label used in web SVG title tag for accessibility",
8605
+ "required": false
8606
+ },
8607
+ "scalesWithText": {
8608
+ "name": "bool",
8609
+ "description": "controls whether the icon size should be proportionate to any accessibility-related font scaling.",
8610
+ "required": false
8611
+ }
8612
+ }
8613
+ },
8614
+ "required": false,
8615
+ "description": "Optional variant that may be passed down to the link's icon if there is one"
8616
+ },
8617
+ "iconPosition": {
8618
+ "type": {
8619
+ "name": "enum",
8620
+ "value": [
8621
+ {
8622
+ "value": "'left'",
8623
+ "computed": false
8624
+ },
8625
+ {
8626
+ "value": "'right'",
8627
+ "computed": false
8628
+ }
8629
+ ]
8630
+ },
8631
+ "required": false,
8632
+ "description": "When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of the button."
8633
+ },
8634
+ "icon": {
8635
+ "type": {
8636
+ "name": "func"
8637
+ },
8638
+ "required": false,
8639
+ "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."
8640
+ },
8526
8641
  "variant": {
8527
8642
  "type": {
8528
8643
  "name": "objectOf",
@@ -9968,7 +10083,7 @@
9968
10083
  },
9969
10084
  "icon": {
9970
10085
  "type": {
9971
- "name": "func"
10086
+ "name": "elementType"
9972
10087
  },
9973
10088
  "required": false,
9974
10089
  "description": "A valid UDS icon component imported from a UDS palette."
@@ -10215,7 +10330,7 @@
10215
10330
  },
10216
10331
  "icon": {
10217
10332
  "type": {
10218
- "name": "func"
10333
+ "name": "elementType"
10219
10334
  },
10220
10335
  "required": false,
10221
10336
  "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
  });
@@ -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
  });
package/package.json CHANGED
@@ -71,5 +71,5 @@
71
71
  "standard-engine": {
72
72
  "skip": true
73
73
  },
74
- "version": "1.13.0"
74
+ "version": "1.14.0"
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
  })