react-native-terra-ui 0.7.2 → 0.8.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/CHANGELOG.md +28 -0
- package/README.md +1 -1
- package/lib/module/components/avatar/Avatar.js +20 -20
- package/lib/module/components/avatar/Avatar.js.map +1 -1
- package/lib/module/components/button/Button.js +11 -11
- package/lib/module/components/button/Button.js.map +1 -1
- package/lib/module/components/chip/Chip.js +32 -32
- package/lib/module/components/chip/Chip.js.map +1 -1
- package/lib/module/components/empty-state/EmptyState.js +3 -3
- package/lib/module/components/empty-state/EmptyState.js.map +1 -1
- package/lib/module/components/header/variants/LargeTitleHeader/index.js +30 -32
- package/lib/module/components/header/variants/LargeTitleHeader/index.js.map +1 -1
- package/lib/module/components/header/variants/TitleHeader/index.js +26 -18
- package/lib/module/components/header/variants/TitleHeader/index.js.map +1 -1
- package/lib/module/components/icon/Icon.js +3 -3
- package/lib/module/components/page-indicator/hooks/use-page-indicator-colors.js +2 -2
- package/lib/module/components/screen/Screen.js +63 -34
- package/lib/module/components/screen/Screen.js.map +1 -1
- package/lib/module/components/screen/ScreenContext.js +28 -9
- package/lib/module/components/screen/ScreenContext.js.map +1 -1
- package/lib/module/components/screen/ScreenFlatList.js +4 -162
- package/lib/module/components/screen/ScreenFlatList.js.map +1 -1
- package/lib/module/components/screen/ScreenList.js +81 -97
- package/lib/module/components/screen/ScreenList.js.map +1 -1
- package/lib/module/components/screen/ScreenScrollView.js +64 -115
- package/lib/module/components/screen/ScreenScrollView.js.map +1 -1
- package/lib/module/components/screen/hooks/use-screen-ref.js +18 -0
- package/lib/module/components/screen/hooks/use-screen-ref.js.map +1 -0
- package/lib/module/components/screen/hooks/use-screen-scroll-handler.js +19 -0
- package/lib/module/components/screen/hooks/use-screen-scroll-handler.js.map +1 -0
- package/lib/module/components/screen/index.js.map +1 -1
- package/lib/module/components/screen/parts/ScreenFrame.js +47 -0
- package/lib/module/components/screen/parts/ScreenFrame.js.map +1 -0
- package/lib/module/components/screen/parts/ScreenHeaderAppearance.js +43 -0
- package/lib/module/components/screen/parts/ScreenHeaderAppearance.js.map +1 -0
- package/lib/module/components/screen/parts/ScreenPlaceholder.js +11 -13
- package/lib/module/components/screen/parts/ScreenPlaceholder.js.map +1 -1
- package/lib/module/components/screen/parts/ScreenSafeArea.android.js +27 -0
- package/lib/module/components/screen/parts/ScreenSafeArea.android.js.map +1 -0
- package/lib/module/components/screen/parts/ScreenSafeArea.js +26 -0
- package/lib/module/components/screen/parts/ScreenSafeArea.js.map +1 -0
- package/lib/module/components/screen/utils.js +18 -9
- package/lib/module/components/screen/utils.js.map +1 -1
- package/lib/module/components/spinner/Spinner.js +2 -2
- package/lib/module/components/text/Text.js +1 -1
- package/lib/module/components/toast/Toast.js +13 -13
- package/lib/module/components/toast/Toast.js.map +1 -1
- package/lib/module/components/toolbar/Toolbar.js +2 -2
- package/lib/module/context/ThemeProvider.js +22 -39
- package/lib/module/context/ThemeProvider.js.map +1 -1
- package/lib/module/context/index.js +1 -1
- package/lib/module/context/index.js.map +1 -1
- package/lib/module/theme/breakpoints.js +1 -1
- package/lib/module/theme/define-config.js +21 -0
- package/lib/module/theme/define-config.js.map +1 -0
- package/lib/module/theme/diagnostics.js +13 -0
- package/lib/module/theme/diagnostics.js.map +1 -0
- package/lib/module/theme/errors.js +15 -0
- package/lib/module/theme/errors.js.map +1 -0
- package/lib/module/theme/index.js +7 -1
- package/lib/module/theme/index.js.map +1 -1
- package/lib/module/theme/legacy-tokens.js +119 -0
- package/lib/module/theme/legacy-tokens.js.map +1 -0
- package/lib/module/theme/registry.js +122 -130
- package/lib/module/theme/registry.js.map +1 -1
- package/lib/module/theme/resolve-config.js +346 -0
- package/lib/module/theme/resolve-config.js.map +1 -0
- package/lib/module/theme/runtime.js +57 -12
- package/lib/module/theme/runtime.js.map +1 -1
- package/lib/module/theme/screen-margin.js +6 -14
- package/lib/module/theme/screen-margin.js.map +1 -1
- package/lib/module/theme/screen-padding.js +17 -0
- package/lib/module/theme/screen-padding.js.map +1 -0
- package/lib/module/theme/selection-store.js +75 -0
- package/lib/module/theme/selection-store.js.map +1 -0
- package/lib/module/theme/theme.js +81 -36
- package/lib/module/theme/theme.js.map +1 -1
- package/lib/module/theme/tokens/canonical-color-keys.js +102 -0
- package/lib/module/theme/tokens/canonical-color-keys.js.map +1 -0
- package/lib/module/theme/tokens/dark.js +72 -88
- package/lib/module/theme/tokens/dark.js.map +1 -1
- package/lib/module/theme/tokens/light.js +69 -83
- package/lib/module/theme/tokens/light.js.map +1 -1
- package/lib/module/theme/tokens/primitives.js +14 -14
- package/lib/module/theme/tokens/primitives.js.map +1 -1
- package/lib/module/theme/tokens/validate.js +238 -0
- package/lib/module/theme/tokens/validate.js.map +1 -0
- package/lib/module/theme/unistyles-adapter.js +77 -0
- package/lib/module/theme/unistyles-adapter.js.map +1 -0
- package/lib/module/utils/accent-generator.js +476 -0
- package/lib/module/utils/accent-generator.js.map +1 -0
- package/lib/module/utils/accent-utils.js +52 -35
- package/lib/module/utils/accent-utils.js.map +1 -1
- package/lib/module/utils/color-utils.js +224 -7
- package/lib/module/utils/color-utils.js.map +1 -1
- package/lib/module/utils/deep-merge.js +1 -1
- package/lib/module/utils/deep-merge.js.map +1 -1
- package/lib/module/utils/resolve-theme-color.js +2 -2
- package/lib/typescript/src/components/chip/types.d.ts +1 -1
- package/lib/typescript/src/components/empty-state/EmptyState.d.ts +1 -1
- package/lib/typescript/src/components/empty-state/EmptyState.d.ts.map +1 -1
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts +6 -5
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts.map +1 -1
- package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts +11 -5
- package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts.map +1 -1
- package/lib/typescript/src/components/icon/Icon.d.ts +2 -2
- package/lib/typescript/src/components/screen/Screen.d.ts +45 -16
- package/lib/typescript/src/components/screen/Screen.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/ScreenContext.d.ts +42 -26
- package/lib/typescript/src/components/screen/ScreenContext.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/ScreenFlatList.d.ts +5 -46
- package/lib/typescript/src/components/screen/ScreenFlatList.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/ScreenList.d.ts +62 -50
- package/lib/typescript/src/components/screen/ScreenList.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/ScreenScrollView.d.ts +18 -58
- package/lib/typescript/src/components/screen/ScreenScrollView.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/hooks/use-screen-ref.d.ts +5 -0
- package/lib/typescript/src/components/screen/hooks/use-screen-ref.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/hooks/use-screen-scroll-handler.d.ts +53 -0
- package/lib/typescript/src/components/screen/hooks/use-screen-scroll-handler.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/index.d.ts +2 -2
- package/lib/typescript/src/components/screen/index.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/parts/ScreenFrame.d.ts +6 -0
- package/lib/typescript/src/components/screen/parts/ScreenFrame.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/parts/ScreenHeaderAppearance.d.ts +21 -0
- package/lib/typescript/src/components/screen/parts/ScreenHeaderAppearance.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/parts/ScreenPlaceholder.d.ts +6 -8
- package/lib/typescript/src/components/screen/parts/ScreenPlaceholder.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/parts/ScreenSafeArea.android.d.ts +7 -0
- package/lib/typescript/src/components/screen/parts/ScreenSafeArea.android.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/parts/ScreenSafeArea.d.ts +6 -0
- package/lib/typescript/src/components/screen/parts/ScreenSafeArea.d.ts.map +1 -0
- package/lib/typescript/src/components/screen/types.d.ts +27 -32
- package/lib/typescript/src/components/screen/types.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/utils.d.ts +9 -8
- package/lib/typescript/src/components/screen/utils.d.ts.map +1 -1
- package/lib/typescript/src/components/text/Text.d.ts +1 -1
- package/lib/typescript/src/components/text/Text.d.ts.map +1 -1
- package/lib/typescript/src/components/toolbar/Toolbar.d.ts +2 -2
- package/lib/typescript/src/context/ThemeProvider.d.ts +29 -12
- package/lib/typescript/src/context/ThemeProvider.d.ts.map +1 -1
- package/lib/typescript/src/context/index.d.ts +1 -1
- package/lib/typescript/src/context/index.d.ts.map +1 -1
- package/lib/typescript/src/theme/breakpoints.d.ts +1 -1
- package/lib/typescript/src/theme/define-config.d.ts +23 -0
- package/lib/typescript/src/theme/define-config.d.ts.map +1 -0
- package/lib/typescript/src/theme/diagnostics.d.ts +4 -0
- package/lib/typescript/src/theme/diagnostics.d.ts.map +1 -0
- package/lib/typescript/src/theme/errors.d.ts +10 -0
- package/lib/typescript/src/theme/errors.d.ts.map +1 -0
- package/lib/typescript/src/theme/index.d.ts +10 -2
- package/lib/typescript/src/theme/index.d.ts.map +1 -1
- package/lib/typescript/src/theme/legacy-tokens.d.ts +187 -0
- package/lib/typescript/src/theme/legacy-tokens.d.ts.map +1 -0
- package/lib/typescript/src/theme/registry.d.ts +12 -17
- package/lib/typescript/src/theme/registry.d.ts.map +1 -1
- package/lib/typescript/src/theme/resolve-config.d.ts +99 -0
- package/lib/typescript/src/theme/resolve-config.d.ts.map +1 -0
- package/lib/typescript/src/theme/runtime.d.ts +25 -4
- package/lib/typescript/src/theme/runtime.d.ts.map +1 -1
- package/lib/typescript/src/theme/screen-margin.d.ts +6 -14
- package/lib/typescript/src/theme/screen-margin.d.ts.map +1 -1
- package/lib/typescript/src/theme/screen-padding.d.ts +15 -0
- package/lib/typescript/src/theme/screen-padding.d.ts.map +1 -0
- package/lib/typescript/src/theme/selection-store.d.ts +41 -0
- package/lib/typescript/src/theme/selection-store.d.ts.map +1 -0
- package/lib/typescript/src/theme/theme.d.ts +54 -1
- package/lib/typescript/src/theme/theme.d.ts.map +1 -1
- package/lib/typescript/src/theme/tokens/canonical-color-keys.d.ts +95 -0
- package/lib/typescript/src/theme/tokens/canonical-color-keys.d.ts.map +1 -0
- package/lib/typescript/src/theme/tokens/dark.d.ts +56 -63
- package/lib/typescript/src/theme/tokens/dark.d.ts.map +1 -1
- package/lib/typescript/src/theme/tokens/light.d.ts +56 -71
- package/lib/typescript/src/theme/tokens/light.d.ts.map +1 -1
- package/lib/typescript/src/theme/tokens/primitives.d.ts +11 -10
- package/lib/typescript/src/theme/tokens/primitives.d.ts.map +1 -1
- package/lib/typescript/src/theme/tokens/validate.d.ts +34 -0
- package/lib/typescript/src/theme/tokens/validate.d.ts.map +1 -0
- package/lib/typescript/src/theme/types.d.ts +166 -86
- package/lib/typescript/src/theme/types.d.ts.map +1 -1
- package/lib/typescript/src/theme/unistyles-adapter.d.ts +33 -0
- package/lib/typescript/src/theme/unistyles-adapter.d.ts.map +1 -0
- package/lib/typescript/src/utils/accent-generator.d.ts +103 -0
- package/lib/typescript/src/utils/accent-generator.d.ts.map +1 -0
- package/lib/typescript/src/utils/accent-utils.d.ts +15 -2
- package/lib/typescript/src/utils/accent-utils.d.ts.map +1 -1
- package/lib/typescript/src/utils/color-utils.d.ts +59 -2
- package/lib/typescript/src/utils/color-utils.d.ts.map +1 -1
- package/lib/typescript/src/utils/deep-merge.d.ts +1 -0
- package/lib/typescript/src/utils/deep-merge.d.ts.map +1 -1
- package/lib/typescript/src/utils/resolve-theme-color.d.ts +2 -2
- package/package.json +1 -1
- package/src/components/avatar/Avatar.tsx +20 -20
- package/src/components/button/Button.tsx +11 -11
- package/src/components/chip/Chip.tsx +32 -32
- package/src/components/chip/types.ts +1 -1
- package/src/components/empty-state/EmptyState.tsx +4 -4
- package/src/components/header/variants/LargeTitleHeader/index.tsx +31 -30
- package/src/components/header/variants/TitleHeader/index.tsx +33 -22
- package/src/components/icon/Icon.tsx +4 -4
- package/src/components/page-indicator/hooks/use-page-indicator-colors.ts +2 -2
- package/src/components/screen/Screen.tsx +89 -43
- package/src/components/screen/ScreenContext.tsx +48 -28
- package/src/components/screen/ScreenFlatList.tsx +5 -191
- package/src/components/screen/ScreenList.tsx +197 -175
- package/src/components/screen/ScreenScrollView.tsx +92 -167
- package/src/components/screen/hooks/use-screen-ref.ts +24 -0
- package/src/components/screen/hooks/use-screen-scroll-handler.ts +31 -0
- package/src/components/screen/index.ts +8 -2
- package/src/components/screen/parts/ScreenFrame.tsx +49 -0
- package/src/components/screen/parts/ScreenHeaderAppearance.tsx +52 -0
- package/src/components/screen/parts/ScreenPlaceholder.tsx +16 -16
- package/src/components/screen/parts/ScreenSafeArea.android.tsx +22 -0
- package/src/components/screen/parts/ScreenSafeArea.tsx +20 -0
- package/src/components/screen/types.ts +29 -32
- package/src/components/screen/utils.ts +24 -11
- package/src/components/spinner/Spinner.tsx +2 -2
- package/src/components/text/Text.tsx +2 -2
- package/src/components/toast/Toast.tsx +13 -13
- package/src/components/toolbar/Toolbar.tsx +4 -4
- package/src/context/ThemeProvider.tsx +47 -51
- package/src/context/index.ts +1 -1
- package/src/theme/breakpoints.ts +1 -1
- package/src/theme/define-config.ts +27 -0
- package/src/theme/diagnostics.ts +11 -0
- package/src/theme/errors.ts +14 -0
- package/src/theme/index.ts +40 -1
- package/src/theme/legacy-tokens.ts +227 -0
- package/src/theme/registry.ts +119 -137
- package/src/theme/resolve-config.ts +406 -0
- package/src/theme/runtime.ts +52 -14
- package/src/theme/screen-margin.ts +6 -25
- package/src/theme/screen-padding.ts +26 -0
- package/src/theme/selection-store.ts +76 -0
- package/src/theme/theme.ts +104 -39
- package/src/theme/tokens/canonical-color-keys.ts +107 -0
- package/src/theme/tokens/dark.ts +91 -98
- package/src/theme/tokens/light.ts +88 -93
- package/src/theme/tokens/primitives.ts +14 -14
- package/src/theme/tokens/validate.ts +271 -0
- package/src/theme/types.ts +184 -95
- package/src/theme/unistyles-adapter.ts +75 -0
- package/src/utils/accent-generator.ts +530 -0
- package/src/utils/accent-utils.ts +66 -39
- package/src/utils/color-utils.ts +225 -8
- package/src/utils/deep-merge.ts +1 -1
- package/src/utils/resolve-theme-color.ts +2 -2
- package/lib/module/components/screen/parts/BottomSafeArea.js +0 -62
- package/lib/module/components/screen/parts/BottomSafeArea.js.map +0 -1
- package/lib/typescript/src/components/screen/parts/BottomSafeArea.d.ts +0 -30
- package/lib/typescript/src/components/screen/parts/BottomSafeArea.d.ts.map +0 -1
- package/src/components/screen/parts/BottomSafeArea.tsx +0 -59
|
@@ -9,70 +9,78 @@ import Animated, {
|
|
|
9
9
|
useSharedValue,
|
|
10
10
|
} from "react-native-reanimated";
|
|
11
11
|
|
|
12
|
-
import type {
|
|
12
|
+
import type { ScreenContentPadding, ScreenSafeArea } from "./types";
|
|
13
13
|
|
|
14
|
+
/** Internal animated ref shared by the screen's primary scroll container. */
|
|
14
15
|
export type ScreenScrollRef = AnimatedRef<Animated.ScrollView>;
|
|
15
16
|
|
|
16
|
-
/**
|
|
17
|
+
/** Local portal target for scrollable header content. */
|
|
17
18
|
export const SCREEN_HEADER_PORTAL_HOST = "screen-header";
|
|
18
19
|
|
|
20
|
+
/** Shared configuration and UI-thread scroll values returned by `useScreen`. */
|
|
19
21
|
export interface ScreenContextValue {
|
|
20
22
|
/**
|
|
21
|
-
* Which axes scroll containers pad with `layout.screen.
|
|
22
|
-
*
|
|
23
|
-
* via their own `margins` prop.
|
|
23
|
+
* Which axes scroll containers pad with `layout.screen.padding`.
|
|
24
|
+
* Each scroll container can override this with its own `contentPadding` prop.
|
|
24
25
|
*/
|
|
25
|
-
|
|
26
|
+
contentPadding: ScreenContentPadding;
|
|
27
|
+
/** Safe-area policy applied by the root; descendants must not reapply it. */
|
|
28
|
+
safeArea: ScreenSafeArea;
|
|
29
|
+
/** @deprecated Use contentPadding. */
|
|
30
|
+
margins: ScreenContentPadding;
|
|
26
31
|
/** Whether a `Screen.Header` is present. Used by scroll containers to add top inset. */
|
|
27
32
|
hasHeader: boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Live vertical scroll offset of the screen's scroll container, driven by
|
|
30
|
-
* `Screen.ScrollView` / `Screen.FlatList`. Headers (and consumer UI) read it
|
|
31
|
-
* to animate on scroll.
|
|
32
|
-
*/
|
|
33
|
+
/** Vertical scroll offset, updated on the UI thread for header animations. */
|
|
33
34
|
scrollY: SharedValue<number>;
|
|
34
35
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* disables snap and collapse-range animations (`Header.Title` screens).
|
|
36
|
+
* Optional collapse distance for custom headers. Set via setHeaderCollapseHeight.
|
|
37
|
+
* Built-in headers derive their animation range from the theme.
|
|
38
38
|
*/
|
|
39
39
|
headerCollapseHeight: SharedValue<number>;
|
|
40
40
|
/**
|
|
41
|
-
* Native
|
|
42
|
-
*
|
|
41
|
+
* Native list snap offsets set by setHeaderCollapseHeight. Undefined by default.
|
|
42
|
+
* For Screen.ScrollView, pass these explicitly as snapToOffsets.
|
|
43
43
|
*/
|
|
44
44
|
headerSnapOffsets: number[] | undefined;
|
|
45
|
-
/**
|
|
45
|
+
/** Rounds the height and sets `[0, height]` snap offsets; nonpositive heights clear snapping. */
|
|
46
46
|
setHeaderCollapseHeight: (height: number) => void;
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Ref bound by ScrollView and FlatList containers, including `Screen.List`
|
|
49
|
+
* with FlatList. Custom list implementations do not bind this ref.
|
|
50
|
+
* Its declared ScrollView type does not expose FlatList-specific methods.
|
|
51
|
+
*/
|
|
48
52
|
scrollRef: ScreenScrollRef;
|
|
49
53
|
/** Scroll handler that mirrors offset into `scrollY`. */
|
|
50
54
|
scrollHandler: ScrollHandlerProcessed<Record<string, unknown>>;
|
|
51
55
|
|
|
56
|
+
/** Resolved background color shared with scroll containers. */
|
|
52
57
|
background?: string;
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
export const ScreenContext = createContext<ScreenContextValue | null>(null);
|
|
56
61
|
|
|
62
|
+
/** Internal provider inputs resolved by the Screen root. */
|
|
57
63
|
export interface ScreenScrollProviderProps {
|
|
58
64
|
children: ReactNode;
|
|
59
|
-
/** Which axes scroll containers pad with `layout.screen.
|
|
60
|
-
|
|
65
|
+
/** Which axes scroll containers pad with `layout.screen.padding`. Default `'all'`. */
|
|
66
|
+
contentPadding?: ScreenContentPadding;
|
|
67
|
+
safeArea?: ScreenSafeArea;
|
|
61
68
|
/** Whether a `Screen.Header` child is present. Default false. */
|
|
62
69
|
hasHeader?: boolean;
|
|
63
70
|
|
|
71
|
+
/** Resolved background color shared with scroll containers. */
|
|
64
72
|
background?: string;
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
/**
|
|
68
76
|
* Owns the screen's shared scroll ref, offset, snap offsets, and header collapse
|
|
69
|
-
* metrics.
|
|
70
|
-
* scroll containers bind the ref via {@link useScreen}.
|
|
77
|
+
* metrics. Scroll containers bind the ref via {@link useScreen}.
|
|
71
78
|
*/
|
|
72
79
|
export function ScreenScrollProvider({
|
|
73
80
|
background = "transparent",
|
|
74
81
|
children,
|
|
75
|
-
|
|
82
|
+
contentPadding = "all",
|
|
83
|
+
safeArea = "auto",
|
|
76
84
|
hasHeader = false,
|
|
77
85
|
}: ScreenScrollProviderProps) {
|
|
78
86
|
const scrollY = useSharedValue(0);
|
|
@@ -98,7 +106,9 @@ export function ScreenScrollProvider({
|
|
|
98
106
|
const value = useMemo<ScreenContextValue>(
|
|
99
107
|
() => ({
|
|
100
108
|
background,
|
|
101
|
-
|
|
109
|
+
contentPadding,
|
|
110
|
+
safeArea,
|
|
111
|
+
margins: contentPadding,
|
|
102
112
|
hasHeader,
|
|
103
113
|
scrollY,
|
|
104
114
|
headerCollapseHeight,
|
|
@@ -109,7 +119,8 @@ export function ScreenScrollProvider({
|
|
|
109
119
|
}),
|
|
110
120
|
[
|
|
111
121
|
background,
|
|
112
|
-
|
|
122
|
+
contentPadding,
|
|
123
|
+
safeArea,
|
|
113
124
|
hasHeader,
|
|
114
125
|
scrollY,
|
|
115
126
|
headerCollapseHeight,
|
|
@@ -124,14 +135,23 @@ export function ScreenScrollProvider({
|
|
|
124
135
|
}
|
|
125
136
|
|
|
126
137
|
/**
|
|
127
|
-
*
|
|
138
|
+
* Reads the nearest `Screen`'s configuration, shared scroll state, and ref.
|
|
139
|
+
* Read `scrollY.value` in Reanimated worklets to animate without React renders.
|
|
140
|
+
* The ref belongs to the primary scroll container, not the screen root.
|
|
128
141
|
*
|
|
129
142
|
* @example
|
|
130
143
|
* ```tsx
|
|
131
|
-
*
|
|
144
|
+
* function FadingContent() {
|
|
145
|
+
* const { scrollY } = useScreen();
|
|
146
|
+
* const style = useAnimatedStyle(() => ({
|
|
147
|
+
* opacity: interpolate(scrollY.value, [0, 100], [1, 0], "clamp"),
|
|
148
|
+
* }));
|
|
149
|
+
* return <Animated.View style={style}>{content}</Animated.View>;
|
|
150
|
+
* }
|
|
132
151
|
* ```
|
|
133
152
|
*
|
|
134
|
-
* @
|
|
153
|
+
* @returns The nearest Screen's configuration and scroll state.
|
|
154
|
+
* @throws Error when called outside a Screen provider.
|
|
135
155
|
*/
|
|
136
156
|
export function useScreen(): ScreenContextValue {
|
|
137
157
|
const context = useContext(ScreenContext);
|
|
@@ -1,192 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ScreenList, type ScreenListProps } from "./ScreenList";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "react-native-reanimated";
|
|
8
|
-
import { StyleSheet } from "react-native-unistyles";
|
|
9
|
-
|
|
10
|
-
import { resolveScreenMargin } from "#theme/screen-margin";
|
|
11
|
-
import { PortalHost } from "../portal";
|
|
12
|
-
import { BottomSafeArea } from "./parts/BottomSafeArea";
|
|
13
|
-
import { renderScreenPlaceholder } from "./parts/ScreenPlaceholder";
|
|
14
|
-
import { SCREEN_HEADER_PORTAL_HOST, useScreen } from "./ScreenContext";
|
|
15
|
-
import type { ScreenMargins, ScreenScrollableProps } from "./types";
|
|
16
|
-
import { hasXMargin, hasYMargin, renderListHeader } from "./utils";
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @deprecated Use {@link ScreenListProps} (`Screen.List`) instead —
|
|
20
|
-
* `Screen.List` renders `FlatList` by default and binds the screen's shared
|
|
21
|
-
* scroll ref exactly as `Screen.FlatList` does, but also lets a screen swap in
|
|
22
|
-
* any other FlatList-shaped list (e.g. `FlashList`) via its `as` prop.
|
|
23
|
-
*/
|
|
24
|
-
export interface ScreenFlatListProps<T>
|
|
25
|
-
extends Omit<FlatListProps<T>, "CellRendererComponent" | "horizontal">,
|
|
26
|
-
ScreenScrollableProps {
|
|
27
|
-
/**
|
|
28
|
-
* Extra bottom padding on the list content — clearance for a tab bar or home
|
|
29
|
-
* indicator. Defaults to the `layout.screen.margin.y` token when margins are
|
|
30
|
-
* enabled, otherwise `0`.
|
|
31
|
-
*/
|
|
32
|
-
bottomInset?: number;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* `FlatList` variant of `Screen.ScrollView`: binds the screen's shared scroll
|
|
37
|
-
* ref, mirrors offset into `scrollY`, hosts the portal target above the list,
|
|
38
|
-
* and applies token-driven content padding.
|
|
39
|
-
*
|
|
40
|
-
* Shares `loading` / `LoadingComponent` / `EmptyComponent` / `margins` /
|
|
41
|
-
* `horizontal` with `Screen.ScrollView`, so a screen can swap one container for
|
|
42
|
-
* another without relearning its API.
|
|
43
|
-
*
|
|
44
|
-
* @deprecated Use {@link ScreenList} (`Screen.List`) instead — it renders
|
|
45
|
-
* `FlatList` by default and behaves identically, but also accepts an `as`
|
|
46
|
-
* prop for swapping in another list implementation later without changing
|
|
47
|
-
* the surrounding API.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```tsx
|
|
51
|
-
* <Screen.FlatList data={items} renderItem={({ item }) => <Row item={item} />} />
|
|
52
|
-
* ```
|
|
53
|
-
*
|
|
54
|
-
* @example Loading and empty placeholders
|
|
55
|
-
* ```tsx
|
|
56
|
-
* <Screen.FlatList
|
|
57
|
-
* data={items}
|
|
58
|
-
* loading={isLoading}
|
|
59
|
-
* EmptyComponent={<EmptyState icon="status.info" title="Nothing yet" fill />}
|
|
60
|
-
* renderItem={({ item }) => <Row item={item} />}
|
|
61
|
-
* />
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
export function ScreenFlatList<T>({
|
|
65
|
-
data,
|
|
66
|
-
style,
|
|
67
|
-
contentContainerStyle,
|
|
68
|
-
ListHeaderComponent,
|
|
69
|
-
ListFooterComponent,
|
|
70
|
-
ListEmptyComponent,
|
|
71
|
-
horizontal = false,
|
|
72
|
-
loading = false,
|
|
73
|
-
LoadingComponent,
|
|
74
|
-
EmptyComponent,
|
|
75
|
-
margins,
|
|
76
|
-
bottomInset,
|
|
77
|
-
onScroll,
|
|
78
|
-
...rest
|
|
79
|
-
}: ScreenFlatListProps<T>) {
|
|
80
|
-
const {
|
|
81
|
-
background,
|
|
82
|
-
scrollRef,
|
|
83
|
-
scrollHandler,
|
|
84
|
-
headerSnapOffsets,
|
|
85
|
-
margins: screenMargins,
|
|
86
|
-
hasHeader,
|
|
87
|
-
} = useScreen();
|
|
88
|
-
|
|
89
|
-
const resolvedMargins = margins ?? screenMargins;
|
|
90
|
-
// The placeholder rides in on `ListEmptyComponent` rather than replacing the
|
|
91
|
-
// list, so the header portal, scroll binding and snap offsets all stay put.
|
|
92
|
-
// While loading the list is fed an empty `data` so that slot is the one that
|
|
93
|
-
// renders.
|
|
94
|
-
const placeholder = renderScreenPlaceholder({
|
|
95
|
-
loading,
|
|
96
|
-
LoadingComponent,
|
|
97
|
-
EmptyComponent,
|
|
98
|
-
isEmpty: !data || data.length === 0,
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
const jsScrollHandler = useAnimatedScrollHandler(
|
|
102
|
-
(event) => {
|
|
103
|
-
if (onScroll) onScroll(event as unknown as NativeSyntheticEvent<NativeScrollEvent>);
|
|
104
|
-
},
|
|
105
|
-
[onScroll]
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
const composedHandler = useComposedEventHandler([scrollHandler, jsScrollHandler]);
|
|
109
|
-
|
|
110
|
-
// A caller naming its own `bottomInset` has taken the bottom over entirely,
|
|
111
|
-
// and a horizontal list has no bottom edge to clear.
|
|
112
|
-
const needsBottomSafeArea = bottomInset === undefined && !horizontal;
|
|
113
|
-
|
|
114
|
-
const footerComponent = (
|
|
115
|
-
<>
|
|
116
|
-
{renderListHeader(ListFooterComponent)}
|
|
117
|
-
{needsBottomSafeArea ? <BottomSafeArea /> : null}
|
|
118
|
-
</>
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
const headerComponent = (
|
|
122
|
-
<>
|
|
123
|
-
{/* `headerWrapper`'s negative margin cancels the list's inherited
|
|
124
|
-
content padding for the portaled header (`LargeTitlePortalContent`
|
|
125
|
-
etc. manage their own horizontal padding) — a caller's own
|
|
126
|
-
`ListHeaderComponent` has no such self-padding, so it stays outside
|
|
127
|
-
this wrapper and gets the list's normal item padding instead. */}
|
|
128
|
-
<View style={styles.headerWrapper(resolvedMargins)}>
|
|
129
|
-
<PortalHost name={SCREEN_HEADER_PORTAL_HOST} />
|
|
130
|
-
</View>
|
|
131
|
-
{renderListHeader(ListHeaderComponent)}
|
|
132
|
-
</>
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
return (
|
|
136
|
-
<Animated.FlatList
|
|
137
|
-
ref={scrollRef as unknown as AnimatedRef<Animated.FlatList<T>>}
|
|
138
|
-
data={loading ? [] : data}
|
|
139
|
-
style={[{ backgroundColor: background }, style]}
|
|
140
|
-
horizontal={horizontal}
|
|
141
|
-
contentInsetAdjustmentBehavior={hasHeader ? "never" : undefined}
|
|
142
|
-
contentContainerStyle={[styles.content(resolvedMargins, hasHeader, bottomInset), contentContainerStyle]}
|
|
143
|
-
ListHeaderComponent={headerComponent}
|
|
144
|
-
ListFooterComponent={footerComponent}
|
|
145
|
-
ListEmptyComponent={placeholder ?? ListEmptyComponent}
|
|
146
|
-
showsVerticalScrollIndicator={false}
|
|
147
|
-
scrollEventThrottle={16}
|
|
148
|
-
snapToOffsets={headerSnapOffsets}
|
|
149
|
-
{...rest}
|
|
150
|
-
onScroll={composedHandler}
|
|
151
|
-
/>
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// `resolveScreenMargin` is called *inside* each dynamic function below, not
|
|
156
|
-
// hoisted to the factory's top level — the Babel plugin only attributes a
|
|
157
|
-
// runtime dependency (here, breakpoint) to a style key when the `rt`/
|
|
158
|
-
// `runtime` read it derives from sits inside that key's own value. Hoisting
|
|
159
|
-
// it would silently drop the dependency, so the margin would freeze at
|
|
160
|
-
// whatever breakpoint was active on mount and never update on rotation.
|
|
161
|
-
const styles = StyleSheet.create((theme, runtime) => ({
|
|
162
|
-
scrollContent: {
|
|
163
|
-
flexGrow: 1,
|
|
164
|
-
},
|
|
165
|
-
content: (margins: ScreenMargins, hasHeader: boolean, bottomInset: number | undefined) => {
|
|
166
|
-
const { x: marginX, y: marginY } = resolveScreenMargin(theme, runtime.breakpoint);
|
|
167
|
-
return {
|
|
168
|
-
flexGrow: 1,
|
|
169
|
-
// The header is absolutely positioned, so the list reserves its full
|
|
170
|
-
// height — bar plus top safe area. This assumes the scroll view does not
|
|
171
|
-
// also get UIKit's automatic inset adjustment: on a native tab screen
|
|
172
|
-
// that means `disableAutomaticContentInsets` on the tab, or the two
|
|
173
|
-
// insets are counted twice.
|
|
174
|
-
paddingTop:
|
|
175
|
-
(hasHeader ? theme.layout.header.height + runtime.insets.top : 0) +
|
|
176
|
-
(hasYMargin(margins) ? marginY : 0),
|
|
177
|
-
paddingHorizontal: hasXMargin(margins) ? marginX : 0,
|
|
178
|
-
// The safe area is `BottomSafeArea`'s job; counting it here as well
|
|
179
|
-
// would leave a gap the height of the gesture bar.
|
|
180
|
-
paddingBottom: bottomInset ?? (hasYMargin(margins) ? marginY : 0),
|
|
181
|
-
};
|
|
182
|
-
},
|
|
183
|
-
safeArea: {
|
|
184
|
-
height: runtime.insets.top,
|
|
185
|
-
},
|
|
186
|
-
headerWrapper: (margins: ScreenMargins) => {
|
|
187
|
-
const { x: marginX } = resolveScreenMargin(theme, runtime.breakpoint);
|
|
188
|
-
return {
|
|
189
|
-
marginHorizontal: hasXMargin(margins) ? -marginX : 0,
|
|
190
|
-
};
|
|
191
|
-
},
|
|
192
|
-
}));
|
|
3
|
+
/** @deprecated Use ScreenListProps. */
|
|
4
|
+
export type ScreenFlatListProps<T> = ScreenListProps<T>;
|
|
5
|
+
/** @deprecated Use Screen.List, which exposes the same native FlatList and ref. */
|
|
6
|
+
export const ScreenFlatList: typeof ScreenList = ScreenList;
|