@buoy-gg/shared-ui 2.1.10 → 2.1.12
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/commonjs/dataViewer/DataViewer.js +1 -3
- package/lib/commonjs/dataViewer/VirtualizedDataExplorer.js +3 -4
- package/lib/commonjs/hooks/safe-area-impl.js +1 -1
- package/lib/commonjs/icons/ImageOverlayIcon.js +142 -0
- package/lib/commonjs/icons/index.js +8 -0
- package/lib/commonjs/ui/components/EventHistoryViewer/EventHistoryViewer.js +2 -1
- package/lib/commonjs/ui/components/WindowControls.js +307 -46
- package/lib/commonjs/ui/components/index.js +6 -0
- package/lib/commonjs/utils/time/TickContext.js +43 -0
- package/lib/commonjs/utils/time/index.js +21 -1
- package/lib/commonjs/utils/time/useRelativeTime.js +36 -0
- package/lib/module/dataViewer/DataViewer.js +1 -3
- package/lib/module/dataViewer/VirtualizedDataExplorer.js +3 -4
- package/lib/module/hooks/safe-area-impl.js +1 -1
- package/lib/module/icons/ImageOverlayIcon.js +137 -0
- package/lib/module/icons/index.js +1 -0
- package/lib/module/ui/components/EventHistoryViewer/EventHistoryViewer.js +3 -2
- package/lib/module/ui/components/WindowControls.js +308 -48
- package/lib/module/ui/components/index.js +1 -1
- package/lib/module/utils/time/TickContext.js +38 -0
- package/lib/module/utils/time/index.js +3 -1
- package/lib/module/utils/time/useRelativeTime.js +33 -0
- package/lib/typescript/commonjs/dataViewer/VirtualizedDataExplorer.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/commonjs/icons/ImageOverlayIcon.d.ts +14 -0
- package/lib/typescript/commonjs/icons/ImageOverlayIcon.d.ts.map +1 -0
- package/lib/typescript/commonjs/icons/index.d.ts +1 -0
- package/lib/typescript/commonjs/icons/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/WindowControls.d.ts +8 -3
- package/lib/typescript/commonjs/ui/components/WindowControls.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/index.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/utils/time/TickContext.d.ts +21 -0
- package/lib/typescript/commonjs/utils/time/TickContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/utils/time/index.d.ts +2 -0
- package/lib/typescript/commonjs/utils/time/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/utils/time/useRelativeTime.d.ts +11 -0
- package/lib/typescript/commonjs/utils/time/useRelativeTime.d.ts.map +1 -0
- package/lib/typescript/module/dataViewer/VirtualizedDataExplorer.d.ts.map +1 -1
- package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/module/icons/ImageOverlayIcon.d.ts +14 -0
- package/lib/typescript/module/icons/ImageOverlayIcon.d.ts.map +1 -0
- package/lib/typescript/module/icons/index.d.ts +1 -0
- package/lib/typescript/module/icons/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/WindowControls.d.ts +8 -3
- package/lib/typescript/module/ui/components/WindowControls.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/index.d.ts +1 -1
- package/lib/typescript/module/ui/components/index.d.ts.map +1 -1
- package/lib/typescript/module/utils/time/TickContext.d.ts +21 -0
- package/lib/typescript/module/utils/time/TickContext.d.ts.map +1 -0
- package/lib/typescript/module/utils/time/index.d.ts +2 -0
- package/lib/typescript/module/utils/time/index.d.ts.map +1 -1
- package/lib/typescript/module/utils/time/useRelativeTime.d.ts +11 -0
- package/lib/typescript/module/utils/time/useRelativeTime.d.ts.map +1 -0
- package/package.json +4 -4
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useState, useRef, useCallback, useEffect } from "react";
|
|
4
|
+
import { View, TouchableOpacity, TouchableWithoutFeedback, StyleSheet, Animated, Modal } from "react-native";
|
|
4
5
|
import { X, Minus, DockBottom, FloatWindow } from "../../icons/index.js";
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Global expandable setting — controlled via setExpandableWindowControls()
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
let _expandableEnabled = true; // Default ON
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Set whether window controls use the expandable iPad-style behavior.
|
|
15
|
+
* Called by the floating-tools settings system when the setting changes.
|
|
16
|
+
*/
|
|
17
|
+
export function setExpandableWindowControls(enabled) {
|
|
18
|
+
_expandableEnabled = enabled;
|
|
19
|
+
}
|
|
5
20
|
|
|
6
21
|
// ============================================================================
|
|
7
22
|
// Types
|
|
8
23
|
// ============================================================================
|
|
9
|
-
|
|
24
|
+
|
|
10
25
|
// ============================================================================
|
|
11
26
|
// Constants - macOS Style Window Controls
|
|
12
27
|
// ============================================================================
|
|
@@ -20,19 +35,28 @@ const COLORS = {
|
|
|
20
35
|
toggleMode: "#28C840" // Green - expand/fullscreen button
|
|
21
36
|
};
|
|
22
37
|
|
|
23
|
-
//
|
|
24
|
-
const BUTTON_SIZE = 12;
|
|
25
|
-
const BUTTON_SPACING = 8;
|
|
26
|
-
const ICON_SIZE = 8;
|
|
38
|
+
// Collapsed state (original small dots)
|
|
39
|
+
const BUTTON_SIZE = 12;
|
|
40
|
+
const BUTTON_SPACING = 8;
|
|
41
|
+
const ICON_SIZE = 8;
|
|
42
|
+
|
|
43
|
+
// Expanded state (large easy-to-tap buttons)
|
|
44
|
+
const EXPANDED_BUTTON_SIZE = 36;
|
|
45
|
+
const EXPANDED_BUTTON_SPACING = 12;
|
|
46
|
+
const EXPANDED_ICON_SIZE = 16;
|
|
47
|
+
const EXPANDED_PADDING = 8;
|
|
48
|
+
|
|
49
|
+
// Auto-dismiss timeout
|
|
50
|
+
const AUTO_DISMISS_MS = 3000;
|
|
27
51
|
|
|
28
52
|
// ============================================================================
|
|
29
53
|
// Component
|
|
30
54
|
// ============================================================================
|
|
31
55
|
|
|
32
56
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
57
|
+
* iPad-style expandable window controls.
|
|
58
|
+
* Default: small macOS-style colored dots. On tap, expands to reveal
|
|
59
|
+
* large, easy-to-press buttons. Auto-dismisses after timeout or tap outside.
|
|
36
60
|
*/
|
|
37
61
|
export function WindowControls({
|
|
38
62
|
onClose,
|
|
@@ -41,44 +65,236 @@ export function WindowControls({
|
|
|
41
65
|
mode
|
|
42
66
|
}) {
|
|
43
67
|
// Show action-based icon: what will happen when clicked
|
|
44
|
-
// - If floating, show DockBottom (clicking will dock to bottom)
|
|
45
|
-
// - If bottomSheet, show FloatWindow (clicking will make it float)
|
|
46
68
|
const ToggleModeIcon = mode === "floating" ? DockBottom : FloatWindow;
|
|
47
69
|
const toggleModeLabel = mode === "floating" ? "Dock to bottom sheet" : "Make floating window";
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
style:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
|
|
71
|
+
// When expandable is disabled, render original directly-tappable buttons
|
|
72
|
+
if (!_expandableEnabled) {
|
|
73
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
74
|
+
style: styles.container,
|
|
75
|
+
children: [onMinimize && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
76
|
+
onPress: onMinimize,
|
|
77
|
+
style: [styles.dot, styles.minimizeDot],
|
|
78
|
+
activeOpacity: 0.8,
|
|
79
|
+
accessibilityLabel: "Minimize modal",
|
|
80
|
+
accessibilityRole: "button",
|
|
81
|
+
children: /*#__PURE__*/_jsx(Minus, {
|
|
82
|
+
size: ICON_SIZE,
|
|
83
|
+
color: "#7A5A00",
|
|
84
|
+
strokeWidth: 1.5
|
|
85
|
+
})
|
|
86
|
+
}), onToggleMode && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
87
|
+
onPress: onToggleMode,
|
|
88
|
+
style: [styles.dot, styles.expandDot],
|
|
89
|
+
activeOpacity: 0.8,
|
|
90
|
+
accessibilityLabel: toggleModeLabel,
|
|
91
|
+
accessibilityRole: "button",
|
|
92
|
+
children: /*#__PURE__*/_jsx(ToggleModeIcon, {
|
|
93
|
+
size: ICON_SIZE,
|
|
94
|
+
color: "#004A1A",
|
|
95
|
+
strokeWidth: 1.5
|
|
96
|
+
})
|
|
97
|
+
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
98
|
+
onPress: onClose,
|
|
99
|
+
style: [styles.dot, styles.closeDot],
|
|
100
|
+
activeOpacity: 0.8,
|
|
101
|
+
accessibilityLabel: "Close modal",
|
|
102
|
+
accessibilityRole: "button",
|
|
103
|
+
children: /*#__PURE__*/_jsx(X, {
|
|
104
|
+
size: ICON_SIZE,
|
|
105
|
+
color: "#4A0000",
|
|
106
|
+
strokeWidth: 1.5
|
|
107
|
+
})
|
|
108
|
+
})]
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// On real devices, use iPad-style expandable controls
|
|
113
|
+
return /*#__PURE__*/_jsx(ExpandableWindowControls, {
|
|
114
|
+
onClose: onClose,
|
|
115
|
+
onMinimize: onMinimize,
|
|
116
|
+
onToggleMode: onToggleMode,
|
|
117
|
+
mode: mode
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function ExpandableWindowControls({
|
|
121
|
+
onClose,
|
|
122
|
+
onMinimize,
|
|
123
|
+
onToggleMode,
|
|
124
|
+
mode
|
|
125
|
+
}) {
|
|
126
|
+
const [expanded, setExpanded] = useState(false);
|
|
127
|
+
const [triggerLayout, setTriggerLayout] = useState(null);
|
|
128
|
+
const expandAnim = useRef(new Animated.Value(0)).current;
|
|
129
|
+
const dismissTimeout = useRef(null);
|
|
130
|
+
const triggerRef = useRef(null);
|
|
131
|
+
const ToggleModeIcon = mode === "floating" ? DockBottom : FloatWindow;
|
|
132
|
+
const toggleModeLabel = mode === "floating" ? "Dock to bottom sheet" : "Make floating window";
|
|
133
|
+
const clearDismissTimer = useCallback(() => {
|
|
134
|
+
if (dismissTimeout.current) {
|
|
135
|
+
clearTimeout(dismissTimeout.current);
|
|
136
|
+
dismissTimeout.current = null;
|
|
137
|
+
}
|
|
138
|
+
}, []);
|
|
139
|
+
const collapse = useCallback(() => {
|
|
140
|
+
clearDismissTimer();
|
|
141
|
+
Animated.spring(expandAnim, {
|
|
142
|
+
toValue: 0,
|
|
143
|
+
tension: 200,
|
|
144
|
+
friction: 20,
|
|
145
|
+
useNativeDriver: true
|
|
146
|
+
}).start(() => {
|
|
147
|
+
setExpanded(false);
|
|
148
|
+
});
|
|
149
|
+
}, [expandAnim, clearDismissTimer]);
|
|
150
|
+
const expand = useCallback(() => {
|
|
151
|
+
// Measure trigger position on screen before expanding
|
|
152
|
+
triggerRef.current?.measureInWindow((x, y, width, height) => {
|
|
153
|
+
setTriggerLayout({
|
|
154
|
+
x,
|
|
155
|
+
y,
|
|
156
|
+
width,
|
|
157
|
+
height
|
|
158
|
+
});
|
|
159
|
+
setExpanded(true);
|
|
160
|
+
Animated.spring(expandAnim, {
|
|
161
|
+
toValue: 1,
|
|
162
|
+
tension: 180,
|
|
163
|
+
friction: 18,
|
|
164
|
+
useNativeDriver: true
|
|
165
|
+
}).start();
|
|
166
|
+
|
|
167
|
+
// Auto-dismiss
|
|
168
|
+
clearDismissTimer();
|
|
169
|
+
dismissTimeout.current = setTimeout(collapse, AUTO_DISMISS_MS);
|
|
170
|
+
});
|
|
171
|
+
}, [expandAnim, collapse, clearDismissTimer]);
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
return clearDismissTimer;
|
|
174
|
+
}, [clearDismissTimer]);
|
|
175
|
+
const handleAction = useCallback(action => {
|
|
176
|
+
collapse();
|
|
177
|
+
action();
|
|
178
|
+
}, [collapse]);
|
|
179
|
+
|
|
180
|
+
// Animation interpolations
|
|
181
|
+
const scale = expandAnim.interpolate({
|
|
182
|
+
inputRange: [0, 1],
|
|
183
|
+
outputRange: [0.3, 1]
|
|
184
|
+
});
|
|
185
|
+
const opacity = expandAnim.interpolate({
|
|
186
|
+
inputRange: [0, 0.5, 1],
|
|
187
|
+
outputRange: [0, 0.8, 1]
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Count visible buttons for layout calculation
|
|
191
|
+
const buttonCount = 1 + (onMinimize ? 1 : 0) + (onToggleMode ? 1 : 0);
|
|
192
|
+
const expandedWidth = buttonCount * EXPANDED_BUTTON_SIZE + (buttonCount - 1) * EXPANDED_BUTTON_SPACING + EXPANDED_PADDING * 2;
|
|
193
|
+
const expandedHeight = EXPANDED_BUTTON_SIZE + EXPANDED_PADDING * 2;
|
|
194
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
195
|
+
children: [/*#__PURE__*/_jsx(TouchableOpacity, {
|
|
196
|
+
ref: triggerRef,
|
|
197
|
+
onPress: expand,
|
|
198
|
+
activeOpacity: 0.7,
|
|
199
|
+
accessibilityLabel: "Open window controls",
|
|
66
200
|
accessibilityRole: "button",
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
201
|
+
style: styles.trigger,
|
|
202
|
+
hitSlop: {
|
|
203
|
+
top: 8,
|
|
204
|
+
bottom: 8,
|
|
205
|
+
left: 8,
|
|
206
|
+
right: 8
|
|
207
|
+
},
|
|
208
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
209
|
+
style: styles.container,
|
|
210
|
+
children: [onMinimize && /*#__PURE__*/_jsx(View, {
|
|
211
|
+
style: [styles.dot, styles.minimizeDot],
|
|
212
|
+
children: /*#__PURE__*/_jsx(Minus, {
|
|
213
|
+
size: ICON_SIZE,
|
|
214
|
+
color: "#7A5A00",
|
|
215
|
+
strokeWidth: 1.5
|
|
216
|
+
})
|
|
217
|
+
}), onToggleMode && /*#__PURE__*/_jsx(View, {
|
|
218
|
+
style: [styles.dot, styles.expandDot],
|
|
219
|
+
children: /*#__PURE__*/_jsx(ToggleModeIcon, {
|
|
220
|
+
size: ICON_SIZE,
|
|
221
|
+
color: "#004A1A",
|
|
222
|
+
strokeWidth: 1.5
|
|
223
|
+
})
|
|
224
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
225
|
+
style: [styles.dot, styles.closeDot],
|
|
226
|
+
children: /*#__PURE__*/_jsx(X, {
|
|
227
|
+
size: ICON_SIZE,
|
|
228
|
+
color: "#4A0000",
|
|
229
|
+
strokeWidth: 1.5
|
|
230
|
+
})
|
|
231
|
+
})]
|
|
71
232
|
})
|
|
72
|
-
}), /*#__PURE__*/_jsx(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
233
|
+
}), expanded && /*#__PURE__*/_jsx(Modal, {
|
|
234
|
+
transparent: true,
|
|
235
|
+
visible: true,
|
|
236
|
+
statusBarTranslucent: true,
|
|
237
|
+
children: /*#__PURE__*/_jsx(TouchableWithoutFeedback, {
|
|
238
|
+
onPress: collapse,
|
|
239
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
240
|
+
style: styles.overlay,
|
|
241
|
+
children: /*#__PURE__*/_jsx(Animated.View, {
|
|
242
|
+
style: [styles.expandedPanel, {
|
|
243
|
+
transform: [{
|
|
244
|
+
scale
|
|
245
|
+
}],
|
|
246
|
+
opacity,
|
|
247
|
+
// Position the expanded panel anchored to trigger's top-right
|
|
248
|
+
top: triggerLayout ? triggerLayout.y - EXPANDED_PADDING : 0,
|
|
249
|
+
right: triggerLayout ? Math.max(4,
|
|
250
|
+
// screen width minus trigger's right edge
|
|
251
|
+
// We don't need Dimensions here since we use measureInWindow
|
|
252
|
+
// which gives absolute coords. right = screenWidth - (x + width)
|
|
253
|
+
0) : 0,
|
|
254
|
+
// Position using left instead, anchored to trigger's right edge
|
|
255
|
+
left: triggerLayout ? triggerLayout.x + triggerLayout.width - expandedWidth : undefined
|
|
256
|
+
}],
|
|
257
|
+
children: /*#__PURE__*/_jsx(TouchableWithoutFeedback, {
|
|
258
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
259
|
+
style: styles.expandedContainer,
|
|
260
|
+
children: [onMinimize && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
261
|
+
onPress: () => handleAction(onMinimize),
|
|
262
|
+
style: [styles.expandedButton, styles.minimizeButtonExpanded],
|
|
263
|
+
activeOpacity: 0.7,
|
|
264
|
+
accessibilityLabel: "Minimize modal",
|
|
265
|
+
accessibilityRole: "button",
|
|
266
|
+
children: /*#__PURE__*/_jsx(Minus, {
|
|
267
|
+
size: EXPANDED_ICON_SIZE,
|
|
268
|
+
color: "#7A5A00",
|
|
269
|
+
strokeWidth: 2
|
|
270
|
+
})
|
|
271
|
+
}), onToggleMode && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
272
|
+
onPress: () => handleAction(onToggleMode),
|
|
273
|
+
style: [styles.expandedButton, styles.expandButtonExpanded],
|
|
274
|
+
activeOpacity: 0.7,
|
|
275
|
+
accessibilityLabel: toggleModeLabel,
|
|
276
|
+
accessibilityRole: "button",
|
|
277
|
+
children: /*#__PURE__*/_jsx(ToggleModeIcon, {
|
|
278
|
+
size: EXPANDED_ICON_SIZE,
|
|
279
|
+
color: "#004A1A",
|
|
280
|
+
strokeWidth: 2
|
|
281
|
+
})
|
|
282
|
+
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
283
|
+
onPress: () => handleAction(onClose),
|
|
284
|
+
style: [styles.expandedButton, styles.closeButtonExpanded],
|
|
285
|
+
activeOpacity: 0.7,
|
|
286
|
+
accessibilityLabel: "Close modal",
|
|
287
|
+
accessibilityRole: "button",
|
|
288
|
+
children: /*#__PURE__*/_jsx(X, {
|
|
289
|
+
size: EXPANDED_ICON_SIZE,
|
|
290
|
+
color: "#4A0000",
|
|
291
|
+
strokeWidth: 2
|
|
292
|
+
})
|
|
293
|
+
})]
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
})
|
|
297
|
+
})
|
|
82
298
|
})
|
|
83
299
|
})]
|
|
84
300
|
});
|
|
@@ -89,26 +305,70 @@ export function WindowControls({
|
|
|
89
305
|
// ============================================================================
|
|
90
306
|
|
|
91
307
|
const styles = StyleSheet.create({
|
|
308
|
+
trigger: {
|
|
309
|
+
padding: 2
|
|
310
|
+
},
|
|
92
311
|
container: {
|
|
93
312
|
flexDirection: "row",
|
|
94
313
|
alignItems: "center",
|
|
95
314
|
gap: BUTTON_SPACING
|
|
96
315
|
},
|
|
97
|
-
|
|
316
|
+
dot: {
|
|
98
317
|
width: BUTTON_SIZE,
|
|
99
318
|
height: BUTTON_SIZE,
|
|
100
319
|
borderRadius: BUTTON_SIZE / 2,
|
|
101
|
-
// Perfectly circular
|
|
102
320
|
alignItems: "center",
|
|
103
321
|
justifyContent: "center"
|
|
104
322
|
},
|
|
105
|
-
|
|
323
|
+
closeDot: {
|
|
324
|
+
backgroundColor: COLORS.close
|
|
325
|
+
},
|
|
326
|
+
minimizeDot: {
|
|
327
|
+
backgroundColor: COLORS.minimize
|
|
328
|
+
},
|
|
329
|
+
expandDot: {
|
|
330
|
+
backgroundColor: COLORS.toggleMode
|
|
331
|
+
},
|
|
332
|
+
overlay: {
|
|
333
|
+
flex: 1
|
|
334
|
+
},
|
|
335
|
+
expandedPanel: {
|
|
336
|
+
position: "absolute",
|
|
337
|
+
zIndex: 9999
|
|
338
|
+
},
|
|
339
|
+
expandedContainer: {
|
|
340
|
+
flexDirection: "row",
|
|
341
|
+
alignItems: "center",
|
|
342
|
+
gap: EXPANDED_BUTTON_SPACING,
|
|
343
|
+
backgroundColor: "rgba(16, 22, 35, 0.95)",
|
|
344
|
+
borderRadius: (EXPANDED_BUTTON_SIZE + EXPANDED_PADDING * 2) / 2,
|
|
345
|
+
paddingHorizontal: EXPANDED_PADDING,
|
|
346
|
+
paddingVertical: EXPANDED_PADDING,
|
|
347
|
+
borderWidth: 1,
|
|
348
|
+
borderColor: "rgba(0, 184, 230, 0.3)",
|
|
349
|
+
shadowColor: "#000",
|
|
350
|
+
shadowOffset: {
|
|
351
|
+
width: 0,
|
|
352
|
+
height: 4
|
|
353
|
+
},
|
|
354
|
+
shadowOpacity: 0.4,
|
|
355
|
+
shadowRadius: 12,
|
|
356
|
+
elevation: 30
|
|
357
|
+
},
|
|
358
|
+
expandedButton: {
|
|
359
|
+
width: EXPANDED_BUTTON_SIZE,
|
|
360
|
+
height: EXPANDED_BUTTON_SIZE,
|
|
361
|
+
borderRadius: EXPANDED_BUTTON_SIZE / 2,
|
|
362
|
+
alignItems: "center",
|
|
363
|
+
justifyContent: "center"
|
|
364
|
+
},
|
|
365
|
+
closeButtonExpanded: {
|
|
106
366
|
backgroundColor: COLORS.close
|
|
107
367
|
},
|
|
108
|
-
|
|
368
|
+
minimizeButtonExpanded: {
|
|
109
369
|
backgroundColor: COLORS.minimize
|
|
110
370
|
},
|
|
111
|
-
|
|
371
|
+
expandButtonExpanded: {
|
|
112
372
|
backgroundColor: COLORS.toggleMode
|
|
113
373
|
}
|
|
114
374
|
});
|
|
@@ -27,7 +27,7 @@ export { CollapsibleSection } from "./CollapsibleSection.js";
|
|
|
27
27
|
export { DataInspector } from "./DataInspector.js";
|
|
28
28
|
export { SearchBar } from "./SearchBar.js";
|
|
29
29
|
export { DynamicFilterView } from "./DynamicFilterView.js";
|
|
30
|
-
export { WindowControls } from "./WindowControls.js";
|
|
30
|
+
export { WindowControls, setExpandableWindowControls } from "./WindowControls.js";
|
|
31
31
|
export { EventStepperFooter } from "./EventStepperFooter.js";
|
|
32
32
|
export { ExpandablePopover } from "./ExpandablePopover.js";
|
|
33
33
|
export { PowerToggleButton } from "./PowerToggleButton.js";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
const TickContext = /*#__PURE__*/createContext(null);
|
|
6
|
+
/**
|
|
7
|
+
* Provides a shared clock tick to all descendants.
|
|
8
|
+
* Wrap each devtools modal/screen in a single TickProvider so that all list items
|
|
9
|
+
* share one timer instead of each item creating its own interval.
|
|
10
|
+
*
|
|
11
|
+
* Only mounted (visible) items consume the context, so FlatList virtualization
|
|
12
|
+
* ensures off-screen items don't re-render.
|
|
13
|
+
*/
|
|
14
|
+
export function TickProvider({
|
|
15
|
+
children,
|
|
16
|
+
intervalMs = 5_000
|
|
17
|
+
}) {
|
|
18
|
+
const [tick, setTick] = useState(() => Date.now());
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const id = setInterval(() => {
|
|
21
|
+
setTick(Date.now());
|
|
22
|
+
}, intervalMs);
|
|
23
|
+
return () => {
|
|
24
|
+
clearInterval(id);
|
|
25
|
+
};
|
|
26
|
+
}, [intervalMs]);
|
|
27
|
+
return /*#__PURE__*/_jsx(TickContext.Provider, {
|
|
28
|
+
value: tick,
|
|
29
|
+
children: children
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returns the current tick from the nearest TickProvider, or null if none exists.
|
|
35
|
+
*/
|
|
36
|
+
export function useTick() {
|
|
37
|
+
return useContext(TickContext);
|
|
38
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useState, useEffect } from "react";
|
|
4
|
+
import { formatRelativeTime } from "./formatRelativeTime.js";
|
|
5
|
+
import { useTick } from "./TickContext.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Hook that returns a live-updating relative time string (e.g., "5s ago", "2m ago").
|
|
9
|
+
*
|
|
10
|
+
* When inside a `<TickProvider>`, uses the shared tick — no per-item timer.
|
|
11
|
+
* When used standalone (no provider), falls back to its own interval.
|
|
12
|
+
*
|
|
13
|
+
* @param timestamp - The timestamp to format (Date, number in ms, or nullish)
|
|
14
|
+
* @returns Formatted relative time string, or empty string if no timestamp
|
|
15
|
+
*/
|
|
16
|
+
export function useRelativeTime(timestamp) {
|
|
17
|
+
const contextTick = useTick();
|
|
18
|
+
const hasProvider = contextTick !== null;
|
|
19
|
+
const [fallbackNow, setFallbackNow] = useState(() => Date.now());
|
|
20
|
+
const timestampMs = timestamp ? timestamp instanceof Date ? timestamp.getTime() : timestamp : 0;
|
|
21
|
+
|
|
22
|
+
// Only run a per-item interval when there's no TickProvider
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (hasProvider || !timestampMs) return;
|
|
25
|
+
const id = setInterval(() => {
|
|
26
|
+
setFallbackNow(Date.now());
|
|
27
|
+
}, 5_000);
|
|
28
|
+
return () => clearInterval(id);
|
|
29
|
+
}, [hasProvider, timestampMs]);
|
|
30
|
+
if (!timestampMs) return "";
|
|
31
|
+
const now = hasProvider ? contextTick : fallbackNow;
|
|
32
|
+
return formatRelativeTime(timestampMs, now);
|
|
33
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualizedDataExplorer.d.ts","sourceRoot":"","sources":["../../../../src/dataViewer/VirtualizedDataExplorer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAOL,EAAE,EAEH,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"VirtualizedDataExplorer.d.ts","sourceRoot":"","sources":["../../../../src/dataViewer/VirtualizedDataExplorer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAOL,EAAE,EAEH,MAAM,OAAO,CAAC;AAm+Bf,UAAU,4BAA4B;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,4BAA4B,CAmQpE,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FC } from "react";
|
|
2
|
+
interface ImageOverlayIconProps {
|
|
3
|
+
size?: number;
|
|
4
|
+
color?: string;
|
|
5
|
+
glowColor?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* ImageOverlayIcon - Icon for the Image Overlay dev tool
|
|
9
|
+
* Shows layered image frames with a mountain/sun motif,
|
|
10
|
+
* representing design mockup overlay functionality.
|
|
11
|
+
*/
|
|
12
|
+
export declare const ImageOverlayIcon: FC<ImageOverlayIconProps>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=ImageOverlayIcon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageOverlayIcon.d.ts","sourceRoot":"","sources":["../../../../src/icons/ImageOverlayIcon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAG3B,UAAU,qBAAqB;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAmKtD,CAAC"}
|
|
@@ -10,6 +10,7 @@ export { RouteMapIcon, RouteIcon, NavigationIcon } from "./RouteMapIcon";
|
|
|
10
10
|
export { StackPulseIcon, RenderPulseIcon, HighlightUpdatesIcon, } from "./StackPulseIcon";
|
|
11
11
|
export { RenderCountIcon } from "./RenderCountIcon";
|
|
12
12
|
export { BenchmarkIcon } from "./BenchmarkIcon";
|
|
13
|
+
export { ImageOverlayIcon } from "./ImageOverlayIcon";
|
|
13
14
|
export { IconBackground } from "./IconBackground";
|
|
14
15
|
export * from "./lucide-icons";
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/icons/index.tsx"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/icons/index.tsx"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,cAAc,gBAAgB,CAAC"}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { ModalMode } from "../../JsModal";
|
|
2
|
+
/**
|
|
3
|
+
* Set whether window controls use the expandable iPad-style behavior.
|
|
4
|
+
* Called by the floating-tools settings system when the setting changes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function setExpandableWindowControls(enabled: boolean): void;
|
|
2
7
|
interface WindowControlsProps {
|
|
3
8
|
/** Handler for close button */
|
|
4
9
|
onClose: () => void;
|
|
@@ -10,9 +15,9 @@ interface WindowControlsProps {
|
|
|
10
15
|
mode?: ModalMode;
|
|
11
16
|
}
|
|
12
17
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
18
|
+
* iPad-style expandable window controls.
|
|
19
|
+
* Default: small macOS-style colored dots. On tap, expands to reveal
|
|
20
|
+
* large, easy-to-press buttons. Auto-dismisses after timeout or tap outside.
|
|
16
21
|
*/
|
|
17
22
|
export declare function WindowControls({ onClose, onMinimize, onToggleMode, mode, }: WindowControlsProps): import("react").JSX.Element;
|
|
18
23
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WindowControls.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WindowControls.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WindowControls.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WindowControls.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAQ/C;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,QAE3D;AAMD,UAAU,mBAAmB;IAC3B,+BAA+B;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,2EAA2E;IAC3E,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AA+BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,UAAU,EACV,YAAY,EACZ,IAAI,GACL,EAAE,mBAAmB,+BAoDrB"}
|
|
@@ -28,7 +28,7 @@ export { DataInspector } from "./DataInspector";
|
|
|
28
28
|
export { SearchBar } from "./SearchBar";
|
|
29
29
|
export { DynamicFilterView, } from "./DynamicFilterView";
|
|
30
30
|
export type { DynamicFilterConfig, } from "./DynamicFilterView";
|
|
31
|
-
export { WindowControls } from "./WindowControls";
|
|
31
|
+
export { WindowControls, setExpandableWindowControls } from "./WindowControls";
|
|
32
32
|
export { EventStepperFooter } from "./EventStepperFooter";
|
|
33
33
|
export type { EventStepperFooterProps } from "./EventStepperFooter";
|
|
34
34
|
export { ExpandablePopover } from "./ExpandablePopover";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,eAAe,EACf,UAAU,GACX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,SAAS,EACT,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACvE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EACL,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
interface TickProviderProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
/** Interval in ms between ticks. Defaults to 5_000 (5 seconds). */
|
|
5
|
+
intervalMs?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Provides a shared clock tick to all descendants.
|
|
9
|
+
* Wrap each devtools modal/screen in a single TickProvider so that all list items
|
|
10
|
+
* share one timer instead of each item creating its own interval.
|
|
11
|
+
*
|
|
12
|
+
* Only mounted (visible) items consume the context, so FlatList virtualization
|
|
13
|
+
* ensures off-screen items don't re-render.
|
|
14
|
+
*/
|
|
15
|
+
export declare function TickProvider({ children, intervalMs, }: TickProviderProps): import("react").JSX.Element;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the current tick from the nearest TickProvider, or null if none exists.
|
|
18
|
+
*/
|
|
19
|
+
export declare function useTick(): number | null;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=TickContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TickContext.d.ts","sourceRoot":"","sources":["../../../../../src/utils/time/TickContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,UAAU,iBAAiB;IACzB,QAAQ,EAAE,SAAS,CAAC;IACpB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,UAAkB,GACnB,EAAE,iBAAiB,+BAcnB;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,MAAM,GAAG,IAAI,CAEvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/utils/time/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/utils/time/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook that returns a live-updating relative time string (e.g., "5s ago", "2m ago").
|
|
3
|
+
*
|
|
4
|
+
* When inside a `<TickProvider>`, uses the shared tick — no per-item timer.
|
|
5
|
+
* When used standalone (no provider), falls back to its own interval.
|
|
6
|
+
*
|
|
7
|
+
* @param timestamp - The timestamp to format (Date, number in ms, or nullish)
|
|
8
|
+
* @returns Formatted relative time string, or empty string if no timestamp
|
|
9
|
+
*/
|
|
10
|
+
export declare function useRelativeTime(timestamp: Date | number | null | undefined): string;
|
|
11
|
+
//# sourceMappingURL=useRelativeTime.d.ts.map
|