@telus-uds/components-base 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/.turbo/turbo-build.log +8 -8
  2. package/.turbo/turbo-lint.log +13 -0
  3. package/CHANGELOG.json +154 -1
  4. package/CHANGELOG.md +47 -2
  5. package/__tests__/FlexGrid/Row.test.jsx +100 -25
  6. package/__tests__/utils/containUniqueFields.test.js +25 -0
  7. package/component-docs.json +78 -26
  8. package/generate-component-docs.js +20 -7
  9. package/lib/Button/ButtonBase.js +1 -1
  10. package/lib/Button/ButtonGroup.js +20 -12
  11. package/lib/Card/PressableCardBase.js +1 -1
  12. package/lib/Checkbox/Checkbox.js +27 -16
  13. package/lib/Checkbox/CheckboxGroup.js +19 -5
  14. package/lib/ExpandCollapse/Panel.js +10 -10
  15. package/lib/FlexGrid/Col/Col.js +13 -3
  16. package/lib/FlexGrid/Row/Row.js +8 -2
  17. package/lib/InputLabel/InputLabel.js +27 -25
  18. package/lib/Link/LinkBase.js +19 -6
  19. package/lib/Link/TextButton.js +1 -10
  20. package/lib/List/ListItem.js +22 -12
  21. package/lib/Modal/Modal.js +18 -18
  22. package/lib/Radio/Radio.js +23 -12
  23. package/lib/Radio/RadioGroup.js +12 -3
  24. package/lib/RadioCard/RadioCard.js +1 -1
  25. package/lib/RadioCard/RadioCardGroup.js +11 -2
  26. package/lib/Search/Search.js +27 -19
  27. package/lib/Select/Select.js +2 -3
  28. package/lib/Tags/Tags.js +23 -17
  29. package/lib/TextInput/TextArea.js +2 -2
  30. package/lib/TextInput/TextInput.js +12 -2
  31. package/lib/TextInput/TextInputBase.js +1 -1
  32. package/lib/TextInput/propTypes.js +8 -1
  33. package/lib/ToggleSwitch/ToggleSwitch.js +5 -2
  34. package/lib/ToggleSwitch/ToggleSwitchGroup.js +20 -12
  35. package/lib/Typography/Typography.js +12 -10
  36. package/lib/index.js +22 -1
  37. package/lib/utils/containUniqueFields.js +34 -0
  38. package/lib/utils/index.js +10 -1
  39. package/lib/utils/input.js +5 -6
  40. package/lib/utils/props/handlerProps.js +72 -0
  41. package/lib/utils/props/index.js +32 -0
  42. package/lib/utils/props/inputSupportsProps.js +3 -5
  43. package/lib/utils/props/linkProps.js +3 -7
  44. package/lib/utils/props/textInputProps.js +206 -0
  45. package/lib/utils/props/textProps.js +72 -0
  46. package/lib-module/Button/ButtonBase.js +2 -2
  47. package/lib-module/Button/ButtonGroup.js +15 -6
  48. package/lib-module/Card/PressableCardBase.js +2 -2
  49. package/lib-module/Checkbox/Checkbox.js +28 -17
  50. package/lib-module/Checkbox/CheckboxGroup.js +20 -7
  51. package/lib-module/ExpandCollapse/Panel.js +10 -10
  52. package/lib-module/FlexGrid/Col/Col.js +13 -3
  53. package/lib-module/FlexGrid/Row/Row.js +8 -2
  54. package/lib-module/InputLabel/InputLabel.js +28 -25
  55. package/lib-module/Link/LinkBase.js +19 -6
  56. package/lib-module/Link/TextButton.js +1 -10
  57. package/lib-module/List/ListItem.js +22 -12
  58. package/lib-module/Modal/Modal.js +19 -19
  59. package/lib-module/Radio/Radio.js +24 -13
  60. package/lib-module/Radio/RadioGroup.js +13 -4
  61. package/lib-module/RadioCard/RadioCard.js +2 -2
  62. package/lib-module/RadioCard/RadioCardGroup.js +12 -3
  63. package/lib-module/Search/Search.js +29 -21
  64. package/lib-module/Select/Select.js +2 -3
  65. package/lib-module/Tags/Tags.js +18 -11
  66. package/lib-module/TextInput/TextArea.js +3 -3
  67. package/lib-module/TextInput/TextInput.js +11 -3
  68. package/lib-module/TextInput/TextInputBase.js +2 -2
  69. package/lib-module/TextInput/propTypes.js +7 -1
  70. package/lib-module/ToggleSwitch/ToggleSwitch.js +6 -3
  71. package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +15 -6
  72. package/lib-module/Typography/Typography.js +13 -11
  73. package/lib-module/index.js +1 -1
  74. package/lib-module/utils/containUniqueFields.js +26 -0
  75. package/lib-module/utils/index.js +2 -1
  76. package/lib-module/utils/input.js +6 -6
  77. package/lib-module/utils/props/handlerProps.js +59 -0
  78. package/lib-module/utils/props/index.js +3 -0
  79. package/lib-module/utils/props/inputSupportsProps.js +3 -5
  80. package/lib-module/utils/props/linkProps.js +3 -7
  81. package/lib-module/utils/props/textInputProps.js +193 -0
  82. package/lib-module/utils/props/textProps.js +59 -0
  83. package/package.json +5 -5
  84. package/src/Button/ButtonBase.jsx +8 -2
  85. package/src/Button/ButtonGroup.jsx +51 -34
  86. package/src/Card/PressableCardBase.jsx +6 -1
  87. package/src/Checkbox/Checkbox.jsx +35 -23
  88. package/src/Checkbox/CheckboxGroup.jsx +52 -22
  89. package/src/ExpandCollapse/Panel.jsx +9 -9
  90. package/src/FlexGrid/Col/Col.jsx +11 -2
  91. package/src/FlexGrid/Row/Row.jsx +8 -2
  92. package/src/InputLabel/InputLabel.jsx +36 -27
  93. package/src/Link/LinkBase.jsx +20 -4
  94. package/src/Link/TextButton.jsx +1 -19
  95. package/src/List/ListItem.jsx +17 -9
  96. package/src/Modal/Modal.jsx +30 -26
  97. package/src/Radio/Radio.jsx +26 -14
  98. package/src/Radio/RadioGroup.jsx +39 -21
  99. package/src/RadioCard/RadioCard.jsx +6 -1
  100. package/src/RadioCard/RadioCardGroup.jsx +17 -1
  101. package/src/Search/Search.jsx +33 -21
  102. package/src/Select/Select.jsx +2 -2
  103. package/src/Tags/Tags.jsx +23 -9
  104. package/src/TextInput/TextArea.jsx +7 -1
  105. package/src/TextInput/TextInput.jsx +15 -3
  106. package/src/TextInput/TextInputBase.jsx +8 -1
  107. package/src/TextInput/propTypes.js +7 -1
  108. package/src/ToggleSwitch/ToggleSwitch.jsx +11 -2
  109. package/src/ToggleSwitch/ToggleSwitchGroup.jsx +19 -6
  110. package/src/Typography/Typography.jsx +13 -9
  111. package/src/index.js +4 -1
  112. package/src/utils/containUniqueFields.js +32 -0
  113. package/src/utils/index.js +1 -0
  114. package/src/utils/input.js +5 -7
  115. package/src/utils/props/handlerProps.js +47 -0
  116. package/src/utils/props/index.js +3 -0
  117. package/src/utils/props/inputSupportsProps.js +3 -4
  118. package/src/utils/props/linkProps.js +3 -6
  119. package/src/utils/props/textInputProps.js +177 -0
  120. package/src/utils/props/textProps.js +58 -0
  121. package/stories/InputLabel/InputLabel.stories.jsx +25 -28
  122. package/stories/Modal/Modal.stories.jsx +25 -0
  123. package/stories/Search/Search.stories.jsx +53 -3
  124. package/stories/TextInput/TextInput.stories.jsx +40 -2
  125. package/__tests__/Link/LinkBase.test.jsx +0 -22
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+
10
+ var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
11
+
12
+ var _getPropSelector = _interopRequireDefault(require("./getPropSelector"));
13
+
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+
16
+ // These are the props accepted specifically on React Native (Web) `Text` elements.
17
+ // They are generally concerned with the behaviour of multiline text.
18
+ const crossPlatform = {
19
+ /**
20
+ * Truncates text after this many lines with an ellipsis at the end.
21
+ * On native, ellipsis behaviour may be changed with `ellipsizeMode` prop.
22
+ */
23
+ numberOfLines: _propTypes.default.number,
24
+
25
+ /**
26
+ * Default is true on web and false on native
27
+ */
28
+ selectable: _propTypes.default.bool
29
+ };
30
+ /**
31
+ * See React Native docs for latest details on these.
32
+ * https://reactnative.dev/docs/text
33
+ */
34
+
35
+ const nativeOnly = {
36
+ ellipsizeMode: _propTypes.default.string,
37
+ maxFontSizeMultiplier: _propTypes.default.number,
38
+ minimumFontScale: _propTypes.default.number,
39
+ onTextLayout: _propTypes.default.func,
40
+ suppressHighlighting: _propTypes.default.bool,
41
+ textBreakStrategy: _propTypes.default.string
42
+ };
43
+ /**
44
+ * These set HTML attributes of the same name.
45
+ */
46
+
47
+ const webOnly = {
48
+ dir: _propTypes.default.oneOf(['auto', 'ltr', 'rtl']),
49
+ lang: _propTypes.default.string
50
+ };
51
+ var _default = {
52
+ /**
53
+ * Set of prop types specific to React Native and React Native Web `Text`,
54
+ * which largely revolve around the behaviour of multiline non-pressable text.
55
+ */
56
+ types: { ...crossPlatform,
57
+ ...webOnly,
58
+ ...nativeOnly
59
+ },
60
+
61
+ /**
62
+ * Filters a props object, returning only props specific to `Text` elements
63
+ * on the current platform. Does not include props applicable to `Text` and `View`.
64
+ */
65
+ select: (0, _getPropSelector.default)({ ...crossPlatform,
66
+ ..._Platform.default.select({
67
+ web: webOnly,
68
+ default: nativeOnly
69
+ })
70
+ })
71
+ };
72
+ exports.default = _default;
@@ -6,9 +6,9 @@ import StyleSheet from "react-native-web/dist/exports/StyleSheet";
6
6
  import Platform from "react-native-web/dist/exports/Platform";
7
7
  import { applyTextStyles, applyShadowToken, applyOuterBorder } from '../ThemeProvider/utils';
8
8
  import buttonPropTypes from './propTypes';
9
- import { a11yProps, getCursorStyle, clickProps, linkProps, resolvePressableState, resolvePressableTokens, selectSystemProps, viewProps, wrapStringsInText, withLinkRouter } from '../utils';
9
+ import { a11yProps, clickProps, focusHandlerProps, getCursorStyle, linkProps, resolvePressableState, resolvePressableTokens, selectSystemProps, viewProps, wrapStringsInText, withLinkRouter } from '../utils';
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
11
- const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, linkProps, viewProps]);
11
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, linkProps, viewProps]);
12
12
 
13
13
  const getOuterBorderOffset = ({
14
14
  outerBorderGap = 0,
@@ -6,11 +6,11 @@ import ButtonBase from './ButtonBase';
6
6
  import { StackWrap } from '../StackView';
7
7
  import { useViewport } from '../ViewportProvider';
8
8
  import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider';
9
- import { a11yProps, pressProps, getTokensPropType, selectSystemProps, selectTokens, variantProp, viewProps } from '../utils/props';
10
- import { useMultipleInputValues } from '../utils/input';
9
+ import { a11yProps, containUniqueFields, focusHandlerProps, pressProps, getTokensPropType, selectSystemProps, selectTokens, useMultipleInputValues, variantProp, viewProps } from '../utils';
11
10
  import { getPressHandlersWithArgs } from '../utils/pressability';
12
11
  import { jsx as _jsx } from "react/jsx-runtime";
13
- const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, pressProps, viewProps]);
12
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
13
+ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, pressProps, viewProps]);
14
14
  const ButtonGroup = /*#__PURE__*/forwardRef(({
15
15
  variant,
16
16
  tokens,
@@ -53,6 +53,12 @@ const ButtonGroup = /*#__PURE__*/forwardRef(({
53
53
  ...rest
54
54
  });
55
55
  const itemA11yRole = systemProps.accessibilityRole === 'radiogroup' ? 'radio' : 'checkbox';
56
+ const uniqueFields = ['id', 'label'];
57
+
58
+ if (!containUniqueFields(items, uniqueFields)) {
59
+ throw new Error(`ButtonGroup items must have unique ${uniqueFields.join(', ')}`);
60
+ }
61
+
56
62
  return /*#__PURE__*/_jsx(StackWrap, { ...systemProps,
57
63
  space: space,
58
64
  direction: direction,
@@ -62,7 +68,8 @@ const ButtonGroup = /*#__PURE__*/forwardRef(({
62
68
  label,
63
69
  id = label,
64
70
  accessibilityLabel,
65
- ref: itemRef
71
+ ref: itemRef,
72
+ ...itemRest
66
73
  }, index) => {
67
74
  const isSelected = currentValues.includes(id); // Pass an object of relevant component state as first argument for any passed-in press handlers
68
75
 
@@ -73,7 +80,7 @@ const ButtonGroup = /*#__PURE__*/forwardRef(({
73
80
  }]);
74
81
 
75
82
  const handlePress = event => {
76
- if (pressHandlers.onPress) pressHandlers.onPress();
83
+ if (pressHandlers.onPress) pressHandlers.onPress(event);
77
84
  toggleOneValue(id, event);
78
85
  };
79
86
 
@@ -95,6 +102,7 @@ const ButtonGroup = /*#__PURE__*/forwardRef(({
95
102
  selected: isSelected,
96
103
  inactive: inactive,
97
104
  ...itemA11y,
105
+ ...selectItemProps(itemRest),
98
106
  children: label
99
107
  }, id);
100
108
  })
@@ -114,7 +122,8 @@ ButtonGroup.propTypes = { ...selectedSystemPropTypes,
114
122
  /**
115
123
  * The options a user may select
116
124
  */
117
- items: PropTypes.arrayOf(PropTypes.shape({
125
+ items: PropTypes.arrayOf(PropTypes.shape({ ...selectedItemPropTypes,
126
+
118
127
  /**
119
128
  * The text displayed to the user in the button, describing this option,
120
129
  * passed to the button as its child.
@@ -4,10 +4,10 @@ import Pressable from "react-native-web/dist/exports/Pressable";
4
4
  import Platform from "react-native-web/dist/exports/Platform";
5
5
  import { useViewport } from '../ViewportProvider';
6
6
  import { applyOuterBorder, validateThemeTokens } from '../ThemeProvider';
7
- import { a11yProps, clickProps, getTokenNames, getTokensSetPropType, linkProps, resolvePressableState, resolvePressableTokens, selectSystemProps, selectTokens, variantProp, viewProps, withLinkRouter } from '../utils';
7
+ import { a11yProps, clickProps, focusHandlerProps, getTokenNames, getTokensSetPropType, linkProps, resolvePressableState, resolvePressableTokens, selectSystemProps, selectTokens, variantProp, viewProps, withLinkRouter } from '../utils';
8
8
  import CardBase from './CardBase';
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
- const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
10
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, viewProps]);
11
11
  const tokenKeys = [...getTokenNames('Card'), // Outer border tokens. TODO: centralise common token sets like these as part of
12
12
  // https://github.com/telus/universal-design-system/issues/782
13
13
  'outerBorderColor', 'outerBorderWidth', 'outerBorderGap'];
@@ -10,11 +10,11 @@ import CheckboxLabel from '../InputLabel/LabelContent';
10
10
  import Feedback from '../Feedback';
11
11
  import StackView from '../StackView';
12
12
  import { applyShadowToken, applyTextStyles, useThemeTokensCallback } from '../ThemeProvider';
13
- import { a11yProps, getTokensPropType, selectSystemProps, useInputValue, variantProp, viewProps } from '../utils';
13
+ import { a11yProps, focusHandlerProps, getTokensPropType, selectSystemProps, useInputValue, variantProp, viewProps } from '../utils';
14
14
  import useUniqueId from '../utils/useUniqueId';
15
15
  import { jsx as _jsx } from "react/jsx-runtime";
16
16
  import { jsxs as _jsxs } from "react/jsx-runtime";
17
- const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
17
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, viewProps]);
18
18
 
19
19
  const selectInputStyles = ({
20
20
  iconBackgroundColor,
@@ -204,24 +204,31 @@ const Checkbox = /*#__PURE__*/forwardRef(({
204
204
  pressed
205
205
  });
206
206
  const iconTokens = selectIconTokens(stateTokens);
207
+ const labelStyles = selectLabelStyles(stateTokens);
208
+ const alignWithLabel = label ? [staticStyles.alignWithLabel, {
209
+ height: labelStyles.lineHeight
210
+ }] : null;
207
211
  return /*#__PURE__*/_jsxs(View, {
208
212
  style: staticStyles.container,
209
- children: [/*#__PURE__*/_jsxs(View, {
210
- style: StyleSheet.flatten([staticStyles.defaultInputStyles, selectInputStyles(stateTokens, isChecked)]),
211
- testID: "Checkbox-Input",
212
- children: [/*#__PURE__*/_jsx(CheckboxInput, {
213
- checked: isChecked,
214
- defaultChecked: defaultChecked,
215
- disabled: inactive,
216
- id: inputId,
217
- isControlled: isControlled,
218
- name: name,
219
- value: value
220
- }), isChecked && IconComponent && /*#__PURE__*/_jsx(IconComponent, { ...iconTokens,
221
- testID: "Checkbox-Icon"
222
- })]
213
+ children: [/*#__PURE__*/_jsx(View, {
214
+ style: alignWithLabel,
215
+ children: /*#__PURE__*/_jsxs(View, {
216
+ style: [staticStyles.defaultInputStyles, selectInputStyles(stateTokens, isChecked)],
217
+ testID: "Checkbox-Input",
218
+ children: [/*#__PURE__*/_jsx(CheckboxInput, {
219
+ checked: isChecked,
220
+ defaultChecked: defaultChecked,
221
+ disabled: inactive,
222
+ id: inputId,
223
+ isControlled: isControlled,
224
+ name: name,
225
+ value: value
226
+ }), isChecked && IconComponent && /*#__PURE__*/_jsx(IconComponent, { ...iconTokens,
227
+ testID: "Checkbox-Icon"
228
+ })]
229
+ })
223
230
  }), Boolean(label) && /*#__PURE__*/_jsx(Text, {
224
- style: selectLabelStyles(stateTokens),
231
+ style: labelStyles,
225
232
  children: /*#__PURE__*/_jsx(CheckboxLabel, {
226
233
  forId: inputId,
227
234
  children: label
@@ -317,5 +324,9 @@ const staticStyles = StyleSheet.create({
317
324
  defaultInputStyles: {
318
325
  alignItems: 'center',
319
326
  justifyContent: 'center'
327
+ },
328
+ alignWithLabel: {
329
+ alignSelf: 'flex-start',
330
+ justifyContent: 'center'
320
331
  }
321
332
  });
@@ -3,10 +3,13 @@ import PropTypes from 'prop-types';
3
3
  import ABBPropTypes from 'airbnb-prop-types';
4
4
  import { useViewport } from '../ViewportProvider';
5
5
  import { useThemeTokens } from '../ThemeProvider';
6
- import { getTokensPropType, useMultipleInputValues, variantProp } from '../utils';
6
+ import { a11yProps, containUniqueFields, focusHandlerProps, getTokensPropType, selectSystemProps, useMultipleInputValues, variantProp, viewProps } from '../utils';
7
7
  import { getStackedContent } from '../StackView';
8
8
  import Checkbox from './Checkbox';
9
9
  import Fieldset from '../Fieldset';
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
12
+ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, viewProps]);
10
13
  /**
11
14
  * A group of Checkboxs that behave as a fieldset. Use when users select any number of choices from options.
12
15
  *
@@ -55,7 +58,6 @@ import Fieldset from '../Fieldset';
55
58
  * ```
56
59
  */
57
60
 
58
- import { jsx as _jsx } from "react/jsx-runtime";
59
61
  const CheckboxGroup = /*#__PURE__*/forwardRef(({
60
62
  tokens,
61
63
  radioTokens,
@@ -71,7 +73,8 @@ const CheckboxGroup = /*#__PURE__*/forwardRef(({
71
73
  onChange,
72
74
  readOnly,
73
75
  name: inputGroupName,
74
- inactive
76
+ inactive,
77
+ ...rest
75
78
  }, ref) => {
76
79
  const viewport = useViewport();
77
80
  const {
@@ -89,11 +92,18 @@ const CheckboxGroup = /*#__PURE__*/forwardRef(({
89
92
  onChange,
90
93
  readOnly: readOnly || inactive
91
94
  });
95
+ const uniqueFields = ['id', 'label'];
96
+
97
+ if (!containUniqueFields(items, uniqueFields)) {
98
+ throw new Error(`CheckboxGroup items must have unique ${uniqueFields.join(', ')}`);
99
+ }
100
+
92
101
  const checkboxes = items.map(({
93
102
  label,
94
103
  id,
95
104
  onChange: itemOnChange,
96
- ref: itemRef
105
+ ref: itemRef,
106
+ ...itemRest
97
107
  }, index) => {
98
108
  const checkboxId = id || `Checkbox[${index}]`;
99
109
 
@@ -111,7 +121,8 @@ const CheckboxGroup = /*#__PURE__*/forwardRef(({
111
121
  label: label,
112
122
  name: inputGroupName,
113
123
  tokens: radioTokens,
114
- variant: variant
124
+ variant: variant,
125
+ ...selectItemProps(itemRest)
115
126
  }, checkboxId);
116
127
  });
117
128
  return /*#__PURE__*/_jsx(Fieldset, {
@@ -124,6 +135,7 @@ const CheckboxGroup = /*#__PURE__*/forwardRef(({
124
135
  feedback: feedback,
125
136
  inactive: inactive,
126
137
  validation: validation,
138
+ ...selectProps(rest),
127
139
  children: getStackedContent(checkboxes, {
128
140
  space,
129
141
  direction: 'column'
@@ -131,7 +143,8 @@ const CheckboxGroup = /*#__PURE__*/forwardRef(({
131
143
  });
132
144
  });
133
145
  CheckboxGroup.displayName = 'CheckboxGroup';
134
- CheckboxGroup.propTypes = {
146
+ CheckboxGroup.propTypes = { ...selectedSystemPropTypes,
147
+
135
148
  /**
136
149
  * Optional theme token overrides for the outer CheckboxGroup component
137
150
  */
@@ -150,7 +163,7 @@ CheckboxGroup.propTypes = {
150
163
  /**
151
164
  * Array of objects containing specifics for each Checkbox to be rendered in the group.
152
165
  */
153
- items: PropTypes.arrayOf(PropTypes.exact({
166
+ items: PropTypes.arrayOf(PropTypes.exact({ ...selectedItemPropTypes,
154
167
  label: PropTypes.string,
155
168
  id: PropTypes.string,
156
169
  onChange: PropTypes.func,
@@ -64,12 +64,13 @@ const ExpandCollapsePanel = /*#__PURE__*/forwardRef(({
64
64
  };
65
65
 
66
66
  const onContainerLayout = event => {
67
- if (containerHeight === null) {
68
- const {
69
- layout: {
70
- height = 0
71
- } = {}
72
- } = event.nativeEvent;
67
+ const {
68
+ layout: {
69
+ height = 0
70
+ } = {}
71
+ } = event.nativeEvent;
72
+
73
+ if (Platform.OS === 'web' || Platform.OS !== 'web' && containerHeight === null) {
73
74
  setContainerHeight(height);
74
75
  }
75
76
  };
@@ -94,12 +95,11 @@ const ExpandCollapsePanel = /*#__PURE__*/forwardRef(({
94
95
  tokens: controlTokens,
95
96
  onPress: handleControlPress,
96
97
  children: control
97
- }), /*#__PURE__*/_jsx(View, {
98
- style: overflowContainerStyles,
98
+ }), /*#__PURE__*/_jsx(Animated.View, {
99
+ style: [overflowContainerStyles, animatedStyles, staticStyles.itemsContainer],
99
100
  ...focusabilityProps,
100
- children: /*#__PURE__*/_jsx(Animated.View, {
101
+ children: /*#__PURE__*/_jsx(View, {
101
102
  onLayout: onContainerLayout,
102
- style: [staticStyles.itemsContainer, animatedStyles],
103
103
  children: /*#__PURE__*/_jsx(View, {
104
104
  style: selectContainerStyles(themeTokens),
105
105
  children: children
@@ -22,6 +22,7 @@ const Col = /*#__PURE__*/forwardRef(({
22
22
  mdOffset,
23
23
  lgOffset,
24
24
  xlOffset,
25
+ flex,
25
26
  ...viewProps
26
27
  }, ref) => {
27
28
  const gutter = useContext(GutterContext);
@@ -95,8 +96,11 @@ const Col = /*#__PURE__*/forwardRef(({
95
96
  paddingLeft: gutter ? 16 : 0,
96
97
  paddingRight: gutter ? 16 : 0
97
98
  };
98
- let hidingStyles = {};
99
- const shown = Platform.OS === 'web' ? 'block' : 'flex';
99
+ let hidingStyles = {}; // TODO: consider setting this to always 'flex' in a major release.
100
+ // `display: block` is invalid in native apps.
101
+ // See https://telusdigital.atlassian.net/browse/UDS1-92
102
+
103
+ const shown = !flex && Platform.OS === 'web' ? 'block' : 'flex';
100
104
 
101
105
  if (viewPort === viewports.xs) {
102
106
  hidingStyles = {
@@ -260,6 +264,12 @@ Col.propTypes = {
260
264
  *
261
265
  * Accepts a `PropType.string` following the [responsive prop](#/Layout?id=responsive) structure.
262
266
  */
263
- horizontalAlign: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['left', 'center', 'right']))
267
+ horizontalAlign: responsiveProps.getTypeOptionallyByViewport(PropTypes.oneOf(['left', 'center', 'right'])),
268
+
269
+ /**
270
+ * (web only) Stretches the column to fill vertical space using `display: flex`.
271
+ * In native apps, FlexGrid.Col behaves as if this is always true (as do all `View`s).
272
+ */
273
+ flex: PropTypes.bool
264
274
  };
265
275
  export default Col;
@@ -86,25 +86,31 @@ const Row = /*#__PURE__*/forwardRef(({
86
86
  const viewPort = useViewport();
87
87
  const reverseLevel = applyInheritance([xsReverse, smReverse, mdReverse, lgReverse, xlReverse]);
88
88
  let flexDirection = '';
89
+ let flexWrap = '';
89
90
 
90
91
  if (viewPort === viewports.xs) {
91
92
  flexDirection = reverseLevel[0] ? 'row-reverse' : 'row';
93
+ flexWrap = reverseLevel[0] ? 'wrap-reverse' : 'wrap';
92
94
  }
93
95
 
94
96
  if (viewPort === viewports.sm) {
95
97
  flexDirection = reverseLevel[1] ? 'row-reverse' : 'row';
98
+ flexWrap = reverseLevel[1] ? 'wrap-reverse' : 'wrap';
96
99
  }
97
100
 
98
101
  if (viewPort === viewports.md) {
99
102
  flexDirection = reverseLevel[2] ? 'row-reverse' : 'row';
103
+ flexWrap = reverseLevel[2] ? 'wrap-reverse' : 'wrap';
100
104
  }
101
105
 
102
106
  if (viewPort === viewports.lg) {
103
107
  flexDirection = reverseLevel[3] ? 'row-reverse' : 'row';
108
+ flexWrap = reverseLevel[3] ? 'wrap-reverse' : 'wrap';
104
109
  }
105
110
 
106
111
  if (viewPort === viewports.xl) {
107
112
  flexDirection = reverseLevel[4] ? 'row-reverse' : 'row';
113
+ flexWrap = reverseLevel[4] ? 'wrap-reverse' : 'wrap';
108
114
  }
109
115
 
110
116
  return /*#__PURE__*/_jsx(View, {
@@ -112,6 +118,7 @@ const Row = /*#__PURE__*/forwardRef(({
112
118
  ...rest,
113
119
  style: [styles.row, {
114
120
  flexDirection,
121
+ flexWrap,
115
122
  ...horizontalAlignStyles(horizontalAlign),
116
123
  ...verticalAlignStyles(verticalAlign),
117
124
  ...distributeStyles(distribute)
@@ -128,8 +135,7 @@ const styles = StyleSheet.create({
128
135
  flexGrow: 0,
129
136
  flexShrink: 1,
130
137
  flexBasis: 'auto',
131
- flexDirection: 'row',
132
- flexWrap: 'wrap'
138
+ flexDirection: 'row'
133
139
  }
134
140
  });
135
141
  Row.propTypes = {
@@ -9,6 +9,7 @@ import LabelContent from './LabelContent';
9
9
  import Tooltip from '../Tooltip';
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
11
11
  import { jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { Fragment as _Fragment } from "react/jsx-runtime";
12
13
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
13
14
 
14
15
  const selectLabelStyles = tokens => applyTextStyles(selectTokens('Typography', tokens));
@@ -47,25 +48,29 @@ const InputLabel = /*#__PURE__*/forwardRef(({
47
48
  const themeTokens = useThemeTokens('InputLabel', tokens, variant);
48
49
  const hasTooltip = tooltip !== undefined;
49
50
  const isHintInline = hintPosition === 'inline';
50
- return /*#__PURE__*/_jsxs(View, {
51
- ref: ref,
52
- style: [staticStyles.container, !isHintInline && staticStyles.containerWithHintBelow],
53
- ...selectProps(rest),
54
- children: [/*#__PURE__*/_jsx(Text, {
55
- style: [selectLabelStyles(themeTokens), selectGapStyles(themeTokens), staticStyles.label],
56
- children: /*#__PURE__*/_jsx(LabelContent, {
57
- forId: forId,
58
- children: label
59
- })
60
- }), hint && isHintInline && /*#__PURE__*/_jsx(Text, {
61
- style: [selectHintStyles(themeTokens), hasTooltip && selectGapStyles(themeTokens)],
62
- nativeID: hintId,
63
- children: hint
64
- }), hasTooltip && /*#__PURE__*/_jsx(View, {
65
- style: staticStyles.tooltipAlign,
66
- children: /*#__PURE__*/_jsx(Tooltip, {
67
- content: tooltip
68
- })
51
+ return /*#__PURE__*/_jsxs(_Fragment, {
52
+ children: [/*#__PURE__*/_jsxs(View, {
53
+ ref: ref,
54
+ style: staticStyles.container,
55
+ ...selectProps(rest),
56
+ children: [/*#__PURE__*/_jsx(Text, {
57
+ style: [selectLabelStyles(themeTokens), selectGapStyles(themeTokens), staticStyles.label],
58
+ children: /*#__PURE__*/_jsx(LabelContent, {
59
+ forId: forId,
60
+ children: label
61
+ })
62
+ }), hint && isHintInline && /*#__PURE__*/_jsx(Text, {
63
+ style: [selectHintStyles(themeTokens), hasTooltip && selectGapStyles(themeTokens), staticStyles.label],
64
+ nativeID: hintId,
65
+ children: hint
66
+ }), hasTooltip && /*#__PURE__*/_jsx(View, {
67
+ style: [staticStyles.tooltipAlign, {
68
+ height: themeTokens.fontSize * themeTokens.lineHeight
69
+ }],
70
+ children: /*#__PURE__*/_jsx(Tooltip, {
71
+ content: tooltip
72
+ })
73
+ })]
69
74
  }), hint && !isHintInline && /*#__PURE__*/_jsx(Text, {
70
75
  style: [selectHintStyles(themeTokens), staticStyles.hintBelow],
71
76
  nativeID: hintId,
@@ -111,21 +116,19 @@ InputLabel.propTypes = { ...selectedSystemPropTypes,
111
116
  export default InputLabel;
112
117
  const staticStyles = StyleSheet.create({
113
118
  container: {
114
- display: 'flex',
119
+ flexShrink: 1,
115
120
  flexDirection: 'row',
116
121
  alignItems: 'baseline'
117
122
  },
118
- containerWithHintBelow: {
119
- flexWrap: 'wrap'
120
- },
121
123
  label: {
122
- flexShrink: 0
124
+ flexShrink: 1
123
125
  },
124
126
  hintBelow: {
125
127
  flexBasis: '100%',
126
128
  flexShrink: 0
127
129
  },
128
130
  tooltipAlign: {
129
- alignSelf: 'center'
131
+ alignSelf: 'flex-start',
132
+ justifyContent: 'center'
130
133
  }
131
134
  });
@@ -35,13 +35,9 @@ Platform.OS === 'web' ? {
35
35
  } : {};
36
36
 
37
37
  const selectTextStyles = ({
38
- color,
39
- textLine,
40
- textLineStyle
38
+ color
41
39
  }) => ({
42
40
  color,
43
- textDecorationLine: textLine,
44
- textDecorationStyle: textLineStyle,
45
41
  ...Platform.select({
46
42
  web: {
47
43
  // TODO: https://github.com/telus/universal-design-system/issues/487
@@ -62,6 +58,22 @@ const selectBlockStyles = ({
62
58
  fontName: blockFontName
63
59
  });
64
60
 
61
+ const selectDecorationStyles = ({
62
+ color,
63
+ textLine,
64
+ textLineStyle
65
+ }) => ({
66
+ color,
67
+ textDecorationLine: textLine,
68
+ textDecorationStyle: textLineStyle,
69
+ ...Platform.select({
70
+ web: {
71
+ // TODO: https://github.com/telus/universal-design-system/issues/487
72
+ transition: 'color 200ms'
73
+ }
74
+ })
75
+ });
76
+
65
77
  const selectIconTokens = ({
66
78
  color,
67
79
  iconSize,
@@ -138,8 +150,9 @@ const LinkBase = /*#__PURE__*/forwardRef(({
138
150
  style: linkState => {
139
151
  const themeTokens = resolveLinkTokens(linkState);
140
152
  const outerBorderStyles = selectOuterBorderStyles(themeTokens);
153
+ const decorationStyles = selectDecorationStyles(themeTokens);
141
154
  const hasIcon = Boolean(icon || themeTokens.icon);
142
- return [outerBorderStyles, blockLeftStyle, hasIcon && staticStyles.rowContainer];
155
+ return [outerBorderStyles, blockLeftStyle, decorationStyles, hasIcon && staticStyles.rowContainer];
143
156
  },
144
157
  children: linkState => {
145
158
  const themeTokens = resolveLinkTokens(linkState);
@@ -1,5 +1,3 @@
1
- var _TextButton$propTypes;
2
-
3
1
  import React, { forwardRef } from 'react';
4
2
  import PropTypes from 'prop-types';
5
3
  import { useThemeTokensCallback } from '../ThemeProvider';
@@ -16,8 +14,6 @@ const TextButton = /*#__PURE__*/forwardRef(({
16
14
  children,
17
15
  variant,
18
16
  tokens,
19
- // TODO: this may need to use `link` role on Web in the case of being passed both `href` and
20
- // `onPress` in an omniplatform app that uses React Navigation's useLinkProps for internal nav.
21
17
  accessibilityRole = 'button',
22
18
  ...linkProps
23
19
  }, ref) => {
@@ -34,10 +30,5 @@ const TextButton = /*#__PURE__*/forwardRef(({
34
30
  TextButton.displayName = 'TextButton';
35
31
  TextButton.propTypes = { ...LinkBase.propTypes,
36
32
  onPress: PropTypes.func.isRequired
37
- }; // Remove incompatible Link prop (if this build includes propTypes)
38
- // TODO: test if this works with web navigation in omniplatform React Navigation
39
- // https://github.com/telus/universal-design-system/issues/665
40
- // eslint-disable-next-line react/forbid-foreign-prop-types
41
-
42
- if ((_TextButton$propTypes = TextButton.propTypes) !== null && _TextButton$propTypes !== void 0 && _TextButton$propTypes.href) delete TextButton.propTypes.href;
33
+ };
43
34
  export default TextButton;