react-native-terra-ui 0.11.11 → 0.11.13

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 (69) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/TerraUI.podspec +16 -0
  3. package/ios/TerraHeaderInsetsComponentView.h +4 -0
  4. package/ios/TerraHeaderInsetsComponentView.mm +93 -0
  5. package/lib/module/components/header/hooks/use-header-color.js +16 -0
  6. package/lib/module/components/header/hooks/use-header-color.js.map +1 -0
  7. package/lib/module/components/header/hooks/use-large-title-header.js +81 -0
  8. package/lib/module/components/header/hooks/use-large-title-header.js.map +1 -0
  9. package/lib/module/components/header/parts/HeaderAccessory.js +21 -6
  10. package/lib/module/components/header/parts/HeaderAccessory.js.map +1 -1
  11. package/lib/module/components/header/parts/HeaderBar.js +140 -0
  12. package/lib/module/components/header/parts/HeaderBar.js.map +1 -0
  13. package/lib/module/components/header/parts/HeaderGradientOverlay.js +5 -3
  14. package/lib/module/components/header/parts/HeaderGradientOverlay.js.map +1 -1
  15. package/lib/module/components/header/parts/HeaderSurface.js +8 -14
  16. package/lib/module/components/header/parts/HeaderSurface.js.map +1 -1
  17. package/lib/module/components/header/parts/HeaderWindowInsets.ios.js +29 -0
  18. package/lib/module/components/header/parts/HeaderWindowInsets.ios.js.map +1 -0
  19. package/lib/module/components/header/parts/HeaderWindowInsets.js +7 -0
  20. package/lib/module/components/header/parts/HeaderWindowInsets.js.map +1 -0
  21. package/lib/module/components/header/variants/LargeTitleHeader/index.js +51 -386
  22. package/lib/module/components/header/variants/LargeTitleHeader/index.js.map +1 -1
  23. package/lib/module/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.js +72 -0
  24. package/lib/module/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.js.map +1 -0
  25. package/lib/module/components/header/variants/TitleHeader/index.js +32 -160
  26. package/lib/module/components/header/variants/TitleHeader/index.js.map +1 -1
  27. package/lib/module/components/surface/Surface.js +2 -0
  28. package/lib/module/components/surface/Surface.js.map +1 -1
  29. package/lib/module/specs/TerraHeaderInsetsNativeComponent.ts +12 -0
  30. package/lib/typescript/src/components/header/hooks/use-header-color.d.ts +4 -0
  31. package/lib/typescript/src/components/header/hooks/use-header-color.d.ts.map +1 -0
  32. package/lib/typescript/src/components/header/hooks/use-large-title-header.d.ts +36 -0
  33. package/lib/typescript/src/components/header/hooks/use-large-title-header.d.ts.map +1 -0
  34. package/lib/typescript/src/components/header/parts/HeaderAccessory.d.ts +8 -5
  35. package/lib/typescript/src/components/header/parts/HeaderAccessory.d.ts.map +1 -1
  36. package/lib/typescript/src/components/header/parts/HeaderBar.d.ts +17 -0
  37. package/lib/typescript/src/components/header/parts/HeaderBar.d.ts.map +1 -0
  38. package/lib/typescript/src/components/header/parts/HeaderGradientOverlay.d.ts +3 -1
  39. package/lib/typescript/src/components/header/parts/HeaderGradientOverlay.d.ts.map +1 -1
  40. package/lib/typescript/src/components/header/parts/HeaderSurface.d.ts +5 -9
  41. package/lib/typescript/src/components/header/parts/HeaderSurface.d.ts.map +1 -1
  42. package/lib/typescript/src/components/header/parts/HeaderWindowInsets.d.ts +9 -0
  43. package/lib/typescript/src/components/header/parts/HeaderWindowInsets.d.ts.map +1 -0
  44. package/lib/typescript/src/components/header/parts/HeaderWindowInsets.ios.d.ts +3 -0
  45. package/lib/typescript/src/components/header/parts/HeaderWindowInsets.ios.d.ts.map +1 -0
  46. package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts +3 -23
  47. package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts.map +1 -1
  48. package/lib/typescript/src/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.d.ts +11 -0
  49. package/lib/typescript/src/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.d.ts.map +1 -0
  50. package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts +3 -19
  51. package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts.map +1 -1
  52. package/lib/typescript/src/components/surface/Surface.d.ts.map +1 -1
  53. package/lib/typescript/src/specs/TerraHeaderInsetsNativeComponent.d.ts +10 -0
  54. package/lib/typescript/src/specs/TerraHeaderInsetsNativeComponent.d.ts.map +1 -0
  55. package/package.json +14 -1
  56. package/react-native.config.js +7 -0
  57. package/src/components/header/hooks/use-header-color.ts +14 -0
  58. package/src/components/header/hooks/use-large-title-header.ts +78 -0
  59. package/src/components/header/parts/HeaderAccessory.tsx +26 -7
  60. package/src/components/header/parts/HeaderBar.tsx +139 -0
  61. package/src/components/header/parts/HeaderGradientOverlay.tsx +9 -3
  62. package/src/components/header/parts/HeaderSurface.tsx +11 -17
  63. package/src/components/header/parts/HeaderWindowInsets.ios.tsx +24 -0
  64. package/src/components/header/parts/HeaderWindowInsets.tsx +8 -0
  65. package/src/components/header/variants/LargeTitleHeader/index.tsx +44 -369
  66. package/src/components/header/variants/LargeTitleHeader/parts/LargeTitleContent.tsx +88 -0
  67. package/src/components/header/variants/TitleHeader/index.tsx +32 -146
  68. package/src/components/surface/Surface.tsx +2 -1
  69. package/src/specs/TerraHeaderInsetsNativeComponent.ts +12 -0
@@ -1,19 +1,16 @@
1
- import { type ReactNode, useCallback, useContext } from "react";
2
- import { Text, View } from "react-native";
1
+ import { type ReactNode, useContext } from "react";
2
+ import { View } from "react-native";
3
3
 
4
- import { StyleSheet, useUnistyles } from "react-native-unistyles";
4
+ import { StyleSheet } from "react-native-unistyles";
5
5
 
6
6
  import type { ColorToken } from "#theme/types";
7
- import { resolveThemeColor } from "#utils/resolve-theme-color";
8
- import { FONT_WEIGHT_VALUE } from "#utils/typography";
9
7
  import { useHeaderBackground } from "../../../screen/parts/ScreenHeaderAppearance";
10
8
  import { ScreenContext } from "../../../screen/ScreenContext";
11
- import { Toolbar } from "../../../toolbar";
12
- import { HeaderDismissButton, type HeaderDismissProps } from "../../header-buttons";
9
+ import type { HeaderDismissProps } from "../../header-buttons";
10
+ import { useHeaderColor } from "../../hooks/use-header-color";
13
11
  import { HeaderAccessory } from "../../parts/HeaderAccessory";
14
- import { HeaderSurface } from "../../parts/HeaderSurface";
12
+ import { HeaderBar } from "../../parts/HeaderBar";
15
13
  import type { HeaderAccessoryPadding } from "../../types";
16
- import { isCustomTitle, isTextTitle } from "../../utils";
17
14
 
18
15
  export interface TitleHeaderProps extends HeaderDismissProps {
19
16
  /**
@@ -56,23 +53,7 @@ export interface TitleHeaderProps extends HeaderDismissProps {
56
53
  bg?: ColorToken;
57
54
  }
58
55
 
59
- /**
60
- * Compact title bar (leading slot · title · trailing slot) with a top safe-area
61
- * inset outside Screen. Within Screen, the root owns safe-area clearance. The inline counterpart to `Header.LargeTitle`; use it for screens that
62
- * don't need a collapsing large title.
63
- *
64
- * @example
65
- * ```tsx
66
- * <Screen.Header>
67
- * <Header.Title
68
- * title="Stats"
69
- * trailingActions={
70
- * <Toolbar.Button icon="add" accessibilityLabel="Add" onPress={add} />
71
- * }
72
- * />
73
- * </Screen.Header>
74
- * ```
75
- */
56
+ /** Compact header. Screen owns the safe area when present; standalone headers reserve it here. */
76
57
  export function TitleHeader({
77
58
  title,
78
59
  leadingActions,
@@ -81,137 +62,42 @@ export function TitleHeader({
81
62
  RightToolbar,
82
63
  accessory,
83
64
  accessoryPadding = "x",
84
- dismissAction = "none",
85
- navigation,
86
- onDismiss,
87
65
  titleAlignment = "center",
88
66
  background,
89
67
  bg,
68
+ ...dismissProps
90
69
  }: TitleHeaderProps) {
91
- const { theme } = useUnistyles();
92
-
93
70
  const screen = useContext(ScreenContext);
94
- const colorToken = background ?? bg;
95
- const bgColor =
96
- (colorToken ? resolveThemeColor(colorToken, theme) : screen?.background) ?? theme.color["surface.canvas"];
97
- const leadingContent = leadingActions !== undefined ? leadingActions : LeftToolbar;
98
- const trailingContent = trailingActions !== undefined ? trailingActions : RightToolbar;
99
- const setAccessoryInset = screen?.setHeaderAccessoryHeight;
100
- // Compact headers always reserve the accessory height as top padding.
101
- const handleAccessoryHeightChange = useCallback(
102
- (height: number) => setAccessoryInset?.(height),
103
- [setAccessoryInset]
104
- );
105
- const isTransparent = bgColor === "transparent";
106
- useHeaderBackground(bgColor);
107
- styles.useVariants({ titleAlignment });
108
-
109
- const leading =
110
- dismissAction === "back" ? (
111
- <>
112
- <HeaderDismissButton dismissAction={dismissAction} navigation={navigation} onDismiss={onDismiss} />
113
- {leadingContent}
114
- </>
115
- ) : (
116
- leadingContent
117
- );
118
-
119
- const trailing =
120
- dismissAction === "close" ? (
121
- <>
122
- {trailingContent}
123
- <HeaderDismissButton dismissAction={dismissAction} navigation={navigation} onDismiss={onDismiss} />
124
- </>
125
- ) : (
126
- trailingContent
127
- );
71
+ const color = useHeaderColor(background ?? bg);
72
+ useHeaderBackground(color);
128
73
  return (
129
74
  <View style={styles.container}>
130
- <View style={styles.safeArea(isTransparent, bgColor, screen !== null)} />
131
- <View style={styles.barGroup}>
132
- <HeaderSurface color={bgColor} />
133
- <View style={styles.bar}>
134
- {leading != null && <Toolbar>{leading}</Toolbar>}
135
- {/* Text can never be the touch target, but custom content may be, so its
136
- container passes touches through to it instead of swallowing them. */}
137
- <View style={styles.titleContainer} pointerEvents={isCustomTitle(title) ? "box-none" : "none"}>
138
- {isTextTitle(title)
139
- ? String(title).trim().length > 0 && <Text style={styles.title}>{title}</Text>
140
- : title}
141
- </View>
142
- {trailing != null && <Toolbar style={styles.trailing}>{trailing}</Toolbar>}
143
- </View>
144
- {accessory != null && (
145
- <HeaderAccessory padding={accessoryPadding} onHeightChange={handleAccessoryHeightChange}>
146
- {accessory}
147
- </HeaderAccessory>
148
- )}
149
- </View>
75
+ <View style={styles.safeArea(color, screen !== null)} />
76
+ <HeaderBar
77
+ {...dismissProps}
78
+ title={title}
79
+ titleAlignment={titleAlignment}
80
+ color={color}
81
+ leading={leadingActions !== undefined ? leadingActions : LeftToolbar}
82
+ trailing={trailingActions !== undefined ? trailingActions : RightToolbar}
83
+ />
84
+ {accessory != null && (
85
+ <HeaderAccessory
86
+ padding={accessoryPadding}
87
+ color={color}
88
+ onHeightChange={screen?.setHeaderAccessoryHeight}
89
+ >
90
+ {accessory}
91
+ </HeaderAccessory>
92
+ )}
150
93
  </View>
151
94
  );
152
95
  }
153
96
 
154
- const styles = StyleSheet.create((theme, runtime) => ({
155
- container: {
156
- position: "absolute",
157
- top: 0,
158
- left: 0,
159
- right: 0,
160
- zIndex: 1000,
161
- },
162
- safeArea: (isTransparent: boolean, bgColor: string, withinScreen: boolean) => ({
97
+ const styles = StyleSheet.create((_, runtime) => ({
98
+ container: { position: "absolute", top: 0, left: 0, right: 0, zIndex: 1000 },
99
+ safeArea: (color: string, withinScreen: boolean) => ({
163
100
  height: withinScreen ? 0 : runtime.insets.top,
164
- backgroundColor: isTransparent ? "transparent" : bgColor,
101
+ backgroundColor: color,
165
102
  }),
166
- // Anchors the absolutely positioned surface over the bar and the accessory both.
167
- barGroup: { position: "relative" },
168
- bar: {
169
- height: theme.layout.header.height,
170
- flexDirection: "row",
171
- alignItems: "center",
172
- paddingHorizontal: theme.layout.screen.padding.x,
173
- gap: theme.spacing["3"],
174
- justifyContent: "space-between",
175
- },
176
- // A centered title is absolutely positioned, so it leaves the flex row. With
177
- // no leading slot the trailing toolbar would be the only in-flow child and
178
- // `space-between` would park it on the left — the auto margin pins it right.
179
- trailing: {
180
- justifyContent: "flex-end",
181
- variants: {
182
- titleAlignment: {
183
- center: { marginLeft: "auto" },
184
- left: {},
185
- },
186
- },
187
- },
188
- titleContainer: {
189
- variants: {
190
- titleAlignment: {
191
- center: {
192
- position: "absolute",
193
- left: 0,
194
- right: 0,
195
- alignItems: "center",
196
- },
197
- left: {
198
- flex: 1,
199
- alignItems: "flex-start",
200
- },
201
- },
202
- },
203
- },
204
- title: {
205
- fontSize: theme.typography.variants["title-md"].fontSize,
206
- lineHeight: theme.typography.variants["title-md"].lineHeight,
207
- letterSpacing: theme.typography.variants["title-md"].letterSpacing,
208
- fontWeight: FONT_WEIGHT_VALUE[theme.typography.variants["title-md"].fontWeight],
209
- color: (theme.color as unknown as Record<string, string | undefined>)["text.primary"] ?? "",
210
- variants: {
211
- titleAlignment: {
212
- center: { textAlign: "center" },
213
- left: { textAlign: "left" },
214
- },
215
- },
216
- },
217
103
  }));
@@ -69,7 +69,7 @@ const resolveElevation = (variant: SurfaceVariant, elevation?: ElevationKey): El
69
69
  * ```
70
70
  */
71
71
  export const Surface = forwardRef<ComponentRef<typeof View>, SurfaceProps>(function Surface(
72
- { variant = "base", elevation, radius, borderWidth, borderColor, ...rest },
72
+ { variant = "base", p = "3", elevation, radius, borderWidth, borderColor, ...rest },
73
73
  ref
74
74
  ) {
75
75
  const variantBorder = VARIANT_BORDER[variant];
@@ -78,6 +78,7 @@ export const Surface = forwardRef<ComponentRef<typeof View>, SurfaceProps>(funct
78
78
  <Box
79
79
  ref={ref}
80
80
  background={VARIANT_BG[variant]}
81
+ p={p}
81
82
  radius={radius ?? getDefaultRadius("surface")}
82
83
  borderWidth={borderWidth ?? variantBorder.borderWidth}
83
84
  borderColor={borderColor ?? variantBorder.borderColor}
@@ -0,0 +1,12 @@
1
+ import type { CodegenTypes, ViewProps } from "react-native";
2
+ import { codegenNativeComponent } from "react-native";
3
+
4
+ export interface NativeProps extends ViewProps {
5
+ onInsetsChange?: CodegenTypes.DirectEventHandler<
6
+ Readonly<{ left: CodegenTypes.Double; right: CodegenTypes.Double }>
7
+ >;
8
+ }
9
+
10
+ export default codegenNativeComponent<NativeProps>("TerraHeaderInsets", {
11
+ excludedPlatforms: ["android"],
12
+ });