@coinbase/cds-mobile-visualization 3.4.0-beta.17 → 3.4.0-beta.19

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 (68) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dts/chart/Path.d.ts +35 -13
  3. package/dts/chart/Path.d.ts.map +1 -1
  4. package/dts/chart/area/Area.d.ts +7 -11
  5. package/dts/chart/area/Area.d.ts.map +1 -1
  6. package/dts/chart/area/AreaChart.d.ts +1 -1
  7. package/dts/chart/area/DottedArea.d.ts.map +1 -1
  8. package/dts/chart/area/GradientArea.d.ts.map +1 -1
  9. package/dts/chart/area/SolidArea.d.ts.map +1 -1
  10. package/dts/chart/bar/Bar.d.ts +32 -2
  11. package/dts/chart/bar/Bar.d.ts.map +1 -1
  12. package/dts/chart/bar/BarChart.d.ts +2 -0
  13. package/dts/chart/bar/BarChart.d.ts.map +1 -1
  14. package/dts/chart/bar/BarPlot.d.ts +2 -1
  15. package/dts/chart/bar/BarPlot.d.ts.map +1 -1
  16. package/dts/chart/bar/BarStack.d.ts +5 -10
  17. package/dts/chart/bar/BarStack.d.ts.map +1 -1
  18. package/dts/chart/bar/BarStackGroup.d.ts +1 -0
  19. package/dts/chart/bar/BarStackGroup.d.ts.map +1 -1
  20. package/dts/chart/bar/DefaultBar.d.ts.map +1 -1
  21. package/dts/chart/bar/DefaultBarStack.d.ts.map +1 -1
  22. package/dts/chart/line/DottedLine.d.ts.map +1 -1
  23. package/dts/chart/line/Line.d.ts +4 -9
  24. package/dts/chart/line/Line.d.ts.map +1 -1
  25. package/dts/chart/line/LineChart.d.ts +1 -1
  26. package/dts/chart/line/SolidLine.d.ts.map +1 -1
  27. package/dts/chart/point/Point.d.ts +18 -2
  28. package/dts/chart/point/Point.d.ts.map +1 -1
  29. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts +9 -1
  30. package/dts/chart/scrubber/DefaultScrubberBeacon.d.ts.map +1 -1
  31. package/dts/chart/scrubber/Scrubber.d.ts +45 -24
  32. package/dts/chart/scrubber/Scrubber.d.ts.map +1 -1
  33. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts +9 -1
  34. package/dts/chart/scrubber/ScrubberBeaconLabelGroup.d.ts.map +1 -1
  35. package/dts/chart/utils/bar.d.ts +34 -0
  36. package/dts/chart/utils/bar.d.ts.map +1 -1
  37. package/dts/chart/utils/path.d.ts +6 -0
  38. package/dts/chart/utils/path.d.ts.map +1 -1
  39. package/dts/chart/utils/transition.d.ts +59 -21
  40. package/dts/chart/utils/transition.d.ts.map +1 -1
  41. package/esm/chart/Path.js +18 -17
  42. package/esm/chart/__stories__/CartesianChart.stories.js +3 -77
  43. package/esm/chart/__stories__/ChartTransitions.stories.js +629 -0
  44. package/esm/chart/area/Area.js +2 -0
  45. package/esm/chart/area/DottedArea.js +7 -3
  46. package/esm/chart/area/GradientArea.js +4 -2
  47. package/esm/chart/area/SolidArea.js +4 -2
  48. package/esm/chart/bar/Bar.js +2 -0
  49. package/esm/chart/bar/BarChart.js +4 -2
  50. package/esm/chart/bar/BarPlot.js +2 -0
  51. package/esm/chart/bar/BarStack.js +3 -0
  52. package/esm/chart/bar/DefaultBar.js +15 -15
  53. package/esm/chart/bar/DefaultBarStack.js +14 -3
  54. package/esm/chart/bar/__stories__/BarChart.stories.js +448 -52
  55. package/esm/chart/line/DottedLine.js +4 -2
  56. package/esm/chart/line/Line.js +6 -17
  57. package/esm/chart/line/SolidLine.js +4 -2
  58. package/esm/chart/line/__stories__/LineChart.stories.js +130 -235
  59. package/esm/chart/line/__stories__/ReferenceLine.stories.js +95 -1
  60. package/esm/chart/point/Point.js +33 -35
  61. package/esm/chart/scrubber/DefaultScrubberBeacon.js +2 -5
  62. package/esm/chart/scrubber/Scrubber.js +15 -14
  63. package/esm/chart/scrubber/ScrubberBeaconLabelGroup.js +29 -7
  64. package/esm/chart/utils/bar.js +43 -0
  65. package/esm/chart/utils/path.js +8 -0
  66. package/esm/chart/utils/transition.js +96 -61
  67. package/package.json +5 -5
  68. package/esm/chart/__stories__/Chart.stories.js +0 -77
@@ -1,20 +1,29 @@
1
1
  const _excluded = ["children"],
2
- _excluded2 = ["animate"];
2
+ _excluded2 = ["animate"],
3
+ _excluded3 = ["x", "y", "width", "height", "originY", "dataX"],
4
+ _excluded4 = ["data", "height"];
3
5
  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
6
  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); }
5
- import { memo, useEffect, useState } from 'react';
6
- import { Button } from '@coinbase/cds-mobile/buttons';
7
- import { Example, ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
7
+ import { memo, useCallback, useEffect, useId, useMemo, useState } from 'react';
8
+ import { useDerivedValue } from 'react-native-reanimated';
9
+ import { candles as btcCandles } from '@coinbase/cds-common/internal/data/candles';
10
+ import { Button, IconButton } from '@coinbase/cds-mobile/buttons';
11
+ import { ExampleScreen } from '@coinbase/cds-mobile/examples/ExampleScreen';
8
12
  import { useTheme } from '@coinbase/cds-mobile/hooks/useTheme';
9
- import { VStack } from '@coinbase/cds-mobile/layout';
13
+ import { Box, HStack, VStack } from '@coinbase/cds-mobile/layout';
14
+ import { Text } from '@coinbase/cds-mobile/typography';
15
+ import { Line as SkiaLine, Rect } from '@shopify/react-native-skia';
10
16
  import { XAxis, YAxis } from '../../axis';
11
17
  import { CartesianChart } from '../../CartesianChart';
18
+ import { useCartesianChartContext } from '../../ChartProvider';
12
19
  import { ReferenceLine, SolidLine } from '../../line';
20
+ import { Scrubber } from '../../scrubber';
21
+ import { getPointOnSerializableScale, unwrapAnimatedValue, useScrubberContext } from '../../utils';
13
22
  import { Bar } from '../Bar';
14
23
  import { BarChart } from '../BarChart';
15
24
  import { BarPlot } from '../BarPlot';
16
25
  import { DefaultBarStack } from '../DefaultBarStack';
17
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
26
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
18
27
  const ThinSolidLine = /*#__PURE__*/memo(props => /*#__PURE__*/_jsx(SolidLine, _extends({}, props, {
19
28
  strokeWidth: 1
20
29
  })));
@@ -649,49 +658,386 @@ const BandGridPositionExample = _ref6 => {
649
658
  }), /*#__PURE__*/_jsx(BarPlot, {})]
650
659
  });
651
660
  };
652
- const BarChartStories = () => {
653
- return /*#__PURE__*/_jsxs(ExampleScreen, {
654
- children: [/*#__PURE__*/_jsx(Example, {
655
- title: "Basic",
656
- children: /*#__PURE__*/_jsx(UpdatingChartValues, {})
657
- }), /*#__PURE__*/_jsx(Example, {
658
- title: "Animated Auto-Updating",
659
- children: /*#__PURE__*/_jsx(AnimatedUpdatingChartValues, {})
660
- }), /*#__PURE__*/_jsx(Example, {
661
- title: "Negative Values with Top Axis",
662
- children: /*#__PURE__*/_jsx(NegativeValuesWithTopAxis, {})
663
- }), /*#__PURE__*/_jsx(Example, {
664
- title: "Positive and Negative Cash Flow",
665
- children: /*#__PURE__*/_jsx(PositiveAndNegativeCashFlow, {})
666
- }), /*#__PURE__*/_jsx(Example, {
667
- title: "Fiat & Stablecoin Balance",
668
- children: /*#__PURE__*/_jsx(FiatAndStablecoinBalance, {})
669
- }), /*#__PURE__*/_jsx(Example, {
670
- title: "Monthly Rewards",
671
- children: /*#__PURE__*/_jsx(MonthlyRewards, {})
672
- }), /*#__PURE__*/_jsx(Example, {
673
- title: "Multiple Y Axes",
674
- children: /*#__PURE__*/_jsx(MultipleYAxes, {})
675
- }), /*#__PURE__*/_jsx(Example, {
676
- title: "Y-Axis Continuous ColorMap",
677
- children: /*#__PURE__*/_jsx(YAxisContinuousColorMap, {})
678
- }), /*#__PURE__*/_jsx(Example, {
679
- title: "Y-Axis Discrete ColorMap",
680
- children: /*#__PURE__*/_jsx(YAxisDiscreteColorMap, {})
681
- }), /*#__PURE__*/_jsx(Example, {
682
- title: "X-Axis Continuous ColorMap",
683
- children: /*#__PURE__*/_jsx(XAxisContinuousColorMap, {})
684
- }), /*#__PURE__*/_jsx(Example, {
685
- title: "X-Axis Discrete ColorMap",
686
- children: /*#__PURE__*/_jsx(XAxisDiscreteColorMap, {})
687
- }), /*#__PURE__*/_jsx(Example, {
688
- title: "X-Axis Multi-Segment ColorMap",
689
- children: /*#__PURE__*/_jsx(XAxisMultiSegmentColorMap, {})
690
- }), /*#__PURE__*/_jsx(Example, {
691
- title: "ColorMap with Opacity",
692
- children: /*#__PURE__*/_jsx(ColorMapWithOpacity, {})
693
- }), /*#__PURE__*/_jsxs(Example, {
694
- title: "Band Grid Position",
661
+
662
+ // --- Composed Examples ---
663
+
664
+ const candlestickStockData = btcCandles.slice(0, 90).reverse();
665
+ const CandlesticksHeader = /*#__PURE__*/memo(_ref7 => {
666
+ let {
667
+ currentIndex
668
+ } = _ref7;
669
+ const formatPrice = useCallback(price => {
670
+ return new Intl.NumberFormat('en-US', {
671
+ style: 'currency',
672
+ currency: 'USD'
673
+ }).format(parseFloat(price));
674
+ }, []);
675
+ const formatThousandsPriceNumber = useCallback(price => {
676
+ const formattedPrice = new Intl.NumberFormat('en-US', {
677
+ style: 'currency',
678
+ currency: 'USD',
679
+ minimumFractionDigits: 0,
680
+ maximumFractionDigits: 0
681
+ }).format(price / 1000);
682
+ return formattedPrice + "k";
683
+ }, []);
684
+ const currentText = useMemo(() => {
685
+ if (currentIndex !== undefined) {
686
+ return "Open: " + formatThousandsPriceNumber(parseFloat(candlestickStockData[currentIndex].open)) + ", Close: " + formatThousandsPriceNumber(parseFloat(candlestickStockData[currentIndex].close)) + ", Volume: " + (parseFloat(candlestickStockData[currentIndex].volume) / 1000).toFixed(2) + "k";
687
+ }
688
+ return formatPrice(candlestickStockData[candlestickStockData.length - 1].close);
689
+ }, [currentIndex, formatThousandsPriceNumber, formatPrice]);
690
+ return /*#__PURE__*/_jsx(Text, {
691
+ "aria-live": "polite",
692
+ font: "headline",
693
+ children: currentText
694
+ });
695
+ });
696
+ const CandlesticksChart = /*#__PURE__*/memo(_ref8 => {
697
+ let {
698
+ infoTextId,
699
+ onScrubberPositionChange
700
+ } = _ref8;
701
+ const theme = useTheme();
702
+ const min = useMemo(() => Math.min(...candlestickStockData.map(data => parseFloat(data.low))), []);
703
+ const CandleThinSolidLine = /*#__PURE__*/memo(props => /*#__PURE__*/_jsx(SolidLine, _extends({}, props, {
704
+ strokeWidth: 1
705
+ })));
706
+ const BandwidthHighlight = /*#__PURE__*/memo(_ref9 => {
707
+ let {
708
+ stroke
709
+ } = _ref9;
710
+ const {
711
+ getXSerializableScale,
712
+ drawingArea
713
+ } = useCartesianChartContext();
714
+ const {
715
+ scrubberPosition
716
+ } = useScrubberContext();
717
+ const xScale = useMemo(() => getXSerializableScale(), [getXSerializableScale]);
718
+ const rectWidth = useMemo(() => {
719
+ if (xScale !== undefined && xScale.type === 'band') {
720
+ return xScale.bandwidth;
721
+ }
722
+ return 0;
723
+ }, [xScale]);
724
+ const xPos = useDerivedValue(() => {
725
+ const position = unwrapAnimatedValue(scrubberPosition);
726
+ const xPos = position !== undefined && xScale ? getPointOnSerializableScale(position, xScale) : undefined;
727
+ return xPos !== undefined ? xPos - rectWidth / 2 : 0;
728
+ }, [scrubberPosition, xScale]);
729
+ const opacity = useDerivedValue(() => xPos.value !== undefined ? 1 : 0, [xPos]);
730
+ return /*#__PURE__*/_jsx(Rect, {
731
+ color: stroke,
732
+ height: drawingArea.height,
733
+ opacity: opacity,
734
+ width: rectWidth,
735
+ x: xPos,
736
+ y: drawingArea.y
737
+ });
738
+ });
739
+ const candlesData = useMemo(() => candlestickStockData.map(data => [parseFloat(data.low), parseFloat(data.high)]), []);
740
+ const CandlestickBarComponent = /*#__PURE__*/memo(_ref0 => {
741
+ var _yScale, _yScale2;
742
+ let {
743
+ x,
744
+ y,
745
+ width,
746
+ height,
747
+ dataX
748
+ } = _ref0,
749
+ props = _objectWithoutPropertiesLoose(_ref0, _excluded3);
750
+ const {
751
+ getYScale
752
+ } = useCartesianChartContext();
753
+ const yScale = getYScale();
754
+ const wickX = x + width / 2;
755
+ const timePeriodValue = candlestickStockData[dataX];
756
+ const open = parseFloat(timePeriodValue.open);
757
+ const close = parseFloat(timePeriodValue.close);
758
+ const bullish = open < close;
759
+ const theme = useTheme();
760
+ const color = bullish ? theme.color.fgPositive : theme.color.fgNegative;
761
+ const openY = (_yScale = yScale == null ? void 0 : yScale(open)) != null ? _yScale : 0;
762
+ const closeY = (_yScale2 = yScale == null ? void 0 : yScale(close)) != null ? _yScale2 : 0;
763
+ const bodyHeight = Math.abs(openY - closeY);
764
+ const bodyY = openY < closeY ? openY : closeY;
765
+ return /*#__PURE__*/_jsxs(_Fragment, {
766
+ children: [/*#__PURE__*/_jsx(SkiaLine, {
767
+ color: color,
768
+ p1: {
769
+ x: wickX,
770
+ y
771
+ },
772
+ p2: {
773
+ x: wickX,
774
+ y: y + height
775
+ },
776
+ strokeWidth: 1
777
+ }), /*#__PURE__*/_jsx(Rect, {
778
+ color: color,
779
+ height: bodyHeight,
780
+ width: width,
781
+ x: x,
782
+ y: bodyY
783
+ })]
784
+ });
785
+ });
786
+ const formatThousandsPriceNumber = useCallback(price => {
787
+ const formattedPrice = new Intl.NumberFormat('en-US', {
788
+ style: 'currency',
789
+ currency: 'USD',
790
+ minimumFractionDigits: 0,
791
+ maximumFractionDigits: 0
792
+ }).format(price / 1000);
793
+ return formattedPrice + "k";
794
+ }, []);
795
+ const formatTime = useCallback(index => {
796
+ if (index === null || index === undefined || index >= candlestickStockData.length) return '';
797
+ const ts = parseInt(candlestickStockData[index].start);
798
+ return new Date(ts * 1000).toLocaleDateString('en-US', {
799
+ month: 'short',
800
+ day: 'numeric'
801
+ });
802
+ }, []);
803
+ return /*#__PURE__*/_jsxs(CartesianChart, {
804
+ enableScrubbing: true,
805
+ animate: false,
806
+ "aria-labelledby": infoTextId,
807
+ borderRadius: 0,
808
+ height: 150,
809
+ inset: {
810
+ top: 8,
811
+ bottom: 8,
812
+ left: 0,
813
+ right: 0
814
+ },
815
+ onScrubberPositionChange: onScrubberPositionChange,
816
+ series: [{
817
+ id: 'stock-prices',
818
+ data: candlesData
819
+ }],
820
+ xAxis: {
821
+ scaleType: 'band'
822
+ },
823
+ yAxis: {
824
+ domain: {
825
+ min
826
+ }
827
+ },
828
+ children: [/*#__PURE__*/_jsx(XAxis, {
829
+ tickLabelFormatter: formatTime
830
+ }), /*#__PURE__*/_jsx(YAxis, {
831
+ showGrid: true,
832
+ GridLineComponent: CandleThinSolidLine,
833
+ tickLabelFormatter: formatThousandsPriceNumber,
834
+ width: 40
835
+ }), /*#__PURE__*/_jsx(Scrubber, {
836
+ hideOverlay: true,
837
+ LineComponent: BandwidthHighlight,
838
+ lineStroke: theme.color.fgMuted,
839
+ seriesIds: []
840
+ }), /*#__PURE__*/_jsx(BarPlot, {
841
+ BarComponent: CandlestickBarComponent,
842
+ BarStackComponent: _ref1 => {
843
+ let {
844
+ children
845
+ } = _ref1;
846
+ return /*#__PURE__*/_jsx(_Fragment, {
847
+ children: children
848
+ });
849
+ }
850
+ })]
851
+ });
852
+ });
853
+ const Candlesticks = () => {
854
+ const infoTextId = useId();
855
+ const [currentIndex, setCurrentIndex] = useState();
856
+ return /*#__PURE__*/_jsxs(VStack, {
857
+ gap: 2,
858
+ children: [/*#__PURE__*/_jsx(CandlesticksHeader, {
859
+ currentIndex: currentIndex
860
+ }), /*#__PURE__*/_jsx(CandlesticksChart, {
861
+ infoTextId: infoTextId,
862
+ onScrubberPositionChange: setCurrentIndex
863
+ })]
864
+ });
865
+ };
866
+ const DAY_LENGTH_MINUTES = 1440;
867
+ const sunlightData = [{
868
+ label: 'Jan',
869
+ value: 598
870
+ }, {
871
+ label: 'Feb',
872
+ value: 635
873
+ }, {
874
+ label: 'Mar',
875
+ value: 688
876
+ }, {
877
+ label: 'Apr',
878
+ value: 753
879
+ }, {
880
+ label: 'May',
881
+ value: 812
882
+ }, {
883
+ label: 'Jun',
884
+ value: 855
885
+ }, {
886
+ label: 'Jul',
887
+ value: 861
888
+ }, {
889
+ label: 'Aug',
890
+ value: 828
891
+ }, {
892
+ label: 'Sep',
893
+ value: 772
894
+ }, {
895
+ label: 'Oct',
896
+ value: 710
897
+ }, {
898
+ label: 'Nov',
899
+ value: 648
900
+ }, {
901
+ label: 'Dec',
902
+ value: 605
903
+ }];
904
+ const SunlightChartInner = /*#__PURE__*/memo(_ref10 => {
905
+ let {
906
+ data,
907
+ height = 300
908
+ } = _ref10,
909
+ props = _objectWithoutPropertiesLoose(_ref10, _excluded4);
910
+ const theme = useTheme();
911
+ const SunlightThinSolidLine = /*#__PURE__*/memo(props => /*#__PURE__*/_jsx(SolidLine, _extends({}, props, {
912
+ strokeWidth: 1
913
+ })));
914
+ return /*#__PURE__*/_jsxs(CartesianChart, _extends({}, props, {
915
+ height: height,
916
+ series: [{
917
+ id: 'sunlight',
918
+ data: data.map(_ref11 => {
919
+ let {
920
+ value
921
+ } = _ref11;
922
+ return value;
923
+ }),
924
+ yAxisId: 'sunlight',
925
+ color: "rgb(" + theme.spectrum.yellow40 + ")"
926
+ }, {
927
+ id: 'day',
928
+ data: data.map(() => DAY_LENGTH_MINUTES),
929
+ yAxisId: 'day',
930
+ color: "rgb(" + theme.spectrum.blue100 + ")"
931
+ }],
932
+ xAxis: _extends({}, props.xAxis, {
933
+ scaleType: 'band',
934
+ data: data.map(_ref12 => {
935
+ let {
936
+ label
937
+ } = _ref12;
938
+ return label;
939
+ })
940
+ }),
941
+ yAxis: [{
942
+ id: 'day',
943
+ domain: {
944
+ min: 0,
945
+ max: DAY_LENGTH_MINUTES
946
+ },
947
+ domainLimit: 'strict'
948
+ }, {
949
+ id: 'sunlight',
950
+ domain: {
951
+ min: 0,
952
+ max: DAY_LENGTH_MINUTES
953
+ },
954
+ domainLimit: 'strict'
955
+ }],
956
+ children: [/*#__PURE__*/_jsx(YAxis, {
957
+ showGrid: true,
958
+ showLine: true,
959
+ GridLineComponent: SunlightThinSolidLine,
960
+ axisId: "day",
961
+ position: "left"
962
+ }), /*#__PURE__*/_jsx(XAxis, {
963
+ showLine: true
964
+ }), /*#__PURE__*/_jsx(BarPlot, {
965
+ seriesIds: ['day'],
966
+ transitions: {
967
+ enter: null
968
+ }
969
+ }), /*#__PURE__*/_jsx(BarPlot, {
970
+ borderRadius: 0,
971
+ seriesIds: ['sunlight'],
972
+ transitions: {
973
+ enter: {
974
+ type: 'spring',
975
+ stiffness: 700,
976
+ damping: 40,
977
+ staggerDelay: 1
978
+ }
979
+ }
980
+ })]
981
+ }));
982
+ });
983
+ const SunlightChart = () => {
984
+ return /*#__PURE__*/_jsxs(VStack, {
985
+ gap: 2,
986
+ children: [/*#__PURE__*/_jsx(SunlightChartInner, {
987
+ data: sunlightData
988
+ }), /*#__PURE__*/_jsx(Text, {
989
+ color: "fgMuted",
990
+ font: "caption",
991
+ textAlign: "center",
992
+ children: "2026 Sunlight data for the first day of each month in Atlanta, Georgia, provided by NOAA."
993
+ })]
994
+ });
995
+ };
996
+ function ExampleNavigator() {
997
+ const [currentIndex, setCurrentIndex] = useState(0);
998
+ const examples = useMemo(() => [{
999
+ title: 'Basic',
1000
+ component: /*#__PURE__*/_jsx(UpdatingChartValues, {})
1001
+ }, {
1002
+ title: 'Animated Auto-Updating',
1003
+ component: /*#__PURE__*/_jsx(AnimatedUpdatingChartValues, {})
1004
+ }, {
1005
+ title: 'Negative Values with Top Axis',
1006
+ component: /*#__PURE__*/_jsx(NegativeValuesWithTopAxis, {})
1007
+ }, {
1008
+ title: 'Positive and Negative Cash Flow',
1009
+ component: /*#__PURE__*/_jsx(PositiveAndNegativeCashFlow, {})
1010
+ }, {
1011
+ title: 'Fiat & Stablecoin Balance',
1012
+ component: /*#__PURE__*/_jsx(FiatAndStablecoinBalance, {})
1013
+ }, {
1014
+ title: 'Monthly Rewards',
1015
+ component: /*#__PURE__*/_jsx(MonthlyRewards, {})
1016
+ }, {
1017
+ title: 'Multiple Y Axes',
1018
+ component: /*#__PURE__*/_jsx(MultipleYAxes, {})
1019
+ }, {
1020
+ title: 'Y-Axis Continuous ColorMap',
1021
+ component: /*#__PURE__*/_jsx(YAxisContinuousColorMap, {})
1022
+ }, {
1023
+ title: 'Y-Axis Discrete ColorMap',
1024
+ component: /*#__PURE__*/_jsx(YAxisDiscreteColorMap, {})
1025
+ }, {
1026
+ title: 'X-Axis Continuous ColorMap',
1027
+ component: /*#__PURE__*/_jsx(XAxisContinuousColorMap, {})
1028
+ }, {
1029
+ title: 'X-Axis Discrete ColorMap',
1030
+ component: /*#__PURE__*/_jsx(XAxisDiscreteColorMap, {})
1031
+ }, {
1032
+ title: 'X-Axis Multi-Segment ColorMap',
1033
+ component: /*#__PURE__*/_jsx(XAxisMultiSegmentColorMap, {})
1034
+ }, {
1035
+ title: 'ColorMap with Opacity',
1036
+ component: /*#__PURE__*/_jsx(ColorMapWithOpacity, {})
1037
+ }, {
1038
+ title: 'Band Grid Position',
1039
+ component: /*#__PURE__*/_jsxs(VStack, {
1040
+ gap: 2,
695
1041
  children: [/*#__PURE__*/_jsx(BandGridPositionExample, {
696
1042
  position: "edges"
697
1043
  }), /*#__PURE__*/_jsx(BandGridPositionExample, {
@@ -701,7 +1047,57 @@ const BarChartStories = () => {
701
1047
  }), /*#__PURE__*/_jsx(BandGridPositionExample, {
702
1048
  position: "end"
703
1049
  })]
704
- })]
1050
+ })
1051
+ }, {
1052
+ title: 'Candlesticks',
1053
+ component: /*#__PURE__*/_jsx(Candlesticks, {})
1054
+ }, {
1055
+ title: 'Monthly Sunlight',
1056
+ component: /*#__PURE__*/_jsx(SunlightChart, {})
1057
+ }], []);
1058
+ const currentExample = examples[currentIndex];
1059
+ const handlePrevious = useCallback(() => {
1060
+ setCurrentIndex(prev => (prev - 1 + examples.length) % examples.length);
1061
+ }, [examples.length]);
1062
+ const handleNext = useCallback(() => {
1063
+ setCurrentIndex(prev => (prev + 1 + examples.length) % examples.length);
1064
+ }, [examples.length]);
1065
+ return /*#__PURE__*/_jsx(ExampleScreen, {
1066
+ paddingX: 0,
1067
+ children: /*#__PURE__*/_jsxs(VStack, {
1068
+ gap: 4,
1069
+ children: [/*#__PURE__*/_jsxs(HStack, {
1070
+ alignItems: "center",
1071
+ justifyContent: "space-between",
1072
+ padding: 2,
1073
+ children: [/*#__PURE__*/_jsx(IconButton, {
1074
+ accessibilityHint: "Navigate to previous example",
1075
+ accessibilityLabel: "Previous",
1076
+ name: "arrowLeft",
1077
+ onPress: handlePrevious,
1078
+ variant: "secondary"
1079
+ }), /*#__PURE__*/_jsxs(VStack, {
1080
+ alignItems: "center",
1081
+ children: [/*#__PURE__*/_jsx(Text, {
1082
+ font: "title3",
1083
+ children: currentExample.title
1084
+ }), /*#__PURE__*/_jsxs(Text, {
1085
+ color: "fgMuted",
1086
+ font: "label1",
1087
+ children: [currentIndex + 1, " / ", examples.length]
1088
+ })]
1089
+ }), /*#__PURE__*/_jsx(IconButton, {
1090
+ accessibilityHint: "Navigate to next example",
1091
+ accessibilityLabel: "Next",
1092
+ name: "arrowRight",
1093
+ onPress: handleNext,
1094
+ variant: "secondary"
1095
+ })]
1096
+ }), /*#__PURE__*/_jsx(Box, {
1097
+ padding: 1,
1098
+ children: currentExample.component
1099
+ })]
1100
+ })
705
1101
  });
706
- };
707
- export default BarChartStories;
1102
+ }
1103
+ export default ExampleNavigator;
@@ -1,4 +1,4 @@
1
- const _excluded = ["fill", "stroke", "dashIntervals", "strokeCap", "strokeJoin", "strokeOpacity", "strokeWidth", "gradient", "yAxisId", "d", "animate", "transition"];
1
+ const _excluded = ["fill", "stroke", "dashIntervals", "strokeCap", "strokeJoin", "strokeOpacity", "strokeWidth", "gradient", "yAxisId", "d", "animate", "transitions", "transition"];
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 { memo } from 'react';
@@ -24,6 +24,7 @@ export const DottedLine = /*#__PURE__*/memo(_ref => {
24
24
  yAxisId,
25
25
  d,
26
26
  animate,
27
+ transitions,
27
28
  transition
28
29
  } = _ref,
29
30
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
@@ -38,7 +39,8 @@ export const DottedLine = /*#__PURE__*/memo(_ref => {
38
39
  strokeJoin: strokeJoin,
39
40
  strokeOpacity: strokeOpacity,
40
41
  strokeWidth: strokeWidth,
41
- transition: transition
42
+ transition: transition,
43
+ transitions: transitions
42
44
  }, props, {
43
45
  children: [/*#__PURE__*/_jsx(DashPathEffect, {
44
46
  intervals: dashIntervals
@@ -1,14 +1,13 @@
1
- const _excluded = ["seriesId", "curve", "type", "areaType", "areaBaseline", "stroke", "strokeOpacity", "showArea", "LineComponent", "AreaComponent", "opacity", "points", "connectNulls", "transition", "gradient"];
1
+ const _excluded = ["seriesId", "curve", "type", "areaType", "areaBaseline", "stroke", "strokeOpacity", "showArea", "LineComponent", "AreaComponent", "opacity", "points", "connectNulls", "transitions", "transition", "gradient"];
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
- import React, { memo, useEffect, useMemo } from 'react';
5
- import { useSharedValue, withDelay, withTiming } from 'react-native-reanimated';
4
+ import React, { memo, useMemo } from 'react';
6
5
  import { useTheme } from '@coinbase/cds-mobile';
7
6
  import { Group } from '@shopify/react-native-skia';
8
7
  import { Area } from '../area/Area';
9
8
  import { useCartesianChartContext } from '../ChartProvider';
10
9
  import { Point } from '../point';
11
- import { accessoryFadeTransitionDelay, accessoryFadeTransitionDuration, getLineData, getLinePath } from '../utils';
10
+ import { getLineData, getLinePath } from '../utils';
12
11
  import { evaluateGradientAtValue, getGradientStops } from '../utils/gradient';
13
12
  import { convertToSerializableScale } from '../utils/scale';
14
13
  import { DottedLine } from './DottedLine';
@@ -30,6 +29,7 @@ export const Line = /*#__PURE__*/memo(_ref => {
30
29
  opacity = 1,
31
30
  points,
32
31
  connectNulls,
32
+ transitions,
33
33
  transition,
34
34
  gradient: gradientProp
35
35
  } = _ref,
@@ -43,18 +43,6 @@ export const Line = /*#__PURE__*/memo(_ref => {
43
43
  getYScale,
44
44
  getXAxis
45
45
  } = useCartesianChartContext();
46
-
47
- // Animation state for delayed point rendering (matches web timing)
48
- const pointsOpacity = useSharedValue(animate ? 0 : 1);
49
-
50
- // Delay point appearance until after path enter animation completes
51
- useEffect(() => {
52
- if (animate) {
53
- pointsOpacity.value = withDelay(accessoryFadeTransitionDelay, withTiming(1, {
54
- duration: accessoryFadeTransitionDuration
55
- }));
56
- }
57
- }, [animate, pointsOpacity]);
58
46
  const matchedSeries = useMemo(() => getSeries(seriesId), [getSeries, seriesId]);
59
47
  const gradient = useMemo(() => gradientProp != null ? gradientProp : matchedSeries == null ? void 0 : matchedSeries.gradient, [gradientProp, matchedSeries == null ? void 0 : matchedSeries.gradient]);
60
48
  const sourceData = useMemo(() => getSeriesData(seriesId), [getSeriesData, seriesId]);
@@ -123,6 +111,7 @@ export const Line = /*#__PURE__*/memo(_ref => {
123
111
  gradient: gradient,
124
112
  seriesId: seriesId,
125
113
  transition: transition,
114
+ transitions: transitions,
126
115
  type: areaType
127
116
  }), /*#__PURE__*/_jsx(LineComponent, _extends({
128
117
  d: path,
@@ -130,9 +119,9 @@ export const Line = /*#__PURE__*/memo(_ref => {
130
119
  stroke: stroke,
131
120
  strokeOpacity: strokeOpacity != null ? strokeOpacity : opacity,
132
121
  transition: transition,
122
+ transitions: transitions,
133
123
  yAxisId: matchedSeries == null ? void 0 : matchedSeries.yAxisId
134
124
  }, props)), points && /*#__PURE__*/_jsx(Group, {
135
- opacity: pointsOpacity,
136
125
  children: chartData.map((value, index) => {
137
126
  if (value === null) return;
138
127
  const xValue = xData && xData[index] !== undefined ? xData[index] : index;
@@ -1,4 +1,4 @@
1
- const _excluded = ["fill", "stroke", "strokeCap", "strokeJoin", "strokeOpacity", "strokeWidth", "gradient", "yAxisId", "d", "animate", "transition"];
1
+ const _excluded = ["fill", "stroke", "strokeCap", "strokeJoin", "strokeOpacity", "strokeWidth", "gradient", "yAxisId", "d", "animate", "transitions", "transition"];
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 { memo } from 'react';
@@ -22,6 +22,7 @@ export const SolidLine = /*#__PURE__*/memo(_ref => {
22
22
  yAxisId,
23
23
  d,
24
24
  animate,
25
+ transitions,
25
26
  transition
26
27
  } = _ref,
27
28
  props = _objectWithoutPropertiesLoose(_ref, _excluded);
@@ -36,7 +37,8 @@ export const SolidLine = /*#__PURE__*/memo(_ref => {
36
37
  strokeJoin: strokeJoin,
37
38
  strokeOpacity: strokeOpacity,
38
39
  strokeWidth: strokeWidth,
39
- transition: transition
40
+ transition: transition,
41
+ transitions: transitions
40
42
  }, props, {
41
43
  children: gradient && /*#__PURE__*/_jsx(Gradient, {
42
44
  gradient: gradient,