@coinbase/cds-mobile 9.13.0 → 9.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dts/accordion/Accordion.d.ts +11 -1
  3. package/dts/accordion/Accordion.d.ts.map +1 -1
  4. package/dts/accordion/AccordionHeader.d.ts +33 -5
  5. package/dts/accordion/AccordionHeader.d.ts.map +1 -1
  6. package/dts/accordion/AccordionItem.d.ts +25 -17
  7. package/dts/accordion/AccordionItem.d.ts.map +1 -1
  8. package/dts/accordion/AccordionPanel.d.ts +6 -2
  9. package/dts/accordion/AccordionPanel.d.ts.map +1 -1
  10. package/dts/collapsible/Collapsible.d.ts +5 -2
  11. package/dts/collapsible/Collapsible.d.ts.map +1 -1
  12. package/dts/controls/Switch.d.ts +10 -1
  13. package/dts/controls/Switch.d.ts.map +1 -1
  14. package/dts/core/componentConfig.d.ts +2 -0
  15. package/dts/core/componentConfig.d.ts.map +1 -1
  16. package/dts/tabs/SegmentedTabs.d.ts +10 -2
  17. package/dts/tabs/SegmentedTabs.d.ts.map +1 -1
  18. package/dts/visualizations/chart/axis/Axis.d.ts +12 -0
  19. package/dts/visualizations/chart/axis/Axis.d.ts.map +1 -1
  20. package/dts/visualizations/chart/axis/AxisTickLabelOverflowMask.d.ts +11 -0
  21. package/dts/visualizations/chart/axis/AxisTickLabelOverflowMask.d.ts.map +1 -0
  22. package/dts/visualizations/chart/axis/XAxis.d.ts.map +1 -1
  23. package/dts/visualizations/chart/axis/YAxis.d.ts.map +1 -1
  24. package/dts/visualizations/chart/axis/index.d.ts +1 -0
  25. package/dts/visualizations/chart/axis/index.d.ts.map +1 -1
  26. package/dts/visualizations/chart/line/ReferenceLine.d.ts +1 -0
  27. package/dts/visualizations/chart/line/ReferenceLine.d.ts.map +1 -1
  28. package/dts/visualizations/chart/text/ChartText.d.ts +20 -3
  29. package/dts/visualizations/chart/text/ChartText.d.ts.map +1 -1
  30. package/esm/accordion/Accordion.js +6 -2
  31. package/esm/accordion/AccordionHeader.js +49 -15
  32. package/esm/accordion/AccordionItem.js +40 -6
  33. package/esm/accordion/AccordionPanel.js +3 -1
  34. package/esm/collapsible/Collapsible.js +4 -2
  35. package/esm/controls/Switch.js +25 -4
  36. package/esm/controls/__stories__/Switch.stories.js +26 -1
  37. package/esm/tabs/SegmentedTabs.js +24 -5
  38. package/esm/visualizations/chart/axis/AxisTickLabelOverflowMask.js +44 -0
  39. package/esm/visualizations/chart/axis/XAxis.js +23 -10
  40. package/esm/visualizations/chart/axis/YAxis.js +23 -10
  41. package/esm/visualizations/chart/axis/__stories__/Axis.stories.js +276 -121
  42. package/esm/visualizations/chart/axis/index.js +1 -0
  43. package/esm/visualizations/chart/scrubber/DefaultScrubberBeaconLabel.js +1 -1
  44. package/esm/visualizations/chart/text/ChartText.js +21 -19
  45. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  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); }
2
- import React, { memo, useCallback } from 'react';
2
+ import React, { memo, useCallback, useMemo } from 'react';
3
3
  import { useAccordionContext } from '@coinbase/cds-common/accordion/AccordionProvider';
4
4
  import { accordionIconHiddenRotate, accordionIconVisibleRotate } from '@coinbase/cds-common/animation/accordion';
5
5
  import { listHeight } from '@coinbase/cds-common/tokens/cell';
@@ -11,20 +11,28 @@ import { AnimatedCaret } from '../motion/AnimatedCaret';
11
11
  import { Pressable } from '../system/Pressable';
12
12
  import { Text } from '../typography/Text';
13
13
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
14
- export const AccordionMedia = /*#__PURE__*/memo(_ref => {
14
+ const compactPaddingProps = paddingProps => {
15
+ const entries = Object.entries(paddingProps).filter(_ref => {
16
+ let [, value] = _ref;
17
+ return value !== undefined;
18
+ });
19
+ if (entries.length === 0) return undefined;
20
+ return Object.fromEntries(entries);
21
+ };
22
+ export const AccordionMedia = /*#__PURE__*/memo(_ref2 => {
15
23
  let {
16
24
  media
17
- } = _ref;
25
+ } = _ref2;
18
26
  return /*#__PURE__*/_jsx(Box, {
19
27
  children: media
20
28
  });
21
29
  });
22
- export const AccordionTitle = /*#__PURE__*/memo(_ref2 => {
30
+ export const AccordionTitle = /*#__PURE__*/memo(_ref3 => {
23
31
  let {
24
32
  title,
25
33
  subtitle,
26
34
  tertiaryTitle
27
- } = _ref2;
35
+ } = _ref3;
28
36
  return /*#__PURE__*/_jsx(Box, {
29
37
  flexGrow: 1,
30
38
  flexShrink: 1,
@@ -45,14 +53,16 @@ export const AccordionTitle = /*#__PURE__*/memo(_ref2 => {
45
53
  })
46
54
  });
47
55
  });
48
- export const AccordionIcon = /*#__PURE__*/memo(_ref3 => {
56
+ export const AccordionIcon = /*#__PURE__*/memo(_ref4 => {
49
57
  let {
50
- collapsed
51
- } = _ref3;
58
+ collapsed,
59
+ caretSize = 's'
60
+ } = _ref4;
52
61
  return /*#__PURE__*/_jsx(Box, {
53
62
  justifyContent: "flex-end",
54
63
  children: /*#__PURE__*/_jsx(AnimatedCaret, {
55
- rotate: collapsed ? accordionIconHiddenRotate : accordionIconVisibleRotate
64
+ rotate: collapsed ? accordionIconHiddenRotate : accordionIconVisibleRotate,
65
+ size: caretSize
56
66
  })
57
67
  });
58
68
  });
@@ -60,7 +70,7 @@ export const AccordionIcon = /*#__PURE__*/memo(_ref3 => {
60
70
  * Renders a Pressable element to use as the header to an AccordionItem.
61
71
  * Composes an Accordion Media, Title, and Icon.
62
72
  */
63
- export const AccordionHeader = /*#__PURE__*/memo(_ref4 => {
73
+ export const AccordionHeader = /*#__PURE__*/memo(_ref5 => {
64
74
  let {
65
75
  ref: forwardedRef,
66
76
  itemKey,
@@ -70,13 +80,35 @@ export const AccordionHeader = /*#__PURE__*/memo(_ref4 => {
70
80
  onPress,
71
81
  media,
72
82
  collapsed,
73
- testID
74
- } = _ref4;
83
+ testID,
84
+ style,
85
+ background = 'bg',
86
+ caretSize,
87
+ padding,
88
+ paddingX,
89
+ paddingY,
90
+ paddingTop,
91
+ paddingBottom,
92
+ paddingStart,
93
+ paddingEnd
94
+ } = _ref5;
75
95
  const {
76
96
  setActiveKey,
77
97
  activeKey
78
98
  } = useAccordionContext();
79
- const spacing = useCellSpacing();
99
+ const outerSpacing = useMemo(() => compactPaddingProps({
100
+ padding,
101
+ paddingX,
102
+ paddingY,
103
+ paddingTop,
104
+ paddingBottom,
105
+ paddingStart,
106
+ paddingEnd
107
+ }), [padding, paddingX, paddingY, paddingTop, paddingBottom, paddingStart, paddingEnd]);
108
+ // Header padding follows the same outer spacing rules as Cell.
109
+ const spacing = useCellSpacing({
110
+ outerSpacing
111
+ });
80
112
  const accessibilityLabel = [title, subtitle, tertiaryTitle].filter(Boolean).join(', ');
81
113
  const handlePress = useCallback(() => {
82
114
  onPress == null || onPress(itemKey);
@@ -85,15 +117,16 @@ export const AccordionHeader = /*#__PURE__*/memo(_ref4 => {
85
117
  return /*#__PURE__*/_jsx(Pressable, {
86
118
  ref: forwardedRef,
87
119
  noScaleOnPress: true,
88
- transparentWhileInactive: true,
89
120
  accessibilityLabel: accessibilityLabel,
90
121
  accessibilityRole: "togglebutton",
91
122
  accessibilityState: {
92
123
  expanded: !collapsed
93
124
  },
94
- background: "bg",
125
+ background: background,
95
126
  onPress: handlePress,
127
+ style: style,
96
128
  testID: testID,
129
+ transparentWhileInactive: true,
97
130
  children: /*#__PURE__*/_jsxs(HStack, _extends({
98
131
  alignItems: "center",
99
132
  gap: 2,
@@ -107,6 +140,7 @@ export const AccordionHeader = /*#__PURE__*/memo(_ref4 => {
107
140
  tertiaryTitle: tertiaryTitle,
108
141
  title: title
109
142
  }), /*#__PURE__*/_jsx(AccordionIcon, {
143
+ caretSize: caretSize,
110
144
  collapsed: collapsed
111
145
  })]
112
146
  }))
@@ -1,6 +1,8 @@
1
1
  import React, { memo } from 'react';
2
2
  import { useAccordionContext } from '@coinbase/cds-common/accordion/AccordionProvider';
3
3
  import { accordionMinWidth } from '@coinbase/cds-common/tokens/accordion';
4
+ import { useComponentConfig } from '../hooks/useComponentConfig';
5
+ import { Divider } from '../layout/Divider';
4
6
  import { VStack } from '../layout/VStack';
5
7
  import { AccordionHeader } from './AccordionHeader';
6
8
  import { AccordionPanel } from './AccordionPanel';
@@ -10,8 +12,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
12
  * It composes together an AccordionHeader and a collapsible AccordionPanel.
11
13
  * Accepts a unique `itemKey` prop to uniquely identify one item from another within the same Accordion.
12
14
  */
13
- export const AccordionItem = /*#__PURE__*/memo(_ref => {
14
- let {
15
+ export const AccordionItem = /*#__PURE__*/memo(_props => {
16
+ const mergedProps = useComponentConfig('AccordionItem', _props);
17
+ const {
15
18
  itemKey,
16
19
  title,
17
20
  subtitle,
@@ -22,30 +25,61 @@ export const AccordionItem = /*#__PURE__*/memo(_ref => {
22
25
  testID,
23
26
  headerRef,
24
27
  panelRef,
25
- style
26
- } = _ref;
28
+ style,
29
+ styles,
30
+ showHeaderBorder = false,
31
+ background,
32
+ caretSize,
33
+ borderRadius,
34
+ padding,
35
+ paddingX,
36
+ paddingY,
37
+ paddingTop,
38
+ paddingBottom,
39
+ paddingStart,
40
+ paddingEnd
41
+ } = mergedProps;
27
42
  const {
28
43
  activeKey
29
44
  } = useAccordionContext();
30
45
  const collapsed = activeKey !== itemKey;
31
46
  return /*#__PURE__*/_jsxs(VStack, {
47
+ borderRadius: borderRadius,
32
48
  minWidth: accordionMinWidth,
33
- style: style,
49
+ overflow: borderRadius !== undefined ? 'hidden' : undefined,
50
+ style: [style, styles == null ? void 0 : styles.root],
34
51
  testID: testID,
52
+ width: "100%",
35
53
  children: [/*#__PURE__*/_jsx(AccordionHeader, {
36
54
  ref: headerRef,
55
+ background: background,
56
+ caretSize: caretSize,
37
57
  collapsed: collapsed,
38
58
  itemKey: itemKey,
39
59
  media: media,
40
60
  onPress: onPress,
61
+ padding: padding,
62
+ paddingBottom: paddingBottom,
63
+ paddingEnd: paddingEnd,
64
+ paddingStart: paddingStart,
65
+ paddingTop: paddingTop,
66
+ paddingX: paddingX,
67
+ paddingY: paddingY,
68
+ style: styles == null ? void 0 : styles.header,
41
69
  subtitle: subtitle,
42
70
  tertiaryTitle: tertiaryTitle,
43
71
  testID: testID && testID + "-header",
44
72
  title: title
45
- }), /*#__PURE__*/_jsx(AccordionPanel, {
73
+ }), showHeaderBorder ? /*#__PURE__*/_jsx(Divider, {
74
+ paddingEnd: paddingEnd,
75
+ paddingStart: paddingStart,
76
+ paddingX: paddingX,
77
+ testID: testID && testID + "-divider"
78
+ }) : null, /*#__PURE__*/_jsx(AccordionPanel, {
46
79
  ref: panelRef,
47
80
  collapsed: collapsed,
48
81
  itemKey: itemKey,
82
+ style: styles == null ? void 0 : styles.panel,
49
83
  testID: testID && testID + "-panel",
50
84
  children: children
51
85
  })]
@@ -13,12 +13,14 @@ export const AccordionPanel = /*#__PURE__*/memo(_ref => {
13
13
  ref: forwardedRef,
14
14
  children,
15
15
  collapsed = true,
16
- testID
16
+ testID,
17
+ style
17
18
  } = _ref;
18
19
  return /*#__PURE__*/_jsx(Collapsible, _extends({
19
20
  ref: forwardedRef,
20
21
  collapsed: collapsed,
21
22
  maxHeight: accordionVisibleMaxHeight,
23
+ style: style,
22
24
  testID: testID
23
25
  }, accordionSpacing, {
24
26
  children: children
@@ -34,7 +34,8 @@ export const Collapsible = /*#__PURE__*/memo(_ref => {
34
34
  paddingEnd,
35
35
  paddingBottom,
36
36
  paddingStart,
37
- scrollViewProps
37
+ scrollViewProps,
38
+ style
38
39
  } = mergedProps;
39
40
  const theme = useTheme();
40
41
  // TO DO: Remove this after refactoring useContentSize to default values to null on initial render
@@ -112,10 +113,11 @@ export const Collapsible = /*#__PURE__*/memo(_ref => {
112
113
  }));
113
114
  const animatedContainerStyles = useMemo(() => [styles.container, animatedStyles, animatedInMaxSize], [animatedStyles, animatedInMaxSize]);
114
115
  const containerStyles = isUnmountedExpanded ? styles.container : animatedContainerStyles;
116
+ const mergedContainerStyles = useMemo(() => style ? [containerStyles, style] : containerStyles, [containerStyles, style]);
115
117
  return /*#__PURE__*/_jsx(ReanimatedView, {
116
118
  ref: forwardedRef,
117
119
  "aria-expanded": !collapsed,
118
- style: containerStyles,
120
+ style: mergedContainerStyles,
119
121
  testID: testID,
120
122
  children: /*#__PURE__*/_jsx(ScrollView, _extends({
121
123
  nestedScrollEnabled: true // for Android
@@ -1,5 +1,5 @@
1
1
  const _excluded = ["ref"],
2
- _excluded2 = ["children", "style", "styles"];
2
+ _excluded2 = ["children", "style", "styles", "variant", "background", "checked"];
3
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
4
  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; }
5
5
  import React, { memo, useMemo } from 'react';
@@ -9,14 +9,26 @@ import { useTheme } from '../hooks/useTheme';
9
9
  import { Box } from '../layout/Box';
10
10
  import { Interactable } from '../system/Interactable';
11
11
  import { Control } from './Control';
12
+
13
+ /** Border width of the switch head/handle, kept as a hairline regardless of theme. */
12
14
  import { jsx as _jsx } from "react/jsx-runtime";
15
+ const switchThumbBorderWidth = 0.5;
16
+
17
+ /** Semantic color variants for Switch, matching the semantics used by other control components. */
18
+
19
+ /** Track background color applied when Switch is checked, keyed by `variant`. */
20
+ const switchVariantBackground = {
21
+ primary: 'bgPrimary',
22
+ positive: 'bgPositive',
23
+ negative: 'bgNegative'
24
+ };
13
25
  const SwitchIcon = _ref => {
14
26
  let {
15
27
  pressed,
16
28
  checked,
17
29
  disabled,
18
30
  controlColor,
19
- background = checked ? 'bgPrimary' : 'bgTertiary',
31
+ background = 'bgTertiary',
20
32
  borderColor,
21
33
  borderRadius = 1000,
22
34
  borderWidth = 0,
@@ -45,7 +57,8 @@ const SwitchIcon = _ref => {
45
57
  height: switchThumbSize,
46
58
  position: 'absolute',
47
59
  top: thumbInset - borderSize,
48
- left: thumbInset - borderSize
60
+ left: thumbInset - borderSize,
61
+ borderWidth: switchThumbBorderWidth
49
62
  }, {
50
63
  transform: [{
51
64
  translateX: animatedScaleValue.interpolate({
@@ -85,7 +98,10 @@ const SwitchWithRef = function SwitchWithRef(_ref2) {
85
98
  const {
86
99
  children,
87
100
  style,
88
- styles
101
+ styles,
102
+ variant = 'primary',
103
+ background,
104
+ checked
89
105
  } = mergedProps,
90
106
  props = _objectWithoutPropertiesLoose(mergedProps, _excluded2);
91
107
  const theme = useTheme();
@@ -93,11 +109,16 @@ const SwitchWithRef = function SwitchWithRef(_ref2) {
93
109
  switchHeight
94
110
  } = theme.controlSize;
95
111
  const controlStyles = useMemo(() => StyleSheet.flatten([style, styles == null ? void 0 : styles.control]), [style, styles == null ? void 0 : styles.control]);
112
+ // The variant only informs the track color while checked; the background prop is more
113
+ // specific and always wins when provided.
114
+ const resolvedBackground = useMemo(() => background != null ? background : checked ? switchVariantBackground[variant] : undefined, [background, checked, variant]);
96
115
  const switchNode = /*#__PURE__*/_jsx(Control, _extends({
97
116
  ref: ref,
98
117
  accessible: true,
99
118
  shouldUseSwitchTransition: true,
100
119
  accessibilityRole: "switch",
120
+ background: resolvedBackground,
121
+ checked: checked,
101
122
  label: children,
102
123
  style: controlStyles
103
124
  }, props, {
@@ -1,7 +1,7 @@
1
1
  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); }
2
2
  import React, { useState } from 'react';
3
3
  import { Example, ExampleScreen } from '../../examples/ExampleScreen';
4
- import { VStack } from '../../layout';
4
+ import { HStack, VStack } from '../../layout';
5
5
  import { ThemeProvider } from '../../system/ThemeProvider';
6
6
  import { defaultTheme } from '../../themes/defaultTheme';
7
7
  import { Switch } from '../Switch';
@@ -68,6 +68,31 @@ const SwitchScreen = () => {
68
68
  })]
69
69
  });
70
70
  }
71
+ }), /*#__PURE__*/_jsx(Example, {
72
+ inline: true,
73
+ title: "Variants",
74
+ children: /*#__PURE__*/_jsxs(HStack, {
75
+ flexWrap: "wrap",
76
+ gap: 2,
77
+ children: [/*#__PURE__*/_jsx(Switch, {
78
+ checked: true,
79
+ variant: "primary",
80
+ children: "Primary"
81
+ }), /*#__PURE__*/_jsx(Switch, {
82
+ checked: true,
83
+ variant: "positive",
84
+ children: "Positive"
85
+ }), /*#__PURE__*/_jsx(Switch, {
86
+ checked: true,
87
+ variant: "negative",
88
+ children: "Negative"
89
+ }), /*#__PURE__*/_jsx(Switch, {
90
+ checked: true,
91
+ background: "accentBoldPurple",
92
+ variant: "negative",
93
+ children: "Background override"
94
+ })]
95
+ })
71
96
  }), /*#__PURE__*/_jsx(Example, {
72
97
  inline: true,
73
98
  title: "Custom Theme",
@@ -1,16 +1,23 @@
1
1
  const _excluded = ["ref"],
2
- _excluded2 = ["TabComponent", "TabsActiveIndicatorComponent", "activeBackground", "background", "borderRadius"];
2
+ _excluded2 = ["TabComponent", "TabsActiveIndicatorComponent", "activeBackground", "background", "borderRadius", "equalWidth", "alignSelf", "styles"];
3
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
4
  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; }
5
- import React, { memo } from 'react';
5
+ import React, { memo, useMemo } from 'react';
6
6
  import { useComponentConfig } from '../hooks/useComponentConfig';
7
7
  import { SegmentedTab } from './SegmentedTab';
8
8
  import { SegmentedTabsActiveIndicator } from './SegmentedTabsActiveIndicator';
9
9
  import { Tabs } from './Tabs';
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ const equalWidthTabContainerStyle = {
12
+ flex: 1
13
+ };
14
+ const equalWidthTabStyle = {
15
+ alignSelf: 'stretch'
16
+ };
10
17
 
11
18
  // We do Partial/Pick to allow TabComponent and TabsActiveIndicatorComponent to be optional
12
19
  // We grab 'tabs' from the Omit allowing it to stay required
13
- import { jsx as _jsx } from "react/jsx-runtime";
20
+
14
21
  const SegmentedTabsComponent = /*#__PURE__*/memo(_ref => {
15
22
  let {
16
23
  ref
@@ -22,16 +29,28 @@ const SegmentedTabsComponent = /*#__PURE__*/memo(_ref => {
22
29
  TabsActiveIndicatorComponent = SegmentedTabsActiveIndicator,
23
30
  activeBackground = 'bgInverse',
24
31
  background = 'bgSecondary',
25
- borderRadius = 700
32
+ borderRadius = 700,
33
+ equalWidth,
34
+ alignSelf = equalWidth ? 'stretch' : undefined,
35
+ styles
26
36
  } = mergedProps,
27
37
  props = _objectWithoutPropertiesLoose(mergedProps, _excluded2);
38
+ const resolvedStyles = useMemo(() => {
39
+ if (!equalWidth) return styles;
40
+ return _extends({}, styles, {
41
+ tabContainer: [equalWidthTabContainerStyle, styles == null ? void 0 : styles.tabContainer],
42
+ tab: [equalWidthTabStyle, styles == null ? void 0 : styles.tab]
43
+ });
44
+ }, [equalWidth, styles]);
28
45
  return /*#__PURE__*/_jsx(Tabs, _extends({
29
46
  ref: ref,
30
47
  TabComponent: TabComponent,
31
48
  TabsActiveIndicatorComponent: TabsActiveIndicatorComponent,
32
49
  activeBackground: activeBackground,
50
+ alignSelf: alignSelf,
33
51
  background: background,
34
- borderRadius: borderRadius
52
+ borderRadius: borderRadius,
53
+ styles: resolvedStyles
35
54
  }, props));
36
55
  });
37
56
  SegmentedTabsComponent.displayName = 'SegmentedTabs';
@@ -0,0 +1,44 @@
1
+ import { memo, useMemo } from 'react';
2
+ import { Group, LinearGradient, Rect, vec } from '@shopify/react-native-skia';
3
+ import { useCartesianChartContext } from '../ChartProvider';
4
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
+ const axisTickLabelOverflowFadeWidth = 30;
6
+ const maskOpaque = 'rgba(255, 255, 255, 1)';
7
+ const maskClear = 'rgba(255, 255, 255, 0)';
8
+ export const AxisTickLabelOverflowMask = /*#__PURE__*/memo(_ref => {
9
+ let {
10
+ axis,
11
+ children
12
+ } = _ref;
13
+ const {
14
+ width: chartWidth,
15
+ height: chartHeight
16
+ } = useCartesianChartContext();
17
+ const fadeWidth = axisTickLabelOverflowFadeWidth;
18
+ const isXAxis = axis === 'x';
19
+ const fadeX = Math.min(fadeWidth, chartWidth / 2) / Math.max(chartWidth, 1);
20
+ const fadeY = Math.min(fadeWidth, chartHeight / 2) / Math.max(chartHeight, 1);
21
+ const colors = useMemo(() => [maskClear, maskOpaque, maskOpaque, maskClear], []);
22
+ const positions = useMemo(() => isXAxis ? [0, fadeX, 1 - fadeX, 1] : [0, fadeY, 1 - fadeY, 1], [fadeX, fadeY, isXAxis]);
23
+ if (chartWidth <= 0 || chartHeight <= 0) {
24
+ return /*#__PURE__*/_jsx(Group, {
25
+ children: children
26
+ });
27
+ }
28
+ return /*#__PURE__*/_jsxs(Group, {
29
+ layer: true,
30
+ children: [children, /*#__PURE__*/_jsx(Rect, {
31
+ blendMode: "dstIn",
32
+ height: chartHeight,
33
+ width: chartWidth,
34
+ x: 0,
35
+ y: 0,
36
+ children: /*#__PURE__*/_jsx(LinearGradient, {
37
+ colors: colors,
38
+ end: isXAxis ? vec(chartWidth, 0) : vec(0, chartHeight),
39
+ positions: positions,
40
+ start: vec(0, 0)
41
+ })
42
+ })]
43
+ });
44
+ });
@@ -1,4 +1,4 @@
1
- const _excluded = ["axisId", "position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "tickMinStep", "tickMaxStep", "label", "labelGap", "height", "bandGridLinePlacement", "bandTickMarkPlacement"];
1
+ const _excluded = ["axisId", "position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "tickMinStep", "tickMaxStep", "label", "labelGap", "height", "bandGridLinePlacement", "bandTickMarkPlacement", "tickLabelOverflow"];
2
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
3
  import { memo, useCallback, useEffect, useId, useMemo } from 'react';
4
4
  import { Group } from '@shopify/react-native-skia';
@@ -12,6 +12,7 @@ import { getAxisTicksData, toPointAnchor } from '../utils/axis';
12
12
  import { lineToPath } from '../utils/path';
13
13
  import { getPointOnScale } from '../utils/point';
14
14
  import { isCategoricalScale } from '../utils/scale';
15
+ import { AxisTickLabelOverflowMask } from './AxisTickLabelOverflowMask';
15
16
  import { DefaultAxisTickLabel } from './DefaultAxisTickLabel';
16
17
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
18
  const AXIS_HEIGHT = 32;
@@ -40,7 +41,8 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
40
41
  labelGap = 4,
41
42
  height = label ? AXIS_HEIGHT + LABEL_SIZE : AXIS_HEIGHT,
42
43
  bandGridLinePlacement = 'edges',
43
- bandTickMarkPlacement = 'middle'
44
+ bandTickMarkPlacement = 'middle',
45
+ tickLabelOverflow = 'reposition'
44
46
  } = _ref,
45
47
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
46
48
  const theme = useTheme();
@@ -55,6 +57,7 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
55
57
  unregisterAxis,
56
58
  getAxisBounds
57
59
  } = useCartesianChartContext();
60
+ const fadeTickLabels = tickLabelOverflow === 'fade';
58
61
  const xScale = getXScale(axisId);
59
62
  const xAxis = getXAxis(axisId);
60
63
  const axisBounds = getAxisBounds(registrationId);
@@ -189,11 +192,12 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
189
192
  chartTextProps: {
190
193
  color: theme.color.fgMuted,
191
194
  verticalAlignment: 'middle',
192
- horizontalAlignment: 'center'
195
+ horizontalAlignment: 'center',
196
+ repositionAxes: tickLabelOverflow === 'visible' ? 'none' : fadeTickLabels ? 'y' : 'both'
193
197
  }
194
198
  };
195
199
  });
196
- }, [axisBounds, ticksData, theme.color.fgMuted, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick]);
200
+ }, [axisBounds, ticksData, theme.color.fgMuted, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick, fadeTickLabels, tickLabelOverflow]);
197
201
  if (!xScale || !axisBounds) return;
198
202
  const labelX = axisBounds.x + axisBounds.width / 2;
199
203
  const labelY = position === 'bottom' ? axisBounds.y + axisBounds.height - LABEL_SIZE / 2 : axisBounds.y + LABEL_SIZE / 2;
@@ -221,11 +225,6 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
221
225
  stroke: theme.color.bgLine
222
226
  }, key);
223
227
  })
224
- }), chartTextData && /*#__PURE__*/_jsx(ChartTextGroup, {
225
- prioritizeEndLabels: true,
226
- LabelComponent: TickLabelComponent,
227
- labels: chartTextData,
228
- minGap: minTickLabelGap
229
228
  }), axisBounds && showTickMarks && /*#__PURE__*/_jsx(Group, {
230
229
  children: tickMarkPositions.map(_ref3 => {
231
230
  let {
@@ -248,8 +247,22 @@ export const XAxis = /*#__PURE__*/memo(_ref => {
248
247
  stroke: theme.color.fg,
249
248
  strokeCap: "square",
250
249
  strokeWidth: 1
251
- }), label && /*#__PURE__*/_jsx(ChartText, {
250
+ }), chartTextData && (fadeTickLabels ? /*#__PURE__*/_jsx(AxisTickLabelOverflowMask, {
251
+ axis: "x",
252
+ children: /*#__PURE__*/_jsx(ChartTextGroup, {
253
+ prioritizeEndLabels: true,
254
+ LabelComponent: TickLabelComponent,
255
+ labels: chartTextData,
256
+ minGap: minTickLabelGap
257
+ })
258
+ }) : /*#__PURE__*/_jsx(ChartTextGroup, {
259
+ prioritizeEndLabels: true,
260
+ LabelComponent: TickLabelComponent,
261
+ labels: chartTextData,
262
+ minGap: minTickLabelGap
263
+ })), label && /*#__PURE__*/_jsx(ChartText, {
252
264
  horizontalAlignment: "center",
265
+ repositionAxes: "none",
253
266
  verticalAlignment: "middle",
254
267
  x: labelX,
255
268
  y: labelY,
@@ -1,4 +1,4 @@
1
- const _excluded = ["axisId", "position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "label", "labelGap", "width", "bandGridLinePlacement", "bandTickMarkPlacement"];
1
+ const _excluded = ["axisId", "position", "showGrid", "requestedTickCount", "ticks", "tickLabelFormatter", "TickLabelComponent", "GridLineComponent", "LineComponent", "TickMarkLineComponent", "tickMarkLabelGap", "minTickLabelGap", "showTickMarks", "showLine", "tickMarkSize", "tickInterval", "label", "labelGap", "width", "bandGridLinePlacement", "bandTickMarkPlacement", "tickLabelOverflow"];
2
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
3
  import { memo, useCallback, useEffect, useId, useMemo } from 'react';
4
4
  import { Group, vec } from '@shopify/react-native-skia';
@@ -12,6 +12,7 @@ import { getAxisTicksData, toPointAnchor } from '../utils/axis';
12
12
  import { lineToPath } from '../utils/path';
13
13
  import { getPointOnScale } from '../utils/point';
14
14
  import { isCategoricalScale } from '../utils/scale';
15
+ import { AxisTickLabelOverflowMask } from './AxisTickLabelOverflowMask';
15
16
  import { DefaultAxisTickLabel } from './DefaultAxisTickLabel';
16
17
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
18
  const AXIS_WIDTH = 44;
@@ -38,7 +39,8 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
38
39
  labelGap = 4,
39
40
  width = label ? AXIS_WIDTH + LABEL_SIZE : AXIS_WIDTH,
40
41
  bandGridLinePlacement = 'edges',
41
- bandTickMarkPlacement = 'middle'
42
+ bandTickMarkPlacement = 'middle',
43
+ tickLabelOverflow = 'reposition'
42
44
  } = _ref,
43
45
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
44
46
  const theme = useTheme();
@@ -53,6 +55,7 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
53
55
  unregisterAxis,
54
56
  getAxisBounds
55
57
  } = useCartesianChartContext();
58
+ const fadeTickLabels = tickLabelOverflow === 'fade';
56
59
  const yScale = getYScale(axisId);
57
60
  const yAxis = getYAxis(axisId);
58
61
  const axisBounds = getAxisBounds(registrationId);
@@ -182,11 +185,12 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
182
185
  chartTextProps: {
183
186
  color: theme.color.fgMuted,
184
187
  verticalAlignment: 'middle',
185
- horizontalAlignment: position === 'left' ? 'right' : 'left'
188
+ horizontalAlignment: position === 'left' ? 'right' : 'left',
189
+ repositionAxes: tickLabelOverflow === 'visible' ? 'none' : fadeTickLabels ? 'x' : 'both'
186
190
  }
187
191
  };
188
192
  });
189
- }, [axisBounds, ticksData, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick, theme.color.fgMuted]);
193
+ }, [axisBounds, ticksData, tickMarkLabelGap, showTickMarks, tickMarkSize, position, formatTick, theme.color.fgMuted, fadeTickLabels, tickLabelOverflow]);
190
194
  if (!yScale || !axisBounds) return;
191
195
  const labelX = position === 'left' ? axisBounds.x + LABEL_SIZE / 2 : axisBounds.x + axisBounds.width - LABEL_SIZE / 2;
192
196
  const labelY = axisBounds.y + axisBounds.height / 2;
@@ -214,11 +218,6 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
214
218
  stroke: theme.color.bgLine
215
219
  }, key);
216
220
  })
217
- }), chartTextData && /*#__PURE__*/_jsx(ChartTextGroup, {
218
- prioritizeEndLabels: true,
219
- LabelComponent: TickLabelComponent,
220
- labels: chartTextData,
221
- minGap: minTickLabelGap
222
221
  }), axisBounds && showTickMarks && /*#__PURE__*/_jsx(Group, {
223
222
  children: tickMarkPositions.map(_ref3 => {
224
223
  let {
@@ -241,13 +240,27 @@ export const YAxis = /*#__PURE__*/memo(_ref => {
241
240
  stroke: theme.color.fg,
242
241
  strokeCap: "square",
243
242
  strokeWidth: 1
244
- }), label && /*#__PURE__*/_jsx(Group, {
243
+ }), chartTextData && (fadeTickLabels ? /*#__PURE__*/_jsx(AxisTickLabelOverflowMask, {
244
+ axis: "y",
245
+ children: /*#__PURE__*/_jsx(ChartTextGroup, {
246
+ prioritizeEndLabels: true,
247
+ LabelComponent: TickLabelComponent,
248
+ labels: chartTextData,
249
+ minGap: minTickLabelGap
250
+ })
251
+ }) : /*#__PURE__*/_jsx(ChartTextGroup, {
252
+ prioritizeEndLabels: true,
253
+ LabelComponent: TickLabelComponent,
254
+ labels: chartTextData,
255
+ minGap: minTickLabelGap
256
+ })), label && /*#__PURE__*/_jsx(Group, {
245
257
  origin: vec(labelX, labelY),
246
258
  transform: [{
247
259
  rotate: position === 'left' ? -Math.PI / 2 : Math.PI / 2
248
260
  }],
249
261
  children: /*#__PURE__*/_jsx(ChartText, {
250
262
  horizontalAlignment: "center",
263
+ repositionAxes: "none",
251
264
  verticalAlignment: "middle",
252
265
  x: labelX,
253
266
  y: labelY,