@telus-uds/components-base 0.0.2-prerelease.3 → 0.0.2-prerelease.7

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 (266) hide show
  1. package/.ultra.cache.json +1 -0
  2. package/CHANGELOG.md +55 -0
  3. package/__fixtures__/testTheme.js +528 -42
  4. package/__tests__/Button/ButtonBase.test.jsx +3 -32
  5. package/__tests__/Checkbox/Checkbox.test.jsx +94 -0
  6. package/__tests__/Divider/Divider.test.jsx +26 -5
  7. package/__tests__/Feedback/Feedback.test.jsx +42 -0
  8. package/__tests__/FlexGrid/Col.test.jsx +5 -0
  9. package/__tests__/InputSupports/InputSupports.test.jsx +50 -0
  10. package/__tests__/List/List.test.jsx +60 -0
  11. package/__tests__/Radio/Radio.test.jsx +87 -0
  12. package/__tests__/Select/Select.test.jsx +93 -0
  13. package/__tests__/Skeleton/Skeleton.test.jsx +61 -0
  14. package/__tests__/Spacer/Spacer.test.jsx +63 -0
  15. package/__tests__/StackView/StackView.test.jsx +216 -0
  16. package/__tests__/StackView/StackWrap.test.jsx +47 -0
  17. package/__tests__/StackView/getStackedContent.test.jsx +295 -0
  18. package/__tests__/Tags/Tags.test.jsx +328 -0
  19. package/__tests__/TextInput/TextArea.test.jsx +34 -0
  20. package/__tests__/TextInput/TextInputBase.test.jsx +120 -0
  21. package/__tests__/Tooltip/Tooltip.test.jsx +65 -0
  22. package/__tests__/Tooltip/getTooltipPosition.test.js +79 -0
  23. package/__tests__/utils/useCopy.test.js +31 -0
  24. package/__tests__/utils/useResponsiveProp.test.jsx +202 -0
  25. package/__tests__/utils/{spacing.test.jsx → useSpacingScale.test.jsx} +1 -1
  26. package/__tests__/utils/useUniqueId.test.js +31 -0
  27. package/jest.config.js +8 -2
  28. package/lib/Box/Box.js +7 -2
  29. package/lib/Button/Button.js +10 -3
  30. package/lib/Button/ButtonBase.js +79 -75
  31. package/lib/Button/ButtonGroup.js +24 -49
  32. package/lib/Button/ButtonLink.js +5 -0
  33. package/lib/Checkbox/Checkbox.js +308 -0
  34. package/lib/Checkbox/CheckboxInput.native.js +6 -0
  35. package/lib/Checkbox/CheckboxInput.web.js +57 -0
  36. package/lib/Checkbox/index.js +2 -0
  37. package/lib/Divider/Divider.js +40 -2
  38. package/lib/Feedback/Feedback.js +132 -0
  39. package/lib/Feedback/index.js +2 -0
  40. package/lib/Icon/Icon.js +9 -6
  41. package/lib/Icon/IconText.js +72 -0
  42. package/lib/Icon/index.js +2 -1
  43. package/lib/InputLabel/InputLabel.js +88 -0
  44. package/lib/InputLabel/LabelContent.native.js +8 -0
  45. package/lib/InputLabel/LabelContent.web.js +17 -0
  46. package/lib/InputLabel/index.js +2 -0
  47. package/lib/InputSupports/InputSupports.js +90 -0
  48. package/lib/InputSupports/index.js +2 -0
  49. package/lib/InputSupports/propTypes.js +55 -0
  50. package/lib/Link/ChevronLink.js +35 -10
  51. package/lib/Link/InlinePressable.native.js +78 -0
  52. package/lib/Link/InlinePressable.web.js +32 -0
  53. package/lib/Link/Link.js +11 -10
  54. package/lib/Link/LinkBase.js +69 -124
  55. package/lib/Link/TextButton.js +20 -9
  56. package/lib/Link/index.js +2 -1
  57. package/lib/List/List.js +52 -0
  58. package/lib/List/ListItem.js +207 -0
  59. package/lib/List/index.js +2 -0
  60. package/lib/Pagination/PageButton.js +3 -26
  61. package/lib/Pagination/SideButton.js +32 -42
  62. package/lib/Radio/Radio.js +291 -0
  63. package/lib/Radio/RadioInput.native.js +6 -0
  64. package/lib/Radio/RadioInput.web.js +59 -0
  65. package/lib/Radio/index.js +2 -0
  66. package/lib/Select/Group.native.js +14 -0
  67. package/lib/Select/Group.web.js +18 -0
  68. package/lib/Select/Item.native.js +9 -0
  69. package/lib/Select/Item.web.js +15 -0
  70. package/lib/Select/Picker.native.js +87 -0
  71. package/lib/Select/Picker.web.js +63 -0
  72. package/lib/Select/Select.js +272 -0
  73. package/lib/Select/index.js +6 -0
  74. package/lib/Skeleton/Skeleton.js +119 -0
  75. package/lib/Skeleton/index.js +2 -0
  76. package/lib/Spacer/Spacer.js +98 -0
  77. package/lib/Spacer/index.js +2 -0
  78. package/lib/StackView/StackView.js +107 -0
  79. package/lib/StackView/StackWrap.js +32 -0
  80. package/lib/StackView/StackWrap.native.js +3 -0
  81. package/lib/StackView/StackWrapBox.js +90 -0
  82. package/lib/StackView/StackWrapGap.js +50 -0
  83. package/lib/StackView/common.js +30 -0
  84. package/lib/StackView/getStackedContent.js +111 -0
  85. package/lib/StackView/index.js +5 -0
  86. package/lib/Tags/Tags.js +217 -0
  87. package/lib/Tags/index.js +2 -0
  88. package/lib/TextInput/TextArea.js +82 -0
  89. package/lib/TextInput/TextInput.js +54 -0
  90. package/lib/TextInput/TextInputBase.js +229 -0
  91. package/lib/TextInput/index.js +3 -0
  92. package/lib/TextInput/propTypes.js +31 -0
  93. package/lib/ThemeProvider/useThemeTokens.js +54 -3
  94. package/lib/ToggleSwitch/ToggleSwitch.js +1 -1
  95. package/lib/Tooltip/Backdrop.native.js +35 -0
  96. package/lib/Tooltip/Backdrop.web.js +52 -0
  97. package/lib/Tooltip/Tooltip.js +315 -0
  98. package/lib/Tooltip/dictionary.js +8 -0
  99. package/lib/Tooltip/getTooltipPosition.js +164 -0
  100. package/lib/Tooltip/index.js +2 -0
  101. package/lib/TooltipButton/TooltipButton.js +64 -0
  102. package/lib/TooltipButton/index.js +2 -0
  103. package/lib/Typography/Typography.js +4 -23
  104. package/lib/ViewportProvider/ViewportProvider.js +25 -0
  105. package/lib/ViewportProvider/index.js +2 -43
  106. package/lib/ViewportProvider/useViewport.js +3 -0
  107. package/lib/ViewportProvider/useViewportListener.js +43 -0
  108. package/lib/index.js +15 -1
  109. package/lib/utils/a11y/index.js +1 -0
  110. package/lib/utils/a11y/textSize.js +33 -0
  111. package/lib/utils/index.js +7 -1
  112. package/lib/utils/info/index.js +7 -0
  113. package/lib/utils/info/platform/index.js +11 -0
  114. package/lib/utils/info/platform/platform.android.js +1 -0
  115. package/lib/utils/info/platform/platform.ios.js +1 -0
  116. package/lib/utils/info/platform/platform.native.js +4 -0
  117. package/lib/utils/info/platform/platform.web.js +1 -0
  118. package/lib/utils/info/versions.js +5 -0
  119. package/lib/utils/input.js +3 -1
  120. package/lib/utils/pressability.js +92 -0
  121. package/lib/utils/propTypes.js +77 -8
  122. package/lib/utils/useCopy.js +16 -0
  123. package/lib/utils/useResponsiveProp.js +47 -0
  124. package/lib/utils/{spacing/useSpacingScale.js → useSpacingScale.js} +30 -9
  125. package/lib/utils/useUniqueId.js +12 -0
  126. package/package.json +7 -5
  127. package/release-context.json +4 -4
  128. package/src/Box/Box.jsx +4 -2
  129. package/src/Button/Button.jsx +6 -3
  130. package/src/Button/ButtonBase.jsx +72 -75
  131. package/src/Button/ButtonGroup.jsx +22 -39
  132. package/src/Button/ButtonLink.jsx +11 -2
  133. package/src/Checkbox/Checkbox.jsx +275 -0
  134. package/src/Checkbox/CheckboxInput.native.jsx +6 -0
  135. package/src/Checkbox/CheckboxInput.web.jsx +55 -0
  136. package/src/Checkbox/index.js +3 -0
  137. package/src/Divider/Divider.jsx +38 -3
  138. package/src/Feedback/Feedback.jsx +108 -0
  139. package/src/Feedback/index.js +3 -0
  140. package/src/Icon/Icon.jsx +11 -6
  141. package/src/Icon/IconText.jsx +63 -0
  142. package/src/Icon/index.js +2 -1
  143. package/src/InputLabel/InputLabel.jsx +99 -0
  144. package/src/InputLabel/LabelContent.native.jsx +6 -0
  145. package/src/InputLabel/LabelContent.web.jsx +13 -0
  146. package/src/InputLabel/index.js +3 -0
  147. package/src/InputSupports/InputSupports.jsx +86 -0
  148. package/src/InputSupports/index.js +3 -0
  149. package/src/InputSupports/propTypes.js +44 -0
  150. package/src/Link/ChevronLink.jsx +28 -7
  151. package/src/Link/InlinePressable.native.jsx +73 -0
  152. package/src/Link/InlinePressable.web.jsx +37 -0
  153. package/src/Link/Link.jsx +17 -13
  154. package/src/Link/LinkBase.jsx +62 -139
  155. package/src/Link/TextButton.jsx +25 -11
  156. package/src/Link/index.js +2 -1
  157. package/src/List/List.jsx +47 -0
  158. package/src/List/ListItem.jsx +187 -0
  159. package/src/List/index.js +3 -0
  160. package/src/Pagination/PageButton.jsx +3 -17
  161. package/src/Pagination/SideButton.jsx +27 -38
  162. package/src/Radio/Radio.jsx +270 -0
  163. package/src/Radio/RadioInput.native.jsx +6 -0
  164. package/src/Radio/RadioInput.web.jsx +57 -0
  165. package/src/Radio/index.js +3 -0
  166. package/src/Select/Group.native.jsx +14 -0
  167. package/src/Select/Group.web.jsx +15 -0
  168. package/src/Select/Item.native.jsx +10 -0
  169. package/src/Select/Item.web.jsx +11 -0
  170. package/src/Select/Picker.native.jsx +95 -0
  171. package/src/Select/Picker.web.jsx +67 -0
  172. package/src/Select/Select.jsx +265 -0
  173. package/src/Select/index.js +8 -0
  174. package/src/Skeleton/Skeleton.jsx +101 -0
  175. package/src/Skeleton/index.js +3 -0
  176. package/src/Spacer/Spacer.jsx +91 -0
  177. package/src/Spacer/index.js +3 -0
  178. package/src/StackView/StackView.jsx +104 -0
  179. package/src/StackView/StackWrap.jsx +33 -0
  180. package/src/StackView/StackWrap.native.jsx +4 -0
  181. package/src/StackView/StackWrapBox.jsx +93 -0
  182. package/src/StackView/StackWrapGap.jsx +49 -0
  183. package/src/StackView/common.jsx +28 -0
  184. package/src/StackView/getStackedContent.jsx +106 -0
  185. package/src/StackView/index.js +6 -0
  186. package/src/Tags/Tags.jsx +206 -0
  187. package/src/Tags/index.js +3 -0
  188. package/src/TextInput/TextArea.jsx +78 -0
  189. package/src/TextInput/TextInput.jsx +52 -0
  190. package/src/TextInput/TextInputBase.jsx +220 -0
  191. package/src/TextInput/index.js +4 -0
  192. package/src/TextInput/propTypes.js +29 -0
  193. package/src/ThemeProvider/useThemeTokens.js +54 -3
  194. package/src/ToggleSwitch/ToggleSwitch.jsx +1 -1
  195. package/src/Tooltip/Backdrop.native.jsx +33 -0
  196. package/src/Tooltip/Backdrop.web.jsx +60 -0
  197. package/src/Tooltip/Tooltip.jsx +294 -0
  198. package/src/Tooltip/dictionary.js +8 -0
  199. package/src/Tooltip/getTooltipPosition.js +161 -0
  200. package/src/Tooltip/index.js +3 -0
  201. package/src/TooltipButton/TooltipButton.jsx +53 -0
  202. package/src/TooltipButton/index.js +3 -0
  203. package/src/Typography/Typography.jsx +4 -19
  204. package/src/ViewportProvider/ViewportProvider.jsx +21 -0
  205. package/src/ViewportProvider/index.jsx +2 -41
  206. package/src/ViewportProvider/useViewport.js +5 -0
  207. package/src/ViewportProvider/useViewportListener.js +43 -0
  208. package/src/index.js +15 -1
  209. package/src/utils/a11y/index.js +1 -0
  210. package/src/utils/a11y/textSize.js +30 -0
  211. package/src/utils/index.js +8 -1
  212. package/src/utils/info/index.js +8 -0
  213. package/src/utils/info/platform/index.js +11 -0
  214. package/src/utils/info/platform/platform.android.js +1 -0
  215. package/src/utils/info/platform/platform.ios.js +1 -0
  216. package/src/utils/info/platform/platform.native.js +4 -0
  217. package/src/utils/info/platform/platform.web.js +1 -0
  218. package/src/utils/info/versions.js +6 -0
  219. package/src/utils/input.js +2 -1
  220. package/src/utils/pressability.js +92 -0
  221. package/src/utils/propTypes.js +97 -13
  222. package/src/utils/useCopy.js +13 -0
  223. package/src/utils/useResponsiveProp.js +50 -0
  224. package/src/utils/{spacing/useSpacingScale.js → useSpacingScale.js} +25 -10
  225. package/src/utils/useUniqueId.js +14 -0
  226. package/stories/A11yText/A11yText.stories.jsx +11 -5
  227. package/stories/ActivityIndicator/ActivityIndicator.stories.jsx +11 -2
  228. package/stories/Box/Box.stories.jsx +29 -2
  229. package/stories/Button/Button.stories.jsx +21 -20
  230. package/stories/Button/ButtonGroup.stories.jsx +2 -1
  231. package/stories/Button/ButtonLink.stories.jsx +6 -4
  232. package/stories/Card/Card.stories.jsx +13 -1
  233. package/stories/Checkbox/Checkbox.stories.jsx +71 -0
  234. package/stories/Divider/Divider.stories.jsx +26 -2
  235. package/stories/ExpandCollapse/ExpandCollapse.stories.jsx +74 -79
  236. package/stories/Feedback/Feedback.stories.jsx +96 -0
  237. package/stories/FlexGrid/01 FlexGrid.stories.jsx +20 -7
  238. package/stories/Icon/Icon.stories.jsx +11 -3
  239. package/stories/InputLabel/InputLabel.stories.jsx +42 -0
  240. package/stories/Link/ChevronLink.stories.jsx +20 -4
  241. package/stories/Link/Link.stories.jsx +39 -3
  242. package/stories/Link/TextButton.stories.jsx +24 -2
  243. package/stories/List/List.stories.jsx +117 -0
  244. package/stories/Pagination/Pagination.stories.jsx +28 -14
  245. package/stories/Radio/Radio.stories.jsx +113 -0
  246. package/stories/Select/Select.stories.jsx +55 -0
  247. package/stories/SideNav/SideNav.stories.jsx +17 -2
  248. package/stories/Skeleton/Skeleton.stories.jsx +36 -0
  249. package/stories/Spacer/Spacer.stories.jsx +38 -0
  250. package/stories/StackView/StackView.stories.jsx +75 -0
  251. package/stories/StackView/StackWrap.stories.jsx +64 -0
  252. package/stories/Tags/Tags.stories.jsx +69 -0
  253. package/stories/TextInput/TextArea.stories.jsx +100 -0
  254. package/stories/TextInput/TextInput.stories.jsx +103 -0
  255. package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +16 -3
  256. package/stories/Tooltip/Tooltip.stories.jsx +81 -0
  257. package/stories/TooltipButton/TooltipButton.stories.jsx +11 -0
  258. package/stories/Typography/Typography.stories.jsx +12 -3
  259. package/stories/platform-supports.web.jsx +1 -1
  260. package/stories/supports.jsx +110 -14
  261. package/lib/Pagination/useCopy.js +0 -10
  262. package/lib/utils/spacing/index.js +0 -2
  263. package/lib/utils/spacing/utils.js +0 -32
  264. package/src/Pagination/useCopy.js +0 -7
  265. package/src/utils/spacing/index.js +0 -3
  266. package/src/utils/spacing/utils.js +0 -28
@@ -1,41 +1,31 @@
1
1
  import React from 'react';
2
- import { StyleSheet, View, Text, PixelRatio } from 'react-native';
2
+ import { Text } from 'react-native';
3
3
  import PropTypes from 'prop-types';
4
4
  import ButtonBase from '../Button/ButtonBase';
5
- import { applyTextStyles, useThemeTokensCallback } from '../ThemeProvider';
5
+ import { IconText } from '../Icon';
6
+ import { useThemeTokensCallback } from '../ThemeProvider';
6
7
  import { useViewport } from '../ViewportProvider';
7
8
  import { copyPropTypes, hrefAttrsProp, linkProps, selectTokens } from '../utils';
8
9
  import dictionary from './dictionary';
9
- import useCopy from './useCopy';
10
-
11
- const selectTextStyles = ({
12
- color,
13
- fontName,
14
- fontSize,
15
- fontWeight,
16
- lineHeight
17
- }) => applyTextStyles({
18
- color,
19
- fontName,
20
- fontSize,
21
- fontWeight,
22
- lineHeight
23
- });
10
+ import useCopy from '../utils/useCopy';
24
11
 
25
12
  const selectIconTokens = ({
26
13
  color,
27
14
  iconSize,
28
- iconTranslateX
29
- }) => {
30
- // Scale icon with text, but with a cap so text isn't squashed at large scales
31
- const iconScale = Math.min(PixelRatio.getFontScale(), 2);
15
+ iconDisplace
16
+ }, direction) => {
32
17
  return {
33
18
  color,
34
- size: iconSize * iconScale,
35
- translateX: iconTranslateX
19
+ size: iconSize,
20
+ translateX: iconDisplace * (direction === 'previous' ? -1 : 1)
36
21
  };
37
22
  };
38
23
 
24
+ const directionToSide = {
25
+ previous: 'left',
26
+ next: 'right'
27
+ };
28
+
39
29
  function SideButton({
40
30
  direction = 'previous',
41
31
  onPress,
@@ -57,14 +47,12 @@ function SideButton({
57
47
  copy
58
48
  });
59
49
  const {
60
- icon: IconComponent
50
+ icon
61
51
  } = getTokens(tokens, buttonVariant);
62
52
 
63
53
  const getButtonTokens = buttonState => selectTokens('Button', getTokens(buttonState));
64
54
 
65
- const getIconTokens = buttonState => selectIconTokens(getTokens(buttonState));
66
-
67
- const getTextStyles = buttonState => selectTextStyles(getTokens(buttonState));
55
+ const getIconTokens = buttonState => selectIconTokens(getTokens(buttonState), direction);
68
56
 
69
57
  const label = direction === 'previous' ? getCopy('previousText') : getCopy('nextText');
70
58
  const showLabel = viewport !== 'sm' && viewport !== 'xs';
@@ -84,15 +72,22 @@ function SideButton({
84
72
  };
85
73
  return /*#__PURE__*/React.createElement(ButtonBase, Object.assign({}, buttonProps, {
86
74
  tokens: getButtonTokens
87
- }), buttonState => /*#__PURE__*/React.createElement(View, {
88
- style: staticStyles.contentContainer
89
- }, direction === 'previous' && IconComponent && /*#__PURE__*/React.createElement(IconComponent, {
90
- tokens: getIconTokens(buttonState)
91
- }), showLabel && /*#__PURE__*/React.createElement(Text, {
92
- style: getTextStyles(buttonState)
93
- }, label), direction === 'next' && IconComponent && /*#__PURE__*/React.createElement(IconComponent, {
94
- tokens: getIconTokens(buttonState)
95
- })));
75
+ }), ({
76
+ textStyles,
77
+ ...buttonState
78
+ }) => {
79
+ const iconProps = {
80
+ tokens: getIconTokens(buttonState)
81
+ };
82
+ return /*#__PURE__*/React.createElement(IconText, {
83
+ icon: icon,
84
+ space: 1,
85
+ iconPosition: directionToSide[direction],
86
+ iconProps: iconProps
87
+ }, showLabel && /*#__PURE__*/React.createElement(Text, {
88
+ style: textStyles
89
+ }, label));
90
+ });
96
91
  }
97
92
 
98
93
  SideButton.propTypes = {
@@ -100,9 +95,4 @@ SideButton.propTypes = {
100
95
  copy: copyPropTypes,
101
96
  ...linkProps.types
102
97
  };
103
- export default SideButton;
104
- const staticStyles = StyleSheet.create({
105
- contentContainer: {
106
- flexDirection: 'row'
107
- }
108
- });
98
+ export default SideButton;
@@ -0,0 +1,291 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Pressable, StyleSheet, Text, View } from 'react-native';
4
+ import RadioInput from './RadioInput'; // @todo move `LabelContent` outside of the `InputLabel` and fix
5
+ // the issue with the cursor not being pointer on Web
6
+
7
+ import RadioLabel from '../InputLabel/LabelContent';
8
+ import { applyShadowToken, applyTextStyles, useThemeTokensCallback } from '../ThemeProvider';
9
+ import { getTokensPropType, useInputValue, useUniqueId, variantProp } from '../utils';
10
+ import { a11yProps } from '../utils/propTypes';
11
+ import StackView from '../StackView';
12
+
13
+ const selectCheckedStyles = ({
14
+ checkedBackgroundColor,
15
+ checkedSize
16
+ }) => ({
17
+ backgroundColor: checkedBackgroundColor,
18
+ borderRadius: checkedSize / 2,
19
+ height: checkedSize,
20
+ width: checkedSize
21
+ });
22
+
23
+ const selectContainerStyles = ({
24
+ containerBackgroundColor,
25
+ containerBorderRadius,
26
+ containerMarginBottom,
27
+ containerOpacity,
28
+ containerPaddingBottom,
29
+ containerPaddingLeft,
30
+ containerPaddingRight,
31
+ containerPaddingTop,
32
+ containerShadow
33
+ }) => ({
34
+ backgroundColor: containerBackgroundColor,
35
+ borderRadius: containerBorderRadius,
36
+ marginBottom: containerMarginBottom,
37
+ opacity: containerOpacity,
38
+ paddingBottom: containerPaddingBottom,
39
+ paddingLeft: containerPaddingLeft,
40
+ paddingRight: containerPaddingRight,
41
+ paddingTop: containerPaddingTop,
42
+ ...applyShadowToken(containerShadow)
43
+ });
44
+
45
+ const selectDescriptionStyles = ({
46
+ containerPaddingLeft = 0,
47
+ descriptionFontSize,
48
+ descriptionLineHeight,
49
+ descriptionMarginLeft,
50
+ inputSize,
51
+ labelMarginLeft = 0
52
+ }) => ({
53
+ marginLeft: descriptionMarginLeft ?? containerPaddingLeft + inputSize + labelMarginLeft,
54
+ ...applyTextStyles({
55
+ fontSize: descriptionFontSize,
56
+ lineHeight: descriptionLineHeight
57
+ })
58
+ });
59
+
60
+ const selectInputStyles = ({
61
+ inputBackgroundColor,
62
+ inputBorderColor,
63
+ inputBorderWidth,
64
+ inputOutlineColor,
65
+ inputOutlineWidth,
66
+ inputSize
67
+ }) => ({
68
+ borderColor: inputBorderColor,
69
+ borderRadius: inputSize / 2,
70
+ borderWidth: inputBorderWidth,
71
+ backgroundColor: inputBackgroundColor,
72
+ height: inputSize,
73
+ outlineStyle: 'solid',
74
+ outlineColor: inputOutlineColor,
75
+ outlineWidth: inputOutlineWidth,
76
+ width: inputSize
77
+ });
78
+
79
+ const selectLabelStyles = ({
80
+ labelColor,
81
+ labelFontName,
82
+ labelFontSize,
83
+ labelFontWeight,
84
+ labelMarginLeft,
85
+ labelLineHeight
86
+ }) => applyTextStyles({
87
+ color: labelColor,
88
+ fontName: labelFontName,
89
+ fontWeight: labelFontWeight,
90
+ fontSize: labelFontSize,
91
+ lineHeight: labelLineHeight,
92
+ marginLeft: labelMarginLeft
93
+ });
94
+ /**
95
+ * Basic Radio component.
96
+ *
97
+ * ## Component API
98
+ *
99
+ * Use `label` prop to provide a label for the radio button. For a disabled `Radio` set the `inactive` prop to `true`.
100
+ *
101
+ * ### Controlled version
102
+ *
103
+ * If the radio button is controlled from outside, it needs to receive `checked` and `onChange` props.
104
+ *
105
+ * ### Uncontrolled version
106
+ *
107
+ * In case of uncontrolled radio button you can use `defaultChecked` prop to provide the initial value.
108
+ * Whenever the radio button gets toggled, it calls the `onChange` callback with the new value (boolean).
109
+ *
110
+ * ### Using within forms
111
+ *
112
+ * You can pass `name` and `value` props if you need a particular radio button to be a part of a radio group
113
+ * on a form.
114
+ *
115
+ * ### Validation
116
+ *
117
+ * You can mark a radio button as failing validation by setting the `error` prop to `true`.
118
+ *
119
+ * ## A11y guidelines
120
+ *
121
+ * Radio component accepts all the common accessibility props, but also sets some defaults, including
122
+ * accessibility role `'radio'` and accessibility state that depends on the other props (`checked`, `inactive`)
123
+ * or the internal state in case of uncontrolled radio button.
124
+ *
125
+ */
126
+
127
+
128
+ const Radio = ({
129
+ checked,
130
+ defaultChecked,
131
+ description,
132
+ error = false,
133
+ id,
134
+ inactive,
135
+ label,
136
+ name,
137
+ onChange,
138
+ tokens,
139
+ value,
140
+ variant,
141
+ ...rest
142
+ }) => {
143
+ const {
144
+ currentValue: isChecked,
145
+ setValue: setIsChecked,
146
+ isControlled
147
+ } = useInputValue({
148
+ value: checked,
149
+ initialValue: defaultChecked,
150
+ onChange
151
+ }, 'useRadioValue');
152
+ const getTokens = useThemeTokensCallback('Radio', tokens, {
153
+ checked: isChecked,
154
+ inactive,
155
+ error,
156
+ ...variant
157
+ });
158
+
159
+ const handleChange = () => {
160
+ if (!inactive && !isChecked) {
161
+ setIsChecked(true);
162
+ }
163
+ };
164
+
165
+ const accessibilityProps = a11yProps.select(rest);
166
+ const uniqueId = useUniqueId('radio');
167
+ const inputId = id ?? uniqueId; // @todo our current version of React Native Web doesn't include
168
+ // keyboard support on `Pressable` (which starts with 0.15.3), so
169
+ // the complete accessibility of the `Radio` component on Web
170
+ // (namely, change on key pressed) is pending RNW upgrade
171
+ // (see https://github.com/necolas/react-native-web/issues/1950)
172
+
173
+ return /*#__PURE__*/React.createElement(Pressable, Object.assign({
174
+ disabled: inactive,
175
+ onPress: handleChange,
176
+ accessibilityRole: "radio",
177
+ accessibilityState: {
178
+ checked: isChecked,
179
+ disabled: inactive
180
+ }
181
+ }, accessibilityProps), ({
182
+ focused: focus,
183
+ hovered: hover,
184
+ pressed
185
+ }) => {
186
+ const stateTokens = getTokens({
187
+ focus,
188
+ hover,
189
+ pressed
190
+ });
191
+ return /*#__PURE__*/React.createElement(StackView, {
192
+ space: 0
193
+ }, /*#__PURE__*/React.createElement(View, {
194
+ style: [staticStyles.container, selectContainerStyles(stateTokens)]
195
+ }, /*#__PURE__*/React.createElement(View, {
196
+ style: StyleSheet.flatten([staticStyles.defaultInputStyles, selectInputStyles(stateTokens, isChecked)]),
197
+ testID: "Radio-Input"
198
+ }, /*#__PURE__*/React.createElement(RadioInput, {
199
+ checked: isChecked,
200
+ defaultChecked: defaultChecked,
201
+ disabled: inactive,
202
+ id: inputId,
203
+ isControlled: isControlled,
204
+ name: name,
205
+ value: value
206
+ }), isChecked && /*#__PURE__*/React.createElement(View, {
207
+ style: selectCheckedStyles(stateTokens),
208
+ testID: "Radio-Checked"
209
+ })), Boolean(label) && /*#__PURE__*/React.createElement(Text, {
210
+ style: selectLabelStyles(stateTokens)
211
+ }, /*#__PURE__*/React.createElement(RadioLabel, {
212
+ forId: inputId
213
+ }, label))), Boolean(description) && /*#__PURE__*/React.createElement(Text, {
214
+ style: selectDescriptionStyles(getTokens())
215
+ }, description));
216
+ });
217
+ };
218
+
219
+ Radio.propTypes = { ...a11yProps.propTypes,
220
+
221
+ /**
222
+ * Use `checked` for controlled Radio. For uncontrolled Radio, use the `defaultChecked` prop.
223
+ */
224
+ checked: PropTypes.bool,
225
+
226
+ /**
227
+ * Use `defaultChecked` to provide the initial value for an uncontrolled Radio.
228
+ */
229
+ defaultChecked: PropTypes.bool,
230
+
231
+ /**
232
+ * An optional radio button description.
233
+ */
234
+ description: PropTypes.string,
235
+
236
+ /**
237
+ * Radio button ID.
238
+ */
239
+ id: PropTypes.string,
240
+
241
+ /**
242
+ * Whether the corresponding input is disabled or active.
243
+ */
244
+ inactive: PropTypes.bool,
245
+
246
+ /**
247
+ * The label.
248
+ */
249
+ label: PropTypes.string,
250
+
251
+ /**
252
+ * Associate this radio button with a group (set as the name attribute).
253
+ */
254
+ name: PropTypes.string,
255
+
256
+ /**
257
+ * Whether the underlying input triggered a validation error or not.
258
+ */
259
+ error: PropTypes.bool,
260
+
261
+ /**
262
+ * The value. Must be unique within the group.
263
+ */
264
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]),
265
+
266
+ /**
267
+ * Callback called when a controlled radio button gets interacted with.
268
+ */
269
+ onChange: PropTypes.func,
270
+
271
+ /**
272
+ * Radio tokens.
273
+ */
274
+ tokens: getTokensPropType('Radio'),
275
+
276
+ /**
277
+ * Radio variant.
278
+ */
279
+ variant: variantProp.propType
280
+ };
281
+ export default Radio;
282
+ const staticStyles = StyleSheet.create({
283
+ container: {
284
+ flexDirection: 'row',
285
+ alignItems: 'center'
286
+ },
287
+ defaultInputStyles: {
288
+ alignItems: 'center',
289
+ justifyContent: 'center'
290
+ }
291
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * There's no radio button input on native platforms, so this is a noop.
3
+ */
4
+ const RadioInput = () => null;
5
+
6
+ export default RadioInput;
@@ -0,0 +1,59 @@
1
+ import React, { forwardRef } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ /**
4
+ * On Web we need to include an actual input but hide it.
5
+ */
6
+
7
+ const RadioInput = /*#__PURE__*/forwardRef(({
8
+ checked,
9
+ defaultChecked,
10
+ disabled,
11
+ id,
12
+ isControlled,
13
+ name,
14
+ onChange,
15
+ value
16
+ }, ref) => {
17
+ const handleClick = event => {
18
+ // Cancel the click dispatched via the label tag, since it's already wrapped
19
+ // in <Pressable>
20
+ event.preventDefault();
21
+ event.stopPropagation();
22
+ };
23
+
24
+ return /*#__PURE__*/React.createElement("input", {
25
+ checked: isControlled ? checked : undefined,
26
+ defaultChecked: isControlled ? undefined : defaultChecked,
27
+ disabled: disabled,
28
+ hidden: true,
29
+ id: id,
30
+ name: name,
31
+ onChange: onChange,
32
+ onClick: handleClick,
33
+ ref: ref,
34
+ type: "radio",
35
+ value: value
36
+ });
37
+ });
38
+ RadioInput.displayName = 'Radio';
39
+ RadioInput.propTypes = {
40
+ checked: PropTypes.bool,
41
+ defaultChecked: PropTypes.bool,
42
+ disabled: PropTypes.bool,
43
+ id: PropTypes.string,
44
+ isControlled: PropTypes.bool,
45
+ name: PropTypes.string,
46
+ onChange: PropTypes.func,
47
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool])
48
+ };
49
+ RadioInput.defaultProps = {
50
+ checked: undefined,
51
+ defaultChecked: undefined,
52
+ disabled: false,
53
+ id: null,
54
+ isControlled: false,
55
+ name: undefined,
56
+ onChange: () => {},
57
+ value: undefined
58
+ };
59
+ export default RadioInput;
@@ -0,0 +1,2 @@
1
+ import Radio from './Radio';
2
+ export default Radio;
@@ -0,0 +1,14 @@
1
+ import PropTypes from 'prop-types';
2
+ import { componentPropType } from '../utils';
3
+
4
+ const Group = ({
5
+ children
6
+ }) => {
7
+ return children;
8
+ };
9
+
10
+ export default Group;
11
+ Group.propTypes = {
12
+ children: componentPropType('Item'),
13
+ label: PropTypes.string.isRequired
14
+ };
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { componentPropType } from '../utils';
4
+
5
+ const Group = ({
6
+ children,
7
+ label
8
+ }) => {
9
+ return /*#__PURE__*/React.createElement("optgroup", {
10
+ label: label
11
+ }, children);
12
+ };
13
+
14
+ export default Group;
15
+ Group.propTypes = {
16
+ children: componentPropType('Item'),
17
+ label: PropTypes.string.isRequired
18
+ };
@@ -0,0 +1,9 @@
1
+ import PropTypes from 'prop-types';
2
+
3
+ const Item = () => null;
4
+
5
+ export default Item;
6
+ Item.propTypes = {
7
+ children: PropTypes.string.isRequired,
8
+ value: PropTypes.string.isRequired
9
+ };
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+
4
+ const Item = ({
5
+ children,
6
+ value
7
+ }) => /*#__PURE__*/React.createElement("option", {
8
+ value: value
9
+ }, children);
10
+
11
+ export default Item;
12
+ Item.propTypes = {
13
+ children: PropTypes.string.isRequired,
14
+ value: PropTypes.string.isRequired
15
+ };
@@ -0,0 +1,87 @@
1
+ import React, { Children } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { View, Platform } from 'react-native';
4
+ import NativePicker from 'react-native-picker-select';
5
+ import { a11yProps, componentPropType } from '../utils';
6
+ import Group from './Group'; // styling of the native input is very limited, most of the styles have to be applied to an additional View
7
+
8
+ const selectAndroidInputStyles = ({
9
+ height = 0,
10
+ paddingBottom = 0,
11
+ paddingTop = 0,
12
+ borderWidth = 0,
13
+ color
14
+ }) => ({
15
+ height: height - paddingTop - paddingBottom - 2 * borderWidth,
16
+ color
17
+ }); // the native input has a side padding of 8px, which can't be adjusted, so we have to account for that in the container
18
+
19
+
20
+ const selectAndroidContainerStyles = ({
21
+ paddingLeft = 0,
22
+ paddingRight = 0,
23
+ ...rest
24
+ }) => ({
25
+ paddingLeft: paddingLeft > 8 ? paddingLeft - 8 : 0,
26
+ paddingRight: paddingRight > 8 ? paddingRight - 8 : 0,
27
+ ...rest
28
+ });
29
+
30
+ const Picker = ({
31
+ value,
32
+ onChange,
33
+ onFocus,
34
+ onBlur,
35
+ style,
36
+ inactive,
37
+ children,
38
+ placeholder,
39
+ ...rest
40
+ }) => {
41
+ // ungroup items, since there's no way to support groups on native
42
+ const flatChildren = Children.toArray(children).flatMap(child => {
43
+ if (child.type === Group) {
44
+ return child.props.children;
45
+ }
46
+
47
+ return child;
48
+ });
49
+ const items = flatChildren.map(({
50
+ props
51
+ }) => ({
52
+ label: props.children,
53
+ value: props.value
54
+ }));
55
+ const picker = /*#__PURE__*/React.createElement(NativePicker, {
56
+ touchableWrapperProps: a11yProps.select(rest),
57
+ onOpen: onFocus,
58
+ onClose: onBlur,
59
+ disabled: inactive,
60
+ items: items,
61
+ value: value,
62
+ onValueChange: onChange,
63
+ style: {
64
+ inputIOS: style,
65
+ inputAndroid: selectAndroidInputStyles(style)
66
+ },
67
+ placeholder: placeholder !== undefined ? placeholder : {}
68
+ });
69
+ return /*#__PURE__*/React.createElement(React.Fragment, null, Platform.OS === 'android' ? /*#__PURE__*/React.createElement(View, {
70
+ style: selectAndroidContainerStyles(style)
71
+ }, picker) : picker);
72
+ };
73
+
74
+ export default Picker;
75
+ Picker.propTypes = {
76
+ value: PropTypes.string,
77
+ onChange: PropTypes.func,
78
+ onFocus: PropTypes.func,
79
+ onBlur: PropTypes.func,
80
+ style: PropTypes.object,
81
+ inactive: PropTypes.bool,
82
+ children: componentPropType(['Item', 'Group']),
83
+ placeholder: PropTypes.shape({
84
+ value: PropTypes.string,
85
+ label: PropTypes.string
86
+ })
87
+ };
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { componentPropType } from '../utils';
4
+
5
+ const Picker = ({
6
+ value,
7
+ onChange,
8
+ onFocus,
9
+ onBlur,
10
+ onMouseOver,
11
+ onMouseOut,
12
+ style,
13
+ inactive,
14
+ children,
15
+ placeholder,
16
+ nativeID,
17
+ testID,
18
+ ...rest
19
+ }) => {
20
+ const {
21
+ accessibilityLabel,
22
+ accessibilityDescribedBy,
23
+ accessibilityInvalid
24
+ } = rest;
25
+ return /*#__PURE__*/React.createElement("select", {
26
+ style: style,
27
+ onMouseOver: onMouseOver,
28
+ onMouseOut: onMouseOut,
29
+ onFocus: onFocus,
30
+ onBlur: onBlur,
31
+ disabled: inactive,
32
+ value: value || (placeholder !== undefined ? placeholder.value : undefined),
33
+ onChange: event => onChange(event.target.value),
34
+ id: nativeID,
35
+ "aria-label": accessibilityLabel,
36
+ "aria-describedby": accessibilityDescribedBy,
37
+ "aria-invalid": accessibilityInvalid,
38
+ "data-testid": testID
39
+ }, placeholder !== undefined && /*#__PURE__*/React.createElement("option", {
40
+ value: placeholder.value,
41
+ disabled: true,
42
+ hidden: true
43
+ }, placeholder.label), children);
44
+ };
45
+
46
+ export default Picker;
47
+ Picker.propTypes = {
48
+ value: PropTypes.string,
49
+ onChange: PropTypes.func,
50
+ onFocus: PropTypes.func,
51
+ onBlur: PropTypes.func,
52
+ onMouseOver: PropTypes.func,
53
+ onMouseOut: PropTypes.func,
54
+ style: PropTypes.object,
55
+ inactive: PropTypes.bool,
56
+ children: componentPropType(['Item', 'Group']),
57
+ placeholder: PropTypes.shape({
58
+ value: PropTypes.string,
59
+ label: PropTypes.string
60
+ }),
61
+ nativeID: PropTypes.string,
62
+ testID: PropTypes.string
63
+ };