@coinbase/cds-mobile 8.62.1 → 8.66.1

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 (43) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dts/cells/Cell.d.ts.map +1 -1
  3. package/dts/overlays/modal/ModalHeader.d.ts +1 -1
  4. package/dts/overlays/modal/ModalHeader.d.ts.map +1 -1
  5. package/dts/stepper/Stepper.d.ts.map +1 -1
  6. package/dts/tabs/DefaultTab.d.ts +50 -0
  7. package/dts/tabs/DefaultTab.d.ts.map +1 -0
  8. package/dts/tabs/DefaultTabsActiveIndicator.d.ts +11 -0
  9. package/dts/tabs/DefaultTabsActiveIndicator.d.ts.map +1 -0
  10. package/dts/tabs/TabIndicator.d.ts +2 -0
  11. package/dts/tabs/TabIndicator.d.ts.map +1 -1
  12. package/dts/tabs/TabLabel.d.ts +2 -0
  13. package/dts/tabs/TabLabel.d.ts.map +1 -1
  14. package/dts/tabs/TabNavigation.d.ts +16 -0
  15. package/dts/tabs/TabNavigation.d.ts.map +1 -1
  16. package/dts/tabs/Tabs.d.ts +26 -11
  17. package/dts/tabs/Tabs.d.ts.map +1 -1
  18. package/dts/tabs/index.d.ts +2 -0
  19. package/dts/tabs/index.d.ts.map +1 -1
  20. package/dts/tour/DefaultTourStepArrow.d.ts +1 -1
  21. package/dts/tour/DefaultTourStepArrow.d.ts.map +1 -1
  22. package/dts/tour/Tour.d.ts +28 -2
  23. package/dts/tour/Tour.d.ts.map +1 -1
  24. package/dts/tour/TourStep.d.ts +3 -0
  25. package/dts/tour/TourStep.d.ts.map +1 -1
  26. package/esm/cells/Cell.js +2 -1
  27. package/esm/cells/__stories__/ListCell.stories.js +2 -0
  28. package/esm/icons/__figma__/Icon.figma.js +1771 -868
  29. package/esm/overlays/__stories__/ModalCustomHeader.stories.js +86 -0
  30. package/esm/overlays/modal/ModalHeader.js +13 -4
  31. package/esm/stepper/Stepper.js +4 -3
  32. package/esm/tabs/DefaultTab.js +75 -0
  33. package/esm/tabs/DefaultTabsActiveIndicator.js +58 -0
  34. package/esm/tabs/TabIndicator.js +2 -0
  35. package/esm/tabs/TabLabel.js +2 -0
  36. package/esm/tabs/TabNavigation.js +20 -0
  37. package/esm/tabs/Tabs.js +17 -13
  38. package/esm/tabs/__stories__/Tabs.stories.js +165 -64
  39. package/esm/tabs/index.js +2 -0
  40. package/esm/tour/DefaultTourStepArrow.js +1 -2
  41. package/esm/tour/Tour.js +23 -7
  42. package/esm/tour/TourStep.js +11 -6
  43. package/package.json +4 -6
@@ -0,0 +1,86 @@
1
+ import React, { useCallback, useState } from 'react';
2
+ import { Button } from '../../buttons/Button';
3
+ import { Example, ExampleScreen } from '../../examples/ExampleScreen';
4
+ import { LoremIpsum } from '../../layout/__stories__/LoremIpsum';
5
+ import { HStack } from '../../layout/HStack';
6
+ import { Text } from '../../typography/Text';
7
+ import { Modal } from '../modal/Modal';
8
+ import { ModalBody } from '../modal/ModalBody';
9
+ import { ModalFooter } from '../modal/ModalFooter';
10
+ import { ModalHeader } from '../modal/ModalHeader';
11
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
+ export default function ModalCustomHeaderScreen() {
13
+ const [customFontVisible, setCustomFontVisible] = useState(false);
14
+ const handleCustomFontClose = useCallback(() => setCustomFontVisible(false), []);
15
+ const handleCustomFontOpen = useCallback(() => setCustomFontVisible(true), []);
16
+ const [reactNodeVisible, setReactNodeVisible] = useState(false);
17
+ const handleReactNodeClose = useCallback(() => setReactNodeVisible(false), []);
18
+ const handleReactNodeOpen = useCallback(() => setReactNodeVisible(true), []);
19
+ return /*#__PURE__*/_jsxs(ExampleScreen, {
20
+ children: [/*#__PURE__*/_jsxs(Example, {
21
+ title: "Custom Font Title",
22
+ children: [/*#__PURE__*/_jsx(Button, {
23
+ onPress: handleCustomFontOpen,
24
+ children: "Open"
25
+ }), /*#__PURE__*/_jsxs(Modal, {
26
+ onRequestClose: handleCustomFontClose,
27
+ visible: customFontVisible,
28
+ children: [/*#__PURE__*/_jsx(ModalHeader, {
29
+ closeAccessibilityLabel: "Close",
30
+ font: "title1",
31
+ fontSize: "display3",
32
+ title: "Large Title Modal"
33
+ }), /*#__PURE__*/_jsx(ModalBody, {
34
+ children: /*#__PURE__*/_jsx(LoremIpsum, {})
35
+ }), /*#__PURE__*/_jsx(ModalFooter, {
36
+ primaryAction: /*#__PURE__*/_jsx(Button, {
37
+ onPress: handleCustomFontClose,
38
+ children: "Save"
39
+ }),
40
+ secondaryAction: /*#__PURE__*/_jsx(Button, {
41
+ onPress: handleCustomFontClose,
42
+ variant: "secondary",
43
+ children: "Cancel"
44
+ })
45
+ })]
46
+ })]
47
+ }), /*#__PURE__*/_jsxs(Example, {
48
+ title: "ReactNode Title",
49
+ children: [/*#__PURE__*/_jsx(Button, {
50
+ onPress: handleReactNodeOpen,
51
+ children: "Open"
52
+ }), /*#__PURE__*/_jsxs(Modal, {
53
+ onRequestClose: handleReactNodeClose,
54
+ visible: reactNodeVisible,
55
+ children: [/*#__PURE__*/_jsx(ModalHeader, {
56
+ closeAccessibilityLabel: "Close",
57
+ title: /*#__PURE__*/_jsxs(HStack, {
58
+ alignItems: "center",
59
+ gap: 0.5,
60
+ justifyContent: "center",
61
+ children: [/*#__PURE__*/_jsx(Text, {
62
+ font: "title2",
63
+ children: "Custom Title"
64
+ }), /*#__PURE__*/_jsx(Text, {
65
+ color: "fgMuted",
66
+ font: "caption",
67
+ children: "with subtitle"
68
+ })]
69
+ })
70
+ }), /*#__PURE__*/_jsx(ModalBody, {
71
+ children: /*#__PURE__*/_jsx(LoremIpsum, {})
72
+ }), /*#__PURE__*/_jsx(ModalFooter, {
73
+ primaryAction: /*#__PURE__*/_jsx(Button, {
74
+ onPress: handleReactNodeClose,
75
+ children: "Save"
76
+ }),
77
+ secondaryAction: /*#__PURE__*/_jsx(Button, {
78
+ onPress: handleReactNodeClose,
79
+ variant: "secondary",
80
+ children: "Cancel"
81
+ })
82
+ })]
83
+ })]
84
+ })]
85
+ });
86
+ }
@@ -1,4 +1,4 @@
1
- const _excluded = ["alignItems", "paddingX", "paddingY", "title", "onBackButtonClick", "backAccessibilityLabel", "backAccessibilityHint", "closeAccessibilityLabel", "closeAccessibilityHint"];
1
+ const _excluded = ["alignItems", "paddingX", "paddingY", "font", "fontFamily", "fontSize", "fontWeight", "lineHeight", "title", "onBackButtonClick", "backAccessibilityLabel", "backAccessibilityHint", "closeAccessibilityLabel", "closeAccessibilityHint"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
4
  import React from 'react';
@@ -15,6 +15,11 @@ export const ModalHeader = _props => {
15
15
  alignItems = 'center',
16
16
  paddingX = 3,
17
17
  paddingY = 2,
18
+ font = 'headline',
19
+ fontFamily,
20
+ fontSize,
21
+ fontWeight,
22
+ lineHeight,
18
23
  title,
19
24
  onBackButtonClick,
20
25
  backAccessibilityLabel,
@@ -50,11 +55,15 @@ export const ModalHeader = _props => {
50
55
  flexBasis: 0,
51
56
  flexGrow: 6,
52
57
  justifyContent: "center",
53
- children: title && /*#__PURE__*/_jsx(Text, {
58
+ children: title && (typeof title === 'string' ? /*#__PURE__*/_jsx(Text, {
54
59
  align: "center",
55
- font: "headline",
60
+ font: font,
61
+ fontFamily: fontFamily,
62
+ fontSize: fontSize,
63
+ fontWeight: fontWeight,
64
+ lineHeight: lineHeight,
56
65
  children: title
57
- })
66
+ }) : title)
58
67
  }), /*#__PURE__*/_jsx(Box, {
59
68
  alignItems: "flex-end",
60
69
  flexBasis: 0,
@@ -109,9 +109,10 @@ const StepperBase = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_props, ref) => {
109
109
  const previousComplete = (_usePreviousValue = usePreviousValue(complete)) != null ? _usePreviousValue : false;
110
110
  const previousActiveStepIndex = (_usePreviousValue2 = usePreviousValue(activeStepIndex)) != null ? _usePreviousValue2 : -1;
111
111
  const [progressSprings, progressSpringsApi] = useSprings(steps.length, index => ({
112
- progress: complete ? 1 : 0,
113
- config: progressSpringConfig,
114
- immediate: !animate || disableAnimateOnMount && !hasMounted
112
+ from: {
113
+ progress: complete ? 1 : 0
114
+ },
115
+ config: progressSpringConfig
115
116
  }));
116
117
  useEffect(() => {
117
118
  // update the previous values for next render
@@ -0,0 +1,75 @@
1
+ const _excluded = ["id", "label", "disabled", "onPress", "count", "max", "accessibilityLabel", "style", "testID"];
2
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
+ import React, { forwardRef, memo, useCallback, useMemo } from 'react';
5
+ import { Pressable } from 'react-native';
6
+ import { useTabsContext } from '@coinbase/cds-common/tabs/TabsContext';
7
+ import { accessibleOpacityDisabled } from '@coinbase/cds-common/tokens/interactable';
8
+ import { DotCount } from '../dots/DotCount';
9
+ import { useTheme } from '../hooks/useTheme';
10
+ import { HStack } from '../layout';
11
+ import { Text } from '../typography/Text';
12
+
13
+ /** Optional dot count and a11y overrides for the default tab row. */
14
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
+ const DefaultTabComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
16
+ let {
17
+ id,
18
+ label,
19
+ disabled: disabledProp,
20
+ onPress,
21
+ count,
22
+ max,
23
+ accessibilityLabel,
24
+ style,
25
+ testID
26
+ } = _ref,
27
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
28
+ const theme = useTheme();
29
+ const {
30
+ activeTab,
31
+ updateActiveTab,
32
+ disabled: allTabsDisabled
33
+ } = useTabsContext();
34
+ const isActive = (activeTab == null ? void 0 : activeTab.id) === id;
35
+ const isDisabled = disabledProp || allTabsDisabled;
36
+ const handlePress = useCallback(event => {
37
+ updateActiveTab(id);
38
+ onPress == null || onPress(id, event);
39
+ }, [id, onPress, updateActiveTab]);
40
+ const labelPaddingStyle = useMemo(() => ({
41
+ paddingTop: theme.space[2],
42
+ paddingBottom: theme.space[2] - 2
43
+ }), [theme.space]);
44
+ return /*#__PURE__*/_jsx(Pressable, _extends({
45
+ ref: ref,
46
+ accessibilityLabel: accessibilityLabel,
47
+ accessibilityRole: "tab",
48
+ accessibilityState: {
49
+ disabled: isDisabled,
50
+ selected: isActive
51
+ },
52
+ disabled: isDisabled,
53
+ onPress: handlePress,
54
+ style: [disabledProp && !allTabsDisabled ? {
55
+ opacity: accessibleOpacityDisabled
56
+ } : undefined, style],
57
+ testID: testID
58
+ }, props, {
59
+ children: /*#__PURE__*/_jsxs(HStack, {
60
+ alignItems: "center",
61
+ gap: 0.5,
62
+ children: [/*#__PURE__*/_jsx(Text, {
63
+ color: isActive ? 'fgPrimary' : 'fg',
64
+ font: "headline",
65
+ style: labelPaddingStyle,
66
+ children: label
67
+ }), !!count && /*#__PURE__*/_jsx(DotCount, {
68
+ count: count,
69
+ max: max
70
+ })]
71
+ })
72
+ }));
73
+ }));
74
+ DefaultTabComponent.displayName = 'DefaultTab';
75
+ export const DefaultTab = DefaultTabComponent;
@@ -0,0 +1,58 @@
1
+ const _excluded = ["activeTabRect", "background", "style", "testID"];
2
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
+ import { memo, useEffect } from 'react';
5
+ import Animated, { useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
6
+ import { Box } from '../layout';
7
+ import { tabsSpringConfig } from './Tabs';
8
+
9
+ /**
10
+ * Default underline-style indicator for mobile `Tabs`. Pass as
11
+ * `TabsActiveIndicatorComponent={DefaultTabsActiveIndicator}` with `TabComponent={DefaultTab}`.
12
+ */
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ const AnimatedBox = Animated.createAnimatedComponent(Box);
15
+ export const DefaultTabsActiveIndicator = /*#__PURE__*/memo(_ref => {
16
+ let {
17
+ activeTabRect,
18
+ background = 'bgPrimary',
19
+ style,
20
+ testID
21
+ } = _ref,
22
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
23
+ const {
24
+ width,
25
+ x
26
+ } = activeTabRect;
27
+ const rect = useSharedValue({
28
+ width,
29
+ x
30
+ });
31
+ useEffect(() => {
32
+ if (!width) return;
33
+ rect.value = withSpring({
34
+ x,
35
+ width
36
+ }, tabsSpringConfig);
37
+ }, [rect, width, x]);
38
+ const animatedBoxStyle = useAnimatedStyle(() => ({
39
+ transform: [{
40
+ translateX: rect.value.x
41
+ }],
42
+ width: rect.value.width
43
+ }), []);
44
+ if (!width) return null;
45
+ return /*#__PURE__*/_jsx(AnimatedBox, _extends({
46
+ animated: true,
47
+ background: background,
48
+ bottom: 0,
49
+ height: 2,
50
+ left: 0,
51
+ pointerEvents: "none",
52
+ position: "absolute",
53
+ style: [animatedBoxStyle, style],
54
+ testID: testID,
55
+ zIndex: 0
56
+ }, props));
57
+ });
58
+ DefaultTabsActiveIndicator.displayName = 'DefaultTabsActiveIndicator';
@@ -6,6 +6,8 @@ import { Animated } from 'react-native';
6
6
  import { Box } from '../layout';
7
7
  import { useTabIndicatorStyles } from './hooks/useTabIndicatorStyles';
8
8
  import { jsx as _jsx } from "react/jsx-runtime";
9
+ /** @deprecated Use DefaultTabsActiveIndicator instead. This will be removed in a future major release. */
10
+ /** @deprecationExpectedRemoval v10 */
9
11
  export const TabIndicator = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, forwardedRef) => {
10
12
  let {
11
13
  width,
@@ -19,6 +19,8 @@ const COLORS = {
19
19
  inactive: 'fgMuted'
20
20
  }
21
21
  };
22
+ /** @deprecated Use DefaultTab instead. This will be removed in a future major release. */
23
+ /** @deprecationExpectedRemoval v10 */
22
24
  export const TabLabel = /*#__PURE__*/memo(_ref => {
23
25
  let {
24
26
  active,
@@ -12,6 +12,26 @@ import { VStack } from '../layout/VStack';
12
12
  import { Pressable } from '../system/Pressable';
13
13
  import { TabIndicator } from './TabIndicator';
14
14
  import { TabLabel } from './TabLabel';
15
+
16
+ /**
17
+ * @deprecated Use Tabs instead. This will be removed in a future major release.
18
+ * @deprecationExpectedRemoval v10
19
+ */
20
+
21
+ /**
22
+ * @deprecated Use Tabs instead. This will be removed in a future major release.
23
+ * @deprecationExpectedRemoval v10
24
+ */
25
+
26
+ /**
27
+ * @deprecated Use Tabs instead. This will be removed in a future major release.
28
+ * @deprecationExpectedRemoval v10
29
+ */
30
+
31
+ /**
32
+ * @deprecated Use Tabs instead. This will be removed in a future major release.
33
+ * @deprecationExpectedRemoval v10
34
+ */
15
35
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
36
  const TabNavigationComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, forwardedRef) => {
17
37
  let {
package/esm/tabs/Tabs.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const _excluded = ["id", "registerRef"],
2
- _excluded2 = ["tabs", "TabComponent", "TabsActiveIndicatorComponent", "activeBackground", "activeTab", "disabled", "onChange", "styles", "style", "role", "position", "alignSelf", "opacity", "onActiveTabElementChange", "borderRadius", "borderTopLeftRadius", "borderTopRightRadius", "borderBottomLeftRadius", "borderBottomRightRadius"],
3
- _excluded3 = ["id", "Component", "disabled"],
4
- _excluded4 = ["activeTabRect", "position", "style"];
2
+ _excluded2 = ["tabs", "TabComponent", "TabsActiveIndicatorComponent", "activeBackground", "activeTab", "disabled", "onChange", "styles", "style", "role", "position", "alignSelf", "opacity", "onActiveTabElementChange", "borderRadius", "borderTopLeftRadius", "borderTopRightRadius", "borderBottomLeftRadius", "borderBottomRightRadius", "testID"],
3
+ _excluded3 = ["id", "Component"],
4
+ _excluded4 = ["activeTabRect", "position", "style", "testID"];
5
5
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
6
6
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
7
7
  import React, { forwardRef, memo, useCallback, useImperativeHandle, useRef, useState } from 'react';
@@ -14,6 +14,8 @@ import { accessibleOpacityDisabled } from '@coinbase/cds-common/tokens/interacta
14
14
  import { defaultRect } from '@coinbase/cds-common/types/Rect';
15
15
  import { useComponentConfig } from '../hooks/useComponentConfig';
16
16
  import { Box, HStack } from '../layout';
17
+ import { DefaultTab } from './DefaultTab';
18
+ import { DefaultTabsActiveIndicator } from './DefaultTabsActiveIndicator';
17
19
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
20
  const AnimatedBox = Animated.createAnimatedComponent(Box);
19
21
  const TabContainer = _ref => {
@@ -37,8 +39,8 @@ const TabsComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_props, ref) =>
37
39
  const mergedProps = useComponentConfig('Tabs', _props);
38
40
  const {
39
41
  tabs,
40
- TabComponent,
41
- TabsActiveIndicatorComponent,
42
+ TabComponent = DefaultTab,
43
+ TabsActiveIndicatorComponent = DefaultTabsActiveIndicator,
42
44
  activeBackground,
43
45
  activeTab,
44
46
  disabled,
@@ -54,7 +56,8 @@ const TabsComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_props, ref) =>
54
56
  borderTopLeftRadius,
55
57
  borderTopRightRadius,
56
58
  borderBottomLeftRadius,
57
- borderBottomRightRadius
59
+ borderBottomRightRadius,
60
+ testID
58
61
  } = mergedProps,
59
62
  props = _objectWithoutPropertiesLoose(mergedProps, _excluded2);
60
63
  const tabsContainerRef = useRef(null);
@@ -101,7 +104,8 @@ const TabsComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_props, ref) =>
101
104
  opacity: opacity != null ? opacity : disabled ? accessibleOpacityDisabled : 1,
102
105
  position: position,
103
106
  role: role,
104
- style: styles != null && styles.root ? [style, styles.root] : style
107
+ style: styles != null && styles.root ? [style, styles.root] : style,
108
+ testID: testID
105
109
  }, props, {
106
110
  children: /*#__PURE__*/_jsxs(TabsContext.Provider, {
107
111
  value: api,
@@ -113,12 +117,12 @@ const TabsComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_props, ref) =>
113
117
  borderRadius: borderRadius,
114
118
  borderTopLeftRadius: borderTopLeftRadius,
115
119
  borderTopRightRadius: borderTopRightRadius,
116
- style: styles == null ? void 0 : styles.activeIndicator
120
+ style: styles == null ? void 0 : styles.activeIndicator,
121
+ testID: testID ? testID + "-active-indicator" : undefined
117
122
  }), tabs.map(_ref2 => {
118
123
  let {
119
124
  id,
120
- Component: CustomTabComponent,
121
- disabled: tabDisabled
125
+ Component: CustomTabComponent
122
126
  } = _ref2,
123
127
  props = _objectWithoutPropertiesLoose(_ref2, _excluded3);
124
128
  const RenderedTab = CustomTabComponent != null ? CustomTabComponent : TabComponent;
@@ -126,7 +130,6 @@ const TabsComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_props, ref) =>
126
130
  id: id,
127
131
  registerRef: registerRef,
128
132
  children: /*#__PURE__*/_jsx(RenderedTab, _extends({
129
- disabled: tabDisabled,
130
133
  id: id,
131
134
  style: styles == null ? void 0 : styles.tab
132
135
  }, props))
@@ -141,7 +144,8 @@ export const TabsActiveIndicator = _ref3 => {
141
144
  let {
142
145
  activeTabRect,
143
146
  position = 'absolute',
144
- style
147
+ style,
148
+ testID = 'tabs-active-indicator'
145
149
  } = _ref3,
146
150
  props = _objectWithoutPropertiesLoose(_ref3, _excluded4);
147
151
  const previousActiveTabRect = useRef(activeTabRect);
@@ -170,6 +174,6 @@ export const TabsActiveIndicator = _ref3 => {
170
174
  position: position,
171
175
  role: "none",
172
176
  style: [animatedBoxStyle, style],
173
- testID: "tabs-active-indicator"
177
+ testID: testID
174
178
  }, props));
175
179
  };
@@ -1,79 +1,180 @@
1
- import React, { useState } from 'react';
1
+ const _excluded = ["title", "defaultActiveTab", "TabComponent", "TabsActiveIndicatorComponent"];
2
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
3
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
+ import { useCallback, useState } from 'react';
5
+ import { sampleTabs } from '@coinbase/cds-common/internal/data/tabs';
2
6
  import { gutter } from '@coinbase/cds-common/tokens/sizing';
7
+ import { zIndex } from '@coinbase/cds-common/tokens/zIndex';
3
8
  import { Example, ExampleScreen } from '../../examples/ExampleScreen';
4
- import { VStack } from '../../layout/VStack';
9
+ import { VStack } from '../../layout';
10
+ import { ThemeProvider } from '../../system/ThemeProvider';
11
+ import { defaultTheme } from '../../themes/defaultTheme';
5
12
  import { Text } from '../../typography/Text';
6
- import { TabNavigation } from '../TabNavigation';
13
+ import { DefaultTab } from '../DefaultTab';
14
+ import { DefaultTabsActiveIndicator } from '../DefaultTabsActiveIndicator';
15
+ import { Tabs, TabsActiveIndicator } from '../Tabs';
7
16
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
- const tabs = [{
9
- id: 'first_item',
10
- label: 'First item',
11
- onPress: console.warn
17
+ const basicTabs = [{
18
+ id: 'buy',
19
+ label: 'Buy',
20
+ testID: 'buy-tab'
12
21
  }, {
13
- id: 'second_item',
14
- label: 'Second item'
22
+ id: 'sell',
23
+ label: 'Sell',
24
+ testID: 'sell-tab'
15
25
  }, {
16
- id: 'third_item',
17
- label: 'Third item',
18
- onPress: console.warn
26
+ id: 'convert',
27
+ label: 'Convert',
28
+ testID: 'convert-tab'
29
+ }];
30
+ const longTabs = sampleTabs.slice(0, 9);
31
+ const tabsWithDisabled = [{
32
+ id: 'buy',
33
+ label: 'Buy'
19
34
  }, {
20
- id: 'fourth_item',
21
- label: 'Fourth item'
35
+ id: 'sell',
36
+ label: 'Sell',
37
+ disabled: true
22
38
  }, {
23
- id: 'fifth_item',
24
- label: 'Fifth item'
39
+ id: 'convert',
40
+ label: 'Convert'
25
41
  }];
26
-
27
- // TODO update once _Tabs_ component is complete
28
- const TabScreen = () => {
29
- const [activeTabOne, setActiveTabOne] = useState(tabs[0].id);
30
- return /*#__PURE__*/_jsxs(ExampleScreen, {
31
- children: [/*#__PURE__*/_jsxs(Example, {
32
- overflow: "visible",
33
- padding: gutter,
34
- title: "Tab System",
35
- children: [/*#__PURE__*/_jsx(TabNavigation, {
36
- onChange: setActiveTabOne,
37
- tabs: tabs,
38
- value: activeTabOne
39
- }), /*#__PURE__*/_jsxs(VStack, {
40
- alignItems: "center",
42
+ const typedTabs = [{
43
+ id: 'buy',
44
+ label: 'Buy'
45
+ }, {
46
+ id: 'sell',
47
+ label: 'Sell'
48
+ }, {
49
+ id: 'convert',
50
+ label: 'Convert'
51
+ }];
52
+ const tabsWithDotCounts = basicTabs.map((tab, index) => index === 0 ? _extends({}, tab, {
53
+ count: 3,
54
+ max: 99
55
+ }) : tab);
56
+ const CustomSpringIndicator = props => /*#__PURE__*/_jsx(TabsActiveIndicator, _extends({}, props, {
57
+ background: "bgOverlay"
58
+ }));
59
+ const TabsExample = _ref => {
60
+ let {
61
+ title,
62
+ defaultActiveTab,
63
+ TabComponent = DefaultTab,
64
+ TabsActiveIndicatorComponent = DefaultTabsActiveIndicator
65
+ } = _ref,
66
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
67
+ const [activeTab, setActiveTab] = useState(defaultActiveTab);
68
+ const handleChange = useCallback(next => setActiveTab(next), []);
69
+ return /*#__PURE__*/_jsx(Example, {
70
+ overflow: "visible",
71
+ padding: gutter,
72
+ title: title,
73
+ children: /*#__PURE__*/_jsx(Tabs, _extends({
74
+ TabComponent: TabComponent,
75
+ TabsActiveIndicatorComponent: TabsActiveIndicatorComponent,
76
+ accessibilityLabel: "Example tabs",
77
+ activeBackground: "bgPrimary",
78
+ activeTab: activeTab,
79
+ background: "bg",
80
+ gap: 4,
81
+ onChange: handleChange,
82
+ zIndex: zIndex.navigation
83
+ }, props))
84
+ });
85
+ };
86
+ const panelTabs = sampleTabs.slice(0, 3);
87
+ const TabsWithPanelsExample = () => {
88
+ const [activeTab, setActiveTab] = useState(panelTabs[0]);
89
+ return /*#__PURE__*/_jsx(Example, {
90
+ overflow: "visible",
91
+ padding: gutter,
92
+ title: "With content panels",
93
+ children: /*#__PURE__*/_jsxs(VStack, {
94
+ gap: 3,
95
+ children: [/*#__PURE__*/_jsx(Text, {
96
+ font: "body",
97
+ children: "Pair tab buttons with content regions that follow the active tab (see panel below)."
98
+ }), /*#__PURE__*/_jsx(Tabs, {
99
+ TabComponent: DefaultTab,
100
+ TabsActiveIndicatorComponent: DefaultTabsActiveIndicator,
101
+ accessibilityLabel: "Content sections",
102
+ activeBackground: "bg",
103
+ activeTab: activeTab,
104
+ background: "bgPrimary",
105
+ gap: 4,
106
+ onChange: setActiveTab,
107
+ tabs: panelTabs,
108
+ zIndex: zIndex.navigation
109
+ }), panelTabs.map(tab => (activeTab == null ? void 0 : activeTab.id) === tab.id ? /*#__PURE__*/_jsxs(VStack, {
110
+ accessibilityLabel: tab.label + " panel",
41
111
  background: "bgAlternate",
42
- justifyContent: "center",
43
- paddingY: 6,
44
- children: [/*#__PURE__*/_jsx(Text, {
45
- font: "label1",
46
- children: "Static preview"
47
- }), /*#__PURE__*/_jsx(Text, {
48
- color: "fgPrimary",
112
+ gap: 1,
113
+ padding: 3,
114
+ children: [/*#__PURE__*/_jsxs(Text, {
49
115
  font: "title2",
50
- children: activeTabOne
51
- })]
52
- })]
53
- }), /*#__PURE__*/_jsxs(Example, {
54
- overflow: "visible",
55
- padding: gutter,
56
- title: "Tab System (Secondary)",
57
- children: [/*#__PURE__*/_jsx(TabNavigation, {
58
- onChange: setActiveTabOne,
59
- tabs: tabs,
60
- value: activeTabOne,
61
- variant: "secondary"
62
- }), /*#__PURE__*/_jsxs(VStack, {
63
- alignItems: "center",
64
- background: "bgAlternate",
65
- justifyContent: "center",
66
- paddingY: 6,
67
- children: [/*#__PURE__*/_jsx(Text, {
68
- font: "label1",
69
- children: "Static preview"
116
+ children: ["Panel: ", tab.label]
70
117
  }), /*#__PURE__*/_jsx(Text, {
71
- color: "fgPrimary",
72
- font: "title2",
73
- children: activeTabOne
118
+ font: "body",
119
+ children: "Content for this tab."
74
120
  })]
75
- })]
76
- })]
121
+ }, tab.id) : null)]
122
+ })
77
123
  });
78
124
  };
79
- export default TabScreen;
125
+ const DefaultTabsScreen = () => /*#__PURE__*/_jsxs(ExampleScreen, {
126
+ children: [/*#__PURE__*/_jsx(TabsExample, {
127
+ defaultActiveTab: basicTabs[0],
128
+ tabs: basicTabs,
129
+ title: "DefaultTab + DefaultTabIndicator"
130
+ }), /*#__PURE__*/_jsx(ThemeProvider, {
131
+ activeColorScheme: "dark",
132
+ theme: defaultTheme,
133
+ children: /*#__PURE__*/_jsx(TabsExample, {
134
+ defaultActiveTab: basicTabs[0],
135
+ tabs: basicTabs,
136
+ title: "Dark"
137
+ })
138
+ }), /*#__PURE__*/_jsx(TabsExample, {
139
+ background: "bgAlternate",
140
+ defaultActiveTab: basicTabs[0],
141
+ tabs: basicTabs,
142
+ title: "Alternate background"
143
+ }), /*#__PURE__*/_jsx(TabsExample, {
144
+ defaultActiveTab: basicTabs.slice(0, 2)[0],
145
+ tabs: basicTabs.slice(0, 2),
146
+ title: "Two tabs"
147
+ }), /*#__PURE__*/_jsx(TabsExample, {
148
+ defaultActiveTab: basicTabs[1],
149
+ tabs: basicTabs,
150
+ title: "Initial second tab"
151
+ }), /*#__PURE__*/_jsx(TabsExample, {
152
+ defaultActiveTab: null,
153
+ tabs: basicTabs,
154
+ title: "No initial active tab"
155
+ }), /*#__PURE__*/_jsx(TabsExample, {
156
+ defaultActiveTab: typedTabs[0],
157
+ tabs: typedTabs,
158
+ title: "Typed tab ids"
159
+ }), /*#__PURE__*/_jsx(TabsExample, {
160
+ disabled: true,
161
+ defaultActiveTab: basicTabs[0],
162
+ tabs: basicTabs,
163
+ title: "All tabs disabled"
164
+ }), /*#__PURE__*/_jsx(TabsExample, {
165
+ defaultActiveTab: tabsWithDisabled[0],
166
+ tabs: tabsWithDisabled,
167
+ title: "One tab disabled"
168
+ }), /*#__PURE__*/_jsx(TabsExample, {
169
+ defaultActiveTab: tabsWithDotCounts[0],
170
+ tabs: tabsWithDotCounts,
171
+ title: "Dot counts (DefaultTab)"
172
+ }), /*#__PURE__*/_jsx(TabsExample, {
173
+ TabComponent: DefaultTab,
174
+ TabsActiveIndicatorComponent: CustomSpringIndicator,
175
+ defaultActiveTab: basicTabs[0],
176
+ tabs: basicTabs,
177
+ title: "TabsActiveIndicator (spring) instead of DefaultTabIndicator"
178
+ }), /*#__PURE__*/_jsx(TabsWithPanelsExample, {})]
179
+ });
180
+ export default DefaultTabsScreen;
package/esm/tabs/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ export * from './DefaultTab';
2
+ export * from './DefaultTabsActiveIndicator';
1
3
  export * from './SegmentedTabs';
2
4
  export * from './TabIndicator';
3
5
  export * from './TabLabel';