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.
Files changed (59) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/lib/module/components/box/Box.js +35 -10
  3. package/lib/module/components/box/Box.js.map +1 -1
  4. package/lib/module/components/header/hooks/use-header-color.js +16 -0
  5. package/lib/module/components/header/hooks/use-header-color.js.map +1 -0
  6. package/lib/module/components/header/hooks/use-large-title-header.js +81 -0
  7. package/lib/module/components/header/hooks/use-large-title-header.js.map +1 -0
  8. package/lib/module/components/header/parts/HeaderAccessory.js +21 -6
  9. package/lib/module/components/header/parts/HeaderAccessory.js.map +1 -1
  10. package/lib/module/components/header/parts/HeaderBar.js +122 -0
  11. package/lib/module/components/header/parts/HeaderBar.js.map +1 -0
  12. package/lib/module/components/header/parts/HeaderGradientOverlay.js +20 -76
  13. package/lib/module/components/header/parts/HeaderGradientOverlay.js.map +1 -1
  14. package/lib/module/components/header/parts/HeaderSurface.js +16 -37
  15. package/lib/module/components/header/parts/HeaderSurface.js.map +1 -1
  16. package/lib/module/components/header/variants/LargeTitleHeader/index.js +51 -388
  17. package/lib/module/components/header/variants/LargeTitleHeader/index.js.map +1 -1
  18. package/lib/module/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.js +72 -0
  19. package/lib/module/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.js.map +1 -0
  20. package/lib/module/components/header/variants/TitleHeader/index.js +32 -161
  21. package/lib/module/components/header/variants/TitleHeader/index.js.map +1 -1
  22. package/lib/module/components/surface/Surface.js +2 -0
  23. package/lib/module/components/surface/Surface.js.map +1 -1
  24. package/lib/typescript/src/components/box/Box.d.ts +28 -4
  25. package/lib/typescript/src/components/box/Box.d.ts.map +1 -1
  26. package/lib/typescript/src/components/header/hooks/use-header-color.d.ts +4 -0
  27. package/lib/typescript/src/components/header/hooks/use-header-color.d.ts.map +1 -0
  28. package/lib/typescript/src/components/header/hooks/use-large-title-header.d.ts +36 -0
  29. package/lib/typescript/src/components/header/hooks/use-large-title-header.d.ts.map +1 -0
  30. package/lib/typescript/src/components/header/parts/HeaderAccessory.d.ts +8 -5
  31. package/lib/typescript/src/components/header/parts/HeaderAccessory.d.ts.map +1 -1
  32. package/lib/typescript/src/components/header/parts/HeaderBar.d.ts +17 -0
  33. package/lib/typescript/src/components/header/parts/HeaderBar.d.ts.map +1 -0
  34. package/lib/typescript/src/components/header/parts/HeaderGradientOverlay.d.ts +12 -15
  35. package/lib/typescript/src/components/header/parts/HeaderGradientOverlay.d.ts.map +1 -1
  36. package/lib/typescript/src/components/header/parts/HeaderSurface.d.ts +8 -9
  37. package/lib/typescript/src/components/header/parts/HeaderSurface.d.ts.map +1 -1
  38. package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts +3 -23
  39. package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts.map +1 -1
  40. package/lib/typescript/src/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.d.ts +11 -0
  41. package/lib/typescript/src/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.d.ts.map +1 -0
  42. package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts +3 -19
  43. package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts.map +1 -1
  44. package/lib/typescript/src/components/surface/Surface.d.ts +1 -1
  45. package/lib/typescript/src/components/surface/Surface.d.ts.map +1 -1
  46. package/lib/typescript/src/components/toast/Toast.d.ts +1 -1
  47. package/lib/typescript/src/components/toast/Toast.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/src/components/box/Box.tsx +59 -16
  50. package/src/components/header/hooks/use-header-color.ts +14 -0
  51. package/src/components/header/hooks/use-large-title-header.ts +78 -0
  52. package/src/components/header/parts/HeaderAccessory.tsx +26 -7
  53. package/src/components/header/parts/HeaderBar.tsx +125 -0
  54. package/src/components/header/parts/HeaderGradientOverlay.tsx +18 -70
  55. package/src/components/header/parts/HeaderSurface.tsx +16 -35
  56. package/src/components/header/variants/LargeTitleHeader/index.tsx +44 -371
  57. package/src/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.tsx +88 -0
  58. package/src/components/header/variants/TitleHeader/index.tsx +32 -149
  59. 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
- import { jsx as _jsx } from "react/jsx-runtime";
9
- const STYLE_KEYS = new Set(BOX_STYLE_PROP_KEYS);
8
+
9
+ /** Props owned by Box itself — everything else belongs to the rendered element. */
10
10
 
11
11
  /**
12
- * Base layout primitive: a `View` styled through theme-token props.
13
- * The only component family exposing token style-props.
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
- export const Box = /*#__PURE__*/forwardRef(function Box({
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 viewProps = {};
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 viewProps[key] = value;
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
- ...viewProps,
41
+ ...elementProps,
36
42
  style: mergedStyle,
37
43
  ref
38
44
  },
39
45
  children: children
40
46
  });
41
47
  }
42
- return /*#__PURE__*/_jsx(View, {
48
+ const Component = as ?? View;
49
+ return /*#__PURE__*/_jsx(Component, {
43
50
  ref: ref,
44
51
  style: mergedStyle,
45
- ...viewProps,
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","viewProps","key","Object","keys","value","has","mergedStyle","styles","root","ownerName","slotProps","View","create"],"sourceRoot":"../../../../src","sources":["components/box/Box.tsx"],"mappings":";;;AAAA,SAA4BA,UAAU,QAAQ,OAAO;AAGrD,SAASC,UAAU,EAAEC,YAAY,QAAQ,wBAAwB;AAEjE,SAASC,IAAI;AACb,SAASC,mBAAmB,EAAsBC,eAAe;AAAkB,SAAAC,GAAA,IAAAC,IAAA;AAOnF,MAAMC,UAAU,GAAG,IAAIC,GAAG,CAASL,mBAAwC,CAAC;;AAE5E;AACA;AACA;AACA;AACA,OAAO,MAAMM,GAAG,gBAAGV,UAAU,CAAsC,SAASU,GAAGA,CAC7E;EAAEC,OAAO;EAAEC,KAAK;EAAEC,QAAQ;EAAE,GAAGC;AAAK,CAAC,EACrCC,GAAG,EACH;EACA,MAAM;IAAEC;EAAM,CAAC,GAAGd,YAAY,CAAC,CAAC;EAEhC,MAAMe,UAAmC,GAAG,CAAC,CAAC;EAC9C,MAAMC,SAAkC,GAAG,CAAC,CAAC;EAC7C,KAAK,MAAMC,GAAG,IAAIC,MAAM,CAACC,IAAI,CAACP,IAAI,CAAC,EAAE;IACnC,MAAMQ,KAAK,GAAIR,IAAI,CAA6BK,GAAG,CAAC;IACpD,IAAIX,UAAU,CAACe,GAAG,CAACJ,GAAG,CAAC,EAAEF,UAAU,CAACE,GAAG,CAAC,GAAGG,KAAK,CAAC,KAC5CJ,SAAS,CAACC,GAAG,CAAC,GAAGG,KAAK;EAC7B;EAEA,MAAME,WAAW,GAAG,CAACC,MAAM,CAACC,IAAI,EAAErB,eAAe,CAACY,UAAU,EAAmBD,KAAK,CAAC,EAAEJ,KAAK,CAAC;EAE7F,IAAID,OAAO,EAAE;IACX,oBACEJ,IAAA,CAACJ,IAAI;MAACwB,SAAS,EAAC,KAAK;MAACC,SAAS,EAAE;QAAE,GAAGV,SAAS;QAAEN,KAAK,EAAEY,WAAW;QAAET;MAAI,CAAE;MAAAF,QAAA,EACxEA;IAAQ,CACL,CAAC;EAEX;EAEA,oBACEN,IAAA,CAACsB,IAAI;IAACd,GAAG,EAAEA,GAAI;IAACH,KAAK,EAAEY,WAAY;IAAA,GAAMN,SAAS;IAAAL,QAAA,EAC/CA;EAAQ,CACL,CAAC;AAEX,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMY,MAAM,GAAGxB,UAAU,CAAC6B,MAAM,CAAC,OAAO;EAAEJ,IAAI,EAAE,CAAC;AAAE,CAAC,CAAC,CAAC","ignoreList":[]}
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, useEffect } from "react";
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 { jsx as _jsx } from "react/jsx-runtime";
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
- onHeightChange(event.nativeEvent.layout.height);
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
- useEffect(() => () => onHeightChange(0), [onHeightChange]);
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__*/_jsx(Animated.View, {
34
+ return /*#__PURE__*/_jsxs(Animated.View, {
27
35
  style: [styles.accessory, style],
28
36
  onLayout: handleLayout,
29
- children: 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","useEffect","Animated","StyleSheet","jsx","_jsx","HeaderAccessory","children","padding","onHeightChange","style","handleLayout","event","nativeEvent","layout","height","_styles","styles","useVariants","View","accessory","onLayout","HeaderAccessorySpacer","spacer","create","theme","variants","x","paddingHorizontal","screen","none","uni__dependencies"],"sourceRoot":"../../../../../src","sources":["components/header/parts/HeaderAccessory.tsx"],"mappings":";;;AAAA,SAAyBA,WAAW,EAAEC,SAAS,QAAQ,OAAO;AAG9D,OAAOC,QAAQ,MAAM,yBAAyB;AAC9C,SAASC,UAAU,QAAQ,wBAAwB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAcpD;AACA,OAAO,SAASC,eAAeA,CAAC;EAAEC,QAAQ;EAAEC,OAAO;EAAEC,cAAc;EAAEC;AAA4B,CAAC,EAAE;EAClG,MAAMC,YAAY,GAAGX,WAAW,CAC7BY,KAAwB,IAAK;IAC5BH,cAAc,CAACG,KAAK,CAACC,WAAW,CAACC,MAAM,CAACC,MAAM,CAAC;EACjD,CAAC,EACD,CAACN,cAAc,CACjB,CAAC;;EAED;EACAR,SAAS,CAAC,MAAM,MAAMQ,cAAc,CAAC,CAAC,CAAC,EAAE,CAACA,cAAc,CAAC,CAAC;EAAC,MAAAO,OAAA,GAAAC,MAAA;EAAA;IAAA,MAAAA,MAAA,GAAAD,OAAA,CAAAE,WAAA,CAExC;MAAEV;IAAQ,CAAC;IAE9B,oBACEH,IAAA,CAACH,QAAQ,CAACiB,IAAI;MAACT,KAAK,EAAE,CAACO,MAAM,CAACG,SAAS,EAAEV,KAAK,CAAE;MAACW,QAAQ,EAAEV,YAAa;MAAAJ,QAAA,EACrEA;IAAQ,CACI,CAAC;EAChB;AACJ;;AAEA;AACA,OAAO,SAASe,qBAAqBA,CAAC;EAAEP;AAA2B,CAAC,EAAE;EACpE,oBAAOV,IAAA,CAACc,IAAI;IAACT,KAAK,EAAEO,MAAM,CAACM,MAAM,CAACR,MAAM;EAAE,CAAE,CAAC;AAC/C;AAEA,MAAME,MAAM,GAAGd,UAAU,CAACqB,MAAM,CAAEC,KAAK,KAAM;EAC3CL,SAAS,EAAE;IACTM,QAAQ,EAAE;MACRlB,OAAO,EAAE;QACPmB,CAAC,EAAE;UAAEC,iBAAiB,EAAEH,KAAK,CAACX,MAAM,CAACe,MAAM,CAACrB,OAAO,CAACmB;QAAE,CAAC;QACvDG,IAAI,EAAE,CAAC;MACT;IACF,CAAC;IAAAC,iBAAA;EACH,CAAC;EACDR,MAAM,EAAGR,MAAc,KAAM;IAAEA;EAAO,CAAC;AACzC,CAAC,CAAC,CAAC","ignoreList":[]}
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
- * How far the overlay extends below the bar's bottom edge, in dp.
8
- *
9
- * The fade needs more room than the bar alone can give it: confined to the bar,
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 HEADER_FADE_EXTENT = 8;
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
- * Raised cosine, capped at {@link MAX_FADE_ALPHA}, reaching 0 at the overlay's
39
- * bottom.
14
+ * Vertical fade behind header content, shared by header variants.
40
15
  *
41
- * The curve's slope is zero at both ends, so neither the start of the fade nor
42
- * its finish leaves a seam. A two-stop linear ramp has a constant slope that
43
- * begins and ends abruptly, and those two hard edges are what read as a line
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__*/_jsx(SvgLinearGradient, {
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: STOPS.map(stop => /*#__PURE__*/_jsx(Stop, {
97
- offset: stop.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: stop.opacity
100
- }, stop.offset))
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","HEADER_FADE_EXTENT","FADE_START","FADE_STOPS","MAX_FADE_ALPHA","alphaAt","t","Math","cos","PI","STOPS","offset","opacity","Array","from","length","_","index","HeaderGradientOverlay","color","gradientId","height","width","children","id","x1","y1","x2","y2","map","stop","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;AACA;AACA;AANA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAOA,OAAO,MAAMC,kBAAkB,GAAG,CAAC;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,UAAU,GAAG,GAAG;;AAEtB;AACA;AACA;AACA;AACA;AACA,MAAMC,UAAU,GAAG,CAAC;;AAEpB;AACA,MAAMC,cAAc,GAAG,IAAI;;AAE3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,OAAO,GAAIC,CAAS,IAAK,CAAC,CAAC,GAAGC,IAAI,CAACC,GAAG,CAACD,IAAI,CAACE,EAAE,GAAGH,CAAC,CAAC,GAAGF,cAAc,IAAI,CAAC;;AAE/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMM,KAAK,GAAG,CACZ;EAAEC,MAAM,EAAE,CAAC;EAAEC,OAAO,EAAE;AAAE,CAAC,EACzB,GAAGC,KAAK,CAACC,IAAI,CAAC;EAAEC,MAAM,EAAEZ;AAAW,CAAC,EAAE,CAACa,CAAC,EAAEC,KAAK,KAAK;EAClD,MAAMX,CAAC,GAAGW,KAAK,IAAId,UAAU,GAAG,CAAC,CAAC;EAClC,MAAMQ,MAAM,GAAGT,UAAU,GAAGI,CAAC,IAAI,CAAC,GAAGJ,UAAU,CAAC;EAChD,OAAO;IAAES,MAAM;IAAEC,OAAO,EAAED,MAAM,KAAK,CAAC,GAAG,CAAC,GAAGN,OAAO,CAACC,CAAC;EAAE,CAAC;AAC3D,CAAC,CAAC,CACH;AAOD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASY,qBAAqBA,CAAC;EAAEC;AAAkC,CAAC,EAAE;EAC3E,MAAMC,UAAU,GAAG9B,KAAK,CAAC,CAAC;EAE1B,oBACEU,KAAA,CAACT,GAAG;IAAC8B,MAAM,EAAC,MAAM;IAACC,KAAK,EAAC,MAAM;IAAAC,QAAA,gBAC7BzB,IAAA,CAACN,IAAI;MAAA+B,QAAA,eACHzB,IAAA,CAACF,iBAAiB;QAAC4B,EAAE,EAAEJ,UAAW;QAACK,EAAE,EAAC,GAAG;QAACC,EAAE,EAAC,GAAG;QAACC,EAAE,EAAC,GAAG;QAACC,EAAE,EAAC,GAAG;QAAAL,QAAA,EAC3Db,KAAK,CAACmB,GAAG,CAAEC,IAAI,iBACdhC,IAAA,CAACJ,IAAI;UAAmBiB,MAAM,EAAEmB,IAAI,CAACnB,MAAO;UAACoB,SAAS,EAAEZ,KAAM;UAACa,WAAW,EAAEF,IAAI,CAAClB;QAAQ,GAA9EkB,IAAI,CAACnB,MAA2E,CAC5F;MAAC,CACe;IAAC,CAChB,CAAC,eACPb,IAAA,CAACL,IAAI;MAAC6B,KAAK,EAAC,MAAM;MAACD,MAAM,EAAC,MAAM;MAACY,IAAI,EAAE,QAAQb,UAAU;IAAI,CAAE,CAAC;EAAA,CAC7D,CAAC;AAEV","ignoreList":[]}
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":[]}