@telus-uds/components-base 0.0.2-prerelease.6 → 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 (155) hide show
  1. package/.ultra.cache.json +1 -1
  2. package/CHANGELOG.md +20 -0
  3. package/__fixtures__/testTheme.js +424 -37
  4. package/__tests__/Button/ButtonBase.test.jsx +2 -31
  5. package/__tests__/Checkbox/Checkbox.test.jsx +94 -0
  6. package/__tests__/InputSupports/InputSupports.test.jsx +50 -0
  7. package/__tests__/List/List.test.jsx +60 -0
  8. package/__tests__/Radio/Radio.test.jsx +87 -0
  9. package/__tests__/Select/Select.test.jsx +93 -0
  10. package/__tests__/Skeleton/Skeleton.test.jsx +61 -0
  11. package/__tests__/Tags/Tags.test.jsx +328 -0
  12. package/__tests__/TextInput/TextArea.test.jsx +34 -0
  13. package/__tests__/TextInput/{TextInput.test.jsx → TextInputBase.test.jsx} +20 -46
  14. package/jest.config.js +3 -1
  15. package/lib/Button/Button.js +10 -3
  16. package/lib/Button/ButtonBase.js +73 -59
  17. package/lib/Button/ButtonGroup.js +11 -27
  18. package/lib/Button/ButtonLink.js +5 -0
  19. package/lib/Checkbox/Checkbox.js +308 -0
  20. package/lib/Checkbox/CheckboxInput.native.js +6 -0
  21. package/lib/Checkbox/CheckboxInput.web.js +57 -0
  22. package/lib/Checkbox/index.js +2 -0
  23. package/lib/Feedback/Feedback.js +20 -3
  24. package/lib/Icon/Icon.js +8 -5
  25. package/lib/Icon/IconText.js +72 -0
  26. package/lib/Icon/index.js +2 -1
  27. package/lib/InputSupports/InputSupports.js +90 -0
  28. package/lib/InputSupports/index.js +2 -0
  29. package/lib/InputSupports/propTypes.js +55 -0
  30. package/lib/Link/ChevronLink.js +23 -20
  31. package/lib/Link/InlinePressable.native.js +78 -0
  32. package/lib/Link/InlinePressable.web.js +32 -0
  33. package/lib/Link/Link.js +11 -10
  34. package/lib/Link/LinkBase.js +62 -123
  35. package/lib/Link/TextButton.js +20 -9
  36. package/lib/Link/index.js +2 -1
  37. package/lib/List/List.js +52 -0
  38. package/lib/List/ListItem.js +207 -0
  39. package/lib/List/index.js +2 -0
  40. package/lib/Pagination/PageButton.js +2 -25
  41. package/lib/Pagination/SideButton.js +27 -37
  42. package/lib/Radio/Radio.js +291 -0
  43. package/lib/Radio/RadioInput.native.js +6 -0
  44. package/lib/Radio/RadioInput.web.js +59 -0
  45. package/lib/Radio/index.js +2 -0
  46. package/lib/Select/Group.native.js +14 -0
  47. package/lib/Select/Group.web.js +18 -0
  48. package/lib/Select/Item.native.js +9 -0
  49. package/lib/Select/Item.web.js +15 -0
  50. package/lib/Select/Picker.native.js +87 -0
  51. package/lib/Select/Picker.web.js +63 -0
  52. package/lib/Select/Select.js +272 -0
  53. package/lib/Select/index.js +6 -0
  54. package/lib/Skeleton/Skeleton.js +119 -0
  55. package/lib/Skeleton/index.js +2 -0
  56. package/lib/Tags/Tags.js +217 -0
  57. package/lib/Tags/index.js +2 -0
  58. package/lib/TextInput/TextArea.js +82 -0
  59. package/lib/TextInput/TextInput.js +23 -304
  60. package/lib/TextInput/TextInputBase.js +229 -0
  61. package/lib/TextInput/index.js +2 -1
  62. package/lib/TextInput/propTypes.js +31 -0
  63. package/lib/ThemeProvider/useThemeTokens.js +54 -3
  64. package/lib/ToggleSwitch/ToggleSwitch.js +1 -1
  65. package/lib/Typography/Typography.js +4 -19
  66. package/lib/index.js +8 -1
  67. package/lib/utils/a11y/index.js +1 -0
  68. package/lib/utils/a11y/textSize.js +33 -0
  69. package/lib/utils/index.js +3 -0
  70. package/lib/utils/info/index.js +7 -0
  71. package/lib/utils/info/platform/index.js +11 -0
  72. package/lib/utils/info/platform/platform.android.js +1 -0
  73. package/lib/utils/info/platform/platform.ios.js +1 -0
  74. package/lib/utils/info/platform/platform.native.js +4 -0
  75. package/lib/utils/info/platform/platform.web.js +1 -0
  76. package/lib/utils/info/versions.js +5 -0
  77. package/lib/utils/pressability.js +92 -0
  78. package/lib/utils/propTypes.js +78 -17
  79. package/package.json +5 -4
  80. package/release-context.json +4 -4
  81. package/src/Button/Button.jsx +6 -3
  82. package/src/Button/ButtonBase.jsx +66 -57
  83. package/src/Button/ButtonGroup.jsx +9 -22
  84. package/src/Button/ButtonLink.jsx +11 -2
  85. package/src/Checkbox/Checkbox.jsx +275 -0
  86. package/src/Checkbox/CheckboxInput.native.jsx +6 -0
  87. package/src/Checkbox/CheckboxInput.web.jsx +55 -0
  88. package/src/Checkbox/index.js +3 -0
  89. package/src/Feedback/Feedback.jsx +13 -4
  90. package/src/Icon/Icon.jsx +9 -5
  91. package/src/Icon/IconText.jsx +63 -0
  92. package/src/Icon/index.js +2 -1
  93. package/src/InputSupports/InputSupports.jsx +86 -0
  94. package/src/InputSupports/index.js +3 -0
  95. package/src/InputSupports/propTypes.js +44 -0
  96. package/src/Link/ChevronLink.jsx +20 -17
  97. package/src/Link/InlinePressable.native.jsx +73 -0
  98. package/src/Link/InlinePressable.web.jsx +37 -0
  99. package/src/Link/Link.jsx +17 -13
  100. package/src/Link/LinkBase.jsx +57 -140
  101. package/src/Link/TextButton.jsx +25 -11
  102. package/src/Link/index.js +2 -1
  103. package/src/List/List.jsx +47 -0
  104. package/src/List/ListItem.jsx +187 -0
  105. package/src/List/index.js +3 -0
  106. package/src/Pagination/PageButton.jsx +2 -16
  107. package/src/Pagination/SideButton.jsx +23 -34
  108. package/src/Radio/Radio.jsx +270 -0
  109. package/src/Radio/RadioInput.native.jsx +6 -0
  110. package/src/Radio/RadioInput.web.jsx +57 -0
  111. package/src/Radio/index.js +3 -0
  112. package/src/Select/Group.native.jsx +14 -0
  113. package/src/Select/Group.web.jsx +15 -0
  114. package/src/Select/Item.native.jsx +10 -0
  115. package/src/Select/Item.web.jsx +11 -0
  116. package/src/Select/Picker.native.jsx +95 -0
  117. package/src/Select/Picker.web.jsx +67 -0
  118. package/src/Select/Select.jsx +265 -0
  119. package/src/Select/index.js +8 -0
  120. package/src/Skeleton/Skeleton.jsx +101 -0
  121. package/src/Skeleton/index.js +3 -0
  122. package/src/Tags/Tags.jsx +206 -0
  123. package/src/Tags/index.js +3 -0
  124. package/src/TextInput/TextArea.jsx +78 -0
  125. package/src/TextInput/TextInput.jsx +17 -284
  126. package/src/TextInput/TextInputBase.jsx +220 -0
  127. package/src/TextInput/index.js +2 -1
  128. package/src/TextInput/propTypes.js +29 -0
  129. package/src/ThemeProvider/useThemeTokens.js +54 -3
  130. package/src/ToggleSwitch/ToggleSwitch.jsx +1 -1
  131. package/src/Typography/Typography.jsx +4 -15
  132. package/src/index.js +8 -1
  133. package/src/utils/a11y/index.js +1 -0
  134. package/src/utils/a11y/textSize.js +30 -0
  135. package/src/utils/index.js +3 -0
  136. package/src/utils/info/index.js +8 -0
  137. package/src/utils/info/platform/index.js +11 -0
  138. package/src/utils/info/platform/platform.android.js +1 -0
  139. package/src/utils/info/platform/platform.ios.js +1 -0
  140. package/src/utils/info/platform/platform.native.js +4 -0
  141. package/src/utils/info/platform/platform.web.js +1 -0
  142. package/src/utils/info/versions.js +6 -0
  143. package/src/utils/pressability.js +92 -0
  144. package/src/utils/propTypes.js +97 -22
  145. package/stories/Button/Button.stories.jsx +5 -0
  146. package/stories/Checkbox/Checkbox.stories.jsx +71 -0
  147. package/stories/Feedback/Feedback.stories.jsx +5 -6
  148. package/stories/Link/Link.stories.jsx +15 -1
  149. package/stories/List/List.stories.jsx +117 -0
  150. package/stories/Radio/Radio.stories.jsx +113 -0
  151. package/stories/Select/Select.stories.jsx +55 -0
  152. package/stories/Skeleton/Skeleton.stories.jsx +36 -0
  153. package/stories/Tags/Tags.stories.jsx +69 -0
  154. package/stories/TextInput/TextArea.stories.jsx +100 -0
  155. package/stories/supports.jsx +1 -1
@@ -1,11 +1,11 @@
1
1
  import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
- import { Platform, Text, View } from 'react-native'
3
+ import { Text, View } from 'react-native'
4
4
 
5
5
  import { useThemeTokens } from '../ThemeProvider'
6
6
  import { useViewport } from '../ViewportProvider'
7
7
  import { applyTextStyles } from '../ThemeProvider/utils'
8
- import { a11yProps, variantProp, getTokensPropType } from '../utils/propTypes'
8
+ import { a11yProps, variantProp, getTokensPropType, getMaxFontMultiplier } from '../utils'
9
9
 
10
10
  /**
11
11
  * If passed a string like 'h1', 'h2' etc, returns the heading number as a string,
@@ -16,17 +16,6 @@ function getHeadingLevel(heading) {
16
16
  return match && match[1]
17
17
  }
18
18
 
19
- /**
20
- * Enforces `fontScaleCap` theme tokens as the maximum font size text can become
21
- * after iOS or Android font scaling, to give consistent accessible maximum sizes
22
- * that don't make the content unusable
23
- */
24
- function getMaxFontMultiplier({ fontSize, fontScaleCap }) {
25
- if (!fontScaleCap || !fontSize) return undefined
26
- if (fontScaleCap <= fontSize) return 1
27
- return fontScaleCap / fontSize
28
- }
29
-
30
19
  const selectTextStyles = ({
31
20
  fontWeight,
32
21
  fontSize,
@@ -60,9 +49,9 @@ const Typography = ({
60
49
  const viewport = useViewport()
61
50
  const themeTokens = useThemeTokens('Typography', tokens, variant, { viewport })
62
51
  const textProps = {
63
- style: selectTextStyles(align ? { ...themeTokens, textAlign: align } : themeTokens)
52
+ style: selectTextStyles(align ? { ...themeTokens, textAlign: align } : themeTokens),
53
+ maxFontSizeMultiplier: getMaxFontMultiplier(themeTokens)
64
54
  }
65
- if (Platform.OS !== 'web') textProps.maxFontSizeMultiplier = getMaxFontMultiplier(themeTokens)
66
55
 
67
56
  const headingLevel = getHeadingLevel(heading)
68
57
  const a11y = {
package/src/index.js CHANGED
@@ -1,7 +1,9 @@
1
+ export { default as A11yText } from './A11yText'
1
2
  export { default as ActivityIndicator } from './ActivityIndicator'
2
3
  export { default as Box } from './Box'
3
4
  export * from './Button'
4
5
  export { default as Card } from './Card'
6
+ export { default as Checkbox } from './Checkbox'
5
7
  export { default as Divider } from './Divider'
6
8
  export { default as ExpandCollapse, Accordion } from './ExpandCollapse'
7
9
  export { default as Feedback } from './Feedback'
@@ -9,12 +11,17 @@ export { default as FlexGrid } from './FlexGrid'
9
11
  export { default as Icon } from './Icon'
10
12
  export * from './Icon'
11
13
  export * from './Link'
14
+ export { default as List } from './List'
12
15
  export { default as Pagination } from './Pagination'
16
+ export { default as Radio } from './Radio'
17
+ export { default as Select } from './Select'
13
18
  export { default as SideNav } from './SideNav'
19
+ export { default as Skeleton } from './Skeleton'
14
20
  export { default as Spacer } from './Spacer'
15
21
  export { default as StackView } from './StackView'
16
22
  export * from './StackView'
17
- export { default as TextInput } from './TextInput'
23
+ export { default as Tags } from './Tags'
24
+ export * from './TextInput'
18
25
  export { default as ToggleSwitch } from './ToggleSwitch'
19
26
  export { default as Tooltip } from './Tooltip'
20
27
  export { default as TooltipButton } from './TooltipButton'
@@ -0,0 +1 @@
1
+ export * from './textSize'
@@ -0,0 +1,30 @@
1
+ import { PixelRatio, Platform } from 'react-native'
2
+
3
+ /**
4
+ * When a user increases text size using device accessibility settings, some elements
5
+ * should also scale, such as icons alongside text and space between paragraphs.
6
+ *
7
+ * @param {number} [value] - the value to multiply; defaults to system default font size
8
+ * @param {number} [maxScale] - the maximum multiplier to apply; defaults to no maximum
9
+ */
10
+ export const scaleWithText = (value, maxScale = Infinity) => {
11
+ if (!value) return value
12
+ const scale = Math.min(PixelRatio.getFontScale(), maxScale) || 1
13
+ return value * scale
14
+ }
15
+
16
+ /**
17
+ * Native only, returns `undefined` on Web.
18
+ *
19
+ * Enforces `fontScaleCap` theme tokens as the maximum font size text can become
20
+ * after iOS or Android font scaling, to give consistent accessible maximum sizes
21
+ * that don't make the content unusable.
22
+ *
23
+ * The return value of this function can be used as a React Native `Text` element's
24
+ * `maxFontSizeMultiplier` prop value.
25
+ */
26
+ export const getMaxFontMultiplier = ({ fontSize, fontScaleCap }) => {
27
+ if (Platform.OS === 'web' || !fontScaleCap || !fontSize) return undefined
28
+ if (fontScaleCap <= fontSize) return 1
29
+ return fontScaleCap / fontSize
30
+ }
@@ -1,7 +1,10 @@
1
+ export * from './a11y'
1
2
  export * from './animation'
2
3
  export * from './input'
4
+ export * from './pressability'
3
5
  export * from './propTypes'
4
6
 
7
+ export { default as info } from './info'
5
8
  export { default as useSpacingScale } from './useSpacingScale'
6
9
  export { default as useResponsiveProp } from './useResponsiveProp'
7
10
  export * from './useResponsiveProp'
@@ -0,0 +1,8 @@
1
+ import platform from './platform'
2
+ import versions from './versions'
3
+
4
+ // export an object accessed like info.platform.OS, info.version.uds, etc
5
+ export default {
6
+ platform,
7
+ versions
8
+ }
@@ -0,0 +1,11 @@
1
+ import { Platform } from 'react-native'
2
+ import fileSuffix from './platform'
3
+
4
+ // Allows consuming libraries that might not have a direct dependency on
5
+ // React Native to check what the current platform is.
6
+
7
+ // Particularly useful for validating Jest config: it is possible for Jest to
8
+ // get configured such that Platform.OS returns a different mocked value to the
9
+ // OS being used to select files by platform suffix (e.g. .web, .native).
10
+
11
+ export default { OS: Platform.OS, fileSuffix }
@@ -0,0 +1 @@
1
+ export default '.android'
@@ -0,0 +1 @@
1
+ export default '.ios'
@@ -0,0 +1,4 @@
1
+ // This shouldn't ever be chosen, as the more specific '.ios' and '.android' are available.
2
+ // If this gets picked, either an unsupported React Native platform is being used somehow
3
+ // (e.g. a native Windows app), or there's a serious config problem somewhere.
4
+ export default '.native'
@@ -0,0 +1 @@
1
+ export default '.web'
@@ -0,0 +1,6 @@
1
+ import { version } from '../../../package.json'
2
+
3
+ // Add more versions if they are useful e.g. theme schema version
4
+ export default {
5
+ uds: version
6
+ }
@@ -0,0 +1,92 @@
1
+ import { Platform, StyleSheet } from 'react-native'
2
+ import { pressProps } from './propTypes'
3
+
4
+ // These roles should result in cursor: pointer but don't in current RNW releases
5
+ const shouldUseCursor = ['checkbox', 'radio', 'switch']
6
+
7
+ /**
8
+ * React Native Web has some built-in logic for applying cursor styles based on accessibility roles;
9
+ * however, it misses certain cases. This fills in known cases where widely used versions of RNW
10
+ * fail to apply an expected cursor style.
11
+ *
12
+ * @param {object} props
13
+ * @param {boolean} [props.inactive]
14
+ * @param {boolean} [props.disabled]
15
+ * @param {string} [props.accessibilityRole]
16
+ * @returns
17
+ */
18
+ export const getCursorStyle = ({ inactive, disabled, accessibilityRole }) => {
19
+ if (Platform.OS !== 'web') return undefined
20
+
21
+ if (inactive || disabled) return staticStyles.notAllowed
22
+ if (shouldUseCursor.includes(accessibilityRole)) return staticStyles.pointer
23
+
24
+ return undefined // allows React Native Web's built-in logic to apply
25
+ }
26
+
27
+ /**
28
+ * @typedef {{ pressed: boolean, focused: boolean, hovered?: boolean }} PressableState
29
+ */
30
+
31
+ /**
32
+ * Maps the state object given by the React Native `Pressable` component to the set of
33
+ * equivalent appearance names used in UDS.
34
+ *
35
+ * @param {PressableState} pressableState - state object passed by React Native's `<Pressable>` into
36
+ * render functions passed to its `style` or `children` props.
37
+ * @param {object} [additionalState] - properties specific to the current component,
38
+ * such as `inactive`, `selected`, etc.
39
+ * @returns {object}
40
+ */
41
+ export const resolvePressableState = (
42
+ { pressed = false, focused = false, hovered = false } = {},
43
+ additionalState
44
+ ) => ({
45
+ ...additionalState,
46
+ focus: focused,
47
+ hover: hovered,
48
+ pressed
49
+ })
50
+
51
+ /**
52
+ * Takes a UDS `tokens` prop and, if it is a function, resolves it based on a state
53
+ * object passed from the React Native `Pressable` component and optional extra properties.
54
+ *
55
+ * @param {object|function} tokens - UDS system tokens prop
56
+ * @param {PressableState} pressableState - state object passed by React Native's `<Pressable>`
57
+ * @param {object} [additionalState] - properties specific to the current component
58
+ * @returns {object} - resolved tokens object
59
+ */
60
+ export const resolvePressableTokens = (tokens, pressableState, additionalState) => {
61
+ if (typeof tokens !== 'function') return tokens
62
+ const udsPressableState = resolvePressableState(pressableState, additionalState)
63
+ return tokens(udsPressableState)
64
+ }
65
+
66
+ const staticStyles = StyleSheet.create(
67
+ Platform.select({
68
+ web: {
69
+ notAllowed: { cursor: 'not-allowed' },
70
+ pointer: { cursor: 'pointer' }
71
+ },
72
+ default: {}
73
+ })
74
+ )
75
+
76
+ /**
77
+ * From an object of props, extracts any platform-appropriate press handler functions and wraps
78
+ * them in a function that passes in some provided args. Allows components containing a Pressable
79
+ * to pass in press handlers that are then called with state or values that is otherwise internal.
80
+ */
81
+ export const getPressHandlersWithArgs = (pressableProps = {}, args = []) => {
82
+ // Allow handlers to be passed down for blur, hover, focus, pressIn, etc
83
+ const pressHandlers = Object.fromEntries(
84
+ Object.entries(pressProps.selectHandlers(pressableProps)).map(([key, handler]) => ({
85
+ [key]: (...defaultArgs) => {
86
+ // Pass each handler data on this button and current selection
87
+ handler(...args, ...defaultArgs)
88
+ }
89
+ }))
90
+ )
91
+ return pressHandlers
92
+ }
@@ -1,6 +1,24 @@
1
1
  import PropTypes from 'prop-types'
2
2
  import { Linking, Platform } from 'react-native'
3
- import { tokenKeys } from '@telus-uds/tools-theme'
3
+ import { components as tokenKeys } from '@telus-uds/system-themes/schema'
4
+
5
+ export const paddingProp = {
6
+ propType: PropTypes.shape({
7
+ paddingBottom: PropTypes.number,
8
+ paddingLeft: PropTypes.number,
9
+ paddingRight: PropTypes.number,
10
+ paddingTop: PropTypes.number
11
+ })
12
+ }
13
+
14
+ export const rectProp = {
15
+ propType: PropTypes.shape({
16
+ bottom: PropTypes.number,
17
+ left: PropTypes.number,
18
+ right: PropTypes.number,
19
+ top: PropTypes.number
20
+ })
21
+ }
4
22
 
5
23
  /**
6
24
  * @typedef {{[key: string]: string|number|boolean}} AppearanceSet
@@ -29,7 +47,7 @@ const tokenValueType = PropTypes.oneOfType([tokenValue, PropTypes.objectOf(token
29
47
  const getTokenNames = (componentName) => {
30
48
  const componentTokenNames = tokenKeys[componentName]
31
49
  if (!componentTokenNames) {
32
- throw new Error(`No "${componentName}" tokenKeys in @telus-uds/tools-theme`)
50
+ throw new Error(`No "${componentName}" tokenKeys in @telus-uds/system-themes/schema`)
33
51
  }
34
52
  return componentTokenNames
35
53
  }
@@ -59,14 +77,48 @@ export const selectTokens = (componentName, tokens) => {
59
77
  *
60
78
  * This prop is intended to be used as an 'escape hatch' for difficult or exceptional cases
61
79
  * where the main theming system doesn't apply. It is intentionally permissive about values.
80
+ *
81
+ * @param {...string} componentsNames - one or more ComponentName, which tokens keys are accepted
82
+ * @return {function} - a custom PropTypes validator
83
+ *
84
+ * @example
85
+ * Component.propTypes = {
86
+ * // accepts all tokens keys defined in Component schema
87
+ * tokens: getTokensPropType('Component')
88
+ * }
89
+ *
90
+ * Component.propTypes = {
91
+ * // accepts all tokens keys defined in schemas for Component1 and Component2
92
+ * tokens: getTokensPropType('Component1', 'Component2')
93
+ * }
62
94
  */
63
- export const getTokensPropType = (componentName) =>
64
- PropTypes.oneOfType([
65
- PropTypes.shape(
66
- Object.fromEntries(getTokenNames(componentName).map((key) => [key, tokenValueType]))
67
- ),
68
- PropTypes.func // function that takes current appearances and returns above shape
69
- ])
95
+ export const getTokensPropType = (...componentsNames) => (props, propName, componentName) => {
96
+ PropTypes.checkPropTypes(
97
+ {
98
+ [propName]: PropTypes.oneOfType([PropTypes.object, PropTypes.func])
99
+ },
100
+ props,
101
+ propName,
102
+ componentName
103
+ )
104
+
105
+ if (typeof props[propName] !== 'function') {
106
+ PropTypes.checkPropTypes(
107
+ {
108
+ [propName]: PropTypes.exact(
109
+ Object.fromEntries(
110
+ componentsNames.flatMap((component) =>
111
+ getTokenNames(component).map((key) => [key, tokenValueType])
112
+ )
113
+ )
114
+ )
115
+ },
116
+ props,
117
+ propName,
118
+ componentName
119
+ )
120
+ }
121
+ }
70
122
 
71
123
  function getPropSelector(propTypes, regexp) {
72
124
  const keys = Object.keys(propTypes)
@@ -152,7 +204,27 @@ export const a11yProps = {
152
204
  accessibilityElementsHidden: true
153
205
  }
154
206
  })
155
- }
207
+ },
208
+ /**
209
+ * Generates an object of platform-appropriate a11y props describing an item that has an
210
+ * ordered position in a set. Examples of usage by accessibility tools includes screenreaders
211
+ * saying "Item X of Y" when this item is select.
212
+ *
213
+ * @param {number} itemsCount - the number of items in the set
214
+ * @param {number} index - the current item's index in the set
215
+ * @returns {object} - platform-applicable a11y props describing this position (if available)
216
+ */
217
+ getPositionInSet: (itemsCount, index) =>
218
+ Platform.select({
219
+ web: {
220
+ // accessibilityPosInSet etc exists in React Native Web main branch
221
+ // but not in a release compatible with Expo etc; just use `aria-*`
222
+ 'aria-setsize': itemsCount,
223
+ 'aria-posinset': index + 1
224
+ },
225
+ // No equivalents exist on the native side
226
+ default: {}
227
+ })
156
228
  }
157
229
 
158
230
  // Props related to HTML <a> anchor link attributes.
@@ -199,7 +271,7 @@ export const hrefAttrsProp = {
199
271
  })
200
272
  }
201
273
 
202
- const pressPropTypes = {
274
+ const pressHandlerPropTypes = {
203
275
  onPress: PropTypes.func,
204
276
  onPressIn: PropTypes.func,
205
277
  onPressOut: PropTypes.func,
@@ -210,7 +282,18 @@ const pressPropTypes = {
210
282
  onFocus: PropTypes.func,
211
283
  onBlur: PropTypes.func
212
284
  },
213
- default: {}
285
+ default: {
286
+ onLongPress: PropTypes.func
287
+ }
288
+ })
289
+ }
290
+
291
+ const pressPropTypes = {
292
+ ...pressHandlerPropTypes,
293
+ disabled: PropTypes.bool,
294
+ ...Platform.select({
295
+ hitSlop: PropTypes.number,
296
+ pressRetentionOffset: PropTypes.oneOfType([PropTypes.number, rectProp.propType])
214
297
  })
215
298
  }
216
299
 
@@ -222,7 +305,8 @@ export const pressProps = {
222
305
  /**
223
306
  * Filters a props object, returning only the platform-relevant press props defined above
224
307
  */
225
- select: getPropSelector(pressPropTypes)
308
+ select: getPropSelector(pressPropTypes),
309
+ selectHandlers: getPropSelector(pressHandlerPropTypes)
226
310
  }
227
311
 
228
312
  const linkPropTypes = {
@@ -427,12 +511,3 @@ export const componentPropType = (passedName, checkDisplayName = false) => {
427
511
  }
428
512
 
429
513
  export const copyPropTypes = PropTypes.oneOf(['en', 'fr'])
430
-
431
- export const paddingProp = {
432
- propType: PropTypes.shape({
433
- paddingBottom: PropTypes.number,
434
- paddingLeft: PropTypes.number,
435
- paddingRight: PropTypes.number,
436
- paddingTop: PropTypes.number
437
- })
438
- }
@@ -55,6 +55,11 @@ LongLabelButtonVariants.args = {
55
55
  children: 'This button has a label that is much longer than is considered advisable'
56
56
  }
57
57
 
58
+ export const ShortLabelButtonVariants = VariantsTemplate.bind({})
59
+ ShortLabelButtonVariants.args = {
60
+ children: 'k'
61
+ }
62
+
58
63
  export const ParentTypes = (args) => (
59
64
  <EachParentType componentThemeName="Button" {...args}>
60
65
  {({ label, variant }) => (
@@ -0,0 +1,71 @@
1
+ /* eslint-disable react/no-multi-comp */
2
+ import React from 'react'
3
+
4
+ import { Checkbox, Typography } from '../../lib'
5
+ import { Container, EachParentType, parentTypesParams } from '../supports'
6
+
7
+ export default {
8
+ title: 'Base/Checkbox',
9
+ component: Checkbox,
10
+ argTypes: {
11
+ checked: {
12
+ control: { type: 'radio' },
13
+ options: [true, false, undefined]
14
+ }
15
+ },
16
+ args: {
17
+ label: 'Checkbox',
18
+ checked: undefined
19
+ }
20
+ }
21
+
22
+ const Template = (args) => (
23
+ <Container>
24
+ <Checkbox {...args} />
25
+ </Container>
26
+ )
27
+
28
+ export const Default = Template.bind({})
29
+ Default.argTypes = {
30
+ checked: { table: { disable: true } }
31
+ }
32
+
33
+ export const Controlled = Template.bind({})
34
+ Controlled.argTypes = {
35
+ defaultChecked: { table: { disable: true } }
36
+ }
37
+ Controlled.args = {
38
+ checked: false,
39
+ defaultChecked: undefined
40
+ }
41
+
42
+ export const Inactive = Template.bind({})
43
+ Inactive.argTypes = {
44
+ inactive: { table: { disable: true } }
45
+ }
46
+ Inactive.args = {
47
+ inactive: true
48
+ }
49
+
50
+ export const WithFeedback = Template.bind({})
51
+ WithFeedback.argTypes = {
52
+ feedback: { table: { disable: true } }
53
+ }
54
+ WithFeedback.args = {
55
+ feedback: 'Something happened'
56
+ }
57
+
58
+ export const ParentTypes = (args) => (
59
+ <EachParentType componentThemeName="Checkbox" {...args}>
60
+ {({ label, variant }) => (
61
+ <Container key={label}>
62
+ <Typography>{`${label} `}</Typography>
63
+ <Checkbox {...args} variant={variant} />
64
+ </Container>
65
+ )}
66
+ </EachParentType>
67
+ )
68
+ ParentTypes.parameters = parentTypesParams
69
+ ParentTypes.args = {
70
+ defaultChecked: undefined
71
+ }
@@ -1,9 +1,8 @@
1
1
  import React, { useEffect, useState } from 'react'
2
2
  import { Text } from 'react-native'
3
3
 
4
- import { Feedback, Typography } from '../../lib'
4
+ import { Feedback, Typography, TextInput } from '../../lib'
5
5
  import { Container } from '../supports'
6
- import TextInput from '../../lib/TextInput'
7
6
 
8
7
  export default {
9
8
  title: 'Base/Feedback',
@@ -40,22 +39,22 @@ export const RenderFunctionAndChildren = () => (
40
39
  export const Variants = () => (
41
40
  <>
42
41
  <Container>
43
- <Feedback variant={{ state: 'success' }} title="Success">
42
+ <Feedback validation="success" title="Success">
44
43
  {({ textStyles }) => <Text style={textStyles}>Content from function</Text>}
45
44
  </Feedback>
46
45
  </Container>
47
46
  <Container>
48
- <Feedback variant={{ state: 'success', icon: true }} title="Success with icon">
47
+ <Feedback validation="success" variant={{ icon: true }} title="Success with icon">
49
48
  {({ textStyles }) => <Text style={textStyles}>Content from function</Text>}
50
49
  </Feedback>
51
50
  </Container>
52
51
  <Container>
53
- <Feedback variant={{ state: 'error' }} title="Error">
52
+ <Feedback validation="error" title="Error">
54
53
  {({ textStyles }) => <Text style={textStyles}>Content from function</Text>}
55
54
  </Feedback>
56
55
  </Container>
57
56
  <Container>
58
- <Feedback variant={{ state: 'error', icon: true }} title="Error with icon">
57
+ <Feedback validation="error" variant={{ icon: true }} title="Error with icon">
59
58
  {({ textStyles }) => <Text style={textStyles}>Content from function</Text>}
60
59
  </Feedback>
61
60
  </Container>
@@ -6,7 +6,7 @@ import { View } from 'react-native'
6
6
  // eslint-disable-next-line import/no-extraneous-dependencies
7
7
  import * as Icons from '@telus-uds/palette-allium/build/rn/icons'
8
8
 
9
- import { Link, variantProp } from '../../lib'
9
+ import { Link, Typography, variantProp } from '../../lib'
10
10
  import { Container, EachParentType, parentTypesParams, useVariants } from '../supports'
11
11
 
12
12
  export default {
@@ -62,6 +62,20 @@ IconRight.args = { icon: SampleIcon, iconPosition: 'right' }
62
62
 
63
63
  export const EveryIcon = EveryIconTemplate.bind({})
64
64
 
65
+ export const InText = (args) => (
66
+ <Typography>
67
+ Some text containing a{' '}
68
+ <Link icon={SampleIcon} iconPosition="left" {...args}>
69
+ left icon link
70
+ </Link>
71
+ , alongside a{' '}
72
+ <Link icon={SampleIcon} iconPosition="right" {...args}>
73
+ right icon link
74
+ </Link>
75
+ , and also with a <Link {...args}>text link</Link>, all inline in text.
76
+ </Typography>
77
+ )
78
+
65
79
  export const ParentTypes = (args) => (
66
80
  <EachParentType componentThemeName="Link" {...args}>
67
81
  {({ label, variant }) => (