react-native-terra-ui 0.11.10 → 0.11.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/CHANGELOG.md +17 -0
- package/lib/module/components/box/Box.js +35 -10
- package/lib/module/components/box/Box.js.map +1 -1
- package/lib/module/components/header/hooks/use-header-color.js +16 -0
- package/lib/module/components/header/hooks/use-header-color.js.map +1 -0
- package/lib/module/components/header/hooks/use-large-title-header.js +81 -0
- package/lib/module/components/header/hooks/use-large-title-header.js.map +1 -0
- package/lib/module/components/header/parts/HeaderAccessory.js +21 -6
- package/lib/module/components/header/parts/HeaderAccessory.js.map +1 -1
- package/lib/module/components/header/parts/HeaderBar.js +122 -0
- package/lib/module/components/header/parts/HeaderBar.js.map +1 -0
- package/lib/module/components/header/parts/HeaderGradientOverlay.js +20 -76
- package/lib/module/components/header/parts/HeaderGradientOverlay.js.map +1 -1
- package/lib/module/components/header/parts/HeaderSurface.js +16 -37
- package/lib/module/components/header/parts/HeaderSurface.js.map +1 -1
- package/lib/module/components/header/variants/LargeTitleHeader/index.js +51 -388
- package/lib/module/components/header/variants/LargeTitleHeader/index.js.map +1 -1
- package/lib/module/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.js +72 -0
- package/lib/module/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.js.map +1 -0
- package/lib/module/components/header/variants/TitleHeader/index.js +32 -161
- package/lib/module/components/header/variants/TitleHeader/index.js.map +1 -1
- package/lib/module/components/surface/Surface.js +2 -0
- package/lib/module/components/surface/Surface.js.map +1 -1
- package/lib/typescript/src/components/box/Box.d.ts +28 -4
- package/lib/typescript/src/components/box/Box.d.ts.map +1 -1
- package/lib/typescript/src/components/header/hooks/use-header-color.d.ts +4 -0
- package/lib/typescript/src/components/header/hooks/use-header-color.d.ts.map +1 -0
- package/lib/typescript/src/components/header/hooks/use-large-title-header.d.ts +36 -0
- package/lib/typescript/src/components/header/hooks/use-large-title-header.d.ts.map +1 -0
- package/lib/typescript/src/components/header/parts/HeaderAccessory.d.ts +8 -5
- package/lib/typescript/src/components/header/parts/HeaderAccessory.d.ts.map +1 -1
- package/lib/typescript/src/components/header/parts/HeaderBar.d.ts +17 -0
- package/lib/typescript/src/components/header/parts/HeaderBar.d.ts.map +1 -0
- package/lib/typescript/src/components/header/parts/HeaderGradientOverlay.d.ts +12 -15
- package/lib/typescript/src/components/header/parts/HeaderGradientOverlay.d.ts.map +1 -1
- package/lib/typescript/src/components/header/parts/HeaderSurface.d.ts +8 -9
- package/lib/typescript/src/components/header/parts/HeaderSurface.d.ts.map +1 -1
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts +3 -23
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts.map +1 -1
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.d.ts +11 -0
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.d.ts.map +1 -0
- package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts +3 -19
- package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts.map +1 -1
- package/lib/typescript/src/components/surface/Surface.d.ts +1 -1
- package/lib/typescript/src/components/surface/Surface.d.ts.map +1 -1
- package/lib/typescript/src/components/toast/Toast.d.ts +1 -1
- package/lib/typescript/src/components/toast/Toast.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/box/Box.tsx +59 -16
- package/src/components/header/hooks/use-header-color.ts +14 -0
- package/src/components/header/hooks/use-large-title-header.ts +78 -0
- package/src/components/header/parts/HeaderAccessory.tsx +26 -7
- package/src/components/header/parts/HeaderBar.tsx +125 -0
- package/src/components/header/parts/HeaderGradientOverlay.tsx +18 -70
- package/src/components/header/parts/HeaderSurface.tsx +16 -35
- package/src/components/header/variants/LargeTitleHeader/index.tsx +44 -371
- package/src/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.tsx +88 -0
- package/src/components/header/variants/TitleHeader/index.tsx +32 -149
- package/src/components/surface/Surface.tsx +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.11.12](https://github.com/earthlin9/react-native-terra-ui/compare/v0.11.11...v0.11.12) (2026-09-17)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **ui:** [surface] add default content padding ([966c38a](https://github.com/earthlin9/react-native-terra-ui/commit/966c38adb42d3b596e577f6c4116896680d27d6e))
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **ui:** [header] unify layout and preserve accessory gradients and padding ([637e3e1](https://github.com/earthlin9/react-native-terra-ui/commit/637e3e19fab4b4e30b6f80873d72acd7167a3a69))
|
|
12
|
+
|
|
13
|
+
## [0.11.11](https://github.com/earthlin9/react-native-terra-ui/compare/v0.11.10...v0.11.11) (2026-09-17)
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **ui:** [box] cast the rendered element with an `as` prop ([9f294bb](https://github.com/earthlin9/react-native-terra-ui/commit/9f294bbff87e1a49454f0f1defb255f7f7df2cda))
|
|
18
|
+
* **ui:** [header] keep the background fade inside the surface ([85062d0](https://github.com/earthlin9/react-native-terra-ui/commit/85062d08af02920a8fa3671c4339d54e4915caea))
|
|
19
|
+
|
|
3
20
|
## [0.11.10](https://github.com/earthlin9/react-native-terra-ui/compare/v0.11.9...v0.11.10) (2026-09-15)
|
|
4
21
|
|
|
5
22
|
### Bug Fixes
|
|
@@ -5,14 +5,20 @@ import { forwardRef } from "react";
|
|
|
5
5
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
6
6
|
import { Slot } from "../slot/index.js";
|
|
7
7
|
import { BOX_STYLE_PROP_KEYS, resolveBoxStyle } from "./utils.js";
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
|
|
9
|
+
/** Props owned by Box itself — everything else belongs to the rendered element. */
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Props of `Box` when cast as `T`. Token style-props plus everything the
|
|
13
|
+
* rendered component accepts — `<Box as={Pressable} onPress={…} />` type-checks
|
|
14
|
+
* against `Pressable`, not `View`.
|
|
14
15
|
*/
|
|
15
|
-
|
|
16
|
+
|
|
17
|
+
/** Erased prop shape the implementation works with — the generic lives on the exported cast. */
|
|
18
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
19
|
+
const STYLE_KEYS = new Set(BOX_STYLE_PROP_KEYS);
|
|
20
|
+
const BoxWithRef = /*#__PURE__*/forwardRef(function Box({
|
|
21
|
+
as,
|
|
16
22
|
asChild,
|
|
17
23
|
style,
|
|
18
24
|
children,
|
|
@@ -22,31 +28,50 @@ export const Box = /*#__PURE__*/forwardRef(function Box({
|
|
|
22
28
|
theme
|
|
23
29
|
} = useUnistyles();
|
|
24
30
|
const styleProps = {};
|
|
25
|
-
const
|
|
31
|
+
const elementProps = {};
|
|
26
32
|
for (const key of Object.keys(rest)) {
|
|
27
33
|
const value = rest[key];
|
|
28
|
-
if (STYLE_KEYS.has(key)) styleProps[key] = value;else
|
|
34
|
+
if (STYLE_KEYS.has(key)) styleProps[key] = value;else elementProps[key] = value;
|
|
29
35
|
}
|
|
30
36
|
const mergedStyle = [styles.root, resolveBoxStyle(styleProps, theme), style];
|
|
31
37
|
if (asChild) {
|
|
32
38
|
return /*#__PURE__*/_jsx(Slot, {
|
|
33
39
|
ownerName: "Box",
|
|
34
40
|
slotProps: {
|
|
35
|
-
...
|
|
41
|
+
...elementProps,
|
|
36
42
|
style: mergedStyle,
|
|
37
43
|
ref
|
|
38
44
|
},
|
|
39
45
|
children: children
|
|
40
46
|
});
|
|
41
47
|
}
|
|
42
|
-
|
|
48
|
+
const Component = as ?? View;
|
|
49
|
+
return /*#__PURE__*/_jsx(Component, {
|
|
43
50
|
ref: ref,
|
|
44
51
|
style: mergedStyle,
|
|
45
|
-
...
|
|
52
|
+
...elementProps,
|
|
46
53
|
children: children
|
|
47
54
|
});
|
|
48
55
|
});
|
|
49
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Base layout primitive: a `View` styled through theme-token props.
|
|
59
|
+
* The only component family exposing token style-props.
|
|
60
|
+
*
|
|
61
|
+
* Pass `as` to cast it as another component — the token style-props still
|
|
62
|
+
* resolve, and the rest of the props are typed against that component.
|
|
63
|
+
* Note that `as` renders a component Box does not own, so a Unistyles style
|
|
64
|
+
* handed to it only stays theme-reactive if that component's own module runs
|
|
65
|
+
* through the Unistyles Babel plugin (see the stylesheet note below).
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* <Box row gap="2" p="4" />
|
|
70
|
+
* <Box as={Pressable} onPress={onPress} p="3" radius="md" />
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export const Box = BoxWithRef;
|
|
74
|
+
|
|
50
75
|
// ─── Styles ───────────────────────────────────────────────────────────────────
|
|
51
76
|
//
|
|
52
77
|
// Box has no static style of its own — this stylesheet exists so the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["forwardRef","StyleSheet","useUnistyles","Slot","BOX_STYLE_PROP_KEYS","resolveBoxStyle","jsx","_jsx","STYLE_KEYS","Set","Box","asChild","style","children","rest","ref","theme","styleProps","
|
|
1
|
+
{"version":3,"names":["forwardRef","StyleSheet","useUnistyles","Slot","BOX_STYLE_PROP_KEYS","resolveBoxStyle","jsx","_jsx","STYLE_KEYS","Set","BoxWithRef","Box","as","asChild","style","children","rest","ref","theme","styleProps","elementProps","key","Object","keys","value","has","mergedStyle","styles","root","ownerName","slotProps","Component","View","create"],"sourceRoot":"../../../../src","sources":["components/box/Box.tsx"],"mappings":";;;AAAA,SAGEA,UAAU,QAGL,OAAO;AAGd,SAASC,UAAU,EAAEC,YAAY,QAAQ,wBAAwB;AAEjE,SAASC,IAAI;AACb,SAASC,mBAAmB,EAAsBC,eAAe;;AAEjE;;AAMA;AACA;AACA;AACA;AACA;;AAMA;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAQA,MAAMC,UAAU,GAAG,IAAIC,GAAG,CAASL,mBAAwC,CAAC;AAE5E,MAAMM,UAAU,gBAAGV,UAAU,CAA0B,SAASW,GAAGA,CACjE;EAAEC,EAAE;EAAEC,OAAO;EAAEC,KAAK;EAAEC,QAAQ;EAAE,GAAGC;AAAqB,CAAC,EACzDC,GAAG,EACH;EACA,MAAM;IAAEC;EAAM,CAAC,GAAGhB,YAAY,CAAC,CAAC;EAEhC,MAAMiB,UAAmC,GAAG,CAAC,CAAC;EAC9C,MAAMC,YAAqC,GAAG,CAAC,CAAC;EAChD,KAAK,MAAMC,GAAG,IAAIC,MAAM,CAACC,IAAI,CAACP,IAAI,CAAC,EAAE;IACnC,MAAMQ,KAAK,GAAGR,IAAI,CAACK,GAAG,CAAC;IACvB,IAAIb,UAAU,CAACiB,GAAG,CAACJ,GAAG,CAAC,EAAEF,UAAU,CAACE,GAAG,CAAC,GAAGG,KAAK,CAAC,KAC5CJ,YAAY,CAACC,GAAG,CAAC,GAAGG,KAAK;EAChC;EAEA,MAAME,WAAW,GAAG,CAACC,MAAM,CAACC,IAAI,EAAEvB,eAAe,CAACc,UAAU,EAAmBD,KAAK,CAAC,EAAEJ,KAAK,CAAC;EAE7F,IAAID,OAAO,EAAE;IACX,oBACEN,IAAA,CAACJ,IAAI;MAAC0B,SAAS,EAAC,KAAK;MAACC,SAAS,EAAE;QAAE,GAAGV,YAAY;QAAEN,KAAK,EAAEY,WAAW;QAAET;MAAI,CAAE;MAAAF,QAAA,EAC3EA;IAAQ,CACL,CAAC;EAEX;EAEA,MAAMgB,SAAS,GAAInB,EAAE,IAAIoB,IAAoB;EAE7C,oBACEzB,IAAA,CAACwB,SAAS;IAACd,GAAG,EAAEA,GAAI;IAACH,KAAK,EAAEY,WAAY;IAAA,GAAKN,YAAY;IAAAL,QAAA,EACtDA;EAAQ,CACA,CAAC;AAEhB,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMJ,GAAG,GAAGD,UAEK;;AAExB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMiB,MAAM,GAAG1B,UAAU,CAACgC,MAAM,CAAC,OAAO;EAAEL,IAAI,EAAE,CAAC;AAAE,CAAC,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useContext } from "react";
|
|
4
|
+
import { useUnistyles } from "react-native-unistyles";
|
|
5
|
+
import { resolveThemeColor } from "../../../utils/resolve-theme-color.js";
|
|
6
|
+
import { ScreenContext } from "../../screen/ScreenContext.js";
|
|
7
|
+
|
|
8
|
+
/** Explicit header color wins, then Screen, then the theme canvas. */
|
|
9
|
+
export function useHeaderColor(token) {
|
|
10
|
+
const {
|
|
11
|
+
theme
|
|
12
|
+
} = useUnistyles();
|
|
13
|
+
const screen = useContext(ScreenContext);
|
|
14
|
+
return (token ? resolveThemeColor(token, theme) : screen?.background) ?? theme.color["surface.canvas"];
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=use-header-color.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useContext","useUnistyles","resolveThemeColor","ScreenContext","useHeaderColor","token","theme","screen","background","color"],"sourceRoot":"../../../../../src","sources":["components/header/hooks/use-header-color.ts"],"mappings":";;AAAA,SAASA,UAAU,QAAQ,OAAO;AAElC,SAASC,YAAY,QAAQ,wBAAwB;AAGrD,SAASC,iBAAiB;AAC1B,SAASC,aAAa;;AAEtB;AACA,OAAO,SAASC,cAAcA,CAACC,KAAkB,EAAE;EACjD,MAAM;IAAEC;EAAM,CAAC,GAAGL,YAAY,CAAC,CAAC;EAChC,MAAMM,MAAM,GAAGP,UAAU,CAACG,aAAa,CAAC;EACxC,OAAO,CAACE,KAAK,GAAGH,iBAAiB,CAACG,KAAK,EAAEC,KAAK,CAAC,GAAGC,MAAM,EAAEC,UAAU,KAAKF,KAAK,CAACG,KAAK,CAAC,gBAAgB,CAAC;AACxG","ignoreList":[]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useLayoutEffect, useState } from "react";
|
|
4
|
+
import { interpolate, useAnimatedStyle, useSharedValue } from "react-native-reanimated";
|
|
5
|
+
import { useUnistyles } from "react-native-unistyles";
|
|
6
|
+
import { useScreen } from "../../screen/ScreenContext.js";
|
|
7
|
+
/** Coordinates measured layout and UI-thread animation without animating accessory padding. */
|
|
8
|
+
export function useLargeTitleHeader({
|
|
9
|
+
hasAccessory,
|
|
10
|
+
accessoryBehavior,
|
|
11
|
+
isLargeTitleHidden
|
|
12
|
+
}) {
|
|
13
|
+
const {
|
|
14
|
+
theme
|
|
15
|
+
} = useUnistyles();
|
|
16
|
+
const {
|
|
17
|
+
scrollY,
|
|
18
|
+
contentTopPadding,
|
|
19
|
+
setHeaderAccessoryHeight
|
|
20
|
+
} = useScreen();
|
|
21
|
+
const [accessoryHeight, setAccessoryHeight] = useState(0);
|
|
22
|
+
const [largeTitleHeight, setLargeTitleHeight] = useState(0);
|
|
23
|
+
const hidden = useSharedValue(isLargeTitleHidden);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
hidden.value = isLargeTitleHidden;
|
|
26
|
+
}, [hidden, isLargeTitleHidden]);
|
|
27
|
+
const barHeight = theme.layout.header.height;
|
|
28
|
+
const isSticky = hasAccessory && accessoryBehavior === "sticky" && !isLargeTitleHidden;
|
|
29
|
+
// The measured overlay always includes bottom padding. Expanded scroll content
|
|
30
|
+
// excludes it; compact-only screens reserve the entire accessory.
|
|
31
|
+
const reservedAccessoryHeight = hasAccessory ? Math.max(0, Math.round(accessoryHeight - (isLargeTitleHidden ? 0 : theme.spacing["2"]))) : 0;
|
|
32
|
+
const accessoryOffset = isSticky ? Math.max(0, contentTopPadding + largeTitleHeight - barHeight) : 0;
|
|
33
|
+
useLayoutEffect(() => {
|
|
34
|
+
setHeaderAccessoryHeight(isSticky ? 0 : reservedAccessoryHeight);
|
|
35
|
+
return () => setHeaderAccessoryHeight(0);
|
|
36
|
+
}, [isSticky, reservedAccessoryHeight, setHeaderAccessoryHeight]);
|
|
37
|
+
const accessoryStyle = useAnimatedStyle(() => ({
|
|
38
|
+
transform: [{
|
|
39
|
+
translateY: isSticky && !hidden.value ? Math.max(0, accessoryOffset - scrollY.value) : 0
|
|
40
|
+
}]
|
|
41
|
+
}));
|
|
42
|
+
const surfaceStyle = useAnimatedStyle(() => {
|
|
43
|
+
if (hidden.value) return {
|
|
44
|
+
opacity: 1
|
|
45
|
+
};
|
|
46
|
+
const distance = isSticky ? accessoryOffset : barHeight;
|
|
47
|
+
return {
|
|
48
|
+
opacity: distance > 0 ? interpolate(scrollY.value, [0, distance], [0, 1], "clamp") : isSticky ? 1 : 0
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
const compactTitleStyle = useAnimatedStyle(() => {
|
|
52
|
+
const progress = hidden.value ? 1 : barHeight > 0 ? interpolate(scrollY.value, [0, barHeight], [0, 1], "clamp") : 0;
|
|
53
|
+
return {
|
|
54
|
+
opacity: progress,
|
|
55
|
+
transform: [{
|
|
56
|
+
translateY: (1 - progress) * 8
|
|
57
|
+
}]
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
const largeTitleStyle = useAnimatedStyle(() => {
|
|
61
|
+
const progress = barHeight > 0 ? interpolate(scrollY.value, [0, barHeight], [0, 1], "clamp") : 0;
|
|
62
|
+
return {
|
|
63
|
+
opacity: 1 - progress,
|
|
64
|
+
transform: [{
|
|
65
|
+
translateY: -progress * 6
|
|
66
|
+
}]
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
isSticky,
|
|
71
|
+
accessoryOffset,
|
|
72
|
+
reservedAccessoryHeight,
|
|
73
|
+
setAccessoryHeight,
|
|
74
|
+
setLargeTitleHeight,
|
|
75
|
+
accessoryStyle,
|
|
76
|
+
surfaceStyle,
|
|
77
|
+
compactTitleStyle,
|
|
78
|
+
largeTitleStyle
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=use-large-title-header.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useEffect","useLayoutEffect","useState","interpolate","useAnimatedStyle","useSharedValue","useUnistyles","useScreen","useLargeTitleHeader","hasAccessory","accessoryBehavior","isLargeTitleHidden","theme","scrollY","contentTopPadding","setHeaderAccessoryHeight","accessoryHeight","setAccessoryHeight","largeTitleHeight","setLargeTitleHeight","hidden","value","barHeight","layout","header","height","isSticky","reservedAccessoryHeight","Math","max","round","spacing","accessoryOffset","accessoryStyle","transform","translateY","surfaceStyle","opacity","distance","compactTitleStyle","progress","largeTitleStyle"],"sourceRoot":"../../../../../src","sources":["components/header/hooks/use-large-title-header.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { View } from "react-native-unistyles/components/native/View";
|
|
4
|
-
import { useCallback,
|
|
4
|
+
import { useCallback, useLayoutEffect, useRef } from "react";
|
|
5
5
|
import Animated from "react-native-reanimated";
|
|
6
6
|
import { StyleSheet } from "react-native-unistyles";
|
|
7
|
-
import {
|
|
7
|
+
import { HeaderSurface } from "./HeaderSurface.js";
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
9
|
/** Measures accessory content so the header can reserve space in the scroll container. */
|
|
9
10
|
export function HeaderAccessory({
|
|
10
11
|
children,
|
|
11
12
|
padding,
|
|
13
|
+
color,
|
|
14
|
+
surfaceStyle,
|
|
12
15
|
onHeightChange,
|
|
13
16
|
style
|
|
14
17
|
}) {
|
|
18
|
+
const measuredHeight = useRef(0);
|
|
15
19
|
const handleLayout = useCallback(event => {
|
|
16
|
-
|
|
20
|
+
measuredHeight.current = event.nativeEvent.layout.height;
|
|
21
|
+
onHeightChange?.(measuredHeight.current);
|
|
17
22
|
}, [onHeightChange]);
|
|
18
23
|
|
|
19
24
|
// Release the previous owner’s space when the callback changes or the accessory unmounts.
|
|
20
|
-
|
|
25
|
+
useLayoutEffect(() => {
|
|
26
|
+
onHeightChange?.(measuredHeight.current);
|
|
27
|
+
return () => onHeightChange?.(0);
|
|
28
|
+
}, [onHeightChange]);
|
|
21
29
|
const _styles = styles;
|
|
22
30
|
{
|
|
23
31
|
const styles = _styles.useVariants({
|
|
24
32
|
padding
|
|
25
33
|
});
|
|
26
|
-
return /*#__PURE__*/
|
|
34
|
+
return /*#__PURE__*/_jsxs(Animated.View, {
|
|
27
35
|
style: [styles.accessory, style],
|
|
28
36
|
onLayout: handleLayout,
|
|
29
|
-
children:
|
|
37
|
+
children: [/*#__PURE__*/_jsx(HeaderSurface, {
|
|
38
|
+
color: color,
|
|
39
|
+
animatedStyle: surfaceStyle,
|
|
40
|
+
accessory: true
|
|
41
|
+
}), children]
|
|
30
42
|
});
|
|
31
43
|
}
|
|
32
44
|
}
|
|
@@ -41,6 +53,9 @@ export function HeaderAccessorySpacer({
|
|
|
41
53
|
}
|
|
42
54
|
const styles = StyleSheet.create(theme => ({
|
|
43
55
|
accessory: {
|
|
56
|
+
// Static layout padding is intentional: the background must measure the full
|
|
57
|
+
// padded height even when a horizontal ScrollView is the accessory content.
|
|
58
|
+
paddingBottom: theme.spacing["2"],
|
|
44
59
|
variants: {
|
|
45
60
|
padding: {
|
|
46
61
|
x: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","
|
|
1
|
+
{"version":3,"names":["useCallback","useLayoutEffect","useRef","Animated","StyleSheet","HeaderSurface","jsx","_jsx","jsxs","_jsxs","HeaderAccessory","children","padding","color","surfaceStyle","onHeightChange","style","measuredHeight","handleLayout","event","current","nativeEvent","layout","height","_styles","styles","useVariants","View","accessory","onLayout","animatedStyle","HeaderAccessorySpacer","spacer","create","theme","paddingBottom","spacing","variants","x","paddingHorizontal","screen","none","uni__dependencies"],"sourceRoot":"../../../../../src","sources":["components/header/parts/HeaderAccessory.tsx"],"mappings":";;;AAAA,SAA8CA,WAAW,EAAEC,eAAe,EAAEC,MAAM,QAAQ,OAAO;AAGjG,OAAOC,QAAQ,MAAM,yBAAyB;AAC9C,SAASC,UAAU,QAAQ,wBAAwB;AAGnD,SAASC,aAAa;AAAmD,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAczE;AACA,OAAO,SAASC,eAAeA,CAAC;EAC9BC,QAAQ;EACRC,OAAO;EACPC,KAAK;EACLC,YAAY;EACZC,cAAc;EACdC;AACoB,CAAC,EAAE;EACvB,MAAMC,cAAc,GAAGf,MAAM,CAAC,CAAC,CAAC;EAChC,MAAMgB,YAAY,GAAGlB,WAAW,CAC7BmB,KAAwB,IAAK;IAC5BF,cAAc,CAACG,OAAO,GAAGD,KAAK,CAACE,WAAW,CAACC,MAAM,CAACC,MAAM;IACxDR,cAAc,GAAGE,cAAc,CAACG,OAAO,CAAC;EAC1C,CAAC,EACD,CAACL,cAAc,CACjB,CAAC;;EAED;EACAd,eAAe,CAAC,MAAM;IACpBc,cAAc,GAAGE,cAAc,CAACG,OAAO,CAAC;IACxC,OAAO,MAAML,cAAc,GAAG,CAAC,CAAC;EAClC,CAAC,EAAE,CAACA,cAAc,CAAC,CAAC;EAAC,MAAAS,OAAA,GAAAC,MAAA;EAAA;IAAA,MAAAA,MAAA,GAAAD,OAAA,CAAAE,WAAA,CAEF;MAAEd;IAAQ,CAAC;IAE9B,oBACEH,KAAA,CAACN,QAAQ,CAACwB,IAAI;MAACX,KAAK,EAAE,CAACS,MAAM,CAACG,SAAS,EAAEZ,KAAK,CAAE;MAACa,QAAQ,EAAEX,YAAa;MAAAP,QAAA,gBACtEJ,IAAA,CAACF,aAAa;QAACQ,KAAK,EAAEA,KAAM;QAACiB,aAAa,EAAEhB,YAAa;QAACc,SAAS;MAAA,CAAE,CAAC,EACrEjB,QAAQ;IAAA,CACI,CAAC;EAChB;AACJ;;AAEA;AACA,OAAO,SAASoB,qBAAqBA,CAAC;EAAER;AAA2B,CAAC,EAAE;EACpE,oBAAOhB,IAAA,CAACoB,IAAI;IAACX,KAAK,EAAES,MAAM,CAACO,MAAM,CAACT,MAAM;EAAE,CAAE,CAAC;AAC/C;AAEA,MAAME,MAAM,GAAGrB,UAAU,CAAC6B,MAAM,CAAEC,KAAK,KAAM;EAC3CN,SAAS,EAAE;IACT;IACA;IACAO,aAAa,EAAED,KAAK,CAACE,OAAO,CAAC,GAAG,CAAC;IACjCC,QAAQ,EAAE;MACRzB,OAAO,EAAE;QACP0B,CAAC,EAAE;UAAEC,iBAAiB,EAAEL,KAAK,CAACZ,MAAM,CAACkB,MAAM,CAAC5B,OAAO,CAAC0B;QAAE,CAAC;QACvDG,IAAI,EAAE,CAAC;MACT;IACF,CAAC;IAAAC,iBAAA;EACH,CAAC;EACDV,MAAM,EAAGT,MAAc,KAAM;IAAEA;EAAO,CAAC;AACzC,CAAC,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { View } from "react-native-unistyles/components/native/View";
|
|
4
|
+
import { Text } from "react-native-unistyles/components/native/Text";
|
|
5
|
+
import Animated from "react-native-reanimated";
|
|
6
|
+
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
7
|
+
import { FONT_WEIGHT_VALUE } from "../../../utils/typography.js";
|
|
8
|
+
import { Toolbar } from "../../toolbar/index.js";
|
|
9
|
+
import { HeaderDismissButton } from "../header-buttons.js";
|
|
10
|
+
import { isCustomTitle, isTextTitle } from "../utils.js";
|
|
11
|
+
import { HeaderSurface } from "./HeaderSurface.js";
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
/** Shared compact bar. Only the title and background animate; actions stay interactive. */
|
|
14
|
+
export function HeaderBar({
|
|
15
|
+
title,
|
|
16
|
+
leading,
|
|
17
|
+
trailing,
|
|
18
|
+
titleAlignment,
|
|
19
|
+
color,
|
|
20
|
+
surfaceStyle,
|
|
21
|
+
titleStyle,
|
|
22
|
+
dismissAction = "none",
|
|
23
|
+
navigation,
|
|
24
|
+
onDismiss
|
|
25
|
+
}) {
|
|
26
|
+
const {
|
|
27
|
+
theme
|
|
28
|
+
} = useUnistyles();
|
|
29
|
+
const _styles = styles;
|
|
30
|
+
{
|
|
31
|
+
const styles = _styles.useVariants({
|
|
32
|
+
titleAlignment
|
|
33
|
+
});
|
|
34
|
+
const dismiss = /*#__PURE__*/_jsx(HeaderDismissButton, {
|
|
35
|
+
dismissAction: dismissAction,
|
|
36
|
+
navigation: navigation,
|
|
37
|
+
onDismiss: onDismiss
|
|
38
|
+
});
|
|
39
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
40
|
+
style: styles.bar,
|
|
41
|
+
children: [/*#__PURE__*/_jsx(HeaderSurface, {
|
|
42
|
+
color: color,
|
|
43
|
+
animatedStyle: surfaceStyle
|
|
44
|
+
}), (leading != null || dismissAction === "back") && /*#__PURE__*/_jsxs(Toolbar, {
|
|
45
|
+
children: [dismissAction === "back" && dismiss, leading]
|
|
46
|
+
}), /*#__PURE__*/_jsx(Animated.View, {
|
|
47
|
+
style: [styles.titleContainer, titleStyle],
|
|
48
|
+
pointerEvents: isCustomTitle(title) ? "box-none" : "none",
|
|
49
|
+
children: isTextTitle(title) ? String(title).trim().length > 0 && /*#__PURE__*/_jsx(Text, {
|
|
50
|
+
style: styles.title,
|
|
51
|
+
maxFontSizeMultiplier: theme.typography.variants["title-md"].maxFontSizeMultiplier,
|
|
52
|
+
children: title
|
|
53
|
+
}) : title
|
|
54
|
+
}), (trailing != null || dismissAction === "close") && /*#__PURE__*/_jsxs(Toolbar, {
|
|
55
|
+
style: styles.trailing,
|
|
56
|
+
children: [dismissAction === "close" && dismiss, trailing]
|
|
57
|
+
})]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const styles = StyleSheet.create(theme => ({
|
|
62
|
+
bar: {
|
|
63
|
+
height: theme.layout.header.height,
|
|
64
|
+
flexDirection: "row",
|
|
65
|
+
alignItems: "center",
|
|
66
|
+
paddingHorizontal: theme.layout.screen.padding.x,
|
|
67
|
+
gap: theme.spacing["3"],
|
|
68
|
+
justifyContent: "space-between",
|
|
69
|
+
uni__dependencies: [0]
|
|
70
|
+
},
|
|
71
|
+
// A centered title is absolutely positioned, so it leaves the flex row. With
|
|
72
|
+
// no leading slot the trailing toolbar would be the only in-flow child and
|
|
73
|
+
// `space-between` would park it on the left — the auto margin pins it right.
|
|
74
|
+
trailing: {
|
|
75
|
+
justifyContent: "flex-end",
|
|
76
|
+
variants: {
|
|
77
|
+
titleAlignment: {
|
|
78
|
+
center: {
|
|
79
|
+
marginLeft: "auto"
|
|
80
|
+
},
|
|
81
|
+
left: {}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
uni__dependencies: [4]
|
|
85
|
+
},
|
|
86
|
+
titleContainer: {
|
|
87
|
+
variants: {
|
|
88
|
+
titleAlignment: {
|
|
89
|
+
center: {
|
|
90
|
+
position: "absolute",
|
|
91
|
+
left: 0,
|
|
92
|
+
right: 0,
|
|
93
|
+
alignItems: "center"
|
|
94
|
+
},
|
|
95
|
+
left: {
|
|
96
|
+
flex: 1,
|
|
97
|
+
alignItems: "flex-start"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
uni__dependencies: [4]
|
|
102
|
+
},
|
|
103
|
+
title: {
|
|
104
|
+
fontSize: theme.typography.variants["title-md"].fontSize,
|
|
105
|
+
lineHeight: theme.typography.variants["title-md"].lineHeight,
|
|
106
|
+
letterSpacing: theme.typography.variants["title-md"].letterSpacing,
|
|
107
|
+
fontWeight: FONT_WEIGHT_VALUE[theme.typography.variants["title-md"].fontWeight],
|
|
108
|
+
color: theme.color["text.primary"] ?? "",
|
|
109
|
+
variants: {
|
|
110
|
+
titleAlignment: {
|
|
111
|
+
center: {
|
|
112
|
+
textAlign: "center"
|
|
113
|
+
},
|
|
114
|
+
left: {
|
|
115
|
+
textAlign: "left"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
uni__dependencies: [0, 4]
|
|
120
|
+
}
|
|
121
|
+
}));
|
|
122
|
+
//# sourceMappingURL=HeaderBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Animated","StyleSheet","useUnistyles","FONT_WEIGHT_VALUE","Toolbar","HeaderDismissButton","isCustomTitle","isTextTitle","HeaderSurface","jsx","_jsx","jsxs","_jsxs","HeaderBar","title","leading","trailing","titleAlignment","color","surfaceStyle","titleStyle","dismissAction","navigation","onDismiss","theme","_styles","styles","useVariants","dismiss","View","style","bar","children","animatedStyle","titleContainer","pointerEvents","String","trim","length","Text","maxFontSizeMultiplier","typography","variants","create","height","layout","header","flexDirection","alignItems","paddingHorizontal","screen","padding","x","gap","spacing","justifyContent","uni__dependencies","center","marginLeft","left","position","right","flex","fontSize","lineHeight","letterSpacing","fontWeight","textAlign"],"sourceRoot":"../../../../../src","sources":["components/header/parts/HeaderBar.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -4,100 +4,44 @@ import { useId } from "react";
|
|
|
4
4
|
import Svg, { Defs, Rect, Stop, LinearGradient as SvgLinearGradient } from "react-native-svg";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* the curve has to be steep enough to read as a band. Overhanging lets the tail
|
|
11
|
-
* finish in open space, so the header releases content instead of cutting it.
|
|
7
|
+
* Opacity at the overlay's bottom edge. The top is fully opaque, so the header
|
|
8
|
+
* thins slightly toward the boundary rather than cutting content off square —
|
|
9
|
+
* but never far enough to read as see-through.
|
|
12
10
|
*/
|
|
13
11
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
export const
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Where the fade begins, as a fraction of the overlay's height — the bar plus
|
|
18
|
-
* {@link HEADER_FADE_EXTENT}.
|
|
19
|
-
*
|
|
20
|
-
* Sits inside the bar rather than at its bottom edge, so the tint has already
|
|
21
|
-
* begun thinning before content reaches the boundary. That is the trade this
|
|
22
|
-
* value makes: a longer, gentler ramp, paid for with content being faintly
|
|
23
|
-
* visible through the lower part of the bar.
|
|
24
|
-
*/
|
|
25
|
-
const FADE_START = 0.5;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Stops used to approximate the fade curve. Below ~10 the ramp shows as a series
|
|
29
|
-
* of bands on an 8-bit display; above ~14 the extra stops cost SVG parse time
|
|
30
|
-
* with nothing visible in return.
|
|
31
|
-
*/
|
|
32
|
-
const FADE_STOPS = 4;
|
|
33
|
-
|
|
34
|
-
/** Ceiling on the fade's opacity — see {@link alphaAt}. */
|
|
35
|
-
const MAX_FADE_ALPHA = 0.65;
|
|
36
|
-
|
|
12
|
+
export const HEADER_FADE_END_OPACITY = 0.85;
|
|
37
13
|
/**
|
|
38
|
-
*
|
|
39
|
-
* bottom.
|
|
14
|
+
* Vertical fade behind header content, shared by header variants.
|
|
40
15
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* drawn across the content rather than the header letting go of it.
|
|
45
|
-
*
|
|
46
|
-
* The cap holds the ramp just short of solid, so the whole overlay reads as one
|
|
47
|
-
* continuous gradient rather than an opaque plateau with a curve bolted on.
|
|
48
|
-
*/
|
|
49
|
-
const alphaAt = t => (1 + Math.cos(Math.PI * t) * MAX_FADE_ALPHA) / 2;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Every input is a module constant, so the ramp is built once at load rather
|
|
53
|
-
* than rebuilt per render.
|
|
54
|
-
*
|
|
55
|
-
* The leading stop belongs to this list rather than being a sibling element:
|
|
56
|
-
* `LinearGradient` types its children as a flat `ReactElement[]`, so an element
|
|
57
|
-
* beside a mapped array would nest and fail to type-check.
|
|
58
|
-
*/
|
|
59
|
-
const STOPS = [{
|
|
60
|
-
offset: 0,
|
|
61
|
-
opacity: 1
|
|
62
|
-
}, ...Array.from({
|
|
63
|
-
length: FADE_STOPS
|
|
64
|
-
}, (_, index) => {
|
|
65
|
-
const t = index / (FADE_STOPS - 1);
|
|
66
|
-
const offset = FADE_START + t * (1 - FADE_START);
|
|
67
|
-
return {
|
|
68
|
-
offset,
|
|
69
|
-
opacity: offset === 1 ? 0 : alphaAt(t)
|
|
70
|
-
};
|
|
71
|
-
})];
|
|
72
|
-
/**
|
|
73
|
-
* Vertical fade-out overlay behind header content, shared by header variants.
|
|
74
|
-
*
|
|
75
|
-
* Reaches zero rather than stopping short. An overlay ending at partial opacity
|
|
76
|
-
* leaves a hard step wherever it is clipped, and that step is far more visible
|
|
77
|
-
* than the fade it was meant to hide — it is what cuts content off square as it
|
|
78
|
-
* scrolls under the header.
|
|
79
|
-
*
|
|
80
|
-
* Callers size it to overhang the bar by {@link HEADER_FADE_EXTENT}.
|
|
16
|
+
* A two-stop linear ramp spanning the overlay's own box: it neither overhangs
|
|
17
|
+
* the surface nor reserves a band inside it, so callers size the surface and
|
|
18
|
+
* the ramp simply spans whatever they gave it.
|
|
81
19
|
*/
|
|
82
20
|
export function HeaderGradientOverlay({
|
|
83
|
-
color
|
|
21
|
+
color,
|
|
22
|
+
startOpacity = 1,
|
|
23
|
+
endOpacity = HEADER_FADE_END_OPACITY
|
|
84
24
|
}) {
|
|
85
25
|
const gradientId = useId();
|
|
86
26
|
return /*#__PURE__*/_jsxs(Svg, {
|
|
87
27
|
height: "100%",
|
|
88
28
|
width: "100%",
|
|
89
29
|
children: [/*#__PURE__*/_jsx(Defs, {
|
|
90
|
-
children: /*#__PURE__*/
|
|
30
|
+
children: /*#__PURE__*/_jsxs(SvgLinearGradient, {
|
|
91
31
|
id: gradientId,
|
|
92
32
|
x1: "0",
|
|
93
33
|
y1: "0",
|
|
94
34
|
x2: "0",
|
|
95
35
|
y2: "1",
|
|
96
|
-
children:
|
|
97
|
-
offset:
|
|
36
|
+
children: [/*#__PURE__*/_jsx(Stop, {
|
|
37
|
+
offset: 0,
|
|
38
|
+
stopColor: color,
|
|
39
|
+
stopOpacity: startOpacity
|
|
40
|
+
}), /*#__PURE__*/_jsx(Stop, {
|
|
41
|
+
offset: 1,
|
|
98
42
|
stopColor: color,
|
|
99
|
-
stopOpacity:
|
|
100
|
-
}
|
|
43
|
+
stopOpacity: endOpacity
|
|
44
|
+
})]
|
|
101
45
|
})
|
|
102
46
|
}), /*#__PURE__*/_jsx(Rect, {
|
|
103
47
|
width: "100%",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useId","Svg","Defs","Rect","Stop","LinearGradient","SvgLinearGradient","jsx","_jsx","jsxs","_jsxs","
|
|
1
|
+
{"version":3,"names":["useId","Svg","Defs","Rect","Stop","LinearGradient","SvgLinearGradient","jsx","_jsx","jsxs","_jsxs","HEADER_FADE_END_OPACITY","HeaderGradientOverlay","color","startOpacity","endOpacity","gradientId","height","width","children","id","x1","y1","x2","y2","offset","stopColor","stopOpacity","fill"],"sourceRoot":"../../../../../src","sources":["components/header/parts/HeaderGradientOverlay.tsx"],"mappings":";;AAAA,SAASA,KAAK,QAAQ,OAAO;AAE7B,OAAOC,GAAG,IAAIC,IAAI,EAAEC,IAAI,EAAEC,IAAI,EAAEC,cAAc,IAAIC,iBAAiB,QAAQ,kBAAkB;;AAE7F;AACA;AACA;AACA;AACA;AAJA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAKA,OAAO,MAAMC,uBAAuB,GAAG,IAAI;AAS3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,qBAAqBA,CAAC;EACpCC,KAAK;EACLC,YAAY,GAAG,CAAC;EAChBC,UAAU,GAAGJ;AACa,CAAC,EAAE;EAC7B,MAAMK,UAAU,GAAGhB,KAAK,CAAC,CAAC;EAE1B,oBACEU,KAAA,CAACT,GAAG;IAACgB,MAAM,EAAC,MAAM;IAACC,KAAK,EAAC,MAAM;IAAAC,QAAA,gBAC7BX,IAAA,CAACN,IAAI;MAAAiB,QAAA,eACHT,KAAA,CAACJ,iBAAiB;QAACc,EAAE,EAAEJ,UAAW;QAACK,EAAE,EAAC,GAAG;QAACC,EAAE,EAAC,GAAG;QAACC,EAAE,EAAC,GAAG;QAACC,EAAE,EAAC,GAAG;QAAAL,QAAA,gBAC5DX,IAAA,CAACJ,IAAI;UAACqB,MAAM,EAAE,CAAE;UAACC,SAAS,EAAEb,KAAM;UAACc,WAAW,EAAEb;QAAa,CAAE,CAAC,eAChEN,IAAA,CAACJ,IAAI;UAACqB,MAAM,EAAE,CAAE;UAACC,SAAS,EAAEb,KAAM;UAACc,WAAW,EAAEZ;QAAW,CAAE,CAAC;MAAA,CAC7C;IAAC,CAChB,CAAC,eACPP,IAAA,CAACL,IAAI;MAACe,KAAK,EAAC,MAAM;MAACD,MAAM,EAAC,MAAM;MAACW,IAAI,EAAE,QAAQZ,UAAU;IAAI,CAAE,CAAC;EAAA,CAC7D,CAAC;AAEV","ignoreList":[]}
|