@telus-uds/components-base 1.64.0 → 1.66.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.
@@ -1,4 +1,5 @@
1
1
  import React, { forwardRef, useCallback } from 'react';
2
+ import Platform from "react-native-web/dist/exports/Platform";
2
3
  import PropTypes from 'prop-types';
3
4
  import ABBPropTypes from 'airbnb-prop-types';
4
5
  import { useThemeTokens } from '../ThemeProvider';
@@ -26,6 +27,17 @@ const getDefaultTabItemAccessibilityRole = parentRole => {
26
27
  return undefined;
27
28
  }
28
29
  };
30
+
31
+ const getStackViewTokens = variant => {
32
+ const equalWidth = variant === null || variant === void 0 ? void 0 : variant.equalWidth;
33
+ return Platform.select({
34
+ web: {
35
+ justifyContent: equalWidth ? 'space-evenly' : 'flex-start',
36
+ width: equalWidth ? '100%' : 'auto'
37
+ },
38
+ default: {}
39
+ });
40
+ };
29
41
  /**
30
42
  * Tabs renders a horizontally-scrolling menu of selectable buttons which may link
31
43
  * to a page or control what content is displayed on this page.
@@ -76,6 +88,7 @@ const Tabs = /*#__PURE__*/forwardRef((_ref, ref) => {
76
88
  const restProps = selectProps(rest);
77
89
  const parentAccessibilityRole = restProps.accessibilityRole ?? 'tablist';
78
90
  const defaultTabItemAccessibiltyRole = getDefaultTabItemAccessibilityRole(parentAccessibilityRole);
91
+ const stackViewTokens = getStackViewTokens(variant);
79
92
  return /*#__PURE__*/_jsx(HorizontalScroll, {
80
93
  ref: ref,
81
94
  ScrollButton: HorizontalScrollButton,
@@ -87,6 +100,7 @@ const Tabs = /*#__PURE__*/forwardRef((_ref, ref) => {
87
100
  children: /*#__PURE__*/_jsx(StackView, {
88
101
  space: space,
89
102
  direction: "row",
103
+ tokens: stackViewTokens,
90
104
  children: items.map((_ref3, index) => {
91
105
  let {
92
106
  href,
@@ -7,13 +7,14 @@ import View from "react-native-web/dist/exports/View";
7
7
  import { applyTextStyles, useTheme, useThemeTokens, applyOuterBorder } from '../ThemeProvider';
8
8
  import StackView from '../StackView';
9
9
  import IconButton from '../IconButton';
10
+ import Icon from '../Icon';
10
11
  import { a11yProps, getTokensPropType, selectSystemProps, textInputHandlerProps, textInputProps, useCopy, useInputValue, useSpacingScale, variantProp, viewProps } from '../utils';
11
12
  import dictionary from './dictionary';
12
13
  import { jsx as _jsx } from "react/jsx-runtime";
13
14
  import { jsxs as _jsxs } from "react/jsx-runtime";
14
15
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, textInputHandlerProps, textInputProps, viewProps]);
15
16
 
16
- const selectInputStyles = (_ref, themeOptions, inactive) => {
17
+ const selectInputStyles = (_ref, themeOptions, inactive, type) => {
17
18
  let {
18
19
  backgroundColor,
19
20
  color,
@@ -72,7 +73,7 @@ const selectInputStyles = (_ref, themeOptions, inactive) => {
72
73
  borderWidth,
73
74
  borderColor,
74
75
  borderRadius,
75
- paddingLeft: offsetBorder(paddingLeft),
76
+ paddingLeft: type === 'card' ? offsetBorder(paddingLeft + 34) : offsetBorder(paddingLeft),
76
77
  paddingRight: icon ? offsetBorder(paddingWithIcon) : offsetBorder(paddingRight),
77
78
  paddingTop: offsetBorder(paddingTop),
78
79
  paddingBottom: offsetBorder(paddingBottom),
@@ -126,16 +127,64 @@ const selectIconContainerStyles = (_ref4, buttonCount) => {
126
127
  };
127
128
  };
128
129
 
129
- const selectButtonsContainerStyle = _ref5 => {
130
+ const selectLeftIconContainerStyles = _ref5 => {
130
131
  let {
131
- buttonsPaddingRight
132
+ leftIconPaddingBottom
132
133
  } = _ref5;
134
+ return {
135
+ // not tokenizing paddingLeft as it remains same across brands for now
136
+ paddingLeft: 10,
137
+ paddingBottom: leftIconPaddingBottom
138
+ };
139
+ };
140
+
141
+ const selectButtonsContainerStyle = _ref6 => {
142
+ let {
143
+ buttonsPaddingRight
144
+ } = _ref6;
133
145
  return {
134
146
  paddingRight: buttonsPaddingRight
135
147
  };
136
148
  };
137
149
 
138
- const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
150
+ const getIcon = function () {
151
+ let cardNumber = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
152
+ let {
153
+ defaultCreditIcon,
154
+ amexIcon,
155
+ visaIcon,
156
+ masterCardIcon
157
+ } = arguments.length > 1 ? arguments[1] : undefined;
158
+ const cardType = {
159
+ 1: {
160
+ icon: visaIcon,
161
+ testID: 'visa'
162
+ },
163
+ 2: {
164
+ icon: amexIcon,
165
+ testID: 'amex'
166
+ },
167
+ 4: {
168
+ icon: masterCardIcon,
169
+ testID: 'mastercard'
170
+ }
171
+ };
172
+ const firstDigit = cardNumber ? cardNumber[0] : '';
173
+ const defaultIcon = {
174
+ icon: defaultCreditIcon,
175
+ testID: 'default'
176
+ };
177
+ const selectedIcon = cardNumber.length > 4 ? cardType[firstDigit] || defaultIcon : defaultIcon;
178
+ return /*#__PURE__*/_jsx(Icon, {
179
+ icon: selectedIcon.icon,
180
+ variant: {
181
+ size: 'large'
182
+ },
183
+ testID: selectedIcon.testID
184
+ });
185
+ };
186
+
187
+ const TextInputBase = /*#__PURE__*/forwardRef((_ref7, ref) => {
139
188
  let {
140
189
  buttons = [],
141
190
  copy = 'en',
@@ -154,8 +203,9 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
154
203
  tokens,
155
204
  value,
156
205
  variant = {},
206
+ type,
157
207
  ...rest
158
- } = _ref6;
208
+ } = _ref7;
159
209
  const [isFocused, setIsFocused] = useState(false);
160
210
  const [showPassword, setShowPassword] = useState(false);
161
211
 
@@ -196,6 +246,12 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
196
246
  onChange,
197
247
  readOnly
198
248
  });
249
+ const {
250
+ password,
251
+ numeric
252
+ } = variant;
253
+ const isNumeric = numeric || type === 'card' || type === 'number';
254
+ const isPassword = password || type === 'password';
199
255
  const element = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current;
200
256
  useEffect(() => {
201
257
  if (Platform.OS === 'web' && pattern && element) {
@@ -208,11 +264,16 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
208
264
  const handleChangeText = event => {
209
265
  var _event$nativeEvent, _event$target;
210
266
 
211
- const {
212
- numeric
213
- } = variant;
214
267
  const text = ((_event$nativeEvent = event.nativeEvent) === null || _event$nativeEvent === void 0 ? void 0 : _event$nativeEvent.text) || ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.value);
215
- const filteredText = numeric ? text.replace(/[^\d]/g, '') : text;
268
+ let filteredText = isNumeric ? text === null || text === void 0 ? void 0 : text.replace(/[^\d]/g, '') : text;
269
+
270
+ if (type === 'card' && filteredText) {
271
+ const formattedValue = filteredText.replace(/[^a-zA-Z0-9]/g, '');
272
+ const regex = new RegExp(`([a-zA-Z0-9]{4})(?=[a-zA-Z0-9])`, 'g'); // Add a space every 4 digits starting from the 5th position
273
+
274
+ filteredText = formattedValue.replace(regex, '$1 ').trim();
275
+ }
276
+
216
277
  setValue(filteredText, event);
217
278
  if (typeof onChangeText === 'function') onChangeText(filteredText, event);
218
279
  };
@@ -241,7 +302,11 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
241
302
  clearButtonIcon: ClearButtonIcon,
242
303
  icon: IconComponent,
243
304
  passwordShowButtonIcon,
244
- passwordHideButtonIcon
305
+ passwordHideButtonIcon,
306
+ defaultCreditIcon,
307
+ amexIcon,
308
+ visaIcon,
309
+ masterCardIcon
245
310
  } = themeTokens;
246
311
  const buttonsGapSize = useSpacingScale(buttonsGap);
247
312
  const getCopy = useCopy({
@@ -261,7 +326,7 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
261
326
  }, "clear"));
262
327
  }
263
328
 
264
- if (variant.password) {
329
+ if (isPassword) {
265
330
  textInputButtons === null || textInputButtons === void 0 ? void 0 : textInputButtons.unshift( /*#__PURE__*/_jsx(IconButton, {
266
331
  accessibilityLabel: !showPassword ? getCopy('hidePasswordAccessibilityLabel') : getCopy('showPasswordAccessibilityLabel'),
267
332
  icon: !showPassword ? passwordShowButtonIcon : passwordHideButtonIcon,
@@ -287,6 +352,7 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
287
352
  onMouseOut: handleMouseOut,
288
353
  onChange: handleChangeText,
289
354
  defaultValue: initialValue,
355
+ maxLength: type === 'card' ? 19 : undefined,
290
356
  value: isControlled ? currentValue : undefined
291
357
  };
292
358
  const {
@@ -294,20 +360,29 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
294
360
  } = useTheme();
295
361
  const nativeInputStyle = selectInputStyles({ ...themeTokens,
296
362
  height
297
- }, themeOptions, inactive);
363
+ }, themeOptions, inactive, type);
298
364
  return /*#__PURE__*/_jsxs(View, {
299
365
  style: selectOuterBorderStyles(themeTokens),
300
- children: [/*#__PURE__*/_jsx(NativeTextInput, {
366
+ children: [type === 'card' && /*#__PURE__*/_jsx(View, {
367
+ pointerEvents: "none",
368
+ style: [staticStyles.leftIconContainer, selectLeftIconContainerStyles(themeTokens)],
369
+ children: getIcon(currentValue, {
370
+ defaultCreditIcon,
371
+ amexIcon,
372
+ visaIcon,
373
+ masterCardIcon
374
+ })
375
+ }), /*#__PURE__*/_jsx(NativeTextInput, {
301
376
  ref: inputRef,
302
- keyboardType: variant.numeric && 'numeric',
303
- inputMode: variant.numeric && 'numeric',
377
+ keyboardType: isNumeric && 'numeric',
378
+ inputMode: isNumeric && 'numeric',
304
379
  style: nativeInputStyle,
305
- secureTextEntry: variant.password && !showPassword,
380
+ secureTextEntry: isPassword && !showPassword,
306
381
  ...inputProps
307
382
  }), IconComponent && /*#__PURE__*/_jsx(View, {
308
383
  pointerEvents: "none" // avoid hijacking input press events
309
384
  ,
310
- style: [staticStyles.iconContainer, selectIconContainerStyles({ ...themeTokens,
385
+ style: [staticStyles.rightIconContainer, selectIconContainerStyles({ ...themeTokens,
311
386
  buttonsGapSize
312
387
  }, buttons === null || buttons === void 0 ? void 0 : buttons.length)],
313
388
  children: /*#__PURE__*/_jsx(IconComponent, { ...selectIconTokens(themeTokens)
@@ -333,6 +408,7 @@ TextInputBase.propTypes = { ...selectedSystemPropTypes,
333
408
  copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), PropTypes.shape({
334
409
  clearButtonAccessibilityLabel: PropTypes.string
335
410
  })]),
411
+ type: PropTypes.oneOfType([PropTypes.oneOf(['password', 'card', 'number'])]),
336
412
  height: PropTypes.number,
337
413
  inactive: PropTypes.bool,
338
414
  initialValue: PropTypes.string,
@@ -359,9 +435,15 @@ const staticStyles = StyleSheet.create({
359
435
  bottom: 0,
360
436
  justifyContent: 'center'
361
437
  },
362
- iconContainer: {
438
+ rightIconContainer: {
363
439
  position: 'absolute',
364
440
  right: 0,
365
441
  bottom: 0
442
+ },
443
+ leftIconContainer: {
444
+ position: 'absolute',
445
+ left: 0,
446
+ bottom: 0,
447
+ zIndex: 1
366
448
  }
367
449
  });
@@ -8,6 +8,11 @@ const textInputPropTypes = {
8
8
  */
9
9
  value: PropTypes.string,
10
10
 
11
+ /**
12
+ * Use this to set the type of the input. Defaults to `text`.
13
+ */
14
+ type: PropTypes.string,
15
+
11
16
  /**
12
17
  * Use this to set the initial value of an uncontrolled input.
13
18
  * Updating `initialValue` will **not** update the actual value.
@@ -8,6 +8,7 @@ export * from './Carousel';
8
8
  export { default as Listbox } from './Listbox';
9
9
  export { default as Checkbox } from './Checkbox';
10
10
  export * from './Checkbox';
11
+ export { default as CheckboxCard } from './CheckboxCard';
11
12
  export { default as Divider } from './Divider';
12
13
  export { default as ExpandCollapse, Accordion } from './ExpandCollapse';
13
14
  export { default as Feedback } from './Feedback';
@@ -19,6 +19,7 @@ const textProps = {
19
19
 
20
20
  const inputValueProps = {
21
21
  value: PropTypes.string,
22
+ type: PropTypes.string,
22
23
  initialValue: PropTypes.string,
23
24
  readOnly: PropTypes.bool,
24
25
  inactive: PropTypes.bool
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "@floating-ui/react-native": "^0.8.1",
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@telus-uds/system-constants": "^1.3.0",
14
- "@telus-uds/system-theme-tokens": "^2.41.1",
14
+ "@telus-uds/system-theme-tokens": "^2.43.0",
15
15
  "airbnb-prop-types": "^2.16.0",
16
16
  "lodash.debounce": "^4.0.8",
17
17
  "lodash.merge": "^4.6.2",
@@ -73,5 +73,5 @@
73
73
  "standard-engine": {
74
74
  "skip": true
75
75
  },
76
- "version": "1.64.0"
76
+ "version": "1.66.0"
77
77
  }
@@ -0,0 +1,180 @@
1
+ import React, { forwardRef } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { Platform, StyleSheet, View } from 'react-native'
4
+
5
+ import CheckboxInput from './CheckboxInput'
6
+ import { applyShadowToken, useThemeTokens } from '../ThemeProvider'
7
+ import {
8
+ a11yProps,
9
+ getTokensSetPropType,
10
+ selectSystemProps,
11
+ selectTokens,
12
+ viewProps
13
+ } from '../utils'
14
+
15
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
16
+
17
+ const selectInputStyles = (
18
+ {
19
+ iconBackgroundColor,
20
+ inputBorderColor,
21
+ inputBorderRadius,
22
+ inputBorderWidth,
23
+ inputBackgroundColor,
24
+ inputHeight,
25
+ inputOutlineColor,
26
+ inputOutlineWidth,
27
+ inputOutlineOffset,
28
+ inputShadow,
29
+ inputWidth
30
+ },
31
+ isChecked
32
+ ) => ({
33
+ borderColor: inputBorderColor,
34
+ borderWidth: inputBorderWidth,
35
+ borderRadius: inputBorderRadius,
36
+ backgroundColor: isChecked ? iconBackgroundColor : inputBackgroundColor,
37
+ height: inputHeight,
38
+ width: inputWidth,
39
+ ...applyShadowToken(inputShadow),
40
+ ...Platform.select({
41
+ web: {
42
+ outlineStyle: 'solid',
43
+ outlineColor: inputOutlineColor,
44
+ outlineWidth: inputOutlineWidth,
45
+ outlineOffset: inputOutlineOffset
46
+ }
47
+ })
48
+ })
49
+
50
+ const selectIconTokens = ({ icon, iconColor, iconSize }) => ({
51
+ icon,
52
+ color: iconColor,
53
+ size: iconSize
54
+ })
55
+
56
+ const tokenKeys = [
57
+ 'checkedBackgroundColor',
58
+ 'checkedSize',
59
+ 'inputBackgroundColor',
60
+ 'inputBorderColor',
61
+ 'inputBorderWidth',
62
+ 'inputOutlineColor',
63
+ 'inputOutlineWidth',
64
+ 'inputSize',
65
+ 'outerBorderColor',
66
+ 'outerBorderWidth',
67
+ 'outerBorderGap',
68
+ 'inputSize'
69
+ ]
70
+
71
+ export const selectCheckboxTokens = (themeTokens, prefix) =>
72
+ selectTokens(tokenKeys, themeTokens, prefix)
73
+
74
+ /**
75
+ * The visual toggle of a checkbox input. Is not interactive on its own, should be used inside
76
+ * an interactive parent that passes down props when interacted with. Used in CheckboxCard
77
+ */
78
+ const CheckboxButton = forwardRef(
79
+ (
80
+ {
81
+ isChecked,
82
+ tokens,
83
+ inactive,
84
+ defaultChecked,
85
+ inputId,
86
+ iconId,
87
+ isControlled,
88
+ handleChange,
89
+ name: inputName,
90
+ value,
91
+ ...rest
92
+ },
93
+ ref
94
+ ) => {
95
+ const { icon: IconComponent, ...stateTokens } = useThemeTokens(
96
+ 'Checkbox',
97
+ {},
98
+ { checked: isChecked }
99
+ )
100
+ const iconTokens = selectIconTokens(stateTokens)
101
+
102
+ return (
103
+ <View {...selectProps(rest)}>
104
+ <View
105
+ style={[staticStyles.defaultInputStyles, selectInputStyles(stateTokens, isChecked)]}
106
+ testID={inputId}
107
+ >
108
+ <CheckboxInput
109
+ ref={ref}
110
+ checked={isChecked}
111
+ defaultChecked={defaultChecked}
112
+ disabled={inactive}
113
+ id={inputId}
114
+ isControlled={isControlled}
115
+ onChange={handleChange}
116
+ name={inputName}
117
+ value={value}
118
+ />
119
+ {isChecked && IconComponent && (
120
+ <View testID={iconId}>
121
+ <IconComponent {...iconTokens} />
122
+ </View>
123
+ )}
124
+ </View>
125
+ </View>
126
+ )
127
+ }
128
+ )
129
+ CheckboxButton.displayName = 'CheckboxButton'
130
+
131
+ CheckboxButton.propTypes = {
132
+ ...selectedSystemPropTypes,
133
+ /**
134
+ * Use `checked` for controlled Checkbox. For uncontrolled Checkbox, use the `defaultChecked` prop.
135
+ */
136
+ isChecked: PropTypes.bool,
137
+ /**
138
+ * Checkbox tokens.
139
+ */
140
+ tokens: getTokensSetPropType(tokenKeys, { allowFunction: true }),
141
+ /**
142
+ * Whether the corresponding input is disabled or active.
143
+ */
144
+ inactive: PropTypes.bool,
145
+ /**
146
+ * Use `defaultChecked` to provide the initial value for an uncontrolled Checkbox.
147
+ */
148
+ defaultChecked: PropTypes.bool,
149
+ /**
150
+ * Checkbox input ID.
151
+ */
152
+ inputId: PropTypes.string,
153
+ /**
154
+ * Checkbox icon ID.
155
+ */
156
+ iconId: PropTypes.string,
157
+ /**
158
+ * Can control the checkbox on the card.
159
+ */
160
+ isControlled: PropTypes.bool,
161
+ /**
162
+ * Callback called when a controlled checkbox gets interacted with.
163
+ */
164
+ handleChange: PropTypes.func,
165
+ /**
166
+ * Associate this checkbox with a group (set as the name attribute).
167
+ */
168
+ name: PropTypes.string,
169
+ /**
170
+ * The value of the checkbox: true or false
171
+ */
172
+ value: PropTypes.bool
173
+ }
174
+
175
+ export default CheckboxButton
176
+
177
+ const staticStyles = StyleSheet.create({
178
+ container: { flexDirection: 'row', alignItems: 'center' },
179
+ defaultInputStyles: { alignItems: 'center', justifyContent: 'center' }
180
+ })
@@ -0,0 +1,190 @@
1
+ import React, { forwardRef } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import { StyleSheet, Text, View } from 'react-native'
4
+
5
+ import { applyTextStyles, useTheme, useThemeTokensCallback } from '../ThemeProvider'
6
+ import {
7
+ a11yProps,
8
+ focusHandlerProps,
9
+ getTokensPropType,
10
+ selectSystemProps,
11
+ selectTokens,
12
+ useInputValue,
13
+ useUniqueId,
14
+ variantProp,
15
+ viewProps
16
+ } from '../utils'
17
+ import { PressableCardBase, selectPressableCardTokens } from '../Card'
18
+ import StackView from '../StackView'
19
+ import CheckboxButton, { selectCheckboxTokens } from '../Checkbox/CheckboxButton'
20
+
21
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([
22
+ a11yProps,
23
+ focusHandlerProps,
24
+ viewProps
25
+ ])
26
+
27
+ const CheckboxCard = forwardRef(
28
+ (
29
+ {
30
+ tokens,
31
+ variant,
32
+ title,
33
+ children,
34
+ inactive,
35
+ defaultChecked,
36
+ checked,
37
+ name: inputName,
38
+ value,
39
+ id,
40
+ iconId,
41
+ onChange,
42
+ ...rest
43
+ },
44
+ ref
45
+ ) => {
46
+ const {
47
+ currentValue: isChecked,
48
+ setValue: setIsChecked,
49
+ isControlled
50
+ } = useInputValue({
51
+ value: checked,
52
+ initialValue: defaultChecked,
53
+ onChange
54
+ })
55
+
56
+ const handleChange = (event) => {
57
+ if (!inactive) {
58
+ setIsChecked(!isChecked, event)
59
+ }
60
+ }
61
+ const uniqueId = useUniqueId('CheckboxCard')
62
+ const inputId = id ?? uniqueId
63
+
64
+ const uniqueIconId = useUniqueId('CheckboxIcon')
65
+ const iconCheckboxId = iconId ?? uniqueIconId
66
+
67
+ const getTokens = useThemeTokensCallback('CheckboxCard', tokens, variant)
68
+ const getCardTokens = (cardState) => selectPressableCardTokens(getTokens(cardState))
69
+ const { themeOptions } = useTheme()
70
+
71
+ const selectedProps = selectProps({
72
+ accessibilityRole: 'checkbox',
73
+ accessibilityState: { checked: isChecked, disabled: inactive },
74
+ ...rest
75
+ })
76
+
77
+ return (
78
+ <PressableCardBase
79
+ ref={ref}
80
+ inactive={inactive}
81
+ checked={isChecked}
82
+ tokens={getCardTokens}
83
+ onPress={handleChange}
84
+ {...selectedProps}
85
+ >
86
+ {(cardState) => {
87
+ const { checkboxSpace, contentSpace, ...themeTokens } = getTokens(cardState)
88
+ const checkboxTokens = selectCheckboxTokens(themeTokens, 'checkbox')
89
+ const titleTokens = selectTokens('Typography', themeTokens)
90
+ const textStyle = applyTextStyles({ ...titleTokens, themeOptions })
91
+ return (
92
+ <StackView direction="row" space={checkboxSpace}>
93
+ <View style={[staticStyles.alignWithText, { height: textStyle.lineHeight }]}>
94
+ <CheckboxButton
95
+ tokens={checkboxTokens}
96
+ isControlled={isControlled}
97
+ isChecked={isChecked}
98
+ inactive={inactive}
99
+ defaultChecked={defaultChecked}
100
+ inputId={inputId}
101
+ iconId={iconCheckboxId}
102
+ handleChange={handleChange}
103
+ name={inputName}
104
+ value={value}
105
+ />
106
+ </View>
107
+ <StackView direction="column" space={contentSpace} tokens={{ flexShrink: 1 }}>
108
+ {title ? <Text style={textStyle}>{title}</Text> : null}
109
+ {typeof children === 'function' ? children(cardState, textStyle) : children}
110
+ </StackView>
111
+ </StackView>
112
+ )
113
+ }}
114
+ </PressableCardBase>
115
+ )
116
+ }
117
+ )
118
+ CheckboxCard.displayName = 'CheckboxCard'
119
+
120
+ CheckboxCard.propTypes = {
121
+ ...selectedSystemPropTypes,
122
+ /**
123
+ * Content to be displayed at the top of the card alongside the checkbox
124
+ */
125
+ title: PropTypes.string,
126
+ /**
127
+ * Additional content to be displayed below the checkbox.
128
+ */
129
+ children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
130
+ /**
131
+ * Use `checked` for controlled checkbox. For uncontrolled checkbox, use the `defaultChecked` prop.
132
+ */
133
+ checked: PropTypes.bool,
134
+ /**
135
+ * Use `defaultChecked` to provide the initial value for an uncontrolled checkbox.
136
+ */
137
+ defaultChecked: PropTypes.bool,
138
+ /**
139
+ * An optional checkboxdescription.
140
+ */
141
+ description: PropTypes.string,
142
+ /**
143
+ * Checkbox card ID.
144
+ */
145
+ id: PropTypes.string,
146
+ /**
147
+ * Checkbox icon ID.
148
+ */
149
+ iconId: PropTypes.string,
150
+ /**
151
+ * Whether the corresponding input is disabled or active.
152
+ */
153
+ inactive: PropTypes.bool,
154
+ /**
155
+ * The label.
156
+ */
157
+ label: PropTypes.string,
158
+ /**
159
+ * Associate this checkbox card with a group (set as the name attribute).
160
+ */
161
+ name: PropTypes.string,
162
+ /**
163
+ * Whether the underlying input triggered a validation error or not.
164
+ */
165
+ error: PropTypes.bool,
166
+ /**
167
+ * The value. Must be unique within the group.
168
+ */
169
+ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]),
170
+ /**
171
+ * Callback called when a controlled checkbox card gets interacted with.
172
+ */
173
+ onChange: PropTypes.func,
174
+ /**
175
+ * checkbox card tokens.
176
+ */
177
+ tokens: getTokensPropType('CheckboxCard'),
178
+ /**
179
+ * checkbox variant.
180
+ */
181
+ variant: variantProp.propType
182
+ }
183
+
184
+ export default CheckboxCard
185
+
186
+ const staticStyles = StyleSheet.create({
187
+ alignWithText: {
188
+ justifyContent: 'center'
189
+ }
190
+ })
@@ -0,0 +1,3 @@
1
+ import CheckboxCard from './CheckboxCard'
2
+
3
+ export default CheckboxCard
@@ -89,9 +89,10 @@ const StackView = forwardRef(
89
89
  const content = getStackedContent(children, { direction, divider, space })
90
90
  const themeTokens = useThemeTokens('StackView', tokens, variant, { viewport })
91
91
  const flexStyles = selectFlexStyles(themeTokens)
92
+ const size = { width: themeTokens.width }
92
93
 
93
94
  return (
94
- <View ref={ref} {...selectedProps} style={[flexStyles, staticStyles[direction]]}>
95
+ <View ref={ref} {...selectedProps} style={[flexStyles, staticStyles[direction], size]}>
95
96
  {content}
96
97
  </View>
97
98
  )