expo-router 55.0.0-beta.4 → 55.0.0-canary-20260128-67ce8d5

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 (62) hide show
  1. package/android/build.gradle +2 -2
  2. package/build/layouts/StackClient.d.ts +1 -1
  3. package/build/layouts/stack-utils/StackHeaderComponent.d.ts +11 -0
  4. package/build/layouts/stack-utils/StackHeaderComponent.d.ts.map +1 -1
  5. package/build/layouts/stack-utils/StackHeaderComponent.js +19 -2
  6. package/build/layouts/stack-utils/StackHeaderComponent.js.map +1 -1
  7. package/build/layouts/stack-utils/toolbar/StackToolbarClient.d.ts +1 -1
  8. package/build/layouts/stack-utils/toolbar/StackToolbarClient.d.ts.map +1 -1
  9. package/build/layouts/stack-utils/toolbar/StackToolbarClient.js +27 -11
  10. package/build/layouts/stack-utils/toolbar/StackToolbarClient.js.map +1 -1
  11. package/build/layouts/stack-utils/toolbar/StackToolbarMenu.d.ts.map +1 -1
  12. package/build/layouts/stack-utils/toolbar/StackToolbarMenu.js +38 -11
  13. package/build/layouts/stack-utils/toolbar/StackToolbarMenu.js.map +1 -1
  14. package/build/layouts/stack-utils/toolbar/bottom-toolbar-native-elements.d.ts +1 -0
  15. package/build/layouts/stack-utils/toolbar/bottom-toolbar-native-elements.d.ts.map +1 -1
  16. package/build/layouts/stack-utils/toolbar/bottom-toolbar-native-elements.js +2 -4
  17. package/build/layouts/stack-utils/toolbar/bottom-toolbar-native-elements.js.map +1 -1
  18. package/build/link/preview/native.d.ts +1 -0
  19. package/build/link/preview/native.d.ts.map +1 -1
  20. package/build/link/preview/native.js.map +1 -1
  21. package/expo-module.config.json +1 -1
  22. package/ios/LinkPreview/LinkPreviewNativeActionView.swift +1 -0
  23. package/ios/LinkPreview/LinkPreviewNativeModule.swift +3 -0
  24. package/ios/LinkPreview/LinkZoomTransition.swift +22 -12
  25. package/ios/Toolbar/RouterFontUtils.swift +8 -0
  26. package/ios/Toolbar/RouterToolbarHostView.swift +23 -7
  27. package/ios/Toolbar/RouterToolbarItemView.swift +13 -15
  28. package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.module → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.module} +7 -7
  29. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.module.md5 +1 -0
  30. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.module.sha1 +1 -0
  31. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.module.sha256 +1 -0
  32. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.module.sha512 +1 -0
  33. package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.pom → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.pom} +1 -1
  34. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.pom.md5 +1 -0
  35. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.pom.sha1 +1 -0
  36. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.pom.sha256 +1 -0
  37. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.pom.sha512 +1 -0
  38. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml +4 -4
  39. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.md5 +1 -1
  40. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha1 +1 -1
  41. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha256 +1 -1
  42. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha512 +1 -1
  43. package/package.json +12 -13
  44. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.module.md5 +0 -1
  45. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.module.sha1 +0 -1
  46. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.module.sha256 +0 -1
  47. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.module.sha512 +0 -1
  48. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.pom.md5 +0 -1
  49. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.pom.sha1 +0 -1
  50. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.pom.sha256 +0 -1
  51. package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.pom.sha512 +0 -1
  52. package/plugin/tsconfig.tsbuildinfo +0 -1
  53. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4-sources.jar → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5-sources.jar} +0 -0
  54. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4-sources.jar.md5 → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5-sources.jar.md5} +0 -0
  55. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4-sources.jar.sha1 → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5-sources.jar.sha1} +0 -0
  56. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4-sources.jar.sha256 → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5-sources.jar.sha256} +0 -0
  57. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4-sources.jar.sha512 → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5-sources.jar.sha512} +0 -0
  58. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.aar → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.aar} +0 -0
  59. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.aar.md5 → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.aar.md5} +0 -0
  60. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.aar.sha1 → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.aar.sha1} +0 -0
  61. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.aar.sha256 → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.aar.sha256} +0 -0
  62. /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-beta.4/expo.modules.router-55.0.0-beta.4.aar.sha512 → 55.0.0-canary-20260128-67ce8d5/expo.modules.router-55.0.0-canary-20260128-67ce8d5.aar.sha512} +0 -0
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'expo.modules.router'
7
- version = '55.0.0-beta.4'
7
+ version = '55.0.0-canary-20260128-67ce8d5'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.router"
11
11
  defaultConfig {
12
12
  versionCode 1
13
- versionName "55.0.0-beta.4"
13
+ versionName "55.0.0-canary-20260128-67ce8d5"
14
14
  }
15
15
  lintOptions {
16
16
  abortOnError false
@@ -164,7 +164,7 @@ declare const Stack: ((props: ComponentProps<typeof RNStack>) => React.JSX.Eleme
164
164
  Header: typeof import("./stack-utils/StackHeaderComponent").StackHeaderComponent;
165
165
  SearchBar: typeof StackSearchBar;
166
166
  Toolbar: {
167
- ({ children, placement, asChild }: import("./stack-utils").StackToolbarProps): React.JSX.Element;
167
+ (props: import("./stack-utils").StackToolbarProps): React.JSX.Element;
168
168
  Button: React.FC<import("./stack-utils").StackToolbarButtonProps>;
169
169
  Menu: React.FC<import("./stack-utils").StackToolbarMenuProps>;
170
170
  MenuAction: React.FC<import("./stack-utils").StackToolbarMenuActionProps>;
@@ -20,6 +20,17 @@ export interface StackHeaderProps {
20
20
  * @default false
21
21
  */
22
22
  asChild?: boolean;
23
+ /**
24
+ * Whether the header should be transparent.
25
+ * When `true`, the header is absolutely positioned and content scrolls underneath.
26
+ *
27
+ * Auto-enabled when:
28
+ * - `style.backgroundColor` is 'transparent'
29
+ * - `blurEffect` is set (required for blur to work)
30
+ *
31
+ * @default false
32
+ */
33
+ transparent?: boolean;
23
34
  /**
24
35
  * The blur effect to apply to the header background on iOS.
25
36
  * Common values include 'regular', 'prominent', 'systemMaterial', etc.
@@ -1 +1 @@
1
- {"version":3,"file":"StackHeaderComponent.d.ts","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderComponent.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,EAAc,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAIzE,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,4BAA4B,CAAC,YAAY,CAAC,CAAC;IACxD;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;QAChB,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,eAAe,CAAC,EAAE,4BAA4B,CAAC,iBAAiB,CAAC,CAAC;QAClE,WAAW,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;KACzC,CAAC,CAAC;IACH;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;QACrB,eAAe,CAAC,EAAE,4BAA4B,CAAC,2BAA2B,CAAC,CAAC;QAC5E,WAAW,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;KACzC,CAAC,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,+BAK3D;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,4BAA4B,EACrC,KAAK,EAAE,gBAAgB,GACtB,4BAA4B,CA6B9B"}
1
+ {"version":3,"file":"StackHeaderComponent.d.ts","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderComponent.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,EAAc,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAIzE,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,4BAA4B,CAAC,YAAY,CAAC,CAAC;IACxD;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;QAChB,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,eAAe,CAAC,EAAE,4BAA4B,CAAC,iBAAiB,CAAC,CAAC;QAClE,WAAW,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;KACzC,CAAC,CAAC;IACH;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;QACrB,eAAe,CAAC,EAAE,4BAA4B,CAAC,2BAA2B,CAAC,CAAC;QAC5E,WAAW,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;KACzC,CAAC,CAAC;CACJ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,+BAK3D;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,4BAA4B,EACrC,KAAK,EAAE,gBAAgB,GACtB,4BAA4B,CAiD9B"}
@@ -62,18 +62,35 @@ function appendStackHeaderPropsToOptions(options, props) {
62
62
  if (props.children && !props.asChild) {
63
63
  console.warn(`To render a custom header, set the 'asChild' prop to true on Stack.Header.`);
64
64
  }
65
+ // Determine if header should be transparent:
66
+ // 1. Explicitly set via `transparent` prop
67
+ // 2. Implicitly via backgroundColor === 'transparent'
68
+ // 3. Implicitly when blurEffect is set (required for blurEffect to work)
69
+ const isBackgroundTransparent = flattenedStyle?.backgroundColor === 'transparent';
70
+ const hasBlurEffect = props.blurEffect !== undefined;
71
+ const shouldBeTransparent = props.transparent === true ||
72
+ (props.transparent !== false && (isBackgroundTransparent || hasBlurEffect));
73
+ // Warn if blurEffect is set but transparent is explicitly false
74
+ if (props.blurEffect && props.transparent === false) {
75
+ console.warn(`Stack.Header: 'blurEffect' requires 'transparent' to be enabled.`);
76
+ }
65
77
  return {
66
78
  ...options,
67
79
  headerShown: !props.hidden,
68
80
  headerBlurEffect: props.blurEffect,
81
+ ...(shouldBeTransparent && { headerTransparent: true }),
82
+ ...(props.transparent === false && { headerTransparent: false }),
83
+ ...(flattenedStyle?.color && { headerTintColor: flattenedStyle.color }),
69
84
  headerStyle: {
70
85
  backgroundColor: flattenedStyle?.backgroundColor,
71
86
  },
72
87
  headerLargeStyle: {
73
88
  backgroundColor: flattenedLargeStyle?.backgroundColor,
74
89
  },
75
- headerShadowVisible: flattenedStyle?.shadowColor !== 'transparent',
76
- headerLargeTitleShadowVisible: flattenedLargeStyle?.shadowColor !== 'transparent',
90
+ ...(flattenedStyle?.shadowColor === 'transparent' && { headerShadowVisible: false }),
91
+ ...(flattenedLargeStyle?.shadowColor === 'transparent' && {
92
+ headerLargeTitleShadowVisible: false,
93
+ }),
77
94
  };
78
95
  }
79
96
  //# sourceMappingURL=StackHeaderComponent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StackHeaderComponent.js","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderComponent.tsx"],"names":[],"mappings":";;AA+FA,oDAKC;AAED,0EAgCC;AArID,iCAAgD;AAChD,+CAA2E;AAG3E,+CAA4C;AAmD5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,SAAgB,oBAAoB,CAAC,KAAuB;IAC1D,0DAA0D;IAC1D,gDAAgD;IAChD,MAAM,cAAc,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,+BAA+B,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,eAAM,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,EAAG,CAAC;AAC7C,CAAC;AAED,SAAgB,+BAA+B,CAC7C,OAAqC,EACrC,KAAuB;IAEvB,MAAM,cAAc,GAAG,yBAAU,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,mBAAmB,GAAG,yBAAU,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAEjE,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;IAC7F,CAAC;IAED,OAAO;QACL,GAAG,OAAO;QACV,WAAW,EAAE,CAAC,KAAK,CAAC,MAAM;QAC1B,gBAAgB,EAAE,KAAK,CAAC,UAAU;QAClC,WAAW,EAAE;YACX,eAAe,EAAE,cAAc,EAAE,eAAqC;SACvE;QACD,gBAAgB,EAAE;YAChB,eAAe,EAAE,mBAAmB,EAAE,eAAqC;SAC5E;QACD,mBAAmB,EAAE,cAAc,EAAE,WAAW,KAAK,aAAa;QAClE,6BAA6B,EAAE,mBAAmB,EAAE,WAAW,KAAK,aAAa;KAClF,CAAC;AACJ,CAAC","sourcesContent":["import { NativeStackNavigationOptions } from '@react-navigation/native-stack';\nimport { useMemo, type ReactNode } from 'react';\nimport { StyleSheet, type ColorValue, type StyleProp } from 'react-native';\nimport type { ScreenStackHeaderConfigProps } from 'react-native-screens';\n\nimport { Screen } from '../../views/Screen';\n\nexport interface StackHeaderProps {\n /**\n * Child elements for custom header when `asChild` is true.\n */\n children?: ReactNode;\n /**\n * Whether to hide the header completely. When set to `true`, the header will not be rendered.\n *\n * @default false\n */\n hidden?: boolean;\n /**\n * When `true`, renders children as a custom header component, replacing the default header entirely.\n * Use this to implement fully custom header layouts.\n *\n * @default false\n */\n asChild?: boolean;\n /**\n * The blur effect to apply to the header background on iOS.\n * Common values include 'regular', 'prominent', 'systemMaterial', etc.\n *\n * @platform ios\n */\n blurEffect?: ScreenStackHeaderConfigProps['blurEffect'];\n /**\n * Style properties for the standard-sized header.\n * - `color`: Tint color for header elements (similar to tintColor in React Navigation)\n * - `backgroundColor`: Background color of the header\n * - `shadowColor`: Set to 'transparent' to hide the header shadow/border\n */\n style?: StyleProp<{\n color?: ColorValue; // tintColor from ReactNavigation\n backgroundColor?: ScreenStackHeaderConfigProps['backgroundColor'];\n shadowColor?: undefined | 'transparent';\n }>;\n /**\n * Style properties for the large title header (iOS).\n * - `backgroundColor`: Background color of the large title header\n * - `shadowColor`: Set to 'transparent' to hide the large title shadow/border\n *\n * @platform ios\n */\n largeStyle?: StyleProp<{\n backgroundColor?: ScreenStackHeaderConfigProps['largeTitleBackgroundColor'];\n shadowColor?: undefined | 'transparent';\n }>;\n}\n\n/**\n * The component used to configure header styling for a stack screen.\n *\n * Use this component to set header appearance properties like blur effect, background color,\n * and shadow visibility.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Header\n * blurEffect=\"systemMaterial\"\n * style={{ backgroundColor: '#fff' }}\n * />\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @example\n * When used inside a layout with Stack.Screen:\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Layout() {\n * return (\n * <Stack>\n * <Stack.Screen name=\"index\">\n * <Stack.Header blurEffect=\"systemMaterial\" />\n * </Stack.Screen>\n * </Stack>\n * );\n * }\n * ```\n */\nexport function StackHeaderComponent(props: StackHeaderProps) {\n // This component will only render when used inside a page\n // but only if it is not wrapped in Stack.Screen\n const updatedOptions = useMemo(() => appendStackHeaderPropsToOptions({}, props), [props]);\n return <Screen options={updatedOptions} />;\n}\n\nexport function appendStackHeaderPropsToOptions(\n options: NativeStackNavigationOptions,\n props: StackHeaderProps\n): NativeStackNavigationOptions {\n const flattenedStyle = StyleSheet.flatten(props.style);\n const flattenedLargeStyle = StyleSheet.flatten(props.largeStyle);\n\n if (props.hidden) {\n return { ...options, headerShown: false };\n }\n\n if (props.asChild) {\n return { ...options, header: () => props.children };\n }\n\n if (props.children && !props.asChild) {\n console.warn(`To render a custom header, set the 'asChild' prop to true on Stack.Header.`);\n }\n\n return {\n ...options,\n headerShown: !props.hidden,\n headerBlurEffect: props.blurEffect,\n headerStyle: {\n backgroundColor: flattenedStyle?.backgroundColor as string | undefined,\n },\n headerLargeStyle: {\n backgroundColor: flattenedLargeStyle?.backgroundColor as string | undefined,\n },\n headerShadowVisible: flattenedStyle?.shadowColor !== 'transparent',\n headerLargeTitleShadowVisible: flattenedLargeStyle?.shadowColor !== 'transparent',\n };\n}\n"]}
1
+ {"version":3,"file":"StackHeaderComponent.js","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderComponent.tsx"],"names":[],"mappings":";;AA0GA,oDAKC;AAED,0EAoDC;AApKD,iCAAgD;AAChD,+CAA2E;AAG3E,+CAA4C;AA8D5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,SAAgB,oBAAoB,CAAC,KAAuB;IAC1D,0DAA0D;IAC1D,gDAAgD;IAChD,MAAM,cAAc,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE,CAAC,+BAA+B,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1F,OAAO,CAAC,eAAM,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,EAAG,CAAC;AAC7C,CAAC;AAED,SAAgB,+BAA+B,CAC7C,OAAqC,EACrC,KAAuB;IAEvB,MAAM,cAAc,GAAG,yBAAU,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvD,MAAM,mBAAmB,GAAG,yBAAU,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAEjE,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;IAC7F,CAAC;IAED,6CAA6C;IAC7C,2CAA2C;IAC3C,sDAAsD;IACtD,yEAAyE;IACzE,MAAM,uBAAuB,GAAG,cAAc,EAAE,eAAe,KAAK,aAAa,CAAC;IAClF,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC;IACrD,MAAM,mBAAmB,GACvB,KAAK,CAAC,WAAW,KAAK,IAAI;QAC1B,CAAC,KAAK,CAAC,WAAW,KAAK,KAAK,IAAI,CAAC,uBAAuB,IAAI,aAAa,CAAC,CAAC,CAAC;IAE9E,gEAAgE;IAChE,IAAI,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IACnF,CAAC;IAED,OAAO;QACL,GAAG,OAAO;QACV,WAAW,EAAE,CAAC,KAAK,CAAC,MAAM;QAC1B,gBAAgB,EAAE,KAAK,CAAC,UAAU;QAClC,GAAG,CAAC,mBAAmB,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;QACvD,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,KAAK,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,CAAC;QAChE,GAAG,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE,eAAe,EAAE,cAAc,CAAC,KAAe,EAAE,CAAC;QACjF,WAAW,EAAE;YACX,eAAe,EAAE,cAAc,EAAE,eAAqC;SACvE;QACD,gBAAgB,EAAE;YAChB,eAAe,EAAE,mBAAmB,EAAE,eAAqC;SAC5E;QACD,GAAG,CAAC,cAAc,EAAE,WAAW,KAAK,aAAa,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC;QACpF,GAAG,CAAC,mBAAmB,EAAE,WAAW,KAAK,aAAa,IAAI;YACxD,6BAA6B,EAAE,KAAK;SACrC,CAAC;KACH,CAAC;AACJ,CAAC","sourcesContent":["import { NativeStackNavigationOptions } from '@react-navigation/native-stack';\nimport { useMemo, type ReactNode } from 'react';\nimport { StyleSheet, type ColorValue, type StyleProp } from 'react-native';\nimport type { ScreenStackHeaderConfigProps } from 'react-native-screens';\n\nimport { Screen } from '../../views/Screen';\n\nexport interface StackHeaderProps {\n /**\n * Child elements for custom header when `asChild` is true.\n */\n children?: ReactNode;\n /**\n * Whether to hide the header completely. When set to `true`, the header will not be rendered.\n *\n * @default false\n */\n hidden?: boolean;\n /**\n * When `true`, renders children as a custom header component, replacing the default header entirely.\n * Use this to implement fully custom header layouts.\n *\n * @default false\n */\n asChild?: boolean;\n /**\n * Whether the header should be transparent.\n * When `true`, the header is absolutely positioned and content scrolls underneath.\n *\n * Auto-enabled when:\n * - `style.backgroundColor` is 'transparent'\n * - `blurEffect` is set (required for blur to work)\n *\n * @default false\n */\n transparent?: boolean;\n /**\n * The blur effect to apply to the header background on iOS.\n * Common values include 'regular', 'prominent', 'systemMaterial', etc.\n *\n * @platform ios\n */\n blurEffect?: ScreenStackHeaderConfigProps['blurEffect'];\n /**\n * Style properties for the standard-sized header.\n * - `color`: Tint color for header elements (similar to tintColor in React Navigation)\n * - `backgroundColor`: Background color of the header\n * - `shadowColor`: Set to 'transparent' to hide the header shadow/border\n */\n style?: StyleProp<{\n color?: ColorValue; // tintColor from ReactNavigation\n backgroundColor?: ScreenStackHeaderConfigProps['backgroundColor'];\n shadowColor?: undefined | 'transparent';\n }>;\n /**\n * Style properties for the large title header (iOS).\n * - `backgroundColor`: Background color of the large title header\n * - `shadowColor`: Set to 'transparent' to hide the large title shadow/border\n *\n * @platform ios\n */\n largeStyle?: StyleProp<{\n backgroundColor?: ScreenStackHeaderConfigProps['largeTitleBackgroundColor'];\n shadowColor?: undefined | 'transparent';\n }>;\n}\n\n/**\n * The component used to configure header styling for a stack screen.\n *\n * Use this component to set header appearance properties like blur effect, background color,\n * and shadow visibility.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Header\n * blurEffect=\"systemMaterial\"\n * style={{ backgroundColor: '#fff' }}\n * />\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @example\n * When used inside a layout with Stack.Screen:\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Layout() {\n * return (\n * <Stack>\n * <Stack.Screen name=\"index\">\n * <Stack.Header blurEffect=\"systemMaterial\" />\n * </Stack.Screen>\n * </Stack>\n * );\n * }\n * ```\n */\nexport function StackHeaderComponent(props: StackHeaderProps) {\n // This component will only render when used inside a page\n // but only if it is not wrapped in Stack.Screen\n const updatedOptions = useMemo(() => appendStackHeaderPropsToOptions({}, props), [props]);\n return <Screen options={updatedOptions} />;\n}\n\nexport function appendStackHeaderPropsToOptions(\n options: NativeStackNavigationOptions,\n props: StackHeaderProps\n): NativeStackNavigationOptions {\n const flattenedStyle = StyleSheet.flatten(props.style);\n const flattenedLargeStyle = StyleSheet.flatten(props.largeStyle);\n\n if (props.hidden) {\n return { ...options, headerShown: false };\n }\n\n if (props.asChild) {\n return { ...options, header: () => props.children };\n }\n\n if (props.children && !props.asChild) {\n console.warn(`To render a custom header, set the 'asChild' prop to true on Stack.Header.`);\n }\n\n // Determine if header should be transparent:\n // 1. Explicitly set via `transparent` prop\n // 2. Implicitly via backgroundColor === 'transparent'\n // 3. Implicitly when blurEffect is set (required for blurEffect to work)\n const isBackgroundTransparent = flattenedStyle?.backgroundColor === 'transparent';\n const hasBlurEffect = props.blurEffect !== undefined;\n const shouldBeTransparent =\n props.transparent === true ||\n (props.transparent !== false && (isBackgroundTransparent || hasBlurEffect));\n\n // Warn if blurEffect is set but transparent is explicitly false\n if (props.blurEffect && props.transparent === false) {\n console.warn(`Stack.Header: 'blurEffect' requires 'transparent' to be enabled.`);\n }\n\n return {\n ...options,\n headerShown: !props.hidden,\n headerBlurEffect: props.blurEffect,\n ...(shouldBeTransparent && { headerTransparent: true }),\n ...(props.transparent === false && { headerTransparent: false }),\n ...(flattenedStyle?.color && { headerTintColor: flattenedStyle.color as string }),\n headerStyle: {\n backgroundColor: flattenedStyle?.backgroundColor as string | undefined,\n },\n headerLargeStyle: {\n backgroundColor: flattenedLargeStyle?.backgroundColor as string | undefined,\n },\n ...(flattenedStyle?.shadowColor === 'transparent' && { headerShadowVisible: false }),\n ...(flattenedLargeStyle?.shadowColor === 'transparent' && {\n headerLargeTitleShadowVisible: false,\n }),\n };\n}\n"]}
@@ -88,7 +88,7 @@ export interface StackToolbarProps {
88
88
  * @platform ios
89
89
  */
90
90
  export declare const StackToolbar: {
91
- ({ children, placement, asChild }: StackToolbarProps): React.JSX.Element;
91
+ (props: StackToolbarProps): React.JSX.Element;
92
92
  Button: React.FC<import("./StackToolbarButton").StackToolbarButtonProps>;
93
93
  Menu: React.FC<import("./StackToolbarMenu").StackToolbarMenuProps>;
94
94
  MenuAction: React.FC<import("./StackToolbarMenu").StackToolbarMenuActionProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"StackToolbarClient.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarClient.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,KAAK,EAAE,EAA4B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAkBxE,OAAO,EAAgD,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAOhG,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,eAAO,MAAM,YAAY;uCAAiD,iBAAiB;;;;;;;;;;CA4B1F,CAAC;AAiDF,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,4BAA4B,EACrC,KAAK,EAAE,iBAAiB,GACvB,4BAA4B,CAqC9B;AAYD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"StackToolbarClient.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarClient.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,KAAK,EAAE,EAAuC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAkBnF,OAAO,EAAgD,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAQhG,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,eAAO,MAAM,YAAY;YAAW,iBAAiB;;;;;;;;;;CAWpD,CAAC;AA0FF,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,4BAA4B,EACrC,KAAK,EAAE,iBAAiB,GACvB,4BAA4B,CAqC9B;AAYD,eAAe,YAAY,CAAC"}
@@ -46,6 +46,7 @@ const StackToolbarView_1 = require("./StackToolbarView");
46
46
  const context_1 = require("./context");
47
47
  const NativeMenuContext_1 = require("../../../link/NativeMenuContext");
48
48
  const native_1 = require("../../../toolbar/native");
49
+ const useNavigation_1 = require("../../../useNavigation");
49
50
  const children_1 = require("../../../utils/children");
50
51
  const Screen_1 = require("../../../views/Screen");
51
52
  const common_primitives_1 = require("../common-primitives");
@@ -108,27 +109,42 @@ const common_primitives_1 = require("../common-primitives");
108
109
  *
109
110
  * @platform ios
110
111
  */
111
- const StackToolbar = ({ children, placement = 'bottom', asChild }) => {
112
+ const StackToolbar = (props) => {
112
113
  const parentPlacement = (0, context_1.useToolbarPlacement)();
113
114
  if (parentPlacement) {
114
115
  throw new Error(`Stack.Toolbar cannot be nested inside another Stack.Toolbar.`);
115
116
  }
116
- if (placement === 'bottom') {
117
- return (<context_1.ToolbarPlacementContext.Provider value="bottom">
118
- <NativeMenuContext_1.NativeMenuContext value>
119
- <native_1.RouterToolbarHost>{children}</native_1.RouterToolbarHost>
120
- </NativeMenuContext_1.NativeMenuContext>
121
- </context_1.ToolbarPlacementContext.Provider>);
117
+ if (props.placement === 'bottom' || !props.placement) {
118
+ return <StackToolbarBottom {...props}/>;
119
+ }
120
+ return <StackToolbarHeader {...props} key={props.placement}/>;
121
+ };
122
+ exports.StackToolbar = StackToolbar;
123
+ const StackToolbarBottom = ({ children }) => {
124
+ return (<context_1.ToolbarPlacementContext.Provider value="bottom">
125
+ <NativeMenuContext_1.NativeMenuContext value>
126
+ <native_1.RouterToolbarHost>{children}</native_1.RouterToolbarHost>
127
+ </NativeMenuContext_1.NativeMenuContext>
128
+ </context_1.ToolbarPlacementContext.Provider>);
129
+ };
130
+ const StackToolbarHeader = ({ children, placement, asChild }) => {
131
+ const navigation = (0, useNavigation_1.useNavigation)();
132
+ if (placement !== 'left' && placement !== 'right') {
133
+ throw new Error(`Invalid placement "${placement}" for Stack.Toolbar. Expected "left" or "right".`);
122
134
  }
123
- // placement === 'left' or 'right'
124
- // This component will only render when used inside a page
125
- // eslint-disable-next-line react-hooks/rules-of-hooks
135
+ (0, react_1.useEffect)(() => {
136
+ return () => {
137
+ const optionKey = placement === 'right' ? 'unstable_headerRightItems' : 'unstable_headerLeftItems';
138
+ navigation.setOptions({
139
+ [optionKey]: () => [],
140
+ });
141
+ };
142
+ }, [navigation, placement]);
126
143
  const updatedOptions = (0, react_2.useMemo)(() => appendStackToolbarPropsToOptions({}, { children, placement, asChild }), [children, placement, asChild]);
127
144
  return (<context_1.ToolbarPlacementContext.Provider value={placement}>
128
145
  <Screen_1.Screen options={updatedOptions}/>
129
146
  </context_1.ToolbarPlacementContext.Provider>);
130
147
  };
131
- exports.StackToolbar = StackToolbar;
132
148
  function convertToolbarChildrenToUnstableItems(children, side) {
133
149
  const allChildren = react_1.default.Children.toArray(children);
134
150
  const actions = allChildren.filter((child) => (0, children_1.isChildOfType)(child, StackToolbarButton_1.StackToolbarButton) ||
@@ -1 +1 @@
1
- {"version":3,"file":"StackToolbarClient.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarClient.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport { NativeStackNavigationOptions } from '@react-navigation/native-stack';\nimport React, { Fragment, isValidElement, type ReactNode } from 'react';\nimport { useMemo } from 'react';\n\nimport {\n convertStackToolbarButtonPropsToRNHeaderItem,\n StackToolbarButton,\n} from './StackToolbarButton';\nimport {\n convertStackToolbarMenuPropsToRNHeaderItem,\n StackToolbarMenu,\n StackToolbarMenuAction,\n} from './StackToolbarMenu';\nimport { StackToolbarSearchBarSlot } from './StackToolbarSearchBarSlot';\nimport {\n convertStackToolbarSpacerPropsToRNHeaderItem,\n StackToolbarSpacer,\n} from './StackToolbarSpacer';\nimport { convertStackToolbarViewPropsToRNHeaderItem, StackToolbarView } from './StackToolbarView';\nimport { ToolbarPlacementContext, useToolbarPlacement, type ToolbarPlacement } from './context';\nimport { NativeMenuContext } from '../../../link/NativeMenuContext';\nimport { RouterToolbarHost } from '../../../toolbar/native';\nimport { isChildOfType } from '../../../utils/children';\nimport { Screen } from '../../../views/Screen';\nimport { StackToolbarBadge, StackToolbarIcon, StackToolbarLabel } from '../common-primitives';\n\nexport interface StackToolbarProps {\n /**\n * Child elements to compose the toolbar. Can include Stack.Toolbar.Button,\n * Stack.Toolbar.Menu, Stack.Toolbar.View, Stack.Toolbar.Spacer, and\n * Stack.Toolbar.SearchBarSlot (bottom only) components.\n */\n children?: ReactNode;\n /**\n * The placement of the toolbar.\n *\n * - `'left'`: Renders items in the left area of the header.\n * - `'right'`: Renders items in the right area of the header.\n * - `'bottom'`: Renders items in the bottom toolbar (iOS only).\n *\n * @default 'bottom'\n */\n placement?: ToolbarPlacement;\n /**\n * When `true`, renders children as a custom component in the header area,\n * replacing the default header layout.\n *\n * Only applies to `placement=\"left\"` and `placement=\"right\"`.\n *\n * @default false\n */\n asChild?: boolean;\n}\n\n/**\n * The component used to configure the stack toolbar.\n *\n * - Use `placement=\"left\"` to customize the left side of the header.\n * - Use `placement=\"right\"` to customize the right side of the header.\n * - Use `placement=\"bottom\"` (default) to show a bottom toolbar (iOS only).\n *\n * > **Note:** Using `Stack.Toolbar` with `placement=\"left\"` or `placement=\"right\"` will\n * automatically make the header visible (`headerShown: true`), as the toolbar is rendered\n * as part of the native header.\n *\n * > **Note:** `Stack.Toolbar` with `placement=\"bottom\"` can only be used inside **page**\n * components, not in layout components.\n *\n * > **Note**: Stack.Toolbar is an experimental API and may change without notice.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Layout() {\n * return (\n * <Stack>\n * <Stack.Screen name=\"index\">\n * <Stack.Toolbar placement=\"left\">\n * <Stack.Toolbar.Button icon=\"sidebar.left\" onPress={() => alert('Left button pressed!')} />\n * </Stack.Toolbar>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Button icon=\"ellipsis.circle\" onPress={() => alert('Right button pressed!')} />\n * </Stack.Toolbar>\n * </Stack.Screen>\n * </Stack>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"left\">\n * <Stack.Toolbar.Button icon=\"sidebar.left\" onPress={() => alert('Left button pressed!')} />\n * </Stack.Toolbar>\n * <Stack.Toolbar>\n * <Stack.Toolbar.Spacer />\n * <Stack.Toolbar.Button icon=\"magnifyingglass\" onPress={() => {}} />\n * <Stack.Toolbar.Spacer />\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @platform ios\n */\nexport const StackToolbar = ({ children, placement = 'bottom', asChild }: StackToolbarProps) => {\n const parentPlacement = useToolbarPlacement();\n if (parentPlacement) {\n throw new Error(`Stack.Toolbar cannot be nested inside another Stack.Toolbar.`);\n }\n\n if (placement === 'bottom') {\n return (\n <ToolbarPlacementContext.Provider value=\"bottom\">\n <NativeMenuContext value>\n <RouterToolbarHost>{children}</RouterToolbarHost>\n </NativeMenuContext>\n </ToolbarPlacementContext.Provider>\n );\n }\n\n // placement === 'left' or 'right'\n // This component will only render when used inside a page\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const updatedOptions = useMemo(\n () => appendStackToolbarPropsToOptions({}, { children, placement, asChild }),\n [children, placement, asChild]\n );\n return (\n <ToolbarPlacementContext.Provider value={placement}>\n <Screen options={updatedOptions} />\n </ToolbarPlacementContext.Provider>\n );\n};\n\nfunction convertToolbarChildrenToUnstableItems(\n children: React.ReactNode,\n side: 'left' | 'right'\n):\n | NativeStackNavigationOptions['unstable_headerRightItems']\n | NativeStackNavigationOptions['unstable_headerLeftItems'] {\n const allChildren = React.Children.toArray(children);\n const actions = allChildren.filter(\n (child) =>\n isChildOfType(child, StackToolbarButton) ||\n isChildOfType(child, StackToolbarMenu) ||\n isChildOfType(child, StackToolbarSpacer) ||\n isChildOfType(child, StackToolbarView)\n );\n if (actions.length !== allChildren.length && process.env.NODE_ENV !== 'production') {\n const otherElements = allChildren\n .filter((child) => !actions.some((action) => action === child))\n .map((e) => {\n if (isValidElement(e)) {\n if (e.type === Fragment) {\n return '<Fragment>';\n } else {\n return (e.type as { name: string })?.name ?? e.type;\n }\n }\n\n return String(e);\n });\n console.warn(\n `Stack.Toolbar with placement=\"${side}\" only accepts <Stack.Toolbar.Button>, <Stack.Toolbar.Menu>, <Stack.Toolbar.View>, and <Stack.Toolbar.Spacer> as children. Found invalid children: ${otherElements.join(', ')}`\n );\n }\n return () =>\n actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarButton)) {\n return convertStackToolbarButtonPropsToRNHeaderItem(action.props);\n } else if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarMenuPropsToRNHeaderItem(action.props);\n } else if (isChildOfType(action, StackToolbarSpacer)) {\n return convertStackToolbarSpacerPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarViewPropsToRNHeaderItem(action.props);\n })\n .filter((item) => !!item);\n}\n\nexport function appendStackToolbarPropsToOptions(\n options: NativeStackNavigationOptions,\n props: StackToolbarProps\n): NativeStackNavigationOptions {\n const { children, placement = 'bottom', asChild } = props;\n\n if (placement === 'bottom') {\n // Bottom toolbar doesn't modify navigation options\n return options;\n }\n\n if (asChild) {\n if (placement === 'left') {\n return {\n ...options,\n headerShown: true,\n headerLeft: () => children,\n };\n } else {\n return {\n ...options,\n headerShown: true,\n headerRight: () => children,\n };\n }\n }\n\n if (placement === 'left') {\n return {\n ...options,\n headerShown: true,\n unstable_headerLeftItems: convertToolbarChildrenToUnstableItems(children, 'left'),\n };\n }\n\n return {\n ...options,\n headerShown: true,\n unstable_headerRightItems: convertToolbarChildrenToUnstableItems(children, 'right'),\n };\n}\n\nStackToolbar.Button = StackToolbarButton;\nStackToolbar.Menu = StackToolbarMenu;\nStackToolbar.MenuAction = StackToolbarMenuAction;\nStackToolbar.SearchBarSlot = StackToolbarSearchBarSlot;\nStackToolbar.Spacer = StackToolbarSpacer;\nStackToolbar.View = StackToolbarView;\nStackToolbar.Label = StackToolbarLabel;\nStackToolbar.Icon = StackToolbarIcon;\nStackToolbar.Badge = StackToolbarBadge;\n\nexport default StackToolbar;\n"]}
1
+ {"version":3,"file":"StackToolbarClient.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarClient.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport { NativeStackNavigationOptions } from '@react-navigation/native-stack';\nimport React, { Fragment, isValidElement, useEffect, type ReactNode } from 'react';\nimport { useMemo } from 'react';\n\nimport {\n convertStackToolbarButtonPropsToRNHeaderItem,\n StackToolbarButton,\n} from './StackToolbarButton';\nimport {\n convertStackToolbarMenuPropsToRNHeaderItem,\n StackToolbarMenu,\n StackToolbarMenuAction,\n} from './StackToolbarMenu';\nimport { StackToolbarSearchBarSlot } from './StackToolbarSearchBarSlot';\nimport {\n convertStackToolbarSpacerPropsToRNHeaderItem,\n StackToolbarSpacer,\n} from './StackToolbarSpacer';\nimport { convertStackToolbarViewPropsToRNHeaderItem, StackToolbarView } from './StackToolbarView';\nimport { ToolbarPlacementContext, useToolbarPlacement, type ToolbarPlacement } from './context';\nimport { NativeMenuContext } from '../../../link/NativeMenuContext';\nimport { RouterToolbarHost } from '../../../toolbar/native';\nimport { useNavigation } from '../../../useNavigation';\nimport { isChildOfType } from '../../../utils/children';\nimport { Screen } from '../../../views/Screen';\nimport { StackToolbarBadge, StackToolbarIcon, StackToolbarLabel } from '../common-primitives';\n\nexport interface StackToolbarProps {\n /**\n * Child elements to compose the toolbar. Can include Stack.Toolbar.Button,\n * Stack.Toolbar.Menu, Stack.Toolbar.View, Stack.Toolbar.Spacer, and\n * Stack.Toolbar.SearchBarSlot (bottom only) components.\n */\n children?: ReactNode;\n /**\n * The placement of the toolbar.\n *\n * - `'left'`: Renders items in the left area of the header.\n * - `'right'`: Renders items in the right area of the header.\n * - `'bottom'`: Renders items in the bottom toolbar (iOS only).\n *\n * @default 'bottom'\n */\n placement?: ToolbarPlacement;\n /**\n * When `true`, renders children as a custom component in the header area,\n * replacing the default header layout.\n *\n * Only applies to `placement=\"left\"` and `placement=\"right\"`.\n *\n * @default false\n */\n asChild?: boolean;\n}\n\n/**\n * The component used to configure the stack toolbar.\n *\n * - Use `placement=\"left\"` to customize the left side of the header.\n * - Use `placement=\"right\"` to customize the right side of the header.\n * - Use `placement=\"bottom\"` (default) to show a bottom toolbar (iOS only).\n *\n * > **Note:** Using `Stack.Toolbar` with `placement=\"left\"` or `placement=\"right\"` will\n * automatically make the header visible (`headerShown: true`), as the toolbar is rendered\n * as part of the native header.\n *\n * > **Note:** `Stack.Toolbar` with `placement=\"bottom\"` can only be used inside **page**\n * components, not in layout components.\n *\n * > **Note**: Stack.Toolbar is an experimental API and may change without notice.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Layout() {\n * return (\n * <Stack>\n * <Stack.Screen name=\"index\">\n * <Stack.Toolbar placement=\"left\">\n * <Stack.Toolbar.Button icon=\"sidebar.left\" onPress={() => alert('Left button pressed!')} />\n * </Stack.Toolbar>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Button icon=\"ellipsis.circle\" onPress={() => alert('Right button pressed!')} />\n * </Stack.Toolbar>\n * </Stack.Screen>\n * </Stack>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"left\">\n * <Stack.Toolbar.Button icon=\"sidebar.left\" onPress={() => alert('Left button pressed!')} />\n * </Stack.Toolbar>\n * <Stack.Toolbar>\n * <Stack.Toolbar.Spacer />\n * <Stack.Toolbar.Button icon=\"magnifyingglass\" onPress={() => {}} />\n * <Stack.Toolbar.Spacer />\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @platform ios\n */\nexport const StackToolbar = (props: StackToolbarProps) => {\n const parentPlacement = useToolbarPlacement();\n if (parentPlacement) {\n throw new Error(`Stack.Toolbar cannot be nested inside another Stack.Toolbar.`);\n }\n\n if (props.placement === 'bottom' || !props.placement) {\n return <StackToolbarBottom {...props} />;\n }\n\n return <StackToolbarHeader {...props} key={props.placement} />;\n};\n\nconst StackToolbarBottom = ({ children }: StackToolbarProps) => {\n return (\n <ToolbarPlacementContext.Provider value=\"bottom\">\n <NativeMenuContext value>\n <RouterToolbarHost>{children}</RouterToolbarHost>\n </NativeMenuContext>\n </ToolbarPlacementContext.Provider>\n );\n};\n\nconst StackToolbarHeader = ({ children, placement, asChild }: StackToolbarProps) => {\n const navigation = useNavigation();\n\n if (placement !== 'left' && placement !== 'right') {\n throw new Error(\n `Invalid placement \"${placement}\" for Stack.Toolbar. Expected \"left\" or \"right\".`\n );\n }\n\n useEffect(() => {\n return () => {\n const optionKey =\n placement === 'right' ? 'unstable_headerRightItems' : 'unstable_headerLeftItems';\n navigation.setOptions({\n [optionKey]: () => [],\n } as NativeStackNavigationOptions);\n };\n }, [navigation, placement]);\n\n const updatedOptions = useMemo(\n () => appendStackToolbarPropsToOptions({}, { children, placement, asChild }),\n [children, placement, asChild]\n );\n\n return (\n <ToolbarPlacementContext.Provider value={placement}>\n <Screen options={updatedOptions} />\n </ToolbarPlacementContext.Provider>\n );\n};\n\nfunction convertToolbarChildrenToUnstableItems(\n children: React.ReactNode,\n side: 'left' | 'right'\n):\n | NativeStackNavigationOptions['unstable_headerRightItems']\n | NativeStackNavigationOptions['unstable_headerLeftItems'] {\n const allChildren = React.Children.toArray(children);\n const actions = allChildren.filter(\n (child) =>\n isChildOfType(child, StackToolbarButton) ||\n isChildOfType(child, StackToolbarMenu) ||\n isChildOfType(child, StackToolbarSpacer) ||\n isChildOfType(child, StackToolbarView)\n );\n if (actions.length !== allChildren.length && process.env.NODE_ENV !== 'production') {\n const otherElements = allChildren\n .filter((child) => !actions.some((action) => action === child))\n .map((e) => {\n if (isValidElement(e)) {\n if (e.type === Fragment) {\n return '<Fragment>';\n } else {\n return (e.type as { name: string })?.name ?? e.type;\n }\n }\n\n return String(e);\n });\n console.warn(\n `Stack.Toolbar with placement=\"${side}\" only accepts <Stack.Toolbar.Button>, <Stack.Toolbar.Menu>, <Stack.Toolbar.View>, and <Stack.Toolbar.Spacer> as children. Found invalid children: ${otherElements.join(', ')}`\n );\n }\n return () =>\n actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarButton)) {\n return convertStackToolbarButtonPropsToRNHeaderItem(action.props);\n } else if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarMenuPropsToRNHeaderItem(action.props);\n } else if (isChildOfType(action, StackToolbarSpacer)) {\n return convertStackToolbarSpacerPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarViewPropsToRNHeaderItem(action.props);\n })\n .filter((item) => !!item);\n}\n\nexport function appendStackToolbarPropsToOptions(\n options: NativeStackNavigationOptions,\n props: StackToolbarProps\n): NativeStackNavigationOptions {\n const { children, placement = 'bottom', asChild } = props;\n\n if (placement === 'bottom') {\n // Bottom toolbar doesn't modify navigation options\n return options;\n }\n\n if (asChild) {\n if (placement === 'left') {\n return {\n ...options,\n headerShown: true,\n headerLeft: () => children,\n };\n } else {\n return {\n ...options,\n headerShown: true,\n headerRight: () => children,\n };\n }\n }\n\n if (placement === 'left') {\n return {\n ...options,\n headerShown: true,\n unstable_headerLeftItems: convertToolbarChildrenToUnstableItems(children, 'left'),\n };\n }\n\n return {\n ...options,\n headerShown: true,\n unstable_headerRightItems: convertToolbarChildrenToUnstableItems(children, 'right'),\n };\n}\n\nStackToolbar.Button = StackToolbarButton;\nStackToolbar.Menu = StackToolbarMenu;\nStackToolbar.MenuAction = StackToolbarMenuAction;\nStackToolbar.SearchBarSlot = StackToolbarSearchBarSlot;\nStackToolbar.Spacer = StackToolbarSpacer;\nStackToolbar.View = StackToolbarView;\nStackToolbar.Label = StackToolbarLabel;\nStackToolbar.Icon = StackToolbarIcon;\nStackToolbar.Badge = StackToolbarBadge;\n\nexport default StackToolbar;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"StackToolbarMenu.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,yBAAyB,EACzB,+BAA+B,EAEhC,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAMtD,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAC1C;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,KAAK,CAAC,EAAE,0BAA0B,CAAC,OAAO,CAAC,CAAC;IAC5C;;;;OAIG;IACH,SAAS,CAAC,EAAE,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACpD;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,OAAO,CAAC,EAAE,0BAA0B,CAAC,SAAS,CAAC,CAAC;IAEhD;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;CACrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA+B5D,CAAC;AAEF,wBAAgB,0CAA0C,CACxD,KAAK,EAAE,qBAAqB,GAC3B,yBAAyB,GAAG,SAAS,CA6BvC;AAsDD,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,GAAG,mBAAmB,CAAC;IAEtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAUxE,CAAC;AAEF,wBAAgB,gDAAgD,CAC9D,KAAK,EAAE,2BAA2B,GACjC,+BAA+B,CAyBjC"}
1
+ {"version":3,"file":"StackToolbarMenu.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,yBAAyB,EACzB,+BAA+B,EAEhC,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAWtD,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,WAAW,CAAC;AAqBnB,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAC1C;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,KAAK,CAAC,EAAE,0BAA0B,CAAC,OAAO,CAAC,CAAC;IAC5C;;;;OAIG;IACH,SAAS,CAAC,EAAE,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACpD;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,OAAO,CAAC,EAAE,0BAA0B,CAAC,SAAS,CAAC,CAAC;IAEhD;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;CACrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAkD5D,CAAC;AAEF,wBAAgB,0CAA0C,CACxD,KAAK,EAAE,qBAAqB,GAC3B,yBAAyB,GAAG,SAAS,CAsCvC;AAsDD,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,GAAG,mBAAmB,CAAC;IAEtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAUxE,CAAC;AAEF,wBAAgB,gDAAgD,CAC9D,KAAK,EAAE,2BAA2B,GACjC,+BAA+B,CAyBjC"}
@@ -9,7 +9,23 @@ const bottom_toolbar_native_elements_1 = require("./bottom-toolbar-native-elemen
9
9
  const context_1 = require("./context");
10
10
  const menu_1 = require("../../../primitives/menu");
11
11
  const children_1 = require("../../../utils/children");
12
+ const common_primitives_1 = require("../common-primitives");
12
13
  const shared_1 = require("../shared");
14
+ /**
15
+ * Computes the label and menu title from children and title prop.
16
+ *
17
+ * - If only `title` prop is provided, it is used for both the label (button text) and menu title
18
+ * - If only `.Label` child is provided, it is used for the label and the menu title is an empty string
19
+ * - If both `.Label` child and `title` prop are provided. `.Label` is used for the label, and `title` is used for the menu title
20
+ */
21
+ function computeMenuLabelAndTitle(children, title) {
22
+ const labelChild = (0, children_1.getFirstChildOfType)(children, common_primitives_1.StackToolbarLabel);
23
+ const labelFromChild = labelChild?.props.children;
24
+ return {
25
+ label: labelFromChild ?? title ?? '',
26
+ menuTitle: title ?? '',
27
+ };
28
+ }
13
29
  /**
14
30
  * Use as `Stack.Toolbar.Menu` to provide menus in iOS toolbar.
15
31
  * It accepts `Stack.Toolbar.MenuAction` and nested `Stack.Toolbar.Menu`
@@ -43,21 +59,29 @@ const shared_1 = require("../shared");
43
59
  */
44
60
  const StackToolbarMenu = ({ children, ...props }) => {
45
61
  const placement = (0, context_1.useToolbarPlacement)();
46
- const allowedChildren = (0, react_1.useMemo)(() => placement === 'bottom'
47
- ? [exports.StackToolbarMenu, exports.StackToolbarMenuAction, bottom_toolbar_native_elements_1.NativeToolbarMenu, bottom_toolbar_native_elements_1.NativeToolbarMenuAction]
48
- : [exports.StackToolbarMenu, exports.StackToolbarMenuAction], [placement]);
62
+ if (placement !== 'bottom') {
63
+ // For placement other than bottom, this component will not render, and should be
64
+ // converted to RN header item using convertStackToolbarMenuPropsToRNHeaderItem.
65
+ // So if we reach here, it means we're not inside a toolbar or something else is wrong.
66
+ throw new Error('Stack.Toolbar.Menu must be used inside a Stack.Toolbar');
67
+ }
68
+ const allowedChildren = (0, react_1.useMemo)(() => [
69
+ exports.StackToolbarMenu,
70
+ exports.StackToolbarMenuAction,
71
+ bottom_toolbar_native_elements_1.NativeToolbarMenu,
72
+ bottom_toolbar_native_elements_1.NativeToolbarMenuAction,
73
+ common_primitives_1.StackToolbarLabel,
74
+ ], [placement]);
49
75
  const validChildren = (0, react_1.useMemo)(() => (0, children_1.filterAllowedChildrenElements)(children, allowedChildren), [children, allowedChildren]);
76
+ const { label: computedLabel, menuTitle: computedMenuTitle } = computeMenuLabelAndTitle(children, props.title);
50
77
  if (process.env.NODE_ENV !== 'production') {
51
78
  const allChildren = react_1.Children.toArray(children);
52
79
  if (allChildren.length !== validChildren.length) {
53
80
  throw new Error(`Stack.Toolbar.Menu only accepts Stack.Toolbar.Menu and Stack.Toolbar.MenuAction as its children.`);
54
81
  }
55
82
  }
56
- if (placement === 'bottom') {
57
- // TODO(@ubax): Handle image loading using useImage in a follow-up PR.
58
- return <bottom_toolbar_native_elements_1.NativeToolbarMenu {...props} image={props.image} children={validChildren}/>;
59
- }
60
- return <menu_1.Menu {...props} children={validChildren}/>;
83
+ // TODO(@ubax): Handle image loading using useImage in a follow-up PR.
84
+ return (<bottom_toolbar_native_elements_1.NativeToolbarMenu {...props} image={props.image} label={computedLabel} title={computedMenuTitle} children={validChildren}/>);
61
85
  };
62
86
  exports.StackToolbarMenu = StackToolbarMenu;
63
87
  function convertStackToolbarMenuPropsToRNHeaderItem(props) {
@@ -66,8 +90,11 @@ function convertStackToolbarMenuPropsToRNHeaderItem(props) {
66
90
  }
67
91
  const { title, ...rest } = props;
68
92
  const actions = react_1.Children.toArray(props.children).filter((child) => (0, children_1.isChildOfType)(child, exports.StackToolbarMenuAction) || (0, children_1.isChildOfType)(child, exports.StackToolbarMenu));
93
+ const { label: computedLabel, menuTitle: computedMenuTitle } = computeMenuLabelAndTitle(props.children, title);
94
+ const sharedProps = (0, shared_1.convertStackHeaderSharedPropsToRNSharedHeaderItem)(rest);
69
95
  const item = {
70
- ...(0, shared_1.convertStackHeaderSharedPropsToRNSharedHeaderItem)(rest),
96
+ ...sharedProps,
97
+ label: computedLabel,
71
98
  type: 'menu',
72
99
  menu: {
73
100
  multiselectable: true,
@@ -81,8 +108,8 @@ function convertStackToolbarMenuPropsToRNHeaderItem(props) {
81
108
  .filter((i) => !!i),
82
109
  },
83
110
  };
84
- if (title) {
85
- item.menu.title = title;
111
+ if (computedMenuTitle) {
112
+ item.menu.title = computedMenuTitle;
86
113
  }
87
114
  return item;
88
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"StackToolbarMenu.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport type {\n NativeStackHeaderItemMenu,\n NativeStackHeaderItemMenuAction,\n NativeStackHeaderItemMenuSubmenu,\n} from '@react-navigation/native-stack';\nimport type { ImageRef } from 'expo-image';\nimport { Children, useMemo, type ReactNode } from 'react';\nimport type { ImageSourcePropType } from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport { NativeToolbarMenu, NativeToolbarMenuAction } from './bottom-toolbar-native-elements';\nimport { useToolbarPlacement } from './context';\nimport { Menu, MenuAction } from '../../../primitives/menu';\nimport { filterAllowedChildrenElements, isChildOfType } from '../../../utils/children';\nimport {\n convertStackHeaderSharedPropsToRNSharedHeaderItem,\n type StackHeaderItemSharedProps,\n} from '../shared';\n\nexport interface StackToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n /**\n * Menu content - can include icons, labels, badges and menu actions.\n *\n * @example\n * ```tsx\n * <Stack.Toolbar.Menu>\n * <Stack.Toolbar.Icon sfSymbol=\"ellipsis.circle\" />\n * <Stack.Toolbar.Label>Options</Stack.Toolbar.Label>\n * <Stack.Toolbar.MenuAction onPress={() => {}}>Action 1</Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * ```\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n disabled?: boolean;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n *\n * > **Note**: This prop is only supported in toolbar with `placement=\"bottom\"`.\n */\n image?: ImageRef;\n /**\n * Whether to hide the shared background.\n *\n * @see [Official Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/hidessharedbackground) for more information.\n *\n * @platform iOS 26+\n */\n hidesSharedBackground?: boolean;\n /**\n * Whether the menu should be hidden.\n *\n * @default false\n */\n hidden?: boolean;\n /**\n * Icon for the menu item.\n *\n * Can be an SF Symbol name or an image source.\n *\n * > **Note**: When used in `placement=\"bottom\"`, only string SFSymbols are supported. Use the `image` prop to provide custom images.\n */\n icon?: StackHeaderItemSharedProps['icon'];\n /**\n * If `true`, the menu will be displayed inline.\n * This means that the menu will not be collapsed\n *\n * > **Note**: Inline menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayinline) for more information.\n */\n inline?: boolean;\n /**\n * If `true`, the menu will be displayed as a palette.\n * This means that the menu will be displayed as one row\n *\n * > **Note**: Palette menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayaspalette) for more information.\n */\n palette?: boolean;\n /**\n * Whether to separate the background of this item from other header items.\n *\n * @default false\n */\n separateBackground?: boolean;\n /**\n * Style for the label of the header item.\n */\n style?: StackHeaderItemSharedProps['style'];\n /**\n * The tint color to apply to the button item\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/tintcolor) for more information.\n */\n tintColor?: StackHeaderItemSharedProps['tintColor'];\n /**\n * Optional title to show on top of the menu.\n */\n title?: string;\n /**\n * @default 'plain'\n */\n variant?: StackHeaderItemSharedProps['variant'];\n // TODO(@ubax): Add elementSize support in react-native-screens for header menus.\n /**\n * The preferred size of the menu elements.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/preferredelementsize) for more information.\n *\n * @platform iOS 16.0+\n */\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Use as `Stack.Toolbar.Menu` to provide menus in iOS toolbar.\n * It accepts `Stack.Toolbar.MenuAction` and nested `Stack.Toolbar.Menu`\n * elements. Menu can be configured using both component props and child\n * elements.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n * import { Alert } from 'react-native';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Menu icon=\"ellipsis.circle\">\n * <Stack.Toolbar.MenuAction onPress={() => Alert.alert('Action pressed!')}>\n * Action 1\n * </Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @see [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/menus) for more information about menus on iOS.\n *\n * @platform ios\n */\nexport const StackToolbarMenu: React.FC<StackToolbarMenuProps> = ({ children, ...props }) => {\n const placement = useToolbarPlacement();\n\n const allowedChildren = useMemo(\n () =>\n placement === 'bottom'\n ? [StackToolbarMenu, StackToolbarMenuAction, NativeToolbarMenu, NativeToolbarMenuAction]\n : [StackToolbarMenu, StackToolbarMenuAction],\n [placement]\n );\n\n const validChildren = useMemo(\n () => filterAllowedChildrenElements(children, allowedChildren),\n [children, allowedChildren]\n );\n\n if (process.env.NODE_ENV !== 'production') {\n const allChildren = Children.toArray(children);\n if (allChildren.length !== validChildren.length) {\n throw new Error(\n `Stack.Toolbar.Menu only accepts Stack.Toolbar.Menu and Stack.Toolbar.MenuAction as its children.`\n );\n }\n }\n\n if (placement === 'bottom') {\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n return <NativeToolbarMenu {...props} image={props.image} children={validChildren} />;\n }\n\n return <Menu {...props} children={validChildren} />;\n};\n\nexport function convertStackToolbarMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps\n): NativeStackHeaderItemMenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const { title, ...rest } = props;\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n const item: NativeStackHeaderItemMenu = {\n ...convertStackHeaderSharedPropsToRNSharedHeaderItem(rest),\n type: 'menu',\n menu: {\n multiselectable: true,\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n },\n };\n if (title) {\n item.menu.title = title;\n }\n\n return item;\n}\n\nfunction convertStackToolbarSubmenuMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps\n): NativeStackHeaderItemMenuSubmenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n\n const item: NativeStackHeaderItemMenuSubmenu = {\n type: 'submenu',\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n label: sharedProps.label || props.title || '',\n multiselectable: true,\n };\n\n if (props.inline !== undefined) {\n item.inline = props.inline;\n }\n if (props.palette !== undefined) {\n item.layout = props.palette ? 'palette' : 'default';\n }\n if (props.destructive !== undefined) {\n item.destructive = props.destructive;\n }\n // TODO: Add elementSize to react-native-screens\n\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n // TODO(@ubax): Add support for other images in react-native-screens\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Toolbar.Menu used as a submenu, only sfSymbol icons are supported. This is a limitation of React Native Screens.'\n );\n }\n }\n\n return item;\n}\n\nexport interface StackToolbarMenuActionProps {\n /**\n * Can be an Icon, Label or string title.\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be disabled and not selectable.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/disabled) for more information.\n */\n disabled?: boolean;\n icon?: SFSymbol | ImageSourcePropType;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu action.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n */\n image?: ImageRef;\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n /**\n * If `true`, the menu will be kept presented after the action is selected.\n *\n * This is marked as unstable, because when action is selected it will recreate the menu,\n * which will close all opened submenus and reset the scroll position.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/keepsmenupresented) for more information.\n */\n unstable_keepPresented?: boolean;\n /**\n * If `true`, the menu item will be displayed as selected.\n */\n isOn?: boolean;\n onPress?: () => void;\n /**\n * An elaborated title that explains the purpose of the action.\n */\n discoverabilityLabel?: string;\n /**\n * An optional subtitle for the menu item.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/subtitle) for more information.\n */\n subtitle?: string;\n hidden?: boolean;\n}\n\n/**\n * An action item for a `Stack.Toolbar.Menu`.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Menu icon=\"ellipsis.circle\">\n * <Stack.Toolbar.MenuAction onPress={() => alert('Action pressed!')}>\n * Action 1\n * </Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @platform ios\n */\nexport const StackToolbarMenuAction: React.FC<StackToolbarMenuActionProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if (placement === 'bottom') {\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n const icon = typeof props.icon === 'string' ? props.icon : undefined;\n return <NativeToolbarMenuAction {...props} icon={icon} image={props.image} />;\n }\n\n return <MenuAction {...props} />;\n};\n\nexport function convertStackToolbarMenuActionPropsToRNHeaderItem(\n props: StackToolbarMenuActionProps\n): NativeStackHeaderItemMenuAction {\n const { children, isOn, unstable_keepPresented, icon, ...rest } = props;\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const item: NativeStackHeaderItemMenuAction = {\n ...rest,\n type: 'action',\n label: sharedProps.label,\n state: isOn ? 'on' : 'off',\n onPress: props.onPress ?? (() => {}),\n };\n if (unstable_keepPresented !== undefined) {\n item.keepsMenuPresented = unstable_keepPresented;\n }\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n // TODO(@ubax): Add support for other images in react-native-screens\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Toolbar.MenuAction, only sfSymbol icons are supported. This is a limitation of React Native Screens.'\n );\n }\n }\n return item;\n}\n"]}
1
+ {"version":3,"file":"StackToolbarMenu.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport type {\n NativeStackHeaderItemMenu,\n NativeStackHeaderItemMenuAction,\n NativeStackHeaderItemMenuSubmenu,\n} from '@react-navigation/native-stack';\nimport type { ImageRef } from 'expo-image';\nimport { Children, useMemo, type ReactNode } from 'react';\nimport type { ImageSourcePropType } from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport { NativeToolbarMenu, NativeToolbarMenuAction } from './bottom-toolbar-native-elements';\nimport { useToolbarPlacement } from './context';\nimport { MenuAction } from '../../../primitives/menu';\nimport {\n filterAllowedChildrenElements,\n getFirstChildOfType,\n isChildOfType,\n} from '../../../utils/children';\nimport { StackToolbarLabel } from '../common-primitives';\nimport {\n convertStackHeaderSharedPropsToRNSharedHeaderItem,\n type StackHeaderItemSharedProps,\n} from '../shared';\n\n/**\n * Computes the label and menu title from children and title prop.\n *\n * - If only `title` prop is provided, it is used for both the label (button text) and menu title\n * - If only `.Label` child is provided, it is used for the label and the menu title is an empty string\n * - If both `.Label` child and `title` prop are provided. `.Label` is used for the label, and `title` is used for the menu title\n */\nfunction computeMenuLabelAndTitle(\n children: ReactNode,\n title: string | undefined\n): { label: string; menuTitle: string } {\n const labelChild = getFirstChildOfType(children, StackToolbarLabel);\n const labelFromChild = labelChild?.props.children;\n return {\n label: labelFromChild ?? title ?? '',\n menuTitle: title ?? '',\n };\n}\n\nexport interface StackToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n /**\n * Menu content - can include icons, labels, badges and menu actions.\n *\n * @example\n * ```tsx\n * <Stack.Toolbar.Menu>\n * <Stack.Toolbar.Icon sfSymbol=\"ellipsis.circle\" />\n * <Stack.Toolbar.Label>Options</Stack.Toolbar.Label>\n * <Stack.Toolbar.MenuAction onPress={() => {}}>Action 1</Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * ```\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n disabled?: boolean;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n *\n * > **Note**: This prop is only supported in toolbar with `placement=\"bottom\"`.\n */\n image?: ImageRef;\n /**\n * Whether to hide the shared background.\n *\n * @see [Official Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/hidessharedbackground) for more information.\n *\n * @platform iOS 26+\n */\n hidesSharedBackground?: boolean;\n /**\n * Whether the menu should be hidden.\n *\n * @default false\n */\n hidden?: boolean;\n /**\n * Icon for the menu item.\n *\n * Can be an SF Symbol name or an image source.\n *\n * > **Note**: When used in `placement=\"bottom\"`, only string SFSymbols are supported. Use the `image` prop to provide custom images.\n */\n icon?: StackHeaderItemSharedProps['icon'];\n /**\n * If `true`, the menu will be displayed inline.\n * This means that the menu will not be collapsed\n *\n * > **Note**: Inline menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayinline) for more information.\n */\n inline?: boolean;\n /**\n * If `true`, the menu will be displayed as a palette.\n * This means that the menu will be displayed as one row\n *\n * > **Note**: Palette menus are only supported in submenus.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayaspalette) for more information.\n */\n palette?: boolean;\n /**\n * Whether to separate the background of this item from other header items.\n *\n * @default false\n */\n separateBackground?: boolean;\n /**\n * Style for the label of the header item.\n */\n style?: StackHeaderItemSharedProps['style'];\n /**\n * The tint color to apply to the button item\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/tintcolor) for more information.\n */\n tintColor?: StackHeaderItemSharedProps['tintColor'];\n /**\n * Optional title to show on top of the menu.\n */\n title?: string;\n /**\n * @default 'plain'\n */\n variant?: StackHeaderItemSharedProps['variant'];\n // TODO(@ubax): Add elementSize support in react-native-screens for header menus.\n /**\n * The preferred size of the menu elements.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/preferredelementsize) for more information.\n *\n * @platform iOS 16.0+\n */\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Use as `Stack.Toolbar.Menu` to provide menus in iOS toolbar.\n * It accepts `Stack.Toolbar.MenuAction` and nested `Stack.Toolbar.Menu`\n * elements. Menu can be configured using both component props and child\n * elements.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n * import { Alert } from 'react-native';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Menu icon=\"ellipsis.circle\">\n * <Stack.Toolbar.MenuAction onPress={() => Alert.alert('Action pressed!')}>\n * Action 1\n * </Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @see [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/menus) for more information about menus on iOS.\n *\n * @platform ios\n */\nexport const StackToolbarMenu: React.FC<StackToolbarMenuProps> = ({ children, ...props }) => {\n const placement = useToolbarPlacement();\n\n if (placement !== 'bottom') {\n // For placement other than bottom, this component will not render, and should be\n // converted to RN header item using convertStackToolbarMenuPropsToRNHeaderItem.\n // So if we reach here, it means we're not inside a toolbar or something else is wrong.\n throw new Error('Stack.Toolbar.Menu must be used inside a Stack.Toolbar');\n }\n\n const allowedChildren = useMemo(\n () => [\n StackToolbarMenu,\n StackToolbarMenuAction,\n NativeToolbarMenu,\n NativeToolbarMenuAction,\n StackToolbarLabel,\n ],\n [placement]\n );\n\n const validChildren = useMemo(\n () => filterAllowedChildrenElements(children, allowedChildren),\n [children, allowedChildren]\n );\n\n const { label: computedLabel, menuTitle: computedMenuTitle } = computeMenuLabelAndTitle(\n children,\n props.title\n );\n\n if (process.env.NODE_ENV !== 'production') {\n const allChildren = Children.toArray(children);\n if (allChildren.length !== validChildren.length) {\n throw new Error(\n `Stack.Toolbar.Menu only accepts Stack.Toolbar.Menu and Stack.Toolbar.MenuAction as its children.`\n );\n }\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n return (\n <NativeToolbarMenu\n {...props}\n image={props.image}\n label={computedLabel}\n title={computedMenuTitle}\n children={validChildren}\n />\n );\n};\n\nexport function convertStackToolbarMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps\n): NativeStackHeaderItemMenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const { title, ...rest } = props;\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n\n const { label: computedLabel, menuTitle: computedMenuTitle } = computeMenuLabelAndTitle(\n props.children,\n title\n );\n\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(rest);\n\n const item: NativeStackHeaderItemMenu = {\n ...sharedProps,\n label: computedLabel,\n type: 'menu',\n menu: {\n multiselectable: true,\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n },\n };\n if (computedMenuTitle) {\n item.menu.title = computedMenuTitle;\n }\n\n return item;\n}\n\nfunction convertStackToolbarSubmenuMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps\n): NativeStackHeaderItemMenuSubmenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const actions = Children.toArray(props.children).filter(\n (child) =>\n isChildOfType(child, StackToolbarMenuAction) || isChildOfType(child, StackToolbarMenu)\n );\n\n const item: NativeStackHeaderItemMenuSubmenu = {\n type: 'submenu',\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackToolbarMenu)) {\n return convertStackToolbarSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackToolbarMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n label: sharedProps.label || props.title || '',\n multiselectable: true,\n };\n\n if (props.inline !== undefined) {\n item.inline = props.inline;\n }\n if (props.palette !== undefined) {\n item.layout = props.palette ? 'palette' : 'default';\n }\n if (props.destructive !== undefined) {\n item.destructive = props.destructive;\n }\n // TODO: Add elementSize to react-native-screens\n\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n // TODO(@ubax): Add support for other images in react-native-screens\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Toolbar.Menu used as a submenu, only sfSymbol icons are supported. This is a limitation of React Native Screens.'\n );\n }\n }\n\n return item;\n}\n\nexport interface StackToolbarMenuActionProps {\n /**\n * Can be an Icon, Label or string title.\n */\n children?: ReactNode;\n /**\n * If `true`, the menu item will be disabled and not selectable.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/disabled) for more information.\n */\n disabled?: boolean;\n icon?: SFSymbol | ImageSourcePropType;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu action.\n *\n * > **Note**: This prop is only supported in `Stack.Toolbar.Bottom`.\n */\n image?: ImageRef;\n /**\n * If `true`, the menu item will be displayed as destructive.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.\n */\n destructive?: boolean;\n /**\n * If `true`, the menu will be kept presented after the action is selected.\n *\n * This is marked as unstable, because when action is selected it will recreate the menu,\n * which will close all opened submenus and reset the scroll position.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/keepsmenupresented) for more information.\n */\n unstable_keepPresented?: boolean;\n /**\n * If `true`, the menu item will be displayed as selected.\n */\n isOn?: boolean;\n onPress?: () => void;\n /**\n * An elaborated title that explains the purpose of the action.\n */\n discoverabilityLabel?: string;\n /**\n * An optional subtitle for the menu item.\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/subtitle) for more information.\n */\n subtitle?: string;\n hidden?: boolean;\n}\n\n/**\n * An action item for a `Stack.Toolbar.Menu`.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Toolbar placement=\"right\">\n * <Stack.Toolbar.Menu icon=\"ellipsis.circle\">\n * <Stack.Toolbar.MenuAction onPress={() => alert('Action pressed!')}>\n * Action 1\n * </Stack.Toolbar.MenuAction>\n * </Stack.Toolbar.Menu>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * @platform ios\n */\nexport const StackToolbarMenuAction: React.FC<StackToolbarMenuActionProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if (placement === 'bottom') {\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n const icon = typeof props.icon === 'string' ? props.icon : undefined;\n return <NativeToolbarMenuAction {...props} icon={icon} image={props.image} />;\n }\n\n return <MenuAction {...props} />;\n};\n\nexport function convertStackToolbarMenuActionPropsToRNHeaderItem(\n props: StackToolbarMenuActionProps\n): NativeStackHeaderItemMenuAction {\n const { children, isOn, unstable_keepPresented, icon, ...rest } = props;\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const item: NativeStackHeaderItemMenuAction = {\n ...rest,\n type: 'action',\n label: sharedProps.label,\n state: isOn ? 'on' : 'off',\n onPress: props.onPress ?? (() => {}),\n };\n if (unstable_keepPresented !== undefined) {\n item.keepsMenuPresented = unstable_keepPresented;\n }\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n // TODO(@ubax): Add support for other images in react-native-screens\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Toolbar.MenuAction, only sfSymbol icons are supported. This is a limitation of React Native Screens.'\n );\n }\n }\n return item;\n}\n"]}
@@ -19,6 +19,7 @@ export interface NativeToolbarMenuProps {
19
19
  */
20
20
  image?: ImageRef;
21
21
  inline?: boolean;
22
+ label?: string;
22
23
  palette?: boolean;
23
24
  separateBackground?: boolean;
24
25
  style?: StyleProp<TextStyle>;
@@ -1 +1 @@
1
- {"version":3,"file":"bottom-toolbar-native-elements.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/bottom-toolbar-native-elements.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bottom-toolbar-native-elements.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/bottom-toolbar-native-elements.tsx"],"names":[],"mappings":"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"}
@@ -13,18 +13,16 @@ const children_1 = require("../../../utils/children");
13
13
  * Native toolbar menu component for bottom toolbar.
14
14
  * Renders as NativeLinkPreviewAction.
15
15
  */
16
- const NativeToolbarMenu = ({ accessibilityHint, accessibilityLabel, separateBackground, hidesSharedBackground, palette, inline, hidden, subtitle, title, destructive, children, icon, image, tintColor, variant, style, elementSize, }) => {
16
+ const NativeToolbarMenu = ({ accessibilityHint, accessibilityLabel, separateBackground, hidesSharedBackground, palette, inline, hidden, subtitle, title, label, destructive, children, icon, image, tintColor, variant, style, elementSize, }) => {
17
17
  const identifier = (0, react_1.useId)();
18
- const label = (0, children_1.getFirstChildOfType)(children, primitives_1.Label);
19
18
  const iconComponent = (0, children_1.getFirstChildOfType)(children, primitives_1.Icon);
20
- const computedTitle = title ?? label?.props.children ?? '';
21
19
  const computedIcon = icon ??
22
20
  (iconComponent?.props && 'sf' in iconComponent.props ? iconComponent.props.sf : undefined);
23
21
  const sf = typeof computedIcon === 'string' ? computedIcon : undefined;
24
22
  const titleStyle = react_native_1.StyleSheet.flatten(style);
25
23
  return (<native_1.NativeLinkPreviewAction sharesBackground={!separateBackground} hidesSharedBackground={hidesSharedBackground} hidden={hidden} icon={sf}
26
24
  // TODO(@ubax): Handle image loading using useImage in a follow-up PR.
27
- image={image} destructive={destructive} subtitle={subtitle} accessibilityLabel={accessibilityLabel} accessibilityHint={accessibilityHint} displayAsPalette={palette} displayInline={inline} preferredElementSize={elementSize} tintColor={tintColor} titleStyle={titleStyle} barButtonItemStyle={variant === 'done' ? 'prominent' : variant} title={computedTitle} onSelected={() => { }} children={children} identifier={identifier}/>);
25
+ image={image} destructive={destructive} subtitle={subtitle} accessibilityLabel={accessibilityLabel} accessibilityHint={accessibilityHint} displayAsPalette={palette} displayInline={inline} preferredElementSize={elementSize} tintColor={tintColor} titleStyle={titleStyle} barButtonItemStyle={variant === 'done' ? 'prominent' : variant} title={title ?? ''} label={label} onSelected={() => { }} children={children} identifier={identifier}/>);
28
26
  };
29
27
  exports.NativeToolbarMenu = NativeToolbarMenu;
30
28
  // #endregion
@@ -1 +1 @@
1
- {"version":3,"file":"bottom-toolbar-native-elements.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/bottom-toolbar-native-elements.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport type { ImageRef } from 'expo-image';\nimport { useId, type ReactNode } from 'react';\nimport {\n Platform,\n StyleSheet,\n type ColorValue,\n type ImageSourcePropType,\n type StyleProp,\n type TextStyle,\n} from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport { LinkMenuAction } from '../../../link/elements';\nimport { NativeLinkPreviewAction } from '../../../link/preview/native';\nimport { Label, Icon } from '../../../primitives';\nimport { RouterToolbarItem } from '../../../toolbar/native';\nimport { getFirstChildOfType } from '../../../utils/children';\nimport type { BasicTextStyle } from '../../../utils/font';\n\n// #region NativeToolbarMenu\n\nexport interface NativeToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n children?: ReactNode;\n subtitle?: string;\n destructive?: boolean;\n disabled?: boolean;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n icon?: SFSymbol | ImageSourcePropType;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n */\n image?: ImageRef;\n inline?: boolean;\n palette?: boolean;\n separateBackground?: boolean;\n style?: StyleProp<TextStyle>;\n title?: string;\n tintColor?: ColorValue;\n variant?: 'plain' | 'done' | 'prominent';\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Native toolbar menu component for bottom toolbar.\n * Renders as NativeLinkPreviewAction.\n */\nexport const NativeToolbarMenu: React.FC<NativeToolbarMenuProps> = ({\n accessibilityHint,\n accessibilityLabel,\n separateBackground,\n hidesSharedBackground,\n palette,\n inline,\n hidden,\n subtitle,\n title,\n destructive,\n children,\n icon,\n image,\n tintColor,\n variant,\n style,\n elementSize,\n}) => {\n const identifier = useId();\n const label = getFirstChildOfType(children, Label);\n const iconComponent = getFirstChildOfType(children, Icon);\n\n const computedTitle = title ?? label?.props.children ?? '';\n const computedIcon =\n icon ??\n (iconComponent?.props && 'sf' in iconComponent.props ? iconComponent.props.sf : undefined);\n const sf = typeof computedIcon === 'string' ? computedIcon : undefined;\n const titleStyle = StyleSheet.flatten(style);\n return (\n <NativeLinkPreviewAction\n sharesBackground={!separateBackground}\n hidesSharedBackground={hidesSharedBackground}\n hidden={hidden}\n icon={sf}\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n image={image}\n destructive={destructive}\n subtitle={subtitle}\n accessibilityLabel={accessibilityLabel}\n accessibilityHint={accessibilityHint}\n displayAsPalette={palette}\n displayInline={inline}\n preferredElementSize={elementSize}\n tintColor={tintColor}\n titleStyle={titleStyle}\n barButtonItemStyle={variant === 'done' ? 'prominent' : variant}\n title={computedTitle}\n onSelected={() => {}}\n children={children}\n identifier={identifier}\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarMenuAction\n\n/**\n * Native toolbar menu action - reuses LinkMenuAction.\n */\nexport const NativeToolbarMenuAction = LinkMenuAction;\n\n// #endregion\n\n// #region NativeToolbarButton\n\nexport interface NativeToolbarButtonProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n children?: ReactNode;\n disabled?: boolean;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n icon?: SFSymbol;\n image?: ImageRef;\n onPress?: () => void;\n possibleTitles?: string[];\n selected?: boolean;\n separateBackground?: boolean;\n style?: StyleProp<BasicTextStyle>;\n tintColor?: ColorValue;\n variant?: 'plain' | 'done' | 'prominent';\n}\n\n/**\n * Native toolbar button component for bottom toolbar.\n * Renders as RouterToolbarItem.\n */\nexport const NativeToolbarButton: React.FC<NativeToolbarButtonProps> = (props) => {\n const id = useId();\n const areChildrenString = typeof props.children === 'string';\n const label = areChildrenString\n ? (props.children as string)\n : getFirstChildOfType(props.children, Label)?.props.children;\n const iconComponent =\n !props.icon && !areChildrenString ? getFirstChildOfType(props.children, Icon) : undefined;\n const icon =\n props.icon ??\n (iconComponent?.props && 'sf' in iconComponent.props ? iconComponent.props.sf : undefined);\n const sf = typeof icon === 'string' ? icon : undefined;\n return (\n <RouterToolbarItem\n accessibilityHint={props.accessibilityHint}\n accessibilityLabel={props.accessibilityLabel}\n barButtonItemStyle={props.variant === 'done' ? 'prominent' : props.variant}\n disabled={props.disabled}\n hidden={props.hidden}\n hidesSharedBackground={props.hidesSharedBackground}\n identifier={id}\n image={props.image}\n onSelected={props.onPress}\n possibleTitles={props.possibleTitles}\n selected={props.selected}\n sharesBackground={!props.separateBackground}\n systemImageName={sf}\n title={label}\n tintColor={props.tintColor}\n titleStyle={StyleSheet.flatten(props.style)}\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarSpacer\n\nexport interface NativeToolbarSpacerProps {\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n sharesBackground?: boolean;\n width?: number;\n}\n\n/**\n * Native toolbar spacer component for bottom toolbar.\n * Renders as RouterToolbarItem with type 'fixedSpacer' or 'fluidSpacer'.\n */\nexport const NativeToolbarSpacer: React.FC<NativeToolbarSpacerProps> = (props) => {\n const id = useId();\n return (\n <RouterToolbarItem\n hidesSharedBackground={props.hidesSharedBackground}\n hidden={props.hidden}\n identifier={id}\n sharesBackground={props.sharesBackground}\n type={props.width ? 'fixedSpacer' : 'fluidSpacer'}\n width={props.width}\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarSearchBarSlot\n\nexport interface NativeToolbarSearchBarSlotProps {\n hidesSharedBackground?: boolean;\n hidden?: boolean;\n sharesBackground?: boolean;\n}\n\n/**\n * Native toolbar search bar slot for bottom toolbar (iOS 26+).\n * Renders as RouterToolbarItem with type 'searchBar'.\n */\nexport const NativeToolbarSearchBarSlot: React.FC<NativeToolbarSearchBarSlotProps> = ({\n hidesSharedBackground,\n hidden,\n sharesBackground,\n}) => {\n const id = useId();\n if (process.env.EXPO_OS !== 'ios' || parseInt(String(Platform.Version).split('.')[0], 10) < 26) {\n return null;\n }\n if (hidden) {\n return null;\n }\n return (\n <RouterToolbarItem\n hidesSharedBackground={hidesSharedBackground}\n identifier={id}\n sharesBackground={sharesBackground}\n type=\"searchBar\"\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarView\n\nexport interface NativeToolbarViewProps {\n children?: ReactNode;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n separateBackground?: boolean;\n}\n\n/**\n * Native toolbar view component for bottom toolbar.\n * Renders as RouterToolbarItem with children.\n */\nexport const NativeToolbarView: React.FC<NativeToolbarViewProps> = ({\n children,\n hidden,\n hidesSharedBackground,\n separateBackground,\n}) => {\n const id = useId();\n return (\n <RouterToolbarItem\n hidesSharedBackground={hidesSharedBackground}\n hidden={hidden}\n identifier={id}\n sharesBackground={!separateBackground}>\n {children}\n </RouterToolbarItem>\n );\n};\n\n// #endregion\n"]}
1
+ {"version":3,"file":"bottom-toolbar-native-elements.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/bottom-toolbar-native-elements.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport type { ImageRef } from 'expo-image';\nimport { useId, type ReactNode } from 'react';\nimport {\n Platform,\n StyleSheet,\n type ColorValue,\n type ImageSourcePropType,\n type StyleProp,\n type TextStyle,\n} from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport { LinkMenuAction } from '../../../link/elements';\nimport { NativeLinkPreviewAction } from '../../../link/preview/native';\nimport { Label, Icon } from '../../../primitives';\nimport { RouterToolbarItem } from '../../../toolbar/native';\nimport { getFirstChildOfType } from '../../../utils/children';\nimport type { BasicTextStyle } from '../../../utils/font';\n\n// #region NativeToolbarMenu\n\nexport interface NativeToolbarMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n children?: ReactNode;\n subtitle?: string;\n destructive?: boolean;\n disabled?: boolean;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n icon?: SFSymbol | ImageSourcePropType;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n */\n image?: ImageRef;\n inline?: boolean;\n label?: string;\n palette?: boolean;\n separateBackground?: boolean;\n style?: StyleProp<TextStyle>;\n title?: string;\n tintColor?: ColorValue;\n variant?: 'plain' | 'done' | 'prominent';\n elementSize?: 'auto' | 'small' | 'medium' | 'large';\n}\n\n/**\n * Native toolbar menu component for bottom toolbar.\n * Renders as NativeLinkPreviewAction.\n */\nexport const NativeToolbarMenu: React.FC<NativeToolbarMenuProps> = ({\n accessibilityHint,\n accessibilityLabel,\n separateBackground,\n hidesSharedBackground,\n palette,\n inline,\n hidden,\n subtitle,\n title,\n label,\n destructive,\n children,\n icon,\n image,\n tintColor,\n variant,\n style,\n elementSize,\n}) => {\n const identifier = useId();\n const iconComponent = getFirstChildOfType(children, Icon);\n\n const computedIcon =\n icon ??\n (iconComponent?.props && 'sf' in iconComponent.props ? iconComponent.props.sf : undefined);\n const sf = typeof computedIcon === 'string' ? computedIcon : undefined;\n const titleStyle = StyleSheet.flatten(style);\n return (\n <NativeLinkPreviewAction\n sharesBackground={!separateBackground}\n hidesSharedBackground={hidesSharedBackground}\n hidden={hidden}\n icon={sf}\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n image={image}\n destructive={destructive}\n subtitle={subtitle}\n accessibilityLabel={accessibilityLabel}\n accessibilityHint={accessibilityHint}\n displayAsPalette={palette}\n displayInline={inline}\n preferredElementSize={elementSize}\n tintColor={tintColor}\n titleStyle={titleStyle}\n barButtonItemStyle={variant === 'done' ? 'prominent' : variant}\n title={title ?? ''}\n label={label}\n onSelected={() => {}}\n children={children}\n identifier={identifier}\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarMenuAction\n\n/**\n * Native toolbar menu action - reuses LinkMenuAction.\n */\nexport const NativeToolbarMenuAction = LinkMenuAction;\n\n// #endregion\n\n// #region NativeToolbarButton\n\nexport interface NativeToolbarButtonProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n children?: ReactNode;\n disabled?: boolean;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n icon?: SFSymbol;\n image?: ImageRef;\n onPress?: () => void;\n possibleTitles?: string[];\n selected?: boolean;\n separateBackground?: boolean;\n style?: StyleProp<BasicTextStyle>;\n tintColor?: ColorValue;\n variant?: 'plain' | 'done' | 'prominent';\n}\n\n/**\n * Native toolbar button component for bottom toolbar.\n * Renders as RouterToolbarItem.\n */\nexport const NativeToolbarButton: React.FC<NativeToolbarButtonProps> = (props) => {\n const id = useId();\n const areChildrenString = typeof props.children === 'string';\n const label = areChildrenString\n ? (props.children as string)\n : getFirstChildOfType(props.children, Label)?.props.children;\n const iconComponent =\n !props.icon && !areChildrenString ? getFirstChildOfType(props.children, Icon) : undefined;\n const icon =\n props.icon ??\n (iconComponent?.props && 'sf' in iconComponent.props ? iconComponent.props.sf : undefined);\n const sf = typeof icon === 'string' ? icon : undefined;\n return (\n <RouterToolbarItem\n accessibilityHint={props.accessibilityHint}\n accessibilityLabel={props.accessibilityLabel}\n barButtonItemStyle={props.variant === 'done' ? 'prominent' : props.variant}\n disabled={props.disabled}\n hidden={props.hidden}\n hidesSharedBackground={props.hidesSharedBackground}\n identifier={id}\n image={props.image}\n onSelected={props.onPress}\n possibleTitles={props.possibleTitles}\n selected={props.selected}\n sharesBackground={!props.separateBackground}\n systemImageName={sf}\n title={label}\n tintColor={props.tintColor}\n titleStyle={StyleSheet.flatten(props.style)}\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarSpacer\n\nexport interface NativeToolbarSpacerProps {\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n sharesBackground?: boolean;\n width?: number;\n}\n\n/**\n * Native toolbar spacer component for bottom toolbar.\n * Renders as RouterToolbarItem with type 'fixedSpacer' or 'fluidSpacer'.\n */\nexport const NativeToolbarSpacer: React.FC<NativeToolbarSpacerProps> = (props) => {\n const id = useId();\n return (\n <RouterToolbarItem\n hidesSharedBackground={props.hidesSharedBackground}\n hidden={props.hidden}\n identifier={id}\n sharesBackground={props.sharesBackground}\n type={props.width ? 'fixedSpacer' : 'fluidSpacer'}\n width={props.width}\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarSearchBarSlot\n\nexport interface NativeToolbarSearchBarSlotProps {\n hidesSharedBackground?: boolean;\n hidden?: boolean;\n sharesBackground?: boolean;\n}\n\n/**\n * Native toolbar search bar slot for bottom toolbar (iOS 26+).\n * Renders as RouterToolbarItem with type 'searchBar'.\n */\nexport const NativeToolbarSearchBarSlot: React.FC<NativeToolbarSearchBarSlotProps> = ({\n hidesSharedBackground,\n hidden,\n sharesBackground,\n}) => {\n const id = useId();\n if (process.env.EXPO_OS !== 'ios' || parseInt(String(Platform.Version).split('.')[0], 10) < 26) {\n return null;\n }\n if (hidden) {\n return null;\n }\n return (\n <RouterToolbarItem\n hidesSharedBackground={hidesSharedBackground}\n identifier={id}\n sharesBackground={sharesBackground}\n type=\"searchBar\"\n />\n );\n};\n\n// #endregion\n\n// #region NativeToolbarView\n\nexport interface NativeToolbarViewProps {\n children?: ReactNode;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n separateBackground?: boolean;\n}\n\n/**\n * Native toolbar view component for bottom toolbar.\n * Renders as RouterToolbarItem with children.\n */\nexport const NativeToolbarView: React.FC<NativeToolbarViewProps> = ({\n children,\n hidden,\n hidesSharedBackground,\n separateBackground,\n}) => {\n const id = useId();\n return (\n <RouterToolbarItem\n hidesSharedBackground={hidesSharedBackground}\n hidden={hidden}\n identifier={id}\n sharesBackground={!separateBackground}>\n {children}\n </RouterToolbarItem>\n );\n};\n\n// #endregion\n"]}
@@ -5,6 +5,7 @@ import type { BasicTextStyle } from '../../utils/font';
5
5
  export interface NativeLinkPreviewActionProps {
6
6
  identifier: string;
7
7
  title: string;
8
+ label?: string;
8
9
  icon?: string;
9
10
  image?: ImageRef | null;
10
11
  children?: React.ReactNode;