panelui-native 0.73.0 → 0.75.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 (192) hide show
  1. package/README.md +3 -1
  2. package/lib/module/components/avatar/avatar-group.js +64 -0
  3. package/lib/module/components/avatar/avatar-group.js.map +1 -0
  4. package/lib/module/components/avatar/index.js +84 -2
  5. package/lib/module/components/avatar/index.js.map +1 -1
  6. package/lib/module/components/color-picker/color-picker-accessibility.js +12 -0
  7. package/lib/module/components/color-picker/color-picker-accessibility.js.map +1 -0
  8. package/lib/module/components/color-picker/index.js +9 -5
  9. package/lib/module/components/color-picker/index.js.map +1 -1
  10. package/lib/module/components/date-time-picker/index.js +11 -3
  11. package/lib/module/components/date-time-picker/index.js.map +1 -1
  12. package/lib/module/components/drawer/index.js +58 -13
  13. package/lib/module/components/drawer/index.js.map +1 -1
  14. package/lib/module/components/input/index.js +7 -4
  15. package/lib/module/components/input/index.js.map +1 -1
  16. package/lib/module/components/input/input-content-padding.js +6 -0
  17. package/lib/module/components/input/input-content-padding.js.map +1 -0
  18. package/lib/module/components/input-group/index.js +14 -9
  19. package/lib/module/components/input-group/index.js.map +1 -1
  20. package/lib/module/components/input-group/input-group-measurements.js +60 -0
  21. package/lib/module/components/input-group/input-group-measurements.js.map +1 -0
  22. package/lib/module/components/otp-input/index.js +3 -1
  23. package/lib/module/components/otp-input/index.js.map +1 -1
  24. package/lib/module/components/otp-input/otp-input-state.js +7 -0
  25. package/lib/module/components/otp-input/otp-input-state.js.map +1 -0
  26. package/lib/module/components/planner/index.js +20 -6
  27. package/lib/module/components/planner/index.js.map +1 -1
  28. package/lib/module/components/planner/planner-today.js +8 -0
  29. package/lib/module/components/planner/planner-today.js.map +1 -0
  30. package/lib/module/components/plot/index.js +8 -11
  31. package/lib/module/components/plot/index.js.map +1 -1
  32. package/lib/module/components/plot/plot-series-registry.js +32 -0
  33. package/lib/module/components/plot/plot-series-registry.js.map +1 -0
  34. package/lib/module/components/radio-group/index.js +2 -1
  35. package/lib/module/components/radio-group/index.js.map +1 -1
  36. package/lib/module/components/radio-group/radio-group-value.js +8 -0
  37. package/lib/module/components/radio-group/radio-group-value.js.map +1 -0
  38. package/lib/module/components/rating/index.js +7 -4
  39. package/lib/module/components/rating/index.js.map +1 -1
  40. package/lib/module/components/rating/rating-inputs.js +15 -0
  41. package/lib/module/components/rating/rating-inputs.js.map +1 -0
  42. package/lib/module/components/search-bar/index.js +7 -7
  43. package/lib/module/components/search-bar/index.js.map +1 -1
  44. package/lib/module/components/search-bar/search-bar-debounce.js +23 -0
  45. package/lib/module/components/search-bar/search-bar-debounce.js.map +1 -0
  46. package/lib/module/components/select/index.js +9 -1
  47. package/lib/module/components/select/index.js.map +1 -1
  48. package/lib/module/components/select/native-select-contract.js +11 -0
  49. package/lib/module/components/select/native-select-contract.js.map +1 -0
  50. package/lib/module/components/split-view/index.js +439 -0
  51. package/lib/module/components/split-view/index.js.map +1 -0
  52. package/lib/module/components/split-view/split-view-math.js +132 -0
  53. package/lib/module/components/split-view/split-view-math.js.map +1 -0
  54. package/lib/module/components/splitter/index.js +433 -0
  55. package/lib/module/components/splitter/index.js.map +1 -0
  56. package/lib/module/components/splitter/splitter-math.js +206 -0
  57. package/lib/module/components/splitter/splitter-math.js.map +1 -0
  58. package/lib/module/components/steps/index.js +16 -5
  59. package/lib/module/components/steps/index.js.map +1 -1
  60. package/lib/module/components/steps/steps-trigger.js +6 -0
  61. package/lib/module/components/steps/steps-trigger.js.map +1 -0
  62. package/lib/module/components/tag-input/index.js +15 -10
  63. package/lib/module/components/tag-input/index.js.map +1 -1
  64. package/lib/module/components/tag-input/tag-input-state.js +14 -0
  65. package/lib/module/components/tag-input/tag-input-state.js.map +1 -0
  66. package/lib/module/components/textarea/index.js +9 -4
  67. package/lib/module/components/textarea/index.js.map +1 -1
  68. package/lib/module/components/textarea/textarea-disabled.js +6 -0
  69. package/lib/module/components/textarea/textarea-disabled.js.map +1 -0
  70. package/lib/module/components/timeline/index.js +83 -27
  71. package/lib/module/components/timeline/index.js.map +1 -1
  72. package/lib/module/components/timeline/timeline-geometry.js +11 -0
  73. package/lib/module/components/timeline/timeline-geometry.js.map +1 -0
  74. package/lib/module/components/toast/index.js +18 -1
  75. package/lib/module/components/toast/index.js.map +1 -1
  76. package/lib/module/components/toast/toast-store.js +36 -4
  77. package/lib/module/components/toast/toast-store.js.map +1 -1
  78. package/lib/module/components/tour/index.js +4 -2
  79. package/lib/module/components/tour/index.js.map +1 -1
  80. package/lib/module/components/tour/tour-card-measurement.js +24 -0
  81. package/lib/module/components/tour/tour-card-measurement.js.map +1 -0
  82. package/lib/module/index.js +2 -0
  83. package/lib/module/index.js.map +1 -1
  84. package/lib/typescript/src/components/avatar/avatar-group.d.ts +46 -0
  85. package/lib/typescript/src/components/avatar/avatar-group.d.ts.map +1 -0
  86. package/lib/typescript/src/components/avatar/index.d.ts +23 -1
  87. package/lib/typescript/src/components/avatar/index.d.ts.map +1 -1
  88. package/lib/typescript/src/components/color-picker/color-picker-accessibility.d.ts +8 -0
  89. package/lib/typescript/src/components/color-picker/color-picker-accessibility.d.ts.map +1 -0
  90. package/lib/typescript/src/components/color-picker/index.d.ts.map +1 -1
  91. package/lib/typescript/src/components/date-time-picker/index.d.ts.map +1 -1
  92. package/lib/typescript/src/components/drawer/index.d.ts.map +1 -1
  93. package/lib/typescript/src/components/input/index.d.ts.map +1 -1
  94. package/lib/typescript/src/components/input/input-content-padding.d.ts +2 -0
  95. package/lib/typescript/src/components/input/input-content-padding.d.ts.map +1 -0
  96. package/lib/typescript/src/components/input-group/index.d.ts.map +1 -1
  97. package/lib/typescript/src/components/input-group/input-group-measurements.d.ts +16 -0
  98. package/lib/typescript/src/components/input-group/input-group-measurements.d.ts.map +1 -0
  99. package/lib/typescript/src/components/otp-input/index.d.ts.map +1 -1
  100. package/lib/typescript/src/components/otp-input/otp-input-state.d.ts +3 -0
  101. package/lib/typescript/src/components/otp-input/otp-input-state.d.ts.map +1 -0
  102. package/lib/typescript/src/components/planner/index.d.ts.map +1 -1
  103. package/lib/typescript/src/components/planner/planner-today.d.ts +2 -0
  104. package/lib/typescript/src/components/planner/planner-today.d.ts.map +1 -0
  105. package/lib/typescript/src/components/plot/index.d.ts +1 -1
  106. package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
  107. package/lib/typescript/src/components/plot/plot-series-registry.d.ts +8 -0
  108. package/lib/typescript/src/components/plot/plot-series-registry.d.ts.map +1 -0
  109. package/lib/typescript/src/components/radio-group/index.d.ts.map +1 -1
  110. package/lib/typescript/src/components/radio-group/radio-group-value.d.ts +2 -0
  111. package/lib/typescript/src/components/radio-group/radio-group-value.d.ts.map +1 -0
  112. package/lib/typescript/src/components/rating/index.d.ts.map +1 -1
  113. package/lib/typescript/src/components/rating/rating-inputs.d.ts +4 -0
  114. package/lib/typescript/src/components/rating/rating-inputs.d.ts.map +1 -0
  115. package/lib/typescript/src/components/search-bar/index.d.ts.map +1 -1
  116. package/lib/typescript/src/components/search-bar/search-bar-debounce.d.ts +7 -0
  117. package/lib/typescript/src/components/search-bar/search-bar-debounce.d.ts.map +1 -0
  118. package/lib/typescript/src/components/select/index.d.ts.map +1 -1
  119. package/lib/typescript/src/components/select/native-select-contract.d.ts +11 -0
  120. package/lib/typescript/src/components/select/native-select-contract.d.ts.map +1 -0
  121. package/lib/typescript/src/components/split-view/index.d.ts +159 -0
  122. package/lib/typescript/src/components/split-view/index.d.ts.map +1 -0
  123. package/lib/typescript/src/components/split-view/split-view-math.d.ts +54 -0
  124. package/lib/typescript/src/components/split-view/split-view-math.d.ts.map +1 -0
  125. package/lib/typescript/src/components/splitter/index.d.ts +78 -0
  126. package/lib/typescript/src/components/splitter/index.d.ts.map +1 -0
  127. package/lib/typescript/src/components/splitter/splitter-math.d.ts +67 -0
  128. package/lib/typescript/src/components/splitter/splitter-math.d.ts.map +1 -0
  129. package/lib/typescript/src/components/steps/index.d.ts +2 -2
  130. package/lib/typescript/src/components/steps/index.d.ts.map +1 -1
  131. package/lib/typescript/src/components/steps/steps-trigger.d.ts +2 -0
  132. package/lib/typescript/src/components/steps/steps-trigger.d.ts.map +1 -0
  133. package/lib/typescript/src/components/tag-input/index.d.ts.map +1 -1
  134. package/lib/typescript/src/components/tag-input/tag-input-state.d.ts +12 -0
  135. package/lib/typescript/src/components/tag-input/tag-input-state.d.ts.map +1 -0
  136. package/lib/typescript/src/components/textarea/index.d.ts.map +1 -1
  137. package/lib/typescript/src/components/textarea/textarea-disabled.d.ts +2 -0
  138. package/lib/typescript/src/components/textarea/textarea-disabled.d.ts.map +1 -0
  139. package/lib/typescript/src/components/timeline/index.d.ts +1 -0
  140. package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
  141. package/lib/typescript/src/components/timeline/timeline-geometry.d.ts +4 -0
  142. package/lib/typescript/src/components/timeline/timeline-geometry.d.ts.map +1 -0
  143. package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
  144. package/lib/typescript/src/components/toast/toast-store.d.ts +7 -2
  145. package/lib/typescript/src/components/toast/toast-store.d.ts.map +1 -1
  146. package/lib/typescript/src/components/tour/index.d.ts.map +1 -1
  147. package/lib/typescript/src/components/tour/tour-card-measurement.d.ts +14 -0
  148. package/lib/typescript/src/components/tour/tour-card-measurement.d.ts.map +1 -0
  149. package/lib/typescript/src/index.d.ts +3 -1
  150. package/lib/typescript/src/index.d.ts.map +1 -1
  151. package/package.json +1 -1
  152. package/src/components/avatar/avatar-group.ts +78 -0
  153. package/src/components/avatar/index.tsx +121 -1
  154. package/src/components/color-picker/color-picker-accessibility.ts +12 -0
  155. package/src/components/color-picker/index.tsx +27 -8
  156. package/src/components/date-time-picker/index.tsx +11 -3
  157. package/src/components/drawer/index.tsx +42 -14
  158. package/src/components/input/index.tsx +6 -2
  159. package/src/components/input/input-content-padding.ts +3 -0
  160. package/src/components/input-group/index.tsx +38 -10
  161. package/src/components/input-group/input-group-measurements.ts +98 -0
  162. package/src/components/otp-input/index.tsx +3 -1
  163. package/src/components/otp-input/otp-input-state.ts +7 -0
  164. package/src/components/planner/index.tsx +24 -6
  165. package/src/components/planner/planner-today.ts +5 -0
  166. package/src/components/plot/index.tsx +16 -12
  167. package/src/components/plot/plot-series-registry.ts +41 -0
  168. package/src/components/radio-group/index.tsx +4 -1
  169. package/src/components/radio-group/radio-group-value.ts +9 -0
  170. package/src/components/rating/index.tsx +11 -4
  171. package/src/components/rating/rating-inputs.ts +19 -0
  172. package/src/components/search-bar/index.tsx +12 -7
  173. package/src/components/search-bar/search-bar-debounce.ts +35 -0
  174. package/src/components/select/index.tsx +10 -1
  175. package/src/components/select/native-select-contract.ts +12 -0
  176. package/src/components/split-view/index.tsx +565 -0
  177. package/src/components/split-view/split-view-math.ts +146 -0
  178. package/src/components/splitter/index.tsx +589 -0
  179. package/src/components/splitter/splitter-math.ts +244 -0
  180. package/src/components/steps/index.tsx +35 -9
  181. package/src/components/steps/steps-trigger.ts +6 -0
  182. package/src/components/tag-input/index.tsx +13 -11
  183. package/src/components/tag-input/tag-input-state.ts +18 -0
  184. package/src/components/textarea/index.tsx +8 -4
  185. package/src/components/textarea/textarea-disabled.ts +6 -0
  186. package/src/components/timeline/index.tsx +89 -26
  187. package/src/components/timeline/timeline-geometry.ts +9 -0
  188. package/src/components/toast/index.tsx +26 -1
  189. package/src/components/toast/toast-store.ts +43 -8
  190. package/src/components/tour/index.tsx +11 -3
  191. package/src/components/tour/tour-card-measurement.ts +29 -0
  192. package/src/index.ts +17 -0
@@ -0,0 +1,9 @@
1
+ export const TIMELINE_WIDE_COLUMN = 268;
2
+ export const TIMELINE_NARROW_COLUMN = 76;
3
+
4
+ export function timelineColumnWidth(requested: number | undefined, filled: boolean): number {
5
+ if (requested !== undefined && Number.isFinite(requested) && requested > 0) {
6
+ return requested;
7
+ }
8
+ return filled ? TIMELINE_WIDE_COLUMN : TIMELINE_NARROW_COLUMN;
9
+ }
@@ -18,7 +18,12 @@ import {
18
18
  useSyncExternalStore,
19
19
  type ReactNode,
20
20
  } from 'react';
21
- import { View, type ViewProps } from 'react-native';
21
+ import {
22
+ AppState,
23
+ View,
24
+ type AppStateStatus,
25
+ type ViewProps,
26
+ } from 'react-native';
22
27
  import { Gesture, GestureDetector } from 'react-native-gesture-handler';
23
28
  import Animated, {
24
29
  Easing,
@@ -538,6 +543,26 @@ function ToastStack({
538
543
  export function ToastViewport() {
539
544
  const items = useSyncExternalStore(toastStore.subscribe, toastStore.getSnapshot);
540
545
 
546
+ useEffect(() => {
547
+ /*
548
+ * Pause on the two states that mean nobody can see the toast, rather than
549
+ * on everything that is not `active`. Android reports `unknown` before it
550
+ * has decided, and a toast raised in that window would otherwise have its
551
+ * countdown parked with nothing coming to restart it.
552
+ */
553
+ const syncTimers = (state: AppStateStatus) => {
554
+ if (state === 'background' || state === 'inactive') toastStore.pauseTimers();
555
+ else toastStore.resumeTimers();
556
+ };
557
+
558
+ syncTimers(AppState.currentState);
559
+ const subscription = AppState.addEventListener('change', syncTimers);
560
+ return () => {
561
+ subscription.remove();
562
+ toastStore.pauseTimers();
563
+ };
564
+ }, []);
565
+
541
566
  if (items.length === 0) return null;
542
567
 
543
568
  const top = items.filter((item) => item.placement === 'top');
@@ -44,11 +44,18 @@ const DEFAULT_DURATION = 4000;
44
44
 
45
45
  let counter = 0;
46
46
 
47
- class ToastStore {
47
+ interface ToastTimer {
48
+ remaining: number;
49
+ startedAt?: number;
50
+ timeout?: ReturnType<typeof setTimeout>;
51
+ }
52
+
53
+ export class ToastStore {
48
54
  private items: ToastItem[] = [];
49
55
  private snapshot: readonly ToastItem[] = this.items;
50
56
  private listeners = new Set<() => void>();
51
- private timers = new Map<string, ReturnType<typeof setTimeout>>();
57
+ private timers = new Map<string, ToastTimer>();
58
+ private timersPaused = false;
52
59
 
53
60
  subscribe = (listener: () => void) => {
54
61
  this.listeners.add(listener);
@@ -69,10 +76,9 @@ class ToastStore {
69
76
 
70
77
  const duration = resolved.duration ?? DEFAULT_DURATION;
71
78
  if (duration > 0) {
72
- this.timers.set(
73
- id,
74
- setTimeout(() => this.hide(id), duration)
75
- );
79
+ const timer = { remaining: duration };
80
+ this.timers.set(id, timer);
81
+ if (!this.timersPaused) this.startTimer(id, timer);
76
82
  }
77
83
 
78
84
  return id;
@@ -81,7 +87,7 @@ class ToastStore {
81
87
  hide = (id: string) => {
82
88
  const timer = this.timers.get(id);
83
89
  if (timer) {
84
- clearTimeout(timer);
90
+ if (timer.timeout !== undefined) clearTimeout(timer.timeout);
85
91
  this.timers.delete(id);
86
92
  }
87
93
  if (!this.items.some((item) => item.id === id)) return;
@@ -90,13 +96,42 @@ class ToastStore {
90
96
  };
91
97
 
92
98
  hideAll = () => {
93
- this.timers.forEach(clearTimeout);
99
+ this.timers.forEach((timer) => {
100
+ if (timer.timeout !== undefined) clearTimeout(timer.timeout);
101
+ });
94
102
  this.timers.clear();
95
103
  if (this.items.length === 0) return;
96
104
  this.items = [];
97
105
  this.emit();
98
106
  };
99
107
 
108
+ /** Pause auto-dismiss countdowns while their viewport is not visible. */
109
+ pauseTimers = () => {
110
+ if (this.timersPaused) return;
111
+ this.timersPaused = true;
112
+ const now = Date.now();
113
+
114
+ this.timers.forEach((timer) => {
115
+ if (timer.timeout === undefined || timer.startedAt === undefined) return;
116
+ clearTimeout(timer.timeout);
117
+ timer.remaining = Math.max(0, timer.remaining - (now - timer.startedAt));
118
+ delete timer.timeout;
119
+ delete timer.startedAt;
120
+ });
121
+ };
122
+
123
+ /** Resume each auto-dismiss countdown from its remaining visible time. */
124
+ resumeTimers = () => {
125
+ if (!this.timersPaused) return;
126
+ this.timersPaused = false;
127
+ this.timers.forEach((timer, id) => this.startTimer(id, timer));
128
+ };
129
+
130
+ private startTimer(id: string, timer: ToastTimer) {
131
+ timer.startedAt = Date.now();
132
+ timer.timeout = setTimeout(() => this.hide(id), timer.remaining);
133
+ }
134
+
100
135
  private emit() {
101
136
  this.snapshot = this.items;
102
137
  this.listeners.forEach((listener) => listener());
@@ -74,6 +74,11 @@ import { Portal } from '../../primitives/portal';
74
74
  import { Text } from '../../primitives/text';
75
75
  import { cn } from '../../utils/cn';
76
76
  import { Button } from '../button';
77
+ import {
78
+ currentTourCardHeight,
79
+ nextTourCardMeasurement,
80
+ type TourCardMeasurement,
81
+ } from './tour-card-measurement';
77
82
 
78
83
  const AnimatedPath = Animated.createAnimatedComponent(Path);
79
84
 
@@ -466,7 +471,10 @@ function TourOverlay({
466
471
  const insets = useSafeAreaInsets();
467
472
  const reducedMotion = useReducedMotion();
468
473
  const [spot, setSpot] = useState<(Rect & { radius: number }) | null>(null);
469
- const [cardHeight, setCardHeight] = useState<number | null>(null);
474
+ const [cardMeasurement, setCardMeasurement] = useState<TourCardMeasurement | null>(
475
+ null
476
+ );
477
+ const cardHeight = currentTourCardHeight(active, cardMeasurement);
470
478
 
471
479
  const stepPadding = active?.padding ?? padding;
472
480
  const stepRadius = active?.radius ?? radius;
@@ -570,8 +578,8 @@ function TourOverlay({
570
578
 
571
579
  const onCardLayout = (event: LayoutChangeEvent) => {
572
580
  const measured = event.nativeEvent.layout.height;
573
- setCardHeight((current) =>
574
- current !== null && Math.abs(current - measured) < 1 ? current : measured
581
+ setCardMeasurement((current) =>
582
+ nextTourCardMeasurement(active, measured, current)
575
583
  );
576
584
  };
577
585
 
@@ -0,0 +1,29 @@
1
+ /** A measured Tour card height tied to the step that produced it. */
2
+ export interface TourCardMeasurement {
3
+ owner: object | undefined;
4
+ height: number;
5
+ }
6
+
7
+ /**
8
+ * Returns a height only when it belongs to the step currently being rendered.
9
+ * A previous step can be much taller or shorter, so reusing its height would
10
+ * place the next card incorrectly before that card's first layout pass.
11
+ */
12
+ export function currentTourCardHeight(
13
+ owner: object | undefined,
14
+ measurement: TourCardMeasurement | null
15
+ ): number | null {
16
+ return measurement && measurement.owner === owner ? measurement.height : null;
17
+ }
18
+
19
+ /** Stores a card height without churning state for sub-pixel layout noise. */
20
+ export function nextTourCardMeasurement(
21
+ owner: object | undefined,
22
+ height: number,
23
+ current: TourCardMeasurement | null
24
+ ): TourCardMeasurement {
25
+ if (current && current.owner === owner && Math.abs(current.height - height) < 1) {
26
+ return current;
27
+ }
28
+ return { owner, height };
29
+ }
package/src/index.ts CHANGED
@@ -61,6 +61,7 @@ export {
61
61
  Avatar,
62
62
  type AvatarProps,
63
63
  type AvatarBadgeProps,
64
+ type AvatarGroupProps,
64
65
  } from './components/avatar';
65
66
  export {
66
67
  Attachment,
@@ -1032,6 +1033,22 @@ export {
1032
1033
  type SortableReorderDetails,
1033
1034
  } from './components/sortable';
1034
1035
  export { Spinner, type SpinnerProps } from './components/spinner';
1036
+ export {
1037
+ Splitter,
1038
+ type SplitterProps,
1039
+ type SplitterPanelProps,
1040
+ type SplitterHandleProps,
1041
+ type SplitterOrientation,
1042
+ type SplitterConstraint,
1043
+ } from './components/splitter';
1044
+ export {
1045
+ SplitView,
1046
+ useSplitView,
1047
+ type SplitViewProps,
1048
+ type SplitViewPaneProps,
1049
+ type SplitViewDragAreaProps,
1050
+ type SplitViewHandleProps,
1051
+ } from './components/split-view';
1035
1052
  export {
1036
1053
  Steps,
1037
1054
  type StepsProps,