panelui-native 0.76.0 → 0.78.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.
- package/lib/module/components/ai-input/index.js +23 -7
- package/lib/module/components/ai-input/index.js.map +1 -1
- package/lib/module/components/area-chart/index.js +32 -25
- package/lib/module/components/area-chart/index.js.map +1 -1
- package/lib/module/components/bottom-sheet/index.js +98 -15
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/button/index.js +7 -1
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/funnel-chart/index.js +15 -2
- package/lib/module/components/funnel-chart/index.js.map +1 -1
- package/lib/module/components/heatmap-chart/index.js +19 -27
- package/lib/module/components/heatmap-chart/index.js.map +1 -1
- package/lib/module/components/hex-chart/index.js +2 -0
- package/lib/module/components/hex-chart/index.js.map +1 -1
- package/lib/module/components/line-chart/index.js +38 -31
- package/lib/module/components/line-chart/index.js.map +1 -1
- package/lib/module/components/marquee/index.js +91 -5
- package/lib/module/components/marquee/index.js.map +1 -1
- package/lib/module/components/pie-chart/index.js +15 -2
- package/lib/module/components/pie-chart/index.js.map +1 -1
- package/lib/module/components/plot/index.js +42 -44
- package/lib/module/components/plot/index.js.map +1 -1
- package/lib/module/components/progress-button/index.js +390 -0
- package/lib/module/components/progress-button/index.js.map +1 -0
- package/lib/module/components/progress-button/progress-button-hold.js +57 -0
- package/lib/module/components/progress-button/progress-button-hold.js.map +1 -0
- package/lib/module/components/scatter-chart/index.js +6 -25
- package/lib/module/components/scatter-chart/index.js.map +1 -1
- package/lib/module/components/section-rail/index.js +40 -17
- package/lib/module/components/section-rail/index.js.map +1 -1
- package/lib/module/components/select/index.js +1 -0
- package/lib/module/components/select/index.js.map +1 -1
- package/lib/module/components/slider/index.js +1 -0
- package/lib/module/components/slider/index.js.map +1 -1
- package/lib/module/components/split-view/index.js +54 -10
- package/lib/module/components/split-view/index.js.map +1 -1
- package/lib/module/components/switch/index.js +1 -0
- package/lib/module/components/switch/index.js.map +1 -1
- package/lib/module/components/timeline/index.js +145 -14
- package/lib/module/components/timeline/index.js.map +1 -1
- package/lib/module/components/toast/index.js +45 -11
- package/lib/module/components/toast/index.js.map +1 -1
- package/lib/module/components/treemap-chart/index.js +63 -6
- package/lib/module/components/treemap-chart/index.js.map +1 -1
- package/lib/module/components/waterfall-chart/index.js +20 -4
- package/lib/module/components/waterfall-chart/index.js.map +1 -1
- package/lib/module/hooks/index.js +1 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/use-scroll-sections.js +44 -2
- package/lib/module/hooks/use-scroll-sections.js.map +1 -1
- package/lib/module/hooks/use-skeleton-handoff.js +58 -0
- package/lib/module/hooks/use-skeleton-handoff.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/native/index.js.map +1 -1
- package/lib/typescript/src/components/ai-input/index.d.ts +24 -5
- package/lib/typescript/src/components/ai-input/index.d.ts.map +1 -1
- package/lib/typescript/src/components/area-chart/index.d.ts +1 -1
- package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/button/index.d.ts +15 -0
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/funnel-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/hex-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/marquee/index.d.ts +55 -2
- package/lib/typescript/src/components/marquee/index.d.ts.map +1 -1
- package/lib/typescript/src/components/pie-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/plot/index.d.ts +1 -3
- package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
- package/lib/typescript/src/components/progress-button/index.d.ts +295 -0
- package/lib/typescript/src/components/progress-button/index.d.ts.map +1 -0
- package/lib/typescript/src/components/progress-button/progress-button-hold.d.ts +40 -0
- package/lib/typescript/src/components/progress-button/progress-button-hold.d.ts.map +1 -0
- package/lib/typescript/src/components/scatter-chart/index.d.ts +1 -1
- package/lib/typescript/src/components/scatter-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/section-rail/index.d.ts.map +1 -1
- package/lib/typescript/src/components/split-view/index.d.ts +10 -1
- package/lib/typescript/src/components/split-view/index.d.ts.map +1 -1
- package/lib/typescript/src/components/timeline/index.d.ts +7 -0
- package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
- package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
- package/lib/typescript/src/components/treemap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/waterfall-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/index.d.ts +1 -0
- package/lib/typescript/src/hooks/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-scroll-sections.d.ts +1 -0
- package/lib/typescript/src/hooks/use-scroll-sections.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-skeleton-handoff.d.ts +11 -0
- package/lib/typescript/src/hooks/use-skeleton-handoff.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native/index.d.ts +17 -0
- package/lib/typescript/src/native/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/ai-input/index.tsx +46 -12
- package/src/components/area-chart/index.tsx +49 -37
- package/src/components/bottom-sheet/index.tsx +110 -12
- package/src/components/button/index.tsx +20 -1
- package/src/components/funnel-chart/index.tsx +10 -2
- package/src/components/heatmap-chart/index.tsx +27 -22
- package/src/components/hex-chart/index.tsx +22 -6
- package/src/components/line-chart/index.tsx +57 -43
- package/src/components/marquee/index.tsx +129 -6
- package/src/components/pie-chart/index.tsx +10 -2
- package/src/components/plot/index.tsx +66 -50
- package/src/components/progress-button/index.tsx +465 -0
- package/src/components/progress-button/progress-button-hold.ts +57 -0
- package/src/components/scatter-chart/index.tsx +4 -25
- package/src/components/section-rail/index.tsx +39 -19
- package/src/components/select/index.tsx +1 -1
- package/src/components/slider/index.tsx +1 -1
- package/src/components/split-view/index.tsx +53 -8
- package/src/components/switch/index.tsx +1 -1
- package/src/components/timeline/index.tsx +143 -17
- package/src/components/toast/index.tsx +60 -11
- package/src/components/treemap-chart/index.tsx +65 -8
- package/src/components/waterfall-chart/index.tsx +14 -4
- package/src/hooks/index.ts +5 -0
- package/src/hooks/use-scroll-sections.ts +52 -3
- package/src/hooks/use-skeleton-handoff.ts +69 -0
- package/src/index.ts +10 -0
- package/src/native/index.ts +17 -0
|
@@ -89,7 +89,6 @@ import Animated, {
|
|
|
89
89
|
} from 'react-native-reanimated';
|
|
90
90
|
import Svg, {
|
|
91
91
|
Circle,
|
|
92
|
-
ClipPath,
|
|
93
92
|
Defs,
|
|
94
93
|
G,
|
|
95
94
|
Line as SvgLine,
|
|
@@ -142,7 +141,6 @@ export {
|
|
|
142
141
|
export type { Plot as PlotBox, ChartPoint } from '../../utils/chart';
|
|
143
142
|
|
|
144
143
|
const AnimatedPath = Animated.createAnimatedComponent(Path);
|
|
145
|
-
const AnimatedRect = Animated.createAnimatedComponent(Rect);
|
|
146
144
|
const AnimatedCircle = Animated.createAnimatedComponent(Circle);
|
|
147
145
|
|
|
148
146
|
/** Room left around the plot for the axis labels and the markers' rings. */
|
|
@@ -168,7 +166,7 @@ const LABEL_WIDTH = 120;
|
|
|
168
166
|
* stays a flat list of children instead of three nested slots whose order the
|
|
169
167
|
* caller has to remember.
|
|
170
168
|
*/
|
|
171
|
-
type Layer = 'svg' | 'overlay' | 'header';
|
|
169
|
+
type Layer = 'svg' | 'series' | 'overlay' | 'header';
|
|
172
170
|
|
|
173
171
|
export type PlotStatus = 'loading' | 'ready';
|
|
174
172
|
export type PlotCurve = 'monotone' | 'linear';
|
|
@@ -229,7 +227,6 @@ export interface PlotGeometry {
|
|
|
229
227
|
activeIndexJS: number;
|
|
230
228
|
setActiveIndexJS: (index: number) => void;
|
|
231
229
|
/** The clip every mark shares, so they are revealed as one drawing. */
|
|
232
|
-
clipId: string;
|
|
233
230
|
}
|
|
234
231
|
|
|
235
232
|
const PlotContext = createContext<PlotGeometry | null>(null);
|
|
@@ -355,7 +352,6 @@ const PlotRoot = forwardRef<PlotHandle, PlotProps>(function PlotRoot(
|
|
|
355
352
|
const [size, setSize] = useState({ width: 0, height: 0 });
|
|
356
353
|
const [registrations, setRegistrations] = useState<PlotSeriesRegistration[]>([]);
|
|
357
354
|
const [activeIndexJS, setActiveIndexJS] = useState(-1);
|
|
358
|
-
const clipId = `panelui-plot-${useId().replace(/[^a-zA-Z0-9]/g, '')}`;
|
|
359
355
|
|
|
360
356
|
const reveal = useSharedValue(0);
|
|
361
357
|
const domainMin = useSharedValue(0);
|
|
@@ -584,7 +580,6 @@ const PlotRoot = forwardRef<PlotHandle, PlotProps>(function PlotRoot(
|
|
|
584
580
|
activeIndex,
|
|
585
581
|
activeIndexJS,
|
|
586
582
|
setActiveIndexJS: handleActiveIndex,
|
|
587
|
-
clipId,
|
|
588
583
|
}),
|
|
589
584
|
// `plot` is rebuilt every render from `size`, so it is compared by value.
|
|
590
585
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -608,13 +603,12 @@ const PlotRoot = forwardRef<PlotHandle, PlotProps>(function PlotRoot(
|
|
|
608
603
|
activeIndex,
|
|
609
604
|
activeIndexJS,
|
|
610
605
|
handleActiveIndex,
|
|
611
|
-
clipId,
|
|
612
606
|
]
|
|
613
607
|
);
|
|
614
608
|
|
|
615
|
-
const
|
|
609
|
+
const revealStyle = useAnimatedStyle(() => ({ width: plot.width * reveal.value }));
|
|
616
610
|
|
|
617
|
-
const { svg, overlay, header } = partition(children);
|
|
611
|
+
const { svg, series: seriesLayer, overlay, header } = partition(children);
|
|
618
612
|
|
|
619
613
|
/*
|
|
620
614
|
* Two views, because the header is not part of the plot. `aspectRatio` and
|
|
@@ -649,32 +643,45 @@ const PlotRoot = forwardRef<PlotHandle, PlotProps>(function PlotRoot(
|
|
|
649
643
|
{plot.width > 0 ? (
|
|
650
644
|
<>
|
|
651
645
|
<Svg width="100%" height="100%" style={StyleSheet.absoluteFill}>
|
|
652
|
-
<Defs>
|
|
653
|
-
{/*
|
|
654
|
-
* One clip for every mark. Sharing it is what makes the reveal
|
|
655
|
-
* read as the chart arriving, rather than as four separate
|
|
656
|
-
* things animating in at once — which is the thing a composed
|
|
657
|
-
* chart is most at risk of looking like.
|
|
658
|
-
*
|
|
659
|
-
* `width` is set statically as well as animated, and it has
|
|
660
|
-
* to be. Animated props on an element inside `Defs` do not
|
|
661
|
-
* reach the native clip on every platform, and with the width
|
|
662
|
-
* coming only from the animation there is no width at all
|
|
663
|
-
* when they do not — an empty clip, and marks that never
|
|
664
|
-
* appear while the axes draw normally.
|
|
665
|
-
*/}
|
|
666
|
-
<ClipPath id={clipId}>
|
|
667
|
-
<AnimatedRect
|
|
668
|
-
x={plot.left}
|
|
669
|
-
y={0}
|
|
670
|
-
width={plot.width}
|
|
671
|
-
height={size.height}
|
|
672
|
-
animatedProps={clipProps}
|
|
673
|
-
/>
|
|
674
|
-
</ClipPath>
|
|
675
|
-
</Defs>
|
|
676
646
|
{svg}
|
|
677
647
|
</Svg>
|
|
648
|
+
{/*
|
|
649
|
+
* One reveal for every mark, and it is a view that grows rather
|
|
650
|
+
* than an SVG clip path. Sharing it is what makes the reveal read
|
|
651
|
+
* as the chart arriving, rather than as four separate things
|
|
652
|
+
* animating in at once — which is the thing a composed chart is
|
|
653
|
+
* most at risk of looking like.
|
|
654
|
+
*
|
|
655
|
+
* It used to be an animated `<Rect>` inside `<Defs>`, and on
|
|
656
|
+
* Android those animated props never reach the native clip — the
|
|
657
|
+
* rect keeps whatever width was declared on it, so the marks drew
|
|
658
|
+
* complete and the reveal simply did not play. A view with
|
|
659
|
+
* `overflow: 'hidden'` is clipped by the platform itself, which
|
|
660
|
+
* both platforms agree on.
|
|
661
|
+
*
|
|
662
|
+
* Animating `width` is normally a layout pass per frame. Here the
|
|
663
|
+
* view is absolutely positioned and its only child is an `<Svg>`
|
|
664
|
+
* with an explicit width and height, so the work is one node and
|
|
665
|
+
* nothing around it moves.
|
|
666
|
+
*
|
|
667
|
+
* The inner `<Svg>` is pulled back by `plot.left` so the marks
|
|
668
|
+
* keep the same coordinate space as the grid underneath them.
|
|
669
|
+
*/}
|
|
670
|
+
<Animated.View
|
|
671
|
+
pointerEvents="none"
|
|
672
|
+
style={[
|
|
673
|
+
{ position: 'absolute', top: 0, bottom: 0, left: plot.left, overflow: 'hidden' },
|
|
674
|
+
revealStyle,
|
|
675
|
+
]}
|
|
676
|
+
>
|
|
677
|
+
<Svg
|
|
678
|
+
width={size.width}
|
|
679
|
+
height={size.height}
|
|
680
|
+
style={{ position: 'absolute', top: 0, left: -plot.left }}
|
|
681
|
+
>
|
|
682
|
+
{seriesLayer}
|
|
683
|
+
</Svg>
|
|
684
|
+
</Animated.View>
|
|
678
685
|
{overlay}
|
|
679
686
|
</>
|
|
680
687
|
) : null}
|
|
@@ -688,20 +695,29 @@ PlotRoot.displayName = 'Plot';
|
|
|
688
695
|
/** Sorts the children into the SVG tree, the view layer over it, and the header. */
|
|
689
696
|
function partition(children: ReactNode) {
|
|
690
697
|
const svg: ReactNode[] = [];
|
|
698
|
+
const series: ReactNode[] = [];
|
|
691
699
|
const overlay: ReactNode[] = [];
|
|
692
700
|
const header: ReactNode[] = [];
|
|
693
701
|
|
|
694
702
|
Children.forEach(children, (child, index) => {
|
|
695
703
|
if (!isValidElement(child)) return;
|
|
696
704
|
const layer = (child.type as { layer?: Layer }).layer ?? 'svg';
|
|
697
|
-
|
|
705
|
+
const bucket =
|
|
706
|
+
layer === 'header'
|
|
707
|
+
? header
|
|
708
|
+
: layer === 'overlay'
|
|
709
|
+
? overlay
|
|
710
|
+
: layer === 'series'
|
|
711
|
+
? series
|
|
712
|
+
: svg;
|
|
713
|
+
bucket.push(
|
|
698
714
|
// Children of a `Children.forEach` need keys of their own once they are
|
|
699
715
|
// put into a new array.
|
|
700
716
|
<ChildSlot key={index}>{child}</ChildSlot>
|
|
701
717
|
);
|
|
702
718
|
});
|
|
703
719
|
|
|
704
|
-
return { svg, overlay, header };
|
|
720
|
+
return { svg, series, overlay, header };
|
|
705
721
|
}
|
|
706
722
|
|
|
707
723
|
/** Identity wrapper, purely so the partitioned arrays can carry keys. */
|
|
@@ -801,7 +817,7 @@ function PlotLine({
|
|
|
801
817
|
curve = 'monotone',
|
|
802
818
|
dashArray,
|
|
803
819
|
}: PlotLineProps) {
|
|
804
|
-
const { data, plot, xScale, domainMin, domainMax, status
|
|
820
|
+
const { data, plot, xScale, domainMin, domainMax, status } =
|
|
805
821
|
useChart('Plot.Line');
|
|
806
822
|
const stroke = useMark(dataKey, color, colorIndex);
|
|
807
823
|
|
|
@@ -830,7 +846,7 @@ function PlotLine({
|
|
|
830
846
|
if (status === 'loading') return null;
|
|
831
847
|
|
|
832
848
|
return (
|
|
833
|
-
<G
|
|
849
|
+
<G>
|
|
834
850
|
<AnimatedPath
|
|
835
851
|
animatedProps={animatedProps}
|
|
836
852
|
fill="none"
|
|
@@ -844,7 +860,7 @@ function PlotLine({
|
|
|
844
860
|
);
|
|
845
861
|
}
|
|
846
862
|
PlotLine.displayName = 'Plot.Line';
|
|
847
|
-
PlotLine.layer = '
|
|
863
|
+
PlotLine.layer = 'series' as Layer;
|
|
848
864
|
|
|
849
865
|
export interface PlotAreaProps extends PlotSeriesProps {
|
|
850
866
|
opacity?: number;
|
|
@@ -864,7 +880,7 @@ function PlotArea({
|
|
|
864
880
|
opacity = 0.18,
|
|
865
881
|
curve = 'monotone',
|
|
866
882
|
}: PlotAreaProps) {
|
|
867
|
-
const { data, plot, xScale, domainMin, domainMax, status
|
|
883
|
+
const { data, plot, xScale, domainMin, domainMax, status } =
|
|
868
884
|
useChart('Plot.Area');
|
|
869
885
|
const fill = useMark(dataKey, color, colorIndex);
|
|
870
886
|
const values = useMemo(() => columnValues(data, dataKey), [data, dataKey]);
|
|
@@ -882,13 +898,13 @@ function PlotArea({
|
|
|
882
898
|
if (status === 'loading') return null;
|
|
883
899
|
|
|
884
900
|
return (
|
|
885
|
-
<G
|
|
901
|
+
<G>
|
|
886
902
|
<AnimatedPath animatedProps={animatedProps} fill={fill} fillOpacity={opacity} />
|
|
887
903
|
</G>
|
|
888
904
|
);
|
|
889
905
|
}
|
|
890
906
|
PlotArea.displayName = 'Plot.Area';
|
|
891
|
-
PlotArea.layer = '
|
|
907
|
+
PlotArea.layer = 'series' as Layer;
|
|
892
908
|
|
|
893
909
|
export interface PlotBarsProps extends PlotSeriesProps {
|
|
894
910
|
/** Fraction of each slice left empty, `0` to `1`. */
|
|
@@ -928,7 +944,7 @@ function PlotBars({
|
|
|
928
944
|
opacity = 1,
|
|
929
945
|
baseline = 0,
|
|
930
946
|
}: PlotBarsProps) {
|
|
931
|
-
const { data, plot, domainMin, domainMax, status
|
|
947
|
+
const { data, plot, domainMin, domainMax, status } = useChart('Plot.Bars');
|
|
932
948
|
const fill = useMark(dataKey, color, colorIndex);
|
|
933
949
|
const values = useMemo(() => columnValues(data, dataKey), [data, dataKey]);
|
|
934
950
|
|
|
@@ -972,13 +988,13 @@ function PlotBars({
|
|
|
972
988
|
if (status === 'loading') return null;
|
|
973
989
|
|
|
974
990
|
return (
|
|
975
|
-
<G
|
|
991
|
+
<G>
|
|
976
992
|
<AnimatedPath animatedProps={animatedProps} fill={fill} fillOpacity={opacity} />
|
|
977
993
|
</G>
|
|
978
994
|
);
|
|
979
995
|
}
|
|
980
996
|
PlotBars.displayName = 'Plot.Bars';
|
|
981
|
-
PlotBars.layer = '
|
|
997
|
+
PlotBars.layer = 'series' as Layer;
|
|
982
998
|
// Read by the root before it resolves the scale: a mark with width cannot sit
|
|
983
999
|
// on a point scale without half of the first and last one leaving the plot.
|
|
984
1000
|
PlotBars.mark = 'band' as const;
|
|
@@ -998,7 +1014,7 @@ function PlotDots({
|
|
|
998
1014
|
size = 3.5,
|
|
999
1015
|
ringWidth = 2,
|
|
1000
1016
|
}: PlotDotsProps) {
|
|
1001
|
-
const { data, plot, xScale, domainMin, domainMax, status
|
|
1017
|
+
const { data, plot, xScale, domainMin, domainMax, status } =
|
|
1002
1018
|
useChart('Plot.Dots');
|
|
1003
1019
|
const fill = useMark(dataKey, color, colorIndex);
|
|
1004
1020
|
const ringToken = useCSSVariable('--color-background');
|
|
@@ -1007,7 +1023,7 @@ function PlotDots({
|
|
|
1007
1023
|
const banded = xScale === 'band';
|
|
1008
1024
|
|
|
1009
1025
|
return (
|
|
1010
|
-
<G
|
|
1026
|
+
<G>
|
|
1011
1027
|
{status === 'loading'
|
|
1012
1028
|
? null
|
|
1013
1029
|
: values.map((value, index) =>
|
|
@@ -1034,7 +1050,7 @@ function PlotDots({
|
|
|
1034
1050
|
);
|
|
1035
1051
|
}
|
|
1036
1052
|
PlotDots.displayName = 'Plot.Dots';
|
|
1037
|
-
PlotDots.layer = '
|
|
1053
|
+
PlotDots.layer = 'series' as Layer;
|
|
1038
1054
|
|
|
1039
1055
|
/** One dot, whose y follows the domain tween. */
|
|
1040
1056
|
function Dot({
|
|
@@ -1087,11 +1103,11 @@ export interface PlotLayerProps {
|
|
|
1087
1103
|
* animates has to hold hooks of its own and a render prop is not a component.
|
|
1088
1104
|
*/
|
|
1089
1105
|
function PlotLayer({ children }: PlotLayerProps) {
|
|
1090
|
-
|
|
1091
|
-
return <G
|
|
1106
|
+
useChart('Plot.Layer');
|
|
1107
|
+
return <G>{children}</G>;
|
|
1092
1108
|
}
|
|
1093
1109
|
PlotLayer.displayName = 'Plot.Layer';
|
|
1094
|
-
PlotLayer.layer = '
|
|
1110
|
+
PlotLayer.layer = 'series' as Layer;
|
|
1095
1111
|
|
|
1096
1112
|
/* -------------------------------------------------------------------------- */
|
|
1097
1113
|
/* Overlay layer */
|