panelui-native 0.71.0 → 0.73.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/README.md +2 -1
- package/lib/module/components/accordion/index.js +10 -4
- package/lib/module/components/accordion/index.js.map +1 -1
- package/lib/module/components/area-chart/index.js +1 -0
- package/lib/module/components/area-chart/index.js.map +1 -1
- package/lib/module/components/breadcrumb/index.js +2 -1
- package/lib/module/components/breadcrumb/index.js.map +1 -1
- package/lib/module/components/button/index.js +7 -5
- package/lib/module/components/button/index.js.map +1 -1
- package/lib/module/components/carousel/index.js +1 -1
- package/lib/module/components/carousel/index.js.map +1 -1
- package/lib/module/components/chip/index.js +2 -2
- package/lib/module/components/chip/index.js.map +1 -1
- package/lib/module/components/code-block/index.js.map +1 -1
- package/lib/module/components/collapsible/index.js +5 -1
- package/lib/module/components/collapsible/index.js.map +1 -1
- package/lib/module/components/color-picker/index.js.map +1 -1
- package/lib/module/components/fab/index.js +7 -6
- package/lib/module/components/fab/index.js.map +1 -1
- package/lib/module/components/flow/index.js +1 -1
- package/lib/module/components/flow/index.js.map +1 -1
- package/lib/module/components/frame/index.js +2 -2
- package/lib/module/components/frame/index.js.map +1 -1
- package/lib/module/components/grid-item/index.js +2 -2
- package/lib/module/components/grid-item/index.js.map +1 -1
- package/lib/module/components/heatmap-chart/index.js +1 -0
- package/lib/module/components/heatmap-chart/index.js.map +1 -1
- package/lib/module/components/hex-chart/index.js +1 -0
- package/lib/module/components/hex-chart/index.js.map +1 -1
- package/lib/module/components/input-group/index.js +7 -2
- package/lib/module/components/input-group/index.js.map +1 -1
- package/lib/module/components/item/index.js +2 -2
- package/lib/module/components/item/index.js.map +1 -1
- package/lib/module/components/line-chart/index.js +1 -0
- package/lib/module/components/line-chart/index.js.map +1 -1
- package/lib/module/components/marker/index.js +2 -2
- package/lib/module/components/marker/index.js.map +1 -1
- package/lib/module/components/marquee/index.js +9 -12
- package/lib/module/components/marquee/index.js.map +1 -1
- package/lib/module/components/marquee/marquee-math.js +39 -0
- package/lib/module/components/marquee/marquee-math.js.map +1 -0
- package/lib/module/components/menu/index.js +11 -3
- package/lib/module/components/menu/index.js.map +1 -1
- package/lib/module/components/pagination/index.js +27 -11
- package/lib/module/components/pagination/index.js.map +1 -1
- package/lib/module/components/panelside/index.js +7 -2
- package/lib/module/components/panelside/index.js.map +1 -1
- package/lib/module/components/planner/index.js +26 -5
- package/lib/module/components/planner/index.js.map +1 -1
- package/lib/module/components/plot/index.js +105 -42
- package/lib/module/components/plot/index.js.map +1 -1
- package/lib/module/components/post/index.js +4 -4
- package/lib/module/components/post/index.js.map +1 -1
- package/lib/module/components/search-bar/index.js +331 -0
- package/lib/module/components/search-bar/index.js.map +1 -0
- package/lib/module/components/table/index.js +3 -4
- package/lib/module/components/table/index.js.map +1 -1
- package/lib/module/components/timeline/index.js +288 -39
- package/lib/module/components/timeline/index.js.map +1 -1
- package/lib/module/components/toggle-button/index.js +1 -1
- package/lib/module/components/toggle-button/index.js.map +1 -1
- package/lib/module/components/tree/index.js +13 -8
- package/lib/module/components/tree/index.js.map +1 -1
- package/lib/module/hooks/use-keyboard-avoidance.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/chart.js +50 -7
- package/lib/module/utils/chart.js.map +1 -1
- package/lib/typescript/src/components/accordion/index.d.ts +2 -2
- package/lib/typescript/src/components/accordion/index.d.ts.map +1 -1
- package/lib/typescript/src/components/area-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/breadcrumb/index.d.ts.map +1 -1
- package/lib/typescript/src/components/button/index.d.ts.map +1 -1
- package/lib/typescript/src/components/code-block/index.d.ts +3 -3
- package/lib/typescript/src/components/code-block/index.d.ts.map +1 -1
- package/lib/typescript/src/components/collapsible/index.d.ts +2 -2
- package/lib/typescript/src/components/collapsible/index.d.ts.map +1 -1
- package/lib/typescript/src/components/color-picker/index.d.ts.map +1 -1
- package/lib/typescript/src/components/fab/index.d.ts +4 -2
- package/lib/typescript/src/components/fab/index.d.ts.map +1 -1
- package/lib/typescript/src/components/heatmap-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/hex-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/input-group/index.d.ts.map +1 -1
- package/lib/typescript/src/components/line-chart/index.d.ts.map +1 -1
- package/lib/typescript/src/components/marquee/index.d.ts +1 -1
- package/lib/typescript/src/components/marquee/index.d.ts.map +1 -1
- package/lib/typescript/src/components/marquee/marquee-math.d.ts +21 -0
- package/lib/typescript/src/components/marquee/marquee-math.d.ts.map +1 -0
- package/lib/typescript/src/components/menu/index.d.ts +1 -1
- package/lib/typescript/src/components/menu/index.d.ts.map +1 -1
- package/lib/typescript/src/components/pagination/index.d.ts.map +1 -1
- package/lib/typescript/src/components/panelside/index.d.ts +1 -1
- package/lib/typescript/src/components/panelside/index.d.ts.map +1 -1
- package/lib/typescript/src/components/plan/index.d.ts +2 -2
- package/lib/typescript/src/components/planner/index.d.ts.map +1 -1
- package/lib/typescript/src/components/plot/index.d.ts +59 -5
- package/lib/typescript/src/components/plot/index.d.ts.map +1 -1
- package/lib/typescript/src/components/search-bar/index.d.ts +216 -0
- package/lib/typescript/src/components/search-bar/index.d.ts.map +1 -0
- package/lib/typescript/src/components/timeline/index.d.ts +35 -2
- package/lib/typescript/src/components/timeline/index.d.ts.map +1 -1
- package/lib/typescript/src/components/tree/index.d.ts +3 -4
- package/lib/typescript/src/components/tree/index.d.ts.map +1 -1
- package/lib/typescript/src/hooks/use-keyboard-avoidance.d.ts +2 -2
- package/lib/typescript/src/hooks/use-keyboard-avoidance.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/utils/chart.d.ts +28 -3
- package/lib/typescript/src/utils/chart.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/accordion/index.tsx +17 -7
- package/src/components/area-chart/index.tsx +8 -0
- package/src/components/breadcrumb/index.tsx +2 -1
- package/src/components/button/index.tsx +3 -2
- package/src/components/carousel/index.tsx +1 -1
- package/src/components/chip/index.tsx +2 -2
- package/src/components/code-block/index.tsx +3 -3
- package/src/components/collapsible/index.tsx +13 -4
- package/src/components/color-picker/index.tsx +3 -2
- package/src/components/fab/index.tsx +21 -11
- package/src/components/flow/index.tsx +1 -1
- package/src/components/frame/index.tsx +2 -2
- package/src/components/grid-item/index.tsx +2 -2
- package/src/components/heatmap-chart/index.tsx +7 -1
- package/src/components/hex-chart/index.tsx +7 -1
- package/src/components/input-group/index.tsx +7 -2
- package/src/components/item/index.tsx +2 -2
- package/src/components/line-chart/index.tsx +9 -0
- package/src/components/marker/index.tsx +2 -2
- package/src/components/marquee/index.tsx +14 -12
- package/src/components/marquee/marquee-math.ts +37 -0
- package/src/components/menu/index.tsx +11 -3
- package/src/components/pagination/index.tsx +26 -13
- package/src/components/panelside/index.tsx +7 -2
- package/src/components/plan/index.tsx +2 -2
- package/src/components/planner/index.tsx +20 -5
- package/src/components/plot/index.tsx +183 -39
- package/src/components/post/index.tsx +4 -4
- package/src/components/search-bar/index.tsx +436 -0
- package/src/components/table/index.tsx +2 -2
- package/src/components/timeline/index.tsx +335 -39
- package/src/components/toggle-button/index.tsx +1 -1
- package/src/components/tree/index.tsx +17 -12
- package/src/hooks/use-keyboard-avoidance.ts +7 -2
- package/src/index.ts +2 -0
- package/src/utils/chart.ts +66 -7
|
@@ -328,6 +328,7 @@ const BreadcrumbEllipsis = forwardRef<View, BreadcrumbEllipsisProps>(
|
|
|
328
328
|
return (
|
|
329
329
|
<View
|
|
330
330
|
ref={ref}
|
|
331
|
+
{...(props as ViewProps)}
|
|
331
332
|
accessibilityLabel="More"
|
|
332
333
|
className={cn('h-5 items-center justify-center px-0.5', className)}
|
|
333
334
|
>
|
|
@@ -339,12 +340,12 @@ const BreadcrumbEllipsis = forwardRef<View, BreadcrumbEllipsisProps>(
|
|
|
339
340
|
return (
|
|
340
341
|
<AnimatedPressable
|
|
341
342
|
ref={ref}
|
|
343
|
+
{...props}
|
|
342
344
|
accessibilityRole="button"
|
|
343
345
|
accessibilityLabel="Show more"
|
|
344
346
|
pressScale={0.92}
|
|
345
347
|
onPress={onPress}
|
|
346
348
|
className={cn('h-5 items-center justify-center px-0.5', className)}
|
|
347
|
-
{...props}
|
|
348
349
|
>
|
|
349
350
|
{glyph}
|
|
350
351
|
</AnimatedPressable>
|
|
@@ -300,6 +300,7 @@ export const Button = forwardRef<View, ButtonProps>(
|
|
|
300
300
|
endContent,
|
|
301
301
|
native,
|
|
302
302
|
glass = false,
|
|
303
|
+
accessibilityState,
|
|
303
304
|
...props
|
|
304
305
|
},
|
|
305
306
|
ref
|
|
@@ -441,8 +442,6 @@ export const Button = forwardRef<View, ButtonProps>(
|
|
|
441
442
|
<IconColorProvider color={contentColor}>
|
|
442
443
|
<AnimatedPressable
|
|
443
444
|
ref={ref}
|
|
444
|
-
accessibilityRole="button"
|
|
445
|
-
accessibilityState={{ disabled: isDisabled, busy: loading }}
|
|
446
445
|
disabled={isDisabled}
|
|
447
446
|
// Joined segments cannot borrow room from each other without making
|
|
448
447
|
// two actions claim the same pixels. ButtonGroup owns that layout.
|
|
@@ -451,6 +450,8 @@ export const Button = forwardRef<View, ButtonProps>(
|
|
|
451
450
|
pressScale={attached ? 1 : undefined}
|
|
452
451
|
className={root({ className: cn(attached && ATTACHED, className) })}
|
|
453
452
|
{...props}
|
|
453
|
+
accessibilityRole="button"
|
|
454
|
+
accessibilityState={{ ...accessibilityState, disabled: isDisabled, busy: loading }}
|
|
454
455
|
>
|
|
455
456
|
{loading ? (
|
|
456
457
|
<Spinner size={SPINNER_SIZE[resolvedSize ?? 'md']} className={spinner()} />
|
|
@@ -799,6 +799,7 @@ function makeArrow(direction: 'previous' | 'next') {
|
|
|
799
799
|
|
|
800
800
|
return (
|
|
801
801
|
<Pressable
|
|
802
|
+
{...props}
|
|
802
803
|
disabled={disabled}
|
|
803
804
|
onPress={direction === 'next' ? next : previous}
|
|
804
805
|
accessibilityRole="button"
|
|
@@ -809,7 +810,6 @@ function makeArrow(direction: 'previous' | 'next') {
|
|
|
809
810
|
disabled ? 'opacity-30' : 'active:bg-foreground/10',
|
|
810
811
|
className
|
|
811
812
|
)}
|
|
812
|
-
{...props}
|
|
813
813
|
>
|
|
814
814
|
{children ??
|
|
815
815
|
(direction === 'next' ? (
|
|
@@ -285,9 +285,9 @@ const ChipRoot = forwardRef<View, ChipProps>(
|
|
|
285
285
|
{pressable ? (
|
|
286
286
|
<AnimatedPressable
|
|
287
287
|
ref={ref}
|
|
288
|
-
onPress={handlePress}
|
|
289
|
-
{...sharedProps}
|
|
290
288
|
{...props}
|
|
289
|
+
{...sharedProps}
|
|
290
|
+
onPress={handlePress}
|
|
291
291
|
>
|
|
292
292
|
{body}
|
|
293
293
|
</AnimatedPressable>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* block in a text part, or the fields of a tool call that wrote a file.
|
|
33
33
|
*/
|
|
34
34
|
import { createContext, useContext, useMemo, type ReactNode } from 'react';
|
|
35
|
-
import { ScrollView, View, type ViewProps } from 'react-native';
|
|
35
|
+
import { ScrollView, View, type TextProps, type ViewProps } from 'react-native';
|
|
36
36
|
import { tv } from 'tailwind-variants';
|
|
37
37
|
import { useCSSVariable } from 'uniwind';
|
|
38
38
|
import { useCopyToClipboard } from '../../hooks/use-copy-to-clipboard';
|
|
@@ -240,7 +240,7 @@ function CodeBlockHeader({ className, children, ...props }: CodeBlockHeaderProps
|
|
|
240
240
|
);
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
export interface CodeBlockFilenameProps extends
|
|
243
|
+
export interface CodeBlockFilenameProps extends TextProps {
|
|
244
244
|
className?: string;
|
|
245
245
|
children?: ReactNode;
|
|
246
246
|
}
|
|
@@ -254,7 +254,7 @@ function CodeBlockFilename({ className, children, ...props }: CodeBlockFilenameP
|
|
|
254
254
|
);
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
export interface CodeBlockLanguageProps extends
|
|
257
|
+
export interface CodeBlockLanguageProps extends TextProps {
|
|
258
258
|
className?: string;
|
|
259
259
|
children?: ReactNode;
|
|
260
260
|
}
|
|
@@ -49,7 +49,13 @@ import {
|
|
|
49
49
|
useState,
|
|
50
50
|
type ReactNode,
|
|
51
51
|
} from 'react';
|
|
52
|
-
import {
|
|
52
|
+
import {
|
|
53
|
+
Pressable,
|
|
54
|
+
View,
|
|
55
|
+
type PressableProps,
|
|
56
|
+
type Text as RNText,
|
|
57
|
+
type ViewProps,
|
|
58
|
+
} from 'react-native';
|
|
53
59
|
import Animated, {
|
|
54
60
|
useAnimatedStyle,
|
|
55
61
|
useReducedMotion,
|
|
@@ -160,14 +166,14 @@ const CollapsibleRoot = forwardRef<View, CollapsibleProps>(
|
|
|
160
166
|
);
|
|
161
167
|
CollapsibleRoot.displayName = 'Collapsible';
|
|
162
168
|
|
|
163
|
-
export interface CollapsibleTriggerProps extends
|
|
169
|
+
export interface CollapsibleTriggerProps extends Omit<PressableProps, 'children'> {
|
|
164
170
|
className?: string;
|
|
165
171
|
children?: ReactNode;
|
|
166
172
|
}
|
|
167
173
|
|
|
168
174
|
/** The pressable header row. Bare strings are wrapped in the title style. */
|
|
169
175
|
const CollapsibleTrigger = forwardRef<View, CollapsibleTriggerProps>(
|
|
170
|
-
({ className, children, ...props }, ref) => {
|
|
176
|
+
({ className, children, onPress, ...props }, ref) => {
|
|
171
177
|
const { open, toggle, isDisabled, variant } = useCollapsible('Collapsible.Trigger');
|
|
172
178
|
const { trigger, title } = collapsibleVariants({ variant });
|
|
173
179
|
|
|
@@ -177,9 +183,12 @@ const CollapsibleTrigger = forwardRef<View, CollapsibleTriggerProps>(
|
|
|
177
183
|
accessibilityRole="button"
|
|
178
184
|
accessibilityState={{ expanded: open, disabled: isDisabled }}
|
|
179
185
|
disabled={isDisabled}
|
|
180
|
-
onPress={toggle}
|
|
181
186
|
className={trigger({ className })}
|
|
182
187
|
{...props}
|
|
188
|
+
onPress={(event) => {
|
|
189
|
+
onPress?.(event);
|
|
190
|
+
toggle();
|
|
191
|
+
}}
|
|
183
192
|
>
|
|
184
193
|
{textChildren(children, (text) => (
|
|
185
194
|
<Text className={title()}>{text}</Text>
|
|
@@ -71,6 +71,7 @@ import {
|
|
|
71
71
|
View,
|
|
72
72
|
type AccessibilityActionEvent,
|
|
73
73
|
type LayoutChangeEvent,
|
|
74
|
+
type ViewStyle,
|
|
74
75
|
} from 'react-native';
|
|
75
76
|
import MaskedView from '@react-native-masked-view/masked-view';
|
|
76
77
|
import { LinearGradient } from 'expo-linear-gradient';
|
|
@@ -663,8 +664,8 @@ interface ChannelTrackProps {
|
|
|
663
664
|
/** What fills the track — a hue ramp, or a masked translucency ramp. */
|
|
664
665
|
children: ReactNode;
|
|
665
666
|
gesture: ReturnType<typeof Gesture.Race>;
|
|
666
|
-
thumbStyle: ReturnType<typeof useAnimatedStyle
|
|
667
|
-
thumbFillStyle: ReturnType<typeof useAnimatedStyle
|
|
667
|
+
thumbStyle: ReturnType<typeof useAnimatedStyle<ViewStyle>>;
|
|
668
|
+
thumbFillStyle: ReturnType<typeof useAnimatedStyle<ViewStyle>>;
|
|
668
669
|
onLayout: (event: LayoutChangeEvent) => void;
|
|
669
670
|
size: ColorPickerSize;
|
|
670
671
|
className?: string;
|
|
@@ -85,7 +85,10 @@ import { tv, type VariantProps } from 'tailwind-variants';
|
|
|
85
85
|
import { useCSSVariable } from 'uniwind';
|
|
86
86
|
import { IconColorProvider } from '../../icons';
|
|
87
87
|
import { useBackHandler } from '../../hooks/use-back-handler';
|
|
88
|
-
import {
|
|
88
|
+
import {
|
|
89
|
+
AnimatedPressable,
|
|
90
|
+
type AnimatedPressableProps,
|
|
91
|
+
} from '../../primitives/animated-pressable';
|
|
89
92
|
import { Scrim } from '../../primitives/scrim';
|
|
90
93
|
import { Text } from '../../primitives/text';
|
|
91
94
|
import { cn } from '../../utils/cn';
|
|
@@ -180,7 +183,9 @@ function anchor(placement: FabPlacement, offset: number) {
|
|
|
180
183
|
* Fab
|
|
181
184
|
* -------------------------------------------------------------------------- */
|
|
182
185
|
|
|
183
|
-
export interface FabProps
|
|
186
|
+
export interface FabProps
|
|
187
|
+
extends Omit<AnimatedPressableProps, 'children' | 'style' | 'disabled'>,
|
|
188
|
+
Omit<FabVariantProps, 'disabled'> {
|
|
184
189
|
className?: string;
|
|
185
190
|
/** The glyph. Sized by you — this is the one thing that should not guess. */
|
|
186
191
|
icon?: ReactNode;
|
|
@@ -201,7 +206,8 @@ export interface FabProps extends Omit<ViewProps, 'children'>, FabVariantProps {
|
|
|
201
206
|
placement?: FabPlacement;
|
|
202
207
|
/** Distance from the edges when `placement` is set, in points. */
|
|
203
208
|
offset?: number;
|
|
204
|
-
|
|
209
|
+
/** Placement-aware view style. Press-state styling belongs in `className`. */
|
|
210
|
+
style?: ViewProps['style'];
|
|
205
211
|
disabled?: boolean;
|
|
206
212
|
/**
|
|
207
213
|
* A tick on press. Off by default — needs the optional `expo-haptics`, and
|
|
@@ -231,33 +237,37 @@ const FabRoot = forwardRef<View, FabProps>(
|
|
|
231
237
|
},
|
|
232
238
|
ref
|
|
233
239
|
) => {
|
|
240
|
+
const isDisabled = Boolean(disabled);
|
|
234
241
|
const { root, label } = fabVariants({
|
|
235
242
|
size,
|
|
236
243
|
variant,
|
|
237
244
|
extended: extended && !!children,
|
|
238
|
-
disabled,
|
|
245
|
+
disabled: isDisabled,
|
|
239
246
|
});
|
|
240
247
|
|
|
241
248
|
const themed = useCSSVariable(CONTENT_COLOR_VAR[variant ?? 'primary']);
|
|
242
249
|
const contentColor =
|
|
243
250
|
typeof themed === 'string' ? themed : undefined;
|
|
244
251
|
|
|
245
|
-
const handlePress = useCallback(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
252
|
+
const handlePress = useCallback<NonNullable<AnimatedPressableProps['onPress']>>(
|
|
253
|
+
(event) => {
|
|
254
|
+
if (haptics) selectionTick();
|
|
255
|
+
onPress?.(event);
|
|
256
|
+
},
|
|
257
|
+
[haptics, onPress]
|
|
258
|
+
);
|
|
249
259
|
|
|
250
260
|
return (
|
|
251
261
|
<IconColorProvider color={contentColor}>
|
|
252
262
|
<AnimatedPressable
|
|
253
263
|
ref={ref}
|
|
264
|
+
{...props}
|
|
254
265
|
accessibilityRole="button"
|
|
255
|
-
accessibilityState={{ disabled }}
|
|
256
|
-
disabled={
|
|
266
|
+
accessibilityState={{ disabled: isDisabled }}
|
|
267
|
+
disabled={isDisabled}
|
|
257
268
|
onPress={handlePress}
|
|
258
269
|
className={root({ className })}
|
|
259
270
|
style={[placement ? anchor(placement, offset) : null, style]}
|
|
260
|
-
{...props}
|
|
261
271
|
>
|
|
262
272
|
{icon}
|
|
263
273
|
{extended && children ? (
|
|
@@ -1254,6 +1254,7 @@ function FlowNode({
|
|
|
1254
1254
|
<FlowNodeContext.Provider value={id}>
|
|
1255
1255
|
<GestureDetector gesture={gesture}>
|
|
1256
1256
|
<Animated.View
|
|
1257
|
+
{...props}
|
|
1257
1258
|
collapsable={false}
|
|
1258
1259
|
onLayout={onLayout}
|
|
1259
1260
|
style={[{ position: 'absolute', top: 0, left: 0 }, style]}
|
|
@@ -1267,7 +1268,6 @@ function FlowNode({
|
|
|
1267
1268
|
accessibilityState={{ selected }}
|
|
1268
1269
|
accessibilityActions={nodeActions}
|
|
1269
1270
|
onAccessibilityAction={handleAccessibilityAction}
|
|
1270
|
-
{...props}
|
|
1271
1271
|
>
|
|
1272
1272
|
{textChildren(children)}
|
|
1273
1273
|
</Animated.View>
|
|
@@ -398,7 +398,7 @@ const FrameRow = forwardRef<View, FrameRowProps>(
|
|
|
398
398
|
|
|
399
399
|
if (!onPress) {
|
|
400
400
|
return (
|
|
401
|
-
<View ref={ref}
|
|
401
|
+
<View ref={ref} {...(props as ViewProps)} className={classes}>
|
|
402
402
|
{body}
|
|
403
403
|
</View>
|
|
404
404
|
);
|
|
@@ -407,10 +407,10 @@ const FrameRow = forwardRef<View, FrameRowProps>(
|
|
|
407
407
|
return (
|
|
408
408
|
<Pressable
|
|
409
409
|
ref={ref}
|
|
410
|
+
{...props}
|
|
410
411
|
accessibilityRole="button"
|
|
411
412
|
onPress={onPress}
|
|
412
413
|
className={classes}
|
|
413
|
-
{...props}
|
|
414
414
|
>
|
|
415
415
|
{body}
|
|
416
416
|
</Pressable>
|
|
@@ -334,9 +334,9 @@ const GridItemRoot = forwardRef<View, GridItemProps>(
|
|
|
334
334
|
return (
|
|
335
335
|
<View
|
|
336
336
|
ref={ref}
|
|
337
|
+
{...(props as ViewProps)}
|
|
337
338
|
accessibilityState={{ disabled: !!disabled }}
|
|
338
339
|
className={root({ className })}
|
|
339
|
-
{...(props as ViewProps)}
|
|
340
340
|
>
|
|
341
341
|
{textChildren(children)}
|
|
342
342
|
</View>
|
|
@@ -346,12 +346,12 @@ const GridItemRoot = forwardRef<View, GridItemProps>(
|
|
|
346
346
|
return (
|
|
347
347
|
<AnimatedPressable
|
|
348
348
|
ref={ref}
|
|
349
|
+
{...props}
|
|
349
350
|
accessibilityRole="button"
|
|
350
351
|
accessibilityState={{ disabled: !!disabled }}
|
|
351
352
|
disabled={disabled}
|
|
352
353
|
onPress={onPress}
|
|
353
354
|
className={root({ className })}
|
|
354
|
-
{...props}
|
|
355
355
|
>
|
|
356
356
|
{textChildren(children)}
|
|
357
357
|
</AnimatedPressable>
|
|
@@ -628,7 +628,13 @@ const HeatmapChartRoot = forwardRef<View, HeatmapChartProps>(function HeatmapCha
|
|
|
628
628
|
<Svg width={grid.width} height={grid.height} style={StyleSheet.absoluteFill}>
|
|
629
629
|
<Defs>
|
|
630
630
|
<ClipPath id={clipId}>
|
|
631
|
-
<AnimatedRect
|
|
631
|
+
<AnimatedRect
|
|
632
|
+
x={0}
|
|
633
|
+
y={0}
|
|
634
|
+
width={grid.width}
|
|
635
|
+
height={grid.height}
|
|
636
|
+
animatedProps={clipProps}
|
|
637
|
+
/>
|
|
632
638
|
</ClipPath>
|
|
633
639
|
</Defs>
|
|
634
640
|
<G clipPath={`url(#${clipId})`}>
|
|
@@ -534,7 +534,13 @@ const HexChartRoot = forwardRef<HexChartHandle, HexChartProps>(function HexChart
|
|
|
534
534
|
animatedProps={ellipseProps}
|
|
535
535
|
/>
|
|
536
536
|
) : (
|
|
537
|
-
<AnimatedRect
|
|
537
|
+
<AnimatedRect
|
|
538
|
+
x={0}
|
|
539
|
+
y={0}
|
|
540
|
+
width={width}
|
|
541
|
+
height={height}
|
|
542
|
+
animatedProps={rectProps}
|
|
543
|
+
/>
|
|
538
544
|
)}
|
|
539
545
|
</ClipPath>
|
|
540
546
|
</Defs>
|
|
@@ -146,8 +146,13 @@ const InputGroupInput = forwardRef<TextInput, InputGroupInputProps>(
|
|
|
146
146
|
style={[
|
|
147
147
|
// Only override padding on the side that actually has a decorator —
|
|
148
148
|
// a 0 here would wipe out the field's default horizontal padding.
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
//
|
|
150
|
+
// `paddingStart`/`paddingEnd`, not left/right: the decorators are
|
|
151
|
+
// inset with `start-0`/`end-0`, so under `Direction dir="rtl"` Yoga
|
|
152
|
+
// moves them to the other edge. Physical padding stays where it was
|
|
153
|
+
// written and leaves the value running underneath them.
|
|
154
|
+
group?.prefixWidth ? { paddingStart: group.prefixWidth } : null,
|
|
155
|
+
group?.suffixWidth ? { paddingEnd: group.suffixWidth } : null,
|
|
151
156
|
style,
|
|
152
157
|
]}
|
|
153
158
|
{...props}
|
|
@@ -148,21 +148,21 @@ const ItemRoot = forwardRef<View, ItemProps>(
|
|
|
148
148
|
const body = !onPress ? (
|
|
149
149
|
<View
|
|
150
150
|
ref={ref}
|
|
151
|
+
{...(props as ViewProps)}
|
|
151
152
|
accessibilityState={{ disabled: !!disabled }}
|
|
152
153
|
className={root({ className })}
|
|
153
|
-
{...(props as ViewProps)}
|
|
154
154
|
>
|
|
155
155
|
{textChildren(children)}
|
|
156
156
|
</View>
|
|
157
157
|
) : (
|
|
158
158
|
<AnimatedPressable
|
|
159
159
|
ref={ref}
|
|
160
|
+
{...props}
|
|
160
161
|
accessibilityRole="button"
|
|
161
162
|
accessibilityState={{ disabled: !!disabled }}
|
|
162
163
|
disabled={disabled}
|
|
163
164
|
onPress={onPress}
|
|
164
165
|
className={root({ className })}
|
|
165
|
-
{...props}
|
|
166
166
|
>
|
|
167
167
|
{textChildren(children)}
|
|
168
168
|
</AnimatedPressable>
|
|
@@ -477,11 +477,20 @@ const LineChartRoot = forwardRef<LineChartHandle, LineChartProps>(function LineC
|
|
|
477
477
|
* One clip for everything in the plot. Sharing it is what
|
|
478
478
|
* makes the reveal read as the chart arriving, rather than as
|
|
479
479
|
* three separate things animating in at once.
|
|
480
|
+
*
|
|
481
|
+
* `width` is set statically as well as animated, and it has
|
|
482
|
+
* to be. Animated props on an element inside `Defs` do not
|
|
483
|
+
* reach the native clip on every platform, and with the width
|
|
484
|
+
* coming only from the animation there is no width at all
|
|
485
|
+
* when they do not — an empty clip, and a chart whose marks
|
|
486
|
+
* are all invisible while its axes draw normally. Declared,
|
|
487
|
+
* the worst case is the reveal not playing.
|
|
480
488
|
*/}
|
|
481
489
|
<ClipPath id={clipId}>
|
|
482
490
|
<AnimatedRect
|
|
483
491
|
x={plot.left}
|
|
484
492
|
y={0}
|
|
493
|
+
width={plot.width}
|
|
485
494
|
height={size.height}
|
|
486
495
|
animatedProps={clipProps}
|
|
487
496
|
/>
|
|
@@ -100,21 +100,21 @@ const MarkerRoot = forwardRef<View, MarkerProps>(
|
|
|
100
100
|
const body = !onPress ? (
|
|
101
101
|
<View
|
|
102
102
|
ref={ref}
|
|
103
|
+
{...(props as ViewProps)}
|
|
103
104
|
accessibilityState={{ disabled: !!disabled }}
|
|
104
105
|
className={root({ className })}
|
|
105
|
-
{...(props as ViewProps)}
|
|
106
106
|
>
|
|
107
107
|
{inner}
|
|
108
108
|
</View>
|
|
109
109
|
) : (
|
|
110
110
|
<AnimatedPressable
|
|
111
111
|
ref={ref}
|
|
112
|
+
{...props}
|
|
112
113
|
accessibilityRole="button"
|
|
113
114
|
accessibilityState={{ disabled: !!disabled }}
|
|
114
115
|
disabled={disabled}
|
|
115
116
|
onPress={onPress}
|
|
116
117
|
className={root({ className })}
|
|
117
|
-
{...props}
|
|
118
118
|
>
|
|
119
119
|
{inner}
|
|
120
120
|
</AnimatedPressable>
|
|
@@ -62,12 +62,11 @@ import Animated, {
|
|
|
62
62
|
} from 'react-native-reanimated';
|
|
63
63
|
import { useDirectionSign } from '../../hooks/use-direction';
|
|
64
64
|
import { cn } from '../../utils/cn';
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const DEFAULT_SPEED = 40;
|
|
65
|
+
import {
|
|
66
|
+
DEFAULT_MARQUEE_SPEED,
|
|
67
|
+
marqueeCopyCount,
|
|
68
|
+
normalizeMarqueeSpeed,
|
|
69
|
+
} from './marquee-math';
|
|
71
70
|
|
|
72
71
|
export type MarqueeDirection = 'horizontal' | 'vertical';
|
|
73
72
|
|
|
@@ -98,7 +97,7 @@ export interface MarqueeProps extends Omit<ViewProps, 'children'> {
|
|
|
98
97
|
export function Marquee({
|
|
99
98
|
className,
|
|
100
99
|
children,
|
|
101
|
-
speed =
|
|
100
|
+
speed: speedProp = DEFAULT_MARQUEE_SPEED,
|
|
102
101
|
spacing = 0,
|
|
103
102
|
direction = 'horizontal',
|
|
104
103
|
reverse = false,
|
|
@@ -115,19 +114,22 @@ export function Marquee({
|
|
|
115
114
|
|
|
116
115
|
const [viewport, setViewport] = useState(0);
|
|
117
116
|
const [content, setContent] = useState(0);
|
|
117
|
+
const speed = normalizeMarqueeSpeed(speedProp);
|
|
118
118
|
|
|
119
119
|
// The distance from one copy to the same point on the next, and therefore
|
|
120
120
|
// both the layout step and the exact loop length. They are the same number
|
|
121
121
|
// on purpose: taking the gap from anywhere else is how a seam appears.
|
|
122
|
-
const
|
|
122
|
+
const layout = useMemo(
|
|
123
|
+
() => marqueeCopyCount(viewport, content, spacing),
|
|
124
|
+
[viewport, content, spacing]
|
|
125
|
+
);
|
|
126
|
+
const { period } = layout;
|
|
123
127
|
|
|
124
128
|
const copies = useMemo(() => {
|
|
125
|
-
if (period <= 0 || viewport <= 0) return [];
|
|
126
129
|
// Enough to span the container, plus one trailing into view and one
|
|
127
130
|
// already past it — the two the travel consumes before the loop restarts.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}, [period, viewport]);
|
|
131
|
+
return Array.from({ length: layout.count }, (_, index) => index);
|
|
132
|
+
}, [layout.count]);
|
|
131
133
|
|
|
132
134
|
const offset = useSharedValue(0);
|
|
133
135
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The arithmetic behind the loop, kept out of the component so it can be tested
|
|
3
|
+
* without rendering one.
|
|
4
|
+
*
|
|
5
|
+
* Every value here reaches a Reanimated timing or a layout offset, and both
|
|
6
|
+
* treat `NaN` and `Infinity` as a frame that never resolves rather than as an
|
|
7
|
+
* error. A marquee handed a bad number should hold still, not wedge — so the
|
|
8
|
+
* guards live at the boundary, once, instead of at each use.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Points per second. Slow enough that a word stays readable as it crosses,
|
|
13
|
+
* which is the speed a ticker is actually for.
|
|
14
|
+
*/
|
|
15
|
+
export const DEFAULT_MARQUEE_SPEED = 40;
|
|
16
|
+
|
|
17
|
+
export function normalizeMarqueeSpeed(value: number): number {
|
|
18
|
+
if (!Number.isFinite(value)) return DEFAULT_MARQUEE_SPEED;
|
|
19
|
+
return Math.max(value, 0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function normalizeMarqueeSpacing(value: number): number {
|
|
23
|
+
if (!Number.isFinite(value)) return 0;
|
|
24
|
+
return Math.max(value, 0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function marqueeCopyCount(
|
|
28
|
+
viewport: number,
|
|
29
|
+
content: number,
|
|
30
|
+
spacing: number
|
|
31
|
+
): { period: number; count: number } {
|
|
32
|
+
const safeViewport = Number.isFinite(viewport) ? Math.max(viewport, 0) : 0;
|
|
33
|
+
const safeContent = Number.isFinite(content) ? Math.max(content, 0) : 0;
|
|
34
|
+
const period = safeContent > 0 ? safeContent + normalizeMarqueeSpacing(spacing) : 0;
|
|
35
|
+
if (period <= 0 || safeViewport <= 0) return { period, count: 0 };
|
|
36
|
+
return { period, count: Math.ceil(safeViewport / period) + 2 };
|
|
37
|
+
}
|
|
@@ -451,6 +451,8 @@ export function MenuItem({
|
|
|
451
451
|
closeOnSelect = true,
|
|
452
452
|
onSelect,
|
|
453
453
|
onPress,
|
|
454
|
+
onPressIn,
|
|
455
|
+
onPressOut,
|
|
454
456
|
...props
|
|
455
457
|
}: MenuItemProps) {
|
|
456
458
|
const { close, haptics } = useMenu('Menu.Item');
|
|
@@ -467,15 +469,21 @@ export function MenuItem({
|
|
|
467
469
|
|
|
468
470
|
return (
|
|
469
471
|
<AnimatedPressable
|
|
472
|
+
{...props}
|
|
470
473
|
accessibilityRole="menuitem"
|
|
471
474
|
accessibilityState={{ disabled }}
|
|
472
475
|
disabled={disabled}
|
|
473
476
|
onPress={handlePress}
|
|
474
|
-
onPressIn={
|
|
475
|
-
|
|
477
|
+
onPressIn={(event) => {
|
|
478
|
+
onPressIn?.(event);
|
|
479
|
+
press.onPressIn();
|
|
480
|
+
}}
|
|
481
|
+
onPressOut={(event) => {
|
|
482
|
+
onPressOut?.(event);
|
|
483
|
+
press.onPressOut();
|
|
484
|
+
}}
|
|
476
485
|
style={press.rowStyle}
|
|
477
486
|
className={cn(slots.item(), 'overflow-hidden', className)}
|
|
478
|
-
{...props}
|
|
479
487
|
>
|
|
480
488
|
<Animated.View
|
|
481
489
|
pointerEvents="none"
|
|
@@ -367,7 +367,7 @@ export interface PaginationItemProps
|
|
|
367
367
|
* are on, so the current page is spoken as state rather than only painted.
|
|
368
368
|
*/
|
|
369
369
|
const PaginationItem = forwardRef<View, PaginationItemProps>(
|
|
370
|
-
({ className, labelClassName, page, children, ...props }, ref) => {
|
|
370
|
+
({ className, labelClassName, page, children, onPress, ...props }, ref) => {
|
|
371
371
|
const { page: current, size, disabled, goTo } = usePagination('Pagination.Item');
|
|
372
372
|
const isCurrent = page === current;
|
|
373
373
|
const { item, itemLabel } = paginationVariants({ size, current: isCurrent, disabled });
|
|
@@ -375,14 +375,17 @@ const PaginationItem = forwardRef<View, PaginationItemProps>(
|
|
|
375
375
|
return (
|
|
376
376
|
<AnimatedPressable
|
|
377
377
|
ref={ref}
|
|
378
|
+
{...props}
|
|
378
379
|
accessibilityRole="button"
|
|
379
380
|
accessibilityLabel={`Page ${page}`}
|
|
380
381
|
accessibilityState={{ selected: isCurrent, disabled }}
|
|
381
382
|
disabled={disabled}
|
|
382
383
|
hitSlop={size === 'sm' ? SMALL_HIT_SLOP : undefined}
|
|
383
|
-
onPress={() =>
|
|
384
|
+
onPress={(event) => {
|
|
385
|
+
onPress?.(event);
|
|
386
|
+
goTo(page);
|
|
387
|
+
}}
|
|
384
388
|
className={item({ className })}
|
|
385
|
-
{...props}
|
|
386
389
|
>
|
|
387
390
|
{textChildren(children ?? String(page), (text) => (
|
|
388
391
|
<Text className={itemLabel({ className: labelClassName })}>{text}</Text>
|
|
@@ -437,23 +440,29 @@ function PaginationArrow({
|
|
|
437
440
|
word,
|
|
438
441
|
className,
|
|
439
442
|
label,
|
|
443
|
+
disabled,
|
|
444
|
+
onPress,
|
|
440
445
|
...props
|
|
441
446
|
}: PaginationArrowProps & { step: -1 | 1; part: string; word: string }) {
|
|
442
447
|
const { Glyph, size, spent, color, press } = useArrow(step, part);
|
|
443
|
-
const
|
|
448
|
+
const isDisabled = Boolean(spent || disabled);
|
|
449
|
+
const { item, itemLabel } = paginationVariants({ size, disabled: isDisabled });
|
|
444
450
|
|
|
445
451
|
return (
|
|
446
452
|
<AnimatedPressable
|
|
453
|
+
{...props}
|
|
447
454
|
accessibilityRole="button"
|
|
448
455
|
accessibilityLabel={word}
|
|
449
|
-
accessibilityState={{ disabled:
|
|
450
|
-
disabled={
|
|
456
|
+
accessibilityState={{ disabled: isDisabled }}
|
|
457
|
+
disabled={isDisabled}
|
|
451
458
|
hitSlop={size === 'sm' ? SMALL_HIT_SLOP : undefined}
|
|
452
|
-
onPress={
|
|
459
|
+
onPress={(event) => {
|
|
460
|
+
onPress?.(event);
|
|
461
|
+
press();
|
|
462
|
+
}}
|
|
453
463
|
className={item({
|
|
454
464
|
className: cn('flex-row gap-1', label && (size === 'sm' ? 'px-2' : 'px-3'), className),
|
|
455
465
|
})}
|
|
456
|
-
{...props}
|
|
457
466
|
>
|
|
458
467
|
{step === -1 ? <Glyph size={iconSize[size]} color={color} /> : null}
|
|
459
468
|
{label ? <Text className={itemLabel()}>{word}</Text> : null}
|
|
@@ -489,24 +498,28 @@ export interface PaginationEllipsisProps
|
|
|
489
498
|
* that always went forwards would strand anyone reading the row right to left.
|
|
490
499
|
*/
|
|
491
500
|
const PaginationEllipsis = forwardRef<View, PaginationEllipsisProps>(
|
|
492
|
-
({ className, direction = 1, jump = 5, ...props }, ref) => {
|
|
501
|
+
({ className, direction = 1, jump = 5, disabled: disabledProp, onPress, ...props }, ref) => {
|
|
493
502
|
const { page, size, disabled, goTo } = usePagination('Pagination.Ellipsis');
|
|
494
503
|
const color = useCSSVariable('--color-muted-foreground');
|
|
495
504
|
const { ellipsis } = paginationVariants({ size });
|
|
505
|
+
const isDisabled = Boolean(disabled || disabledProp);
|
|
496
506
|
|
|
497
507
|
return (
|
|
498
508
|
<AnimatedPressable
|
|
499
509
|
ref={ref}
|
|
510
|
+
{...props}
|
|
500
511
|
accessibilityRole="button"
|
|
501
512
|
accessibilityLabel={
|
|
502
513
|
direction === -1 ? `Back ${jump} pages` : `Forward ${jump} pages`
|
|
503
514
|
}
|
|
504
|
-
accessibilityState={{ disabled }}
|
|
505
|
-
disabled={
|
|
515
|
+
accessibilityState={{ disabled: isDisabled }}
|
|
516
|
+
disabled={isDisabled}
|
|
506
517
|
hitSlop={size === 'sm' ? SMALL_HIT_SLOP : undefined}
|
|
507
|
-
onPress={() =>
|
|
518
|
+
onPress={(event) => {
|
|
519
|
+
onPress?.(event);
|
|
520
|
+
goTo(page + direction * jump);
|
|
521
|
+
}}
|
|
508
522
|
className={ellipsis({ className })}
|
|
509
|
-
{...props}
|
|
510
523
|
>
|
|
511
524
|
<EllipsisIcon
|
|
512
525
|
size={iconSize[size]}
|