panelui-native 0.44.0 → 0.46.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 (53) hide show
  1. package/README.md +2 -1
  2. package/lib/module/components/combobox/index.js +7 -1
  3. package/lib/module/components/combobox/index.js.map +1 -1
  4. package/lib/module/components/date-time-picker/index.js +254 -0
  5. package/lib/module/components/date-time-picker/index.js.map +1 -0
  6. package/lib/module/components/grid-item/index.js +486 -0
  7. package/lib/module/components/grid-item/index.js.map +1 -0
  8. package/lib/module/components/{kpi-chart → kpi}/index.js +62 -62
  9. package/lib/module/components/kpi/index.js.map +1 -0
  10. package/lib/module/components/line-chart/index.js +92 -10
  11. package/lib/module/components/line-chart/index.js.map +1 -1
  12. package/lib/module/components/pie-chart/index.js +625 -0
  13. package/lib/module/components/pie-chart/index.js.map +1 -0
  14. package/lib/module/components/scatter-chart/index.js +1173 -0
  15. package/lib/module/components/scatter-chart/index.js.map +1 -0
  16. package/lib/module/components/tabs/index.js +275 -33
  17. package/lib/module/components/tabs/index.js.map +1 -1
  18. package/lib/module/index.js +5 -1
  19. package/lib/module/index.js.map +1 -1
  20. package/lib/module/utils/chart.js +81 -0
  21. package/lib/module/utils/chart.js.map +1 -1
  22. package/lib/typescript/src/components/combobox/index.d.ts.map +1 -1
  23. package/lib/typescript/src/components/date-time-picker/index.d.ts +121 -0
  24. package/lib/typescript/src/components/date-time-picker/index.d.ts.map +1 -0
  25. package/lib/typescript/src/components/grid-item/index.d.ts +292 -0
  26. package/lib/typescript/src/components/grid-item/index.d.ts.map +1 -0
  27. package/lib/typescript/src/components/{kpi-chart → kpi}/index.d.ts +65 -65
  28. package/lib/typescript/src/components/kpi/index.d.ts.map +1 -0
  29. package/lib/typescript/src/components/line-chart/index.d.ts +25 -1
  30. package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
  31. package/lib/typescript/src/components/pie-chart/index.d.ts +245 -0
  32. package/lib/typescript/src/components/pie-chart/index.d.ts.map +1 -0
  33. package/lib/typescript/src/components/scatter-chart/index.d.ts +309 -0
  34. package/lib/typescript/src/components/scatter-chart/index.d.ts.map +1 -0
  35. package/lib/typescript/src/components/tabs/index.d.ts +20 -2
  36. package/lib/typescript/src/components/tabs/index.d.ts.map +1 -1
  37. package/lib/typescript/src/index.d.ts +6 -2
  38. package/lib/typescript/src/index.d.ts.map +1 -1
  39. package/lib/typescript/src/utils/chart.d.ts +34 -0
  40. package/lib/typescript/src/utils/chart.d.ts.map +1 -1
  41. package/package.json +1 -1
  42. package/src/components/combobox/index.tsx +7 -1
  43. package/src/components/date-time-picker/index.tsx +375 -0
  44. package/src/components/grid-item/index.tsx +515 -0
  45. package/src/components/{kpi-chart → kpi}/index.tsx +85 -85
  46. package/src/components/line-chart/index.tsx +98 -8
  47. package/src/components/pie-chart/index.tsx +863 -0
  48. package/src/components/scatter-chart/index.tsx +1401 -0
  49. package/src/components/tabs/index.tsx +305 -35
  50. package/src/index.ts +65 -17
  51. package/src/utils/chart.ts +110 -0
  52. package/lib/module/components/kpi-chart/index.js.map +0 -1
  53. package/lib/typescript/src/components/kpi-chart/index.d.ts.map +0 -1
@@ -15,6 +15,15 @@
15
15
  * <Tabs.Content value="account">…</Tabs.Content>
16
16
  * </Tabs>
17
17
  * ```
18
+ *
19
+ * **Swiping.** Only the visible panel is mounted, so a drag has nothing behind
20
+ * it to reveal. The panel still tracks the finger one to one and dims as it
21
+ * goes, and the panel arriving comes back up through the same fade — the
22
+ * movement carries the change and the dissolve covers the gap. On release the
23
+ * arriving panel picks up a whole panel's width from wherever the outgoing one
24
+ * was let go, so the two views draw one continuous movement between them. The
25
+ * displacement lives on the root for exactly that reason: a value belonging to
26
+ * either panel would be destroyed at the handover.
18
27
  */
19
28
  import {
20
29
  createContext,
@@ -35,11 +44,16 @@ import {
35
44
  } from 'react-native';
36
45
  import { Gesture, GestureDetector } from 'react-native-gesture-handler';
37
46
  import Animated, {
47
+ Easing,
48
+ Extrapolation,
38
49
  FadeIn,
50
+ interpolate,
39
51
  runOnJS,
40
52
  useAnimatedStyle,
53
+ useReducedMotion,
41
54
  useSharedValue,
42
55
  withSpring,
56
+ withTiming,
43
57
  type SharedValue,
44
58
  } from 'react-native-reanimated';
45
59
  import { tv } from 'tailwind-variants';
@@ -64,32 +78,56 @@ const SWIPE_DISTANCE_RATIO = 0.25;
64
78
  const SWIPE_VELOCITY = 500;
65
79
 
66
80
  /**
67
- * How much of the finger's travel the panel actually follows.
81
+ * How much of the finger's travel the panel follows at the ends of the row,
82
+ * where there is nowhere for it to go. Everywhere else it follows all of it.
83
+ */
84
+ const SWIPE_RESISTANCE_AT_END = 0.16;
85
+
86
+ /**
87
+ * How far the panel fades as it is dragged, at a full panel's width.
68
88
  *
69
- * Not all of it: a panel that tracked one-to-one would look like a pager that
70
- * is about to reveal the next panel, and there is nothing behind it to reveal
71
- * — the panels are separate views, only one of which is mounted. A third of
72
- * the distance is enough to say the gesture was received.
89
+ * Tracking the finger one to one leaves the space behind the panel empty,
90
+ * because the panels are separate views and only the visible one is mounted.
91
+ * Dimming as it goes is what keeps that from reading as a hole punched in the
92
+ * card: a panel on its way out is on its way out, and the one arriving comes
93
+ * back up through the same fade. The two together read as a dissolve carried
94
+ * by the movement, rather than as a gap between two slides.
73
95
  */
74
- const SWIPE_FOLLOW = 0.32;
75
- /** …and a fraction of that again at the ends, where there is nowhere to go. */
76
- const SWIPE_FOLLOW_AT_END = 0.1;
96
+ const SWIPE_FADE = 0.75;
77
97
 
78
98
  /**
79
- * How far off its resting place the arriving panel starts, as a share of the
80
- * panel's width.
99
+ * How far off its resting place a panel arriving by a *press* starts, as a
100
+ * share of the panel's width.
81
101
  *
82
- * A swipe that commits should not look like a swipe that was cancelled. Both
83
- * end with a panel settling at rest, and the only thing that distinguishes
84
- * them is which side it settled *from* — so the incoming panel picks up
85
- * roughly where the outgoing one was let go, on the far side, and travels in.
102
+ * A press has no finger travel to continue from, so it is given a throw of its
103
+ * own. A swipe does not use this: the panel it hands over to picks up exactly
104
+ * where the outgoing one was let go — see `setValue`.
86
105
  */
87
106
  const SWIPE_ENTER = 0.3;
88
107
 
89
108
  /** The arriving panel is springier than the one being dragged back into place. */
90
109
  const ENTER_SPRING = { damping: 22, stiffness: 240, mass: 0.6 } as const;
91
110
 
92
- export type TabsVariant = 'segmented' | 'underline' | 'pill';
111
+ /** How far the label's reveal is from its own width, in points — the gap after the icon. */
112
+ const LABEL_GAP = 6;
113
+
114
+ /** Points of room over the measured label, so a rounding error cannot truncate it. */
115
+ const LABEL_SLACK = 2;
116
+
117
+ /** Milliseconds for a tab to open its label, and for the one before it to close. */
118
+ const EXPAND_DURATION = 260;
119
+
120
+ /**
121
+ * A width the ghost label is measured inside.
122
+ *
123
+ * A `Text` measures against the box it is in, and the box it is really in is a
124
+ * pill whose width is the thing being measured. So the copy that gets measured
125
+ * sits in a box wide enough not to be the constraint, and reports the width the
126
+ * label actually wants.
127
+ */
128
+ const MEASURE_WIDTH = 400;
129
+
130
+ export type TabsVariant = 'segmented' | 'underline' | 'pill' | 'expanding';
93
131
 
94
132
  const tabsVariants = tv({
95
133
  slots: {
@@ -120,6 +158,22 @@ const tabsVariants = tv({
120
158
  indicator: 'bottom-0 top-0 rounded-full bg-primary',
121
159
  trigger: 'rounded-full py-2',
122
160
  },
161
+ /*
162
+ * A row of icon pills, one of which is open.
163
+ *
164
+ * Every tab draws its own pill here, so there is no indicator to slide
165
+ * between them — the shape that moves is the open tab itself, widening
166
+ * to let its label out and closing again behind it. An indicator sliding
167
+ * under pills that already have backgrounds would be invisible anyway.
168
+ *
169
+ * The open pill is a step further from the page than the closed ones:
170
+ * lighter in a dark theme, darker in a light one, which is what the
171
+ * tertiary surface token means and why it is used rather than a colour.
172
+ */
173
+ expanding: {
174
+ list: 'gap-1.5',
175
+ trigger: 'rounded-full bg-muted px-3.5 py-2.5',
176
+ },
123
177
  },
124
178
  active: {
125
179
  true: { label: 'text-foreground' },
@@ -136,6 +190,11 @@ const tabsVariants = tv({
136
190
  },
137
191
  compoundVariants: [
138
192
  { variant: 'pill', active: true, class: { label: 'text-primary-foreground' } },
193
+ // A pill is as wide as what is inside it. Equal shares would give every
194
+ // closed tab the width of the open one, which is the layout this variant
195
+ // exists to avoid.
196
+ { variant: 'expanding', class: { trigger: 'flex-none' } },
197
+ { variant: 'expanding', active: true, class: { trigger: 'bg-surface-tertiary' } },
139
198
  ],
140
199
  defaultVariants: {
141
200
  variant: 'segmented',
@@ -148,9 +207,19 @@ interface TabLayout {
148
207
  width: number;
149
208
  }
150
209
 
210
+ /**
211
+ * What a swipe hands over to the tab it commits to: where the finger left the
212
+ * outgoing panel, and how fast it was still going. Absent when the tab was
213
+ * changed by pressing a trigger, which has neither.
214
+ */
215
+ interface SwipeHandover {
216
+ /** Points per second at the moment of release, in the panel's own axis. */
217
+ velocity: number;
218
+ }
219
+
151
220
  interface TabsContextValue {
152
221
  value: string;
153
- setValue: (value: string) => void;
222
+ setValue: (value: string, handover?: SwipeHandover) => void;
154
223
  registerLayout: (value: string, layout: TabLayout) => void;
155
224
  layouts: Record<string, TabLayout>;
156
225
  /**
@@ -200,6 +269,12 @@ export interface TabsProps extends ViewProps {
200
269
  /**
201
270
  * `segmented` is a chip travelling inside a recessed track, `underline` is a
202
271
  * rule under the active tab, `pill` is a filled chip on the page.
272
+ *
273
+ * `expanding` is a row of icon pills where only the selected one is open:
274
+ * it widens to let its label out and closes again behind it. For a short row
275
+ * of destinations that are recognisable by their icons, where the labels
276
+ * would otherwise take the whole width to say things nobody rereads. Give
277
+ * every trigger an `icon` — a closed tab has nothing else.
203
278
  */
204
279
  variant?: TabsVariant;
205
280
  /**
@@ -245,7 +320,7 @@ function TabsRoot({
245
320
  const resolvedValue = isControlled ? value : internalValue;
246
321
 
247
322
  const setValue = useCallback(
248
- (next: string) => {
323
+ (next: string, handover?: SwipeHandover) => {
249
324
  /*
250
325
  * The arriving panel starts on the side it is arriving from, and travels
251
326
  * in. Done here rather than in the panel because only the root knows
@@ -258,9 +333,28 @@ function TabsRoot({
258
333
  const from = tabs.indexOf(resolvedValue);
259
334
  const to = tabs.indexOf(next);
260
335
  if (from !== -1 && to !== -1 && from !== to) {
261
- swipeOffset.value =
262
- (to > from ? 1 : -1) * sign * panelWidth.value * SWIPE_ENTER;
263
- swipeOffset.value = withSpring(0, ENTER_SPRING);
336
+ const direction = to > from ? 1 : -1;
337
+
338
+ if (handover) {
339
+ /*
340
+ * A swipe hands over mid-movement, so the arriving panel starts a
341
+ * whole panel's width from wherever the outgoing one was let go —
342
+ * which is where it *would* have been all along, had both been
343
+ * mounted. Adding to the displacement rather than replacing it is
344
+ * the entire difference between one continuous movement and a jump
345
+ * at the moment the finger lifts.
346
+ */
347
+ swipeOffset.value += direction * sign * panelWidth.value;
348
+ swipeOffset.value = withSpring(0, {
349
+ ...ENTER_SPRING,
350
+ // Carried across too, so a flick keeps its speed instead of
351
+ // stopping dead and starting again from rest.
352
+ velocity: handover.velocity,
353
+ });
354
+ } else {
355
+ swipeOffset.value = direction * sign * panelWidth.value * SWIPE_ENTER;
356
+ swipeOffset.value = withSpring(0, ENTER_SPRING);
357
+ }
264
358
  }
265
359
  }
266
360
 
@@ -414,7 +508,9 @@ function TabsList({ className, scrollable = false, children, ...props }: TabsLis
414
508
 
415
509
  const row = (
416
510
  <View accessibilityRole="tablist" className={cn(list(), className)} {...props}>
417
- <TabsIndicator />
511
+ {/* Nothing to slide: in `expanding` every tab draws its own pill, and the
512
+ open one is the shape that moves. */}
513
+ {variant === 'expanding' ? null : <TabsIndicator />}
418
514
  {textChildren(children)}
419
515
  </View>
420
516
  );
@@ -438,7 +534,10 @@ function TabsList({ className, scrollable = false, children, ...props }: TabsLis
438
534
  export interface TabsTriggerProps {
439
535
  className?: string;
440
536
  value: string;
441
- /** Rendered before the label. */
537
+ /**
538
+ * Rendered before the label. Required by `variant="expanding"`, where it is
539
+ * the only thing a closed tab has left to identify it by.
540
+ */
442
541
  icon?: ReactNode;
443
542
  /** Rendered after the label — a count, a dot, a status. */
444
543
  badge?: ReactNode;
@@ -481,6 +580,23 @@ function TabsTrigger({
481
580
  return () => unregisterTab(value);
482
581
  }, [value, registerTab, unregisterTab]);
483
582
 
583
+ if (context.variant === 'expanding') {
584
+ return (
585
+ <ExpandingTrigger
586
+ active={active}
587
+ disabled={disabled}
588
+ icon={icon}
589
+ badge={badge}
590
+ labelClassName={slots.label()}
591
+ className={cn(slots.trigger(), className)}
592
+ onLayout={handleLayout}
593
+ onPress={() => context.setValue(value)}
594
+ >
595
+ {children}
596
+ </ExpandingTrigger>
597
+ );
598
+ }
599
+
484
600
  return (
485
601
  <Pressable
486
602
  accessibilityRole="tab"
@@ -501,6 +617,142 @@ function TabsTrigger({
501
617
  );
502
618
  }
503
619
 
620
+ /**
621
+ * A tab that is an icon until it is selected, and then an icon and its label.
622
+ *
623
+ * The label is never unmounted, only closed over. Two reasons, and both matter:
624
+ * a screen reader walking a row of unlabelled icons has nothing to read out,
625
+ * and a label that mounts on selection has no width to animate *from*, so the
626
+ * pill would jump to its open size and the text would fade in inside it.
627
+ *
628
+ * So the width is animated instead, which needs a number — and the number is
629
+ * the one thing that cannot be measured in place, because the box the label
630
+ * sits in is the box being resized. A second copy, laid out once in a box wide
631
+ * enough not to constrain it, reports the width and is never seen.
632
+ */
633
+ function ExpandingTrigger({
634
+ active,
635
+ disabled,
636
+ icon,
637
+ badge,
638
+ className,
639
+ labelClassName,
640
+ onLayout,
641
+ onPress,
642
+ children,
643
+ }: {
644
+ active: boolean;
645
+ disabled: boolean;
646
+ icon?: ReactNode;
647
+ badge?: ReactNode;
648
+ className: string;
649
+ labelClassName: string;
650
+ onLayout: (event: LayoutChangeEvent) => void;
651
+ onPress: () => void;
652
+ children: ReactNode;
653
+ }) {
654
+ const [labelWidth, setLabelWidth] = useState(0);
655
+ const reducedMotion = useReducedMotion();
656
+ const open = useSharedValue(active ? 1 : 0);
657
+
658
+ useEffect(() => {
659
+ if (reducedMotion) {
660
+ open.value = active ? 1 : 0;
661
+ return;
662
+ }
663
+ /*
664
+ * A curve, not a spring.
665
+ *
666
+ * This animates a *width*, so every frame of it is a layout pass — and the
667
+ * row is centred, so every other pill moves with it. A spring overshoots
668
+ * past its target and settles back, which on a box that is clipping text
669
+ * means the last word slides in, out and in again, and the whole row
670
+ * wobbles with it. The curve leaves quickly and arrives slowly, and it
671
+ * arrives once.
672
+ */
673
+ open.value = withTiming(active ? 1 : 0, {
674
+ duration: EXPAND_DURATION,
675
+ easing: Easing.bezier(0.2, 0, 0, 1),
676
+ });
677
+ }, [active, reducedMotion, open]);
678
+
679
+ const reveal = useAnimatedStyle(() => ({
680
+ width: (labelWidth + LABEL_GAP) * open.value,
681
+ /*
682
+ * Behind the width, not ahead of it. Text drawn into a box narrower than
683
+ * itself is text with its end cut off, and doing that on purpose for the
684
+ * first half of the animation is the difference between a label arriving
685
+ * and a label being wiped on.
686
+ */
687
+ opacity: interpolate(open.value, [0.35, 0.9], [0, 1], Extrapolation.CLAMP),
688
+ }));
689
+
690
+ const label = textChildren(children, (text) => (
691
+ <Text size="sm" weight="medium" numberOfLines={1} className={labelClassName}>
692
+ {text}
693
+ </Text>
694
+ ));
695
+
696
+ return (
697
+ <Pressable
698
+ accessibilityRole="tab"
699
+ accessibilityState={{ selected: active, disabled }}
700
+ // The label may be closed to nothing, and a tab announced as an unlabelled
701
+ // icon is a tab nobody can choose.
702
+ accessibilityLabel={typeof children === 'string' ? children : undefined}
703
+ disabled={disabled}
704
+ onPress={onPress}
705
+ onLayout={onLayout}
706
+ className={cn('flex-row items-center', className)}
707
+ >
708
+ {icon}
709
+ <Animated.View style={[{ overflow: 'hidden' }, reveal]}>
710
+ {/*
711
+ * Pinned to the measured width so the text does not reflow as the box
712
+ * around it closes — a label that rewraps on its way out reads as a
713
+ * glitch rather than as a reveal.
714
+ *
715
+ * The gap after the icon is padding on this box, so it has to be added
716
+ * to the width rather than taken out of it. Set to the measured width
717
+ * alone, the padding comes off the inside and the label is handed six
718
+ * points less than it asked for, which a single-line `Text` answers by
719
+ * truncating: "Inbox" arrives as "Inbo…" and stays that way.
720
+ */}
721
+ <View style={{ width: labelWidth + LABEL_GAP, paddingStart: LABEL_GAP }}>
722
+ {label}
723
+ </View>
724
+ </Animated.View>
725
+ {/* Measured once, never seen, and out of the layout so it cannot widen
726
+ the pill it is measuring. */}
727
+ <View
728
+ pointerEvents="none"
729
+ style={{ position: 'absolute', opacity: 0, width: MEASURE_WIDTH }}
730
+ >
731
+ <View
732
+ style={{ alignSelf: 'flex-start' }}
733
+ onLayout={(event: LayoutChangeEvent) => {
734
+ /*
735
+ * Rounded up and given a couple of points over.
736
+ *
737
+ * The measurement and the box it is put back into are two different
738
+ * layout passes, and a fraction of a point between them is enough
739
+ * for a single-line `Text` to decide it does not fit and truncate —
740
+ * which shows up as a label permanently missing its last letter.
741
+ */
742
+ const measured = Math.ceil(event.nativeEvent.layout.width) + LABEL_SLACK;
743
+ if (measured > LABEL_SLACK && measured !== labelWidth) {
744
+ setLabelWidth(measured);
745
+ }
746
+ }}
747
+ >
748
+ {label}
749
+ </View>
750
+ </View>
751
+ {badge}
752
+ </Pressable>
753
+ );
754
+ }
755
+
504
756
  export interface TabsContentProps extends ViewProps {
505
757
  className?: string;
506
758
  value: string;
@@ -530,10 +782,10 @@ function TabsContent({ className, value, children, style, ...props }: TabsConten
530
782
  }, [position, tabs.length, index, count]);
531
783
 
532
784
  const step = useCallback(
533
- (delta: number) => {
785
+ (delta: number, velocity: number) => {
534
786
  const from = tabs.indexOf(value);
535
787
  const next = tabs[from + delta];
536
- if (next) setValue(next);
788
+ if (next) setValue(next, { velocity });
537
789
  },
538
790
  [tabs, value, setValue]
539
791
  );
@@ -552,8 +804,16 @@ function TabsContent({ className, value, children, style, ...props }: TabsConten
552
804
  const atEnd =
553
805
  (travel > 0 && index.value === 0) ||
554
806
  (travel < 0 && index.value >= count.value - 1);
555
- offset.value =
556
- event.translationX * (atEnd ? SWIPE_FOLLOW_AT_END : SWIPE_FOLLOW);
807
+ /*
808
+ * One to one, except at the ends. The panel is under the finger for
809
+ * the whole of the drag, which is what lets the handover on release
810
+ * continue the movement rather than restart it — and a panel that
811
+ * moved a third as far as the finger never felt attached to it in
812
+ * the first place.
813
+ */
814
+ offset.value = atEnd
815
+ ? event.translationX * SWIPE_RESISTANCE_AT_END
816
+ : event.translationX;
557
817
  })
558
818
  .onEnd((event) => {
559
819
  const travel = event.translationX * sign;
@@ -569,15 +829,20 @@ function TabsContent({ className, value, children, style, ...props }: TabsConten
569
829
  // reads as a cancel — so the direction comes from whichever of the
570
830
  // two crossed its threshold, speed first.
571
831
  //
572
- // No spring back to zero here: `setValue` on the root throws the
573
- // displacement across to the side the next panel arrives from, and
574
- // springing to rest first would undo it a frame before it happens.
575
- runOnJS(step)(fast ? (speed < 0 ? 1 : -1) : travel < 0 ? 1 : -1);
832
+ // No spring back to zero here: `setValue` on the root carries the
833
+ // displacement across to the arriving panel, and springing to rest
834
+ // first would undo it a frame before it happens.
835
+ runOnJS(step)(
836
+ fast ? (speed < 0 ? 1 : -1) : travel < 0 ? 1 : -1,
837
+ event.velocityX
838
+ );
576
839
  return;
577
840
  }
578
841
 
579
- // Nothing changed hands, so this panel simply comes back.
580
- offset.value = withSpring(0, SPRING);
842
+ // Nothing changed hands, so this panel simply comes back — with the
843
+ // speed it was let go at, so a cancelled flick decelerates rather
844
+ // than stopping and being pulled.
845
+ offset.value = withSpring(0, { ...SPRING, velocity: event.velocityX });
581
846
  })
582
847
  .onFinalize((_event, success) => {
583
848
  // A cancelled gesture never reaches `onEnd`, and would otherwise
@@ -587,9 +852,14 @@ function TabsContent({ className, value, children, style, ...props }: TabsConten
587
852
  [sign, step, offset, width, index, count]
588
853
  );
589
854
 
590
- const followStyle = useAnimatedStyle(() => ({
591
- transform: [{ translateX: offset.value }],
592
- }));
855
+ const followStyle = useAnimatedStyle(() => {
856
+ const span = width.value || 1;
857
+ const travelled = Math.min(1, Math.abs(offset.value) / span);
858
+ return {
859
+ transform: [{ translateX: offset.value }],
860
+ opacity: 1 - SWIPE_FADE * travelled,
861
+ };
862
+ });
593
863
 
594
864
  if (!active && !context.keepMounted) return null;
595
865
 
package/src/index.ts CHANGED
@@ -141,6 +141,11 @@ export {
141
141
  type DatePickerProps,
142
142
  type DatePickerMode,
143
143
  } from './components/date-picker';
144
+ export {
145
+ DateTimePicker,
146
+ type DateTimePickerProps,
147
+ type DateTimePickerPresentation,
148
+ } from './components/date-time-picker';
144
149
  export {
145
150
  Dialog,
146
151
  type DialogProps,
@@ -191,6 +196,18 @@ export {
191
196
  type FrameActionsProps,
192
197
  type FrameVariant,
193
198
  } from './components/frame';
199
+ export {
200
+ GridItem,
201
+ type GridItemProps,
202
+ type GridItemGroupProps,
203
+ type GridItemBackgroundProps,
204
+ type GridItemMediaProps,
205
+ type GridItemTitleProps,
206
+ type GridItemValueProps,
207
+ type GridItemDescriptionProps,
208
+ type GridItemFooterProps,
209
+ type GridItemActionsProps,
210
+ } from './components/grid-item';
194
211
  export {
195
212
  HeatmapChart,
196
213
  useHeatmapChart,
@@ -437,6 +454,19 @@ export {
437
454
  type PaginationSize,
438
455
  type PaginationItemValue,
439
456
  } from './components/pagination';
457
+ export {
458
+ PieChart,
459
+ usePieChart,
460
+ type PieChartProps,
461
+ type PieChartHandle,
462
+ type PieChartHeaderProps,
463
+ type PieChartSlicesProps,
464
+ type PieChartCenterProps,
465
+ type PieChartLegendProps,
466
+ type PieChartSkeletonProps,
467
+ type PieChartStatus,
468
+ type PieDatum,
469
+ } from './components/pie-chart';
440
470
  export { Textarea, type TextareaProps } from './components/textarea';
441
471
  export {
442
472
  Item,
@@ -452,25 +482,25 @@ export {
452
482
  type ItemFooterProps,
453
483
  } from './components/item';
454
484
  export {
455
- KpiChart,
456
- type KpiChartProps,
457
- type KpiChartHeaderProps,
458
- type KpiChartIconProps,
459
- type KpiChartTitleProps,
460
- type KpiChartStatProps,
461
- type KpiChartActionsProps,
462
- type KpiChartContentProps,
463
- type KpiChartValueProps,
464
- type KpiChartTrendProps,
465
- type KpiChartSparklineProps,
466
- type KpiChartProgressProps,
467
- type KpiChartFooterProps,
468
- type KpiChartSeparatorProps,
469
- type KpiChartGroupProps,
470
- type KpiChartGroupOrientation,
485
+ Kpi,
486
+ type KpiProps,
487
+ type KpiHeaderProps,
488
+ type KpiIconProps,
489
+ type KpiTitleProps,
490
+ type KpiStatProps,
491
+ type KpiActionsProps,
492
+ type KpiContentProps,
493
+ type KpiValueProps,
494
+ type KpiTrendProps,
495
+ type KpiSparklineProps,
496
+ type KpiProgressProps,
497
+ type KpiFooterProps,
498
+ type KpiSeparatorProps,
499
+ type KpiGroupProps,
500
+ type KpiGroupOrientation,
471
501
  type KpiGoodDirection,
472
502
  type KpiTone,
473
- } from './components/kpi-chart';
503
+ } from './components/kpi';
474
504
  export { Label, type LabelProps, type LabelTextProps } from './components/label';
475
505
  export {
476
506
  LineChart,
@@ -483,6 +513,7 @@ export {
483
513
  type LineChartAreaProps,
484
514
  type LineChartSkeletonProps,
485
515
  type LineChartXAxisProps,
516
+ type LineChartYAxisProps,
486
517
  type LineChartTooltipProps,
487
518
  type LineChartLegendProps,
488
519
  type LineChartDatum,
@@ -590,6 +621,23 @@ export {
590
621
  type RingChartLegendProps,
591
622
  type RingDatum,
592
623
  } from './components/ring-chart';
624
+ export {
625
+ ScatterChart,
626
+ useScatterChart,
627
+ type ScatterChartProps,
628
+ type ScatterChartHandle,
629
+ type ScatterChartHeaderProps,
630
+ type ScatterChartGridProps,
631
+ type ScatterChartPointsProps,
632
+ type ScatterChartSkeletonProps,
633
+ type ScatterChartXAxisProps,
634
+ type ScatterChartYAxisProps,
635
+ type ScatterChartTooltipProps,
636
+ type ScatterChartLegendProps,
637
+ type ScatterChartDatum,
638
+ type ScatterChartPoint,
639
+ type ScatterChartStatus,
640
+ } from './components/scatter-chart';
593
641
  export {
594
642
  ScrollFade,
595
643
  type ScrollFadeProps,