panelui-native 0.82.0 → 0.84.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/bottom-sheet/index.js +111 -16
- package/lib/module/components/bottom-sheet/index.js.map +1 -1
- package/lib/module/components/circular-text/circular-text-geometry.js +63 -0
- package/lib/module/components/circular-text/circular-text-geometry.js.map +1 -0
- package/lib/module/components/circular-text/index.js +146 -0
- package/lib/module/components/circular-text/index.js.map +1 -0
- package/lib/module/components/image-generation/dot-field.js +66 -9
- package/lib/module/components/image-generation/dot-field.js.map +1 -1
- package/lib/module/components/image-generation/index.js +65 -23
- package/lib/module/components/image-generation/index.js.map +1 -1
- package/lib/module/components/marquee/index.js +12 -5
- package/lib/module/components/marquee/index.js.map +1 -1
- package/lib/module/components/panelside/index.js +15 -417
- package/lib/module/components/panelside/index.js.map +1 -1
- package/lib/module/components/popover/index.js +119 -7
- package/lib/module/components/popover/index.js.map +1 -1
- package/lib/module/icons/index.js +24 -4
- package/lib/module/icons/index.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/native/index.js +52 -0
- package/lib/module/native/index.js.map +1 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts +17 -1
- package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
- package/lib/typescript/src/components/circular-text/circular-text-geometry.d.ts +39 -0
- package/lib/typescript/src/components/circular-text/circular-text-geometry.d.ts.map +1 -0
- package/lib/typescript/src/components/circular-text/index.d.ts +69 -0
- package/lib/typescript/src/components/circular-text/index.d.ts.map +1 -0
- package/lib/typescript/src/components/image-generation/dot-field.d.ts +36 -1
- package/lib/typescript/src/components/image-generation/dot-field.d.ts.map +1 -1
- package/lib/typescript/src/components/image-generation/index.d.ts +16 -8
- package/lib/typescript/src/components/image-generation/index.d.ts.map +1 -1
- package/lib/typescript/src/components/marquee/index.d.ts.map +1 -1
- package/lib/typescript/src/components/panelside/index.d.ts +10 -202
- package/lib/typescript/src/components/panelside/index.d.ts.map +1 -1
- package/lib/typescript/src/components/popover/index.d.ts +25 -1
- package/lib/typescript/src/components/popover/index.d.ts.map +1 -1
- package/lib/typescript/src/icons/index.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/native/index.d.ts +66 -0
- package/lib/typescript/src/native/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/bottom-sheet/index.tsx +139 -16
- package/src/components/circular-text/circular-text-geometry.ts +80 -0
- package/src/components/circular-text/index.tsx +217 -0
- package/src/components/image-generation/dot-field.ts +65 -9
- package/src/components/image-generation/index.tsx +67 -18
- package/src/components/marquee/index.tsx +12 -5
- package/src/components/panelside/index.tsx +16 -604
- package/src/components/popover/index.tsx +146 -4
- package/src/icons/index.tsx +23 -2
- package/src/index.ts +1 -6
- package/src/native/index.ts +100 -0
|
@@ -15,14 +15,22 @@
|
|
|
15
15
|
*
|
|
16
16
|
* ## The dot field
|
|
17
17
|
*
|
|
18
|
-
* A grid of dots with a soft
|
|
19
|
-
*
|
|
20
|
-
* costs twenty-two worklets a frame rather than five hundred — the dots inside
|
|
21
|
-
* a column never move independently of it, and at this scale nobody can tell.
|
|
18
|
+
* A grid of dots with a soft light moving through it, drawn as three layers:
|
|
19
|
+
* the field at rest, and two copies of the lit dots fading into one another.
|
|
22
20
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* Every picture the loop will ever draw is built when the box is measured, so
|
|
22
|
+
* running it hands over a string that already exists. That leaves twenty-four
|
|
23
|
+
* pictures to spread across the pass, which on its own is a flipbook — a new
|
|
24
|
+
* one every 175ms, however fast the screen refreshes. The two layers are what
|
|
25
|
+
* fills the gap: one holds the frame being left and one the frame being
|
|
26
|
+
* arrived at, and only their opacities move, which the compositor animates at
|
|
27
|
+
* the display's own rate without the drawing being touched.
|
|
28
|
+
*
|
|
29
|
+
* They are opacities on views rather than on the dots, and that is not a
|
|
30
|
+
* detail. A value that changes every frame sitting beside the path string
|
|
31
|
+
* pushes the path every frame too, and every push of a path is a re-parse of
|
|
32
|
+
* several hundred subpaths — which is the cost this whole arrangement exists
|
|
33
|
+
* to avoid. Kept apart, the path is pushed only when it actually changes.
|
|
26
34
|
*
|
|
27
35
|
* ## What arrives, and when
|
|
28
36
|
*
|
|
@@ -34,11 +42,11 @@
|
|
|
34
42
|
*
|
|
35
43
|
* ## Reduced motion
|
|
36
44
|
*
|
|
37
|
-
* The
|
|
45
|
+
* The light stops, and the field holds wherever the clock was left. A
|
|
38
46
|
* placeholder that shows nothing is indistinguishable from a component that
|
|
39
47
|
* failed to load, so this is a quieter picture rather than an empty one.
|
|
40
48
|
*/
|
|
41
|
-
import { useEffect,
|
|
49
|
+
import { useEffect, useMemo, useState, type ReactNode } from 'react';
|
|
42
50
|
import {
|
|
43
51
|
Pressable,
|
|
44
52
|
StyleSheet,
|
|
@@ -61,13 +69,14 @@ import Animated, {
|
|
|
61
69
|
} from 'react-native-reanimated';
|
|
62
70
|
import { tv } from 'tailwind-variants';
|
|
63
71
|
import { useCSSVariable } from 'uniwind';
|
|
64
|
-
import { useDirectionSign } from '../../hooks/use-direction';
|
|
65
72
|
import { AlertTriangleIcon, CheckIcon, RotateCcwIcon } from '../../icons';
|
|
66
73
|
import { Text } from '../../primitives/text';
|
|
67
74
|
import { cn } from '../../utils/cn';
|
|
68
75
|
import {
|
|
69
76
|
DOT_REST_OPACITY,
|
|
70
|
-
|
|
77
|
+
FRAMES,
|
|
78
|
+
crossfadeAlphas,
|
|
79
|
+
framePhase,
|
|
71
80
|
gridPath,
|
|
72
81
|
litFrames,
|
|
73
82
|
type DotFieldAnimation,
|
|
@@ -241,8 +250,21 @@ function ImageGenerationField({
|
|
|
241
250
|
* light is somewhere legible rather than dead centre or absent, which is the
|
|
242
251
|
* difference between "not animating" and "failed to load".
|
|
243
252
|
*/
|
|
244
|
-
const
|
|
245
|
-
d: frames[
|
|
253
|
+
const slotA = useAnimatedProps(() => ({
|
|
254
|
+
d: frames[Math.floor(framePhase(clock.value, animation))] ?? '',
|
|
255
|
+
}));
|
|
256
|
+
const slotB = useAnimatedProps(() => ({
|
|
257
|
+
d: frames[(Math.floor(framePhase(clock.value, animation)) + 1) % FRAMES] ?? '',
|
|
258
|
+
}));
|
|
259
|
+
|
|
260
|
+
// Only these move between one frame and the next, and a view's opacity is a
|
|
261
|
+
// layer alpha — so the drawing underneath is composited again rather than
|
|
262
|
+
// drawn again.
|
|
263
|
+
const fadeOut = useAnimatedStyle(() => ({
|
|
264
|
+
opacity: crossfadeAlphas(framePhase(clock.value, animation) % 1)[0],
|
|
265
|
+
}));
|
|
266
|
+
const fadeIn = useAnimatedStyle(() => ({
|
|
267
|
+
opacity: crossfadeAlphas(framePhase(clock.value, animation) % 1)[1],
|
|
246
268
|
}));
|
|
247
269
|
|
|
248
270
|
const onLayout = (event: LayoutChangeEvent) => {
|
|
@@ -261,14 +283,41 @@ function ImageGenerationField({
|
|
|
261
283
|
{...props}
|
|
262
284
|
>
|
|
263
285
|
{grid ? (
|
|
264
|
-
|
|
286
|
+
<>
|
|
265
287
|
{/* The field at rest, under everything and never touched again. */}
|
|
266
|
-
<
|
|
288
|
+
<Svg
|
|
289
|
+
width={size.width}
|
|
290
|
+
height={size.height}
|
|
291
|
+
style={StyleSheet.absoluteFill}
|
|
292
|
+
>
|
|
293
|
+
<Path d={grid} fill={color} fillOpacity={DOT_REST_OPACITY} />
|
|
294
|
+
</Svg>
|
|
267
295
|
{/* The dots the light has reached, drawn larger over their own
|
|
268
296
|
resting copies rather than instead of them — so a dot brightens
|
|
269
|
-
in place instead of appearing to move.
|
|
270
|
-
|
|
271
|
-
|
|
297
|
+
in place instead of appearing to move.
|
|
298
|
+
|
|
299
|
+
Two of them: the frame being left and the frame being arrived at.
|
|
300
|
+
Each carries its dots at full strength and the pair is brought to
|
|
301
|
+
LIT_OPACITY by the views, because what fades has to be the layer
|
|
302
|
+
and not the fill — see crossfadeAlphas for why the ramps are not
|
|
303
|
+
simply t and 1 - t. */}
|
|
304
|
+
<Animated.View
|
|
305
|
+
style={[StyleSheet.absoluteFill, fadeOut]}
|
|
306
|
+
pointerEvents="none"
|
|
307
|
+
>
|
|
308
|
+
<Svg width={size.width} height={size.height}>
|
|
309
|
+
<AnimatedPath animatedProps={slotA} fill={color} />
|
|
310
|
+
</Svg>
|
|
311
|
+
</Animated.View>
|
|
312
|
+
<Animated.View
|
|
313
|
+
style={[StyleSheet.absoluteFill, fadeIn]}
|
|
314
|
+
pointerEvents="none"
|
|
315
|
+
>
|
|
316
|
+
<Svg width={size.width} height={size.height}>
|
|
317
|
+
<AnimatedPath animatedProps={slotB} fill={color} />
|
|
318
|
+
</Svg>
|
|
319
|
+
</Animated.View>
|
|
320
|
+
</>
|
|
272
321
|
) : null}
|
|
273
322
|
</View>
|
|
274
323
|
);
|
|
@@ -258,12 +258,19 @@ function MarqueeRoot({
|
|
|
258
258
|
};
|
|
259
259
|
|
|
260
260
|
/*
|
|
261
|
-
* Whether there is motion here at all:
|
|
262
|
-
*
|
|
263
|
-
*
|
|
264
|
-
*
|
|
261
|
+
* Whether there is motion here at all: copies on screen, a speed to travel
|
|
262
|
+
* them at, and a `playing` that has not already stopped it from outside. A
|
|
263
|
+
* control offering to pause a still marquee is the same lie as a disabled
|
|
264
|
+
* button with no reason on it.
|
|
265
|
+
*
|
|
266
|
+
* The copy count, not the period. Content that measured while its container
|
|
267
|
+
* did not has a period — it is the content's own length — and no copies to
|
|
268
|
+
* draw, because there is no width to lay them across. Asking the period
|
|
269
|
+
* meant a row that renders nothing still reported itself live, and a group
|
|
270
|
+
* drew a pause control for it: a marquee that is one button and no content,
|
|
271
|
+
* which is the shape of the bug this replaced.
|
|
265
272
|
*/
|
|
266
|
-
const live = playing && !reducedMotion &&
|
|
273
|
+
const live = playing && !reducedMotion && layout.count > 0 && speed > 0;
|
|
267
274
|
|
|
268
275
|
// Reported to the group, if there is one, so its single control can be
|
|
269
276
|
// decided the same way this one's is.
|