expo-router 7.0.0-canary-20251216-6e1f9a7 → 7.0.0-canary-20251223-b83b31e

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 (129) hide show
  1. package/android/build.gradle +2 -2
  2. package/build/color/index.d.ts +44 -0
  3. package/build/color/index.d.ts.map +1 -1
  4. package/build/color/index.js +69 -5
  5. package/build/color/index.js.map +1 -1
  6. package/build/exports.d.ts +1 -0
  7. package/build/exports.d.ts.map +1 -1
  8. package/build/exports.js +3 -1
  9. package/build/exports.js.map +1 -1
  10. package/build/layouts/StackClient.d.ts +3 -3
  11. package/build/layouts/stack-utils/StackHeaderButton.d.ts +77 -2
  12. package/build/layouts/stack-utils/StackHeaderButton.d.ts.map +1 -1
  13. package/build/layouts/stack-utils/StackHeaderButton.js +3 -0
  14. package/build/layouts/stack-utils/StackHeaderButton.js.map +1 -1
  15. package/build/layouts/stack-utils/StackHeaderComponent.d.ts +84 -1
  16. package/build/layouts/stack-utils/StackHeaderComponent.d.ts.map +1 -1
  17. package/build/layouts/stack-utils/StackHeaderComponent.js +54 -1
  18. package/build/layouts/stack-utils/StackHeaderComponent.js.map +1 -1
  19. package/build/layouts/stack-utils/StackHeaderLeftRight.d.ts +107 -3
  20. package/build/layouts/stack-utils/StackHeaderLeftRight.d.ts.map +1 -1
  21. package/build/layouts/stack-utils/StackHeaderLeftRight.js +108 -13
  22. package/build/layouts/stack-utils/StackHeaderLeftRight.js.map +1 -1
  23. package/build/layouts/stack-utils/StackHeaderMenu.d.ts +83 -7
  24. package/build/layouts/stack-utils/StackHeaderMenu.d.ts.map +1 -1
  25. package/build/layouts/stack-utils/StackHeaderMenu.js +14 -4
  26. package/build/layouts/stack-utils/StackHeaderMenu.js.map +1 -1
  27. package/build/layouts/stack-utils/StackHeaderSpacer.d.ts +7 -1
  28. package/build/layouts/stack-utils/StackHeaderSpacer.d.ts.map +1 -1
  29. package/build/layouts/stack-utils/StackHeaderSpacer.js +5 -2
  30. package/build/layouts/stack-utils/StackHeaderSpacer.js.map +1 -1
  31. package/build/layouts/stack-utils/{StackHeaderItem.d.ts → StackHeaderView.d.ts} +18 -5
  32. package/build/layouts/stack-utils/StackHeaderView.d.ts.map +1 -0
  33. package/build/layouts/stack-utils/{StackHeaderItem.js → StackHeaderView.js} +14 -10
  34. package/build/layouts/stack-utils/StackHeaderView.js.map +1 -0
  35. package/build/layouts/stack-utils/index.d.ts +5 -5
  36. package/build/layouts/stack-utils/index.d.ts.map +1 -1
  37. package/build/layouts/stack-utils/index.js +4 -4
  38. package/build/layouts/stack-utils/index.js.map +1 -1
  39. package/build/layouts/stack-utils/shared.d.ts +4 -42
  40. package/build/layouts/stack-utils/shared.d.ts.map +1 -1
  41. package/build/layouts/stack-utils/shared.js +3 -22
  42. package/build/layouts/stack-utils/shared.js.map +1 -1
  43. package/build/link/ExpoLink.d.ts.map +1 -1
  44. package/build/link/ExpoLink.js +1 -8
  45. package/build/link/ExpoLink.js.map +1 -1
  46. package/build/link/elements.d.ts +36 -13
  47. package/build/link/elements.d.ts.map +1 -1
  48. package/build/link/elements.js +14 -5
  49. package/build/link/elements.js.map +1 -1
  50. package/build/link/preview/native.d.ts +12 -1
  51. package/build/link/preview/native.d.ts.map +1 -1
  52. package/build/link/preview/native.js.map +1 -1
  53. package/build/navigationEvents/index.d.ts +36 -0
  54. package/build/navigationEvents/index.d.ts.map +1 -0
  55. package/build/navigationEvents/index.js +53 -0
  56. package/build/navigationEvents/index.js.map +1 -0
  57. package/build/toolbar/elements.d.ts +325 -16
  58. package/build/toolbar/elements.d.ts.map +1 -1
  59. package/build/toolbar/elements.js +130 -12
  60. package/build/toolbar/elements.js.map +1 -1
  61. package/build/toolbar/index.d.ts +38 -6
  62. package/build/toolbar/index.d.ts.map +1 -1
  63. package/build/toolbar/index.js +36 -1
  64. package/build/toolbar/index.js.map +1 -1
  65. package/build/toolbar/native.ios.d.ts.map +1 -1
  66. package/build/toolbar/native.ios.js.map +1 -1
  67. package/build/toolbar/native.types.d.ts +6 -5
  68. package/build/toolbar/native.types.d.ts.map +1 -1
  69. package/build/toolbar/native.types.js.map +1 -1
  70. package/build/useScreens.d.ts.map +1 -1
  71. package/build/useScreens.js +50 -0
  72. package/build/useScreens.js.map +1 -1
  73. package/build/utils/font.d.ts +9 -0
  74. package/build/utils/font.d.ts.map +1 -0
  75. package/build/utils/font.js +20 -0
  76. package/build/utils/font.js.map +1 -0
  77. package/expo-module.config.json +1 -1
  78. package/ios/LinkPreview/LinkPreviewNativeActionView.swift +105 -24
  79. package/ios/LinkPreview/LinkPreviewNativeModule.swift +35 -8
  80. package/ios/LinkPreview/LinkPreviewNativeNavigation.swift +16 -20
  81. package/ios/LinkPreview/LinkPreviewNativePreviewView.swift +1 -8
  82. package/ios/LinkPreview/LinkPreviewNativeView.swift +48 -50
  83. package/ios/LinkPreview/LinkZoomTransition.swift +8 -10
  84. package/ios/RouterViewWithLogger.swift +5 -0
  85. package/ios/Toolbar/RouterFontUtils.swift +50 -0
  86. package/ios/Toolbar/RouterToolbarHostView.swift +41 -17
  87. package/ios/Toolbar/RouterToolbarItemView.swift +30 -13
  88. package/ios/Toolbar/RouterToolbarModule.swift +28 -0
  89. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar +0 -0
  90. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar.md5 +1 -0
  91. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar.sha1 +1 -0
  92. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar.sha256 +1 -0
  93. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.aar.sha512 +1 -0
  94. package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.module → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module} +17 -17
  95. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module.md5 +1 -0
  96. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module.sha1 +1 -0
  97. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module.sha256 +1 -0
  98. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.module.sha512 +1 -0
  99. package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.pom → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom} +1 -1
  100. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom.md5 +1 -0
  101. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom.sha1 +1 -0
  102. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom.sha256 +1 -0
  103. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e.pom.sha512 +1 -0
  104. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml +4 -4
  105. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.md5 +1 -1
  106. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha1 +1 -1
  107. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha256 +1 -1
  108. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha512 +1 -1
  109. package/package.json +10 -10
  110. package/build/layouts/stack-utils/StackHeaderItem.d.ts.map +0 -1
  111. package/build/layouts/stack-utils/StackHeaderItem.js.map +0 -1
  112. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.aar +0 -0
  113. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.aar.md5 +0 -1
  114. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.aar.sha1 +0 -1
  115. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.aar.sha256 +0 -1
  116. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.aar.sha512 +0 -1
  117. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.module.md5 +0 -1
  118. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.module.sha1 +0 -1
  119. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.module.sha256 +0 -1
  120. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.module.sha512 +0 -1
  121. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.pom.md5 +0 -1
  122. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.pom.sha1 +0 -1
  123. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.pom.sha256 +0 -1
  124. package/local-maven-repo/expo/modules/router/expo.modules.router/7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7.pom.sha512 +0 -1
  125. /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7-sources.jar → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar} +0 -0
  126. /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7-sources.jar.md5 → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar.md5} +0 -0
  127. /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7-sources.jar.sha1 → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar.sha1} +0 -0
  128. /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7-sources.jar.sha256 → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar.sha256} +0 -0
  129. /package/local-maven-repo/expo/modules/router/expo.modules.router/{7.0.0-canary-20251216-6e1f9a7/expo.modules.router-7.0.0-canary-20251216-6e1f9a7-sources.jar.sha512 → 7.0.0-canary-20251223-b83b31e/expo.modules.router-7.0.0-canary-20251223-b83b31e-sources.jar.sha512} +0 -0
@@ -1,15 +1,119 @@
1
1
  import { NativeStackNavigationOptions } from '@react-navigation/native-stack';
2
- import { type ReactNode } from 'react';
2
+ import React, { type ReactNode } from 'react';
3
3
  export interface StackHeaderLeftProps {
4
+ /**
5
+ * Child elements to compose the left area of the header. Can include Stack.Header.Button,
6
+ * Stack.Header.Menu, Stack.Header.Item, and Stack.Header.Spacer components.
7
+ */
4
8
  children?: ReactNode;
9
+ /**
10
+ * When `true`, renders children as a custom component in the header left area,
11
+ * replacing the default header left layout.
12
+ *
13
+ * @default false
14
+ */
5
15
  asChild?: boolean;
6
16
  }
7
17
  export interface StackHeaderRightProps {
18
+ /**
19
+ * Child elements to compose the right area of the header. Can include Stack.Header.Button,
20
+ * Stack.Header.Menu, Stack.Header.Item, and Stack.Header.Spacer components.
21
+ */
8
22
  children?: ReactNode;
23
+ /**
24
+ * When `true`, renders children as a custom component in the header right area,
25
+ * replacing the default header right layout.
26
+ *
27
+ * @default false
28
+ */
9
29
  asChild?: boolean;
10
30
  }
11
- export declare function StackHeaderLeft(props: StackHeaderLeftProps): null;
12
- export declare function StackHeaderRight(props: StackHeaderRightProps): null;
31
+ /**
32
+ * The component used to configure the left area of the stack header.
33
+ *
34
+ * When used inside a screen, it allows you to customize the left side of the header dynamically.
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * import { Stack } from 'expo-router';
39
+ *
40
+ * export default function Page() {
41
+ * return (
42
+ * <>
43
+ * <Stack.Header.Left>
44
+ * <Stack.Header.Button onPress={() => alert('Left button pressed!')} />
45
+ * </Stack.Header.Left>
46
+ * <ScreenContent />
47
+ * </>
48
+ * );
49
+ * }
50
+ * ```
51
+ *
52
+ * When used inside the layout, it needs to be wrapped in `Stack.Header` to take effect.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * import { Stack } from 'expo-router';
57
+ *
58
+ * export default function Layout() {
59
+ * return (
60
+ * <Stack>
61
+ * <Stack.Screen name="index">
62
+ * <Stack.Header>
63
+ * <Stack.Header.Left>
64
+ * <Stack.Header.Button onPress={() => alert('Left button pressed!')} />
65
+ * </Stack.Header.Left>
66
+ * </Stack.Header>
67
+ * </Stack.Screen>
68
+ * </Stack>
69
+ * );
70
+ * }
71
+ * ```
72
+ */
73
+ export declare const StackHeaderLeft: React.FC<StackHeaderLeftProps>;
74
+ /**
75
+ * The component used to configure the right area of the stack header.
76
+ *
77
+ * When used inside a screen, it allows you to customize the right side of the header dynamically.
78
+ *
79
+ * @example
80
+ * ```tsx
81
+ * import { Stack } from 'expo-router';
82
+ *
83
+ * export default function Page() {
84
+ * return (
85
+ * <>
86
+ * <Stack.Header.Right>
87
+ * <Stack.Header.Button onPress={() => alert('Right button pressed!')} />
88
+ * </Stack.Header.Right>
89
+ * <ScreenContent />
90
+ * </>
91
+ * );
92
+ * }
93
+ * ```
94
+ *
95
+ * When used inside the layout, it needs to be wrapped in `Stack.Header` to take effect.
96
+ *
97
+ * @example
98
+ * ```tsx
99
+ * import { Stack } from 'expo-router';
100
+ *
101
+ * export default function Layout() {
102
+ * return (
103
+ * <Stack>
104
+ * <Stack.Screen name="index">
105
+ * <Stack.Header>
106
+ * <Stack.Header.Right>
107
+ * <Stack.Header.Button onPress={() => alert('Right button pressed!')} />
108
+ * </Stack.Header.Right>
109
+ * </Stack.Header>
110
+ * </Stack.Screen>
111
+ * </Stack>
112
+ * );
113
+ * }
114
+ * ```
115
+ */
116
+ export declare const StackHeaderRight: React.FC<StackHeaderRightProps>;
13
117
  export declare function appendStackHeaderRightPropsToOptions(options: NativeStackNavigationOptions, props: StackHeaderRightProps): NativeStackNavigationOptions;
14
118
  export declare function appendStackHeaderLeftPropsToOptions(options: NativeStackNavigationOptions, props: StackHeaderLeftProps): NativeStackNavigationOptions;
15
119
  //# sourceMappingURL=StackHeaderLeftRight.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StackHeaderLeftRight.d.ts","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderLeftRight.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAc,EAA4B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAcxE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,QAE1D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,QAE5D;AA+CD,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,4BAA4B,EACrC,KAAK,EAAE,qBAAqB,GAC3B,4BAA4B,CAe9B;AAED,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,4BAA4B,EACrC,KAAK,EAAE,oBAAoB,GAC1B,4BAA4B,CAW9B"}
1
+ {"version":3,"file":"StackHeaderLeftRight.d.ts","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderLeftRight.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,KAAK,EAAE,EAA4B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAgBxE,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAK1D,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAK5D,CAAC;AAiDF,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,4BAA4B,EACrC,KAAK,EAAE,qBAAqB,GAC3B,4BAA4B,CAe9B;AAED,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,4BAA4B,EACrC,KAAK,EAAE,oBAAoB,GAC1B,4BAA4B,CAW9B"}
@@ -33,28 +33,121 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.StackHeaderLeft = StackHeaderLeft;
37
- exports.StackHeaderRight = StackHeaderRight;
36
+ exports.StackHeaderRight = exports.StackHeaderLeft = void 0;
38
37
  exports.appendStackHeaderRightPropsToOptions = appendStackHeaderRightPropsToOptions;
39
38
  exports.appendStackHeaderLeftPropsToOptions = appendStackHeaderLeftPropsToOptions;
40
39
  const react_1 = __importStar(require("react"));
40
+ const react_2 = require("react");
41
41
  const StackHeaderButton_1 = require("./StackHeaderButton");
42
- const StackHeaderItem_1 = require("./StackHeaderItem");
43
42
  const StackHeaderMenu_1 = require("./StackHeaderMenu");
44
43
  const StackHeaderSpacer_1 = require("./StackHeaderSpacer");
44
+ const StackHeaderView_1 = require("./StackHeaderView");
45
45
  const children_1 = require("../../utils/children");
46
- function StackHeaderLeft(props) {
47
- return null;
48
- }
49
- function StackHeaderRight(props) {
50
- return null;
51
- }
46
+ const Screen_1 = require("../../views/Screen");
47
+ /**
48
+ * The component used to configure the left area of the stack header.
49
+ *
50
+ * When used inside a screen, it allows you to customize the left side of the header dynamically.
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * import { Stack } from 'expo-router';
55
+ *
56
+ * export default function Page() {
57
+ * return (
58
+ * <>
59
+ * <Stack.Header.Left>
60
+ * <Stack.Header.Button onPress={() => alert('Left button pressed!')} />
61
+ * </Stack.Header.Left>
62
+ * <ScreenContent />
63
+ * </>
64
+ * );
65
+ * }
66
+ * ```
67
+ *
68
+ * When used inside the layout, it needs to be wrapped in `Stack.Header` to take effect.
69
+ *
70
+ * @example
71
+ * ```tsx
72
+ * import { Stack } from 'expo-router';
73
+ *
74
+ * export default function Layout() {
75
+ * return (
76
+ * <Stack>
77
+ * <Stack.Screen name="index">
78
+ * <Stack.Header>
79
+ * <Stack.Header.Left>
80
+ * <Stack.Header.Button onPress={() => alert('Left button pressed!')} />
81
+ * </Stack.Header.Left>
82
+ * </Stack.Header>
83
+ * </Stack.Screen>
84
+ * </Stack>
85
+ * );
86
+ * }
87
+ * ```
88
+ */
89
+ const StackHeaderLeft = (props) => {
90
+ // This component will only render when used inside a page
91
+ // but only if it is not wrapped in Stack.Screen.Header
92
+ const updatedOptions = (0, react_2.useMemo)(() => appendStackHeaderLeftPropsToOptions({}, props), [props]);
93
+ return <Screen_1.Screen options={updatedOptions}/>;
94
+ };
95
+ exports.StackHeaderLeft = StackHeaderLeft;
96
+ /**
97
+ * The component used to configure the right area of the stack header.
98
+ *
99
+ * When used inside a screen, it allows you to customize the right side of the header dynamically.
100
+ *
101
+ * @example
102
+ * ```tsx
103
+ * import { Stack } from 'expo-router';
104
+ *
105
+ * export default function Page() {
106
+ * return (
107
+ * <>
108
+ * <Stack.Header.Right>
109
+ * <Stack.Header.Button onPress={() => alert('Right button pressed!')} />
110
+ * </Stack.Header.Right>
111
+ * <ScreenContent />
112
+ * </>
113
+ * );
114
+ * }
115
+ * ```
116
+ *
117
+ * When used inside the layout, it needs to be wrapped in `Stack.Header` to take effect.
118
+ *
119
+ * @example
120
+ * ```tsx
121
+ * import { Stack } from 'expo-router';
122
+ *
123
+ * export default function Layout() {
124
+ * return (
125
+ * <Stack>
126
+ * <Stack.Screen name="index">
127
+ * <Stack.Header>
128
+ * <Stack.Header.Right>
129
+ * <Stack.Header.Button onPress={() => alert('Right button pressed!')} />
130
+ * </Stack.Header.Right>
131
+ * </Stack.Header>
132
+ * </Stack.Screen>
133
+ * </Stack>
134
+ * );
135
+ * }
136
+ * ```
137
+ */
138
+ const StackHeaderRight = (props) => {
139
+ // This component will only render when used inside a page
140
+ // but only if it is not wrapped in Stack.Screen.Header
141
+ const updatedOptions = (0, react_2.useMemo)(() => appendStackHeaderRightPropsToOptions({}, props), [props]);
142
+ return <Screen_1.Screen options={updatedOptions}/>;
143
+ };
144
+ exports.StackHeaderRight = StackHeaderRight;
52
145
  function convertHeaderRightLeftChildrenToUnstableItems(children, side) {
53
146
  const allChildren = react_1.default.Children.toArray(children);
54
147
  const actions = allChildren.filter((child) => (0, children_1.isChildOfType)(child, StackHeaderButton_1.StackHeaderButton) ||
55
148
  (0, children_1.isChildOfType)(child, StackHeaderMenu_1.StackHeaderMenu) ||
56
149
  (0, children_1.isChildOfType)(child, StackHeaderSpacer_1.StackHeaderSpacer) ||
57
- (0, children_1.isChildOfType)(child, StackHeaderItem_1.StackHeaderItem));
150
+ (0, children_1.isChildOfType)(child, StackHeaderView_1.StackHeaderView));
58
151
  if (actions.length !== allChildren.length && process.env.NODE_ENV !== 'production') {
59
152
  const otherElements = allChildren
60
153
  .filter((child) => !actions.some((action) => action === child))
@@ -71,7 +164,8 @@ function convertHeaderRightLeftChildrenToUnstableItems(children, side) {
71
164
  });
72
165
  console.warn(`Stack.Header.${side} only accepts <Stack.Header.Button>, <Stack.Header.Menu>, <Menu>, and <Stack.Header.Item> as children. Found invalid children: ${otherElements.join(', ')}`);
73
166
  }
74
- return () => actions.map((action) => {
167
+ return () => actions
168
+ .map((action) => {
75
169
  if ((0, children_1.isChildOfType)(action, StackHeaderButton_1.StackHeaderButton)) {
76
170
  return (0, StackHeaderButton_1.convertStackHeaderButtonPropsToRNHeaderItem)(action.props);
77
171
  }
@@ -81,8 +175,9 @@ function convertHeaderRightLeftChildrenToUnstableItems(children, side) {
81
175
  else if ((0, children_1.isChildOfType)(action, StackHeaderSpacer_1.StackHeaderSpacer)) {
82
176
  return (0, StackHeaderSpacer_1.convertStackHeaderSpacerPropsToRNHeaderItem)(action.props);
83
177
  }
84
- return (0, StackHeaderItem_1.convertStackHeaderItemPropsToRNHeaderItem)(action.props);
85
- });
178
+ return (0, StackHeaderView_1.convertStackHeaderViewPropsToRNHeaderItem)(action.props);
179
+ })
180
+ .filter((item) => !!item);
86
181
  }
87
182
  function appendStackHeaderRightPropsToOptions(options, props) {
88
183
  if (props.asChild) {
@@ -1 +1 @@
1
- {"version":3,"file":"StackHeaderLeftRight.js","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderLeftRight.tsx"],"names":[],"mappings":"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","sourcesContent":["import { NativeStackNavigationOptions } from '@react-navigation/native-stack';\nimport React, { Fragment, isValidElement, type ReactNode } from 'react';\n\nimport {\n convertStackHeaderButtonPropsToRNHeaderItem,\n StackHeaderButton,\n} from './StackHeaderButton';\nimport { convertStackHeaderItemPropsToRNHeaderItem, StackHeaderItem } from './StackHeaderItem';\nimport { convertStackHeaderMenuPropsToRNHeaderItem, StackHeaderMenu } from './StackHeaderMenu';\nimport {\n convertStackHeaderSpacerPropsToRNHeaderItem,\n StackHeaderSpacer,\n} from './StackHeaderSpacer';\nimport { isChildOfType } from '../../utils/children';\n\nexport interface StackHeaderLeftProps {\n children?: ReactNode;\n asChild?: boolean;\n}\n\nexport interface StackHeaderRightProps {\n children?: ReactNode;\n asChild?: boolean;\n}\n\nexport function StackHeaderLeft(props: StackHeaderLeftProps) {\n return null;\n}\n\nexport function StackHeaderRight(props: StackHeaderRightProps) {\n return null;\n}\n\nfunction convertHeaderRightLeftChildrenToUnstableItems(\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, StackHeaderButton) ||\n isChildOfType(child, StackHeaderMenu) ||\n isChildOfType(child, StackHeaderSpacer) ||\n isChildOfType(child, StackHeaderItem)\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.Header.${side} only accepts <Stack.Header.Button>, <Stack.Header.Menu>, <Menu>, and <Stack.Header.Item> as children. Found invalid children: ${otherElements.join(', ')}`\n );\n }\n return () =>\n actions.map((action) => {\n if (isChildOfType(action, StackHeaderButton)) {\n return convertStackHeaderButtonPropsToRNHeaderItem(action.props);\n } else if (isChildOfType(action, StackHeaderMenu)) {\n return convertStackHeaderMenuPropsToRNHeaderItem(action.props);\n } else if (isChildOfType(action, StackHeaderSpacer)) {\n return convertStackHeaderSpacerPropsToRNHeaderItem(action.props);\n }\n return convertStackHeaderItemPropsToRNHeaderItem(action.props);\n });\n}\n\nexport function appendStackHeaderRightPropsToOptions(\n options: NativeStackNavigationOptions,\n props: StackHeaderRightProps\n): NativeStackNavigationOptions {\n if (props.asChild) {\n return {\n ...options,\n headerRight: () => props.children,\n };\n }\n\n return {\n ...options,\n unstable_headerRightItems: convertHeaderRightLeftChildrenToUnstableItems(\n props.children,\n 'Right'\n ),\n };\n}\n\nexport function appendStackHeaderLeftPropsToOptions(\n options: NativeStackNavigationOptions,\n props: StackHeaderLeftProps\n): NativeStackNavigationOptions {\n if (props.asChild) {\n return {\n ...options,\n headerLeft: () => props.children,\n };\n }\n return {\n ...options,\n unstable_headerLeftItems: convertHeaderRightLeftChildrenToUnstableItems(props.children, 'Left'),\n };\n}\n"]}
1
+ {"version":3,"file":"StackHeaderLeftRight.js","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderLeftRight.tsx"],"names":[],"mappings":"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","sourcesContent":["import { NativeStackNavigationOptions } from '@react-navigation/native-stack';\nimport React, { Fragment, isValidElement, type ReactNode } from 'react';\nimport { useMemo } from 'react';\n\nimport {\n convertStackHeaderButtonPropsToRNHeaderItem,\n StackHeaderButton,\n} from './StackHeaderButton';\nimport { convertStackHeaderMenuPropsToRNHeaderItem, StackHeaderMenu } from './StackHeaderMenu';\nimport {\n convertStackHeaderSpacerPropsToRNHeaderItem,\n StackHeaderSpacer,\n} from './StackHeaderSpacer';\nimport { convertStackHeaderViewPropsToRNHeaderItem, StackHeaderView } from './StackHeaderView';\nimport { isChildOfType } from '../../utils/children';\nimport { Screen } from '../../views/Screen';\n\nexport interface StackHeaderLeftProps {\n /**\n * Child elements to compose the left area of the header. Can include Stack.Header.Button,\n * Stack.Header.Menu, Stack.Header.Item, and Stack.Header.Spacer components.\n */\n children?: ReactNode;\n /**\n * When `true`, renders children as a custom component in the header left area,\n * replacing the default header left layout.\n *\n * @default false\n */\n asChild?: boolean;\n}\n\nexport interface StackHeaderRightProps {\n /**\n * Child elements to compose the right area of the header. Can include Stack.Header.Button,\n * Stack.Header.Menu, Stack.Header.Item, and Stack.Header.Spacer components.\n */\n children?: ReactNode;\n /**\n * When `true`, renders children as a custom component in the header right area,\n * replacing the default header right layout.\n *\n * @default false\n */\n asChild?: boolean;\n}\n\n/**\n * The component used to configure the left area of the stack header.\n *\n * When used inside a screen, it allows you to customize the left side of the header dynamically.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Header.Left>\n * <Stack.Header.Button onPress={() => alert('Left button pressed!')} />\n * </Stack.Header.Left>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * When used inside the layout, it needs to be wrapped in `Stack.Header` to take effect.\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.Header>\n * <Stack.Header.Left>\n * <Stack.Header.Button onPress={() => alert('Left button pressed!')} />\n * </Stack.Header.Left>\n * </Stack.Header>\n * </Stack.Screen>\n * </Stack>\n * );\n * }\n * ```\n */\nexport const StackHeaderLeft: React.FC<StackHeaderLeftProps> = (props) => {\n // This component will only render when used inside a page\n // but only if it is not wrapped in Stack.Screen.Header\n const updatedOptions = useMemo(() => appendStackHeaderLeftPropsToOptions({}, props), [props]);\n return <Screen options={updatedOptions} />;\n};\n\n/**\n * The component used to configure the right area of the stack header.\n *\n * When used inside a screen, it allows you to customize the right side of the header dynamically.\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * export default function Page() {\n * return (\n * <>\n * <Stack.Header.Right>\n * <Stack.Header.Button onPress={() => alert('Right button pressed!')} />\n * </Stack.Header.Right>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * When used inside the layout, it needs to be wrapped in `Stack.Header` to take effect.\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.Header>\n * <Stack.Header.Right>\n * <Stack.Header.Button onPress={() => alert('Right button pressed!')} />\n * </Stack.Header.Right>\n * </Stack.Header>\n * </Stack.Screen>\n * </Stack>\n * );\n * }\n * ```\n */\nexport const StackHeaderRight: React.FC<StackHeaderRightProps> = (props) => {\n // This component will only render when used inside a page\n // but only if it is not wrapped in Stack.Screen.Header\n const updatedOptions = useMemo(() => appendStackHeaderRightPropsToOptions({}, props), [props]);\n return <Screen options={updatedOptions} />;\n};\n\nfunction convertHeaderRightLeftChildrenToUnstableItems(\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, StackHeaderButton) ||\n isChildOfType(child, StackHeaderMenu) ||\n isChildOfType(child, StackHeaderSpacer) ||\n isChildOfType(child, StackHeaderView)\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.Header.${side} only accepts <Stack.Header.Button>, <Stack.Header.Menu>, <Menu>, and <Stack.Header.Item> as children. Found invalid children: ${otherElements.join(', ')}`\n );\n }\n return () =>\n actions\n .map((action) => {\n if (isChildOfType(action, StackHeaderButton)) {\n return convertStackHeaderButtonPropsToRNHeaderItem(action.props);\n } else if (isChildOfType(action, StackHeaderMenu)) {\n return convertStackHeaderMenuPropsToRNHeaderItem(action.props);\n } else if (isChildOfType(action, StackHeaderSpacer)) {\n return convertStackHeaderSpacerPropsToRNHeaderItem(action.props);\n }\n return convertStackHeaderViewPropsToRNHeaderItem(action.props);\n })\n .filter((item) => !!item);\n}\n\nexport function appendStackHeaderRightPropsToOptions(\n options: NativeStackNavigationOptions,\n props: StackHeaderRightProps\n): NativeStackNavigationOptions {\n if (props.asChild) {\n return {\n ...options,\n headerRight: () => props.children,\n };\n }\n\n return {\n ...options,\n unstable_headerRightItems: convertHeaderRightLeftChildrenToUnstableItems(\n props.children,\n 'Right'\n ),\n };\n}\n\nexport function appendStackHeaderLeftPropsToOptions(\n options: NativeStackNavigationOptions,\n props: StackHeaderLeftProps\n): NativeStackNavigationOptions {\n if (props.asChild) {\n return {\n ...options,\n headerLeft: () => props.children,\n };\n }\n return {\n ...options,\n unstable_headerLeftItems: convertHeaderRightLeftChildrenToUnstableItems(props.children, 'Left'),\n };\n}\n"]}
@@ -3,15 +3,71 @@ import { type ReactNode } from 'react';
3
3
  import type { ImageSourcePropType } from 'react-native';
4
4
  import type { SFSymbol } from 'sf-symbols-typescript';
5
5
  import { type StackHeaderItemSharedProps } from './shared';
6
- export interface StackHeaderMenuProps extends StackHeaderItemSharedProps {
6
+ export interface StackHeaderMenuProps {
7
+ accessibilityLabel?: string;
8
+ accessibilityHint?: string;
7
9
  /**
8
- * Optional title to show on top of the menu.
10
+ * There are two ways to specify the content of the menu header item - using props or child components:
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * import { Stack } from 'expo-router';
15
+ *
16
+ * ...
17
+ * <Stack.Header.Menu icon="star.fill" title="As props">
18
+ * <Stack.Header.MenuAction>Action 1</Stack.Header.MenuAction>
19
+ * </Stack.Header.Menu>
20
+ * ```
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * import { Stack } from 'expo-router';
25
+ *
26
+ * ...
27
+ * <Stack.Header.Menu>
28
+ * <Stack.Header.Icon sf="star.fill" />
29
+ * <Stack.Header.Label>As components</Stack.Header.Label>
30
+ * <Stack.Header.Badge>3</Stack.Header.Badge>
31
+ * <Stack.Header.MenuAction>Action 1</Stack.Header.MenuAction>
32
+ * </Stack.Header.Menu>
33
+ * ```
34
+ *
35
+ * **Note**: When icon is used, the label will not be shown and will be used for accessibility purposes only.
9
36
  */
10
- title?: string;
37
+ children?: ReactNode;
38
+ /**
39
+ * If `true`, the menu item will be displayed as destructive.
40
+ *
41
+ * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.
42
+ */
43
+ destructive?: boolean;
44
+ disabled?: boolean;
45
+ /**
46
+ * Whether to hide the shared background.
47
+ *
48
+ * @see [Official Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/hidessharedbackground) for more information.
49
+ *
50
+ * @platform iOS 26+
51
+ */
52
+ hidesSharedBackground?: boolean;
53
+ /**
54
+ * Whether the menu should be hidden.
55
+ *
56
+ * @default false
57
+ */
58
+ hidden?: boolean;
59
+ /**
60
+ * Icon for the menu item.
61
+ *
62
+ * Can be an SF Symbol name or an image source.
63
+ */
64
+ icon?: StackHeaderItemSharedProps['icon'];
11
65
  /**
12
66
  * If `true`, the menu will be displayed inline.
13
67
  * This means that the menu will not be collapsed
14
68
  *
69
+ * > **Note*: Inline menus are only supported in submenus.
70
+ *
15
71
  * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayinline) for more information.
16
72
  */
17
73
  inline?: boolean;
@@ -19,15 +75,35 @@ export interface StackHeaderMenuProps extends StackHeaderItemSharedProps {
19
75
  * If `true`, the menu will be displayed as a palette.
20
76
  * This means that the menu will be displayed as one row
21
77
  *
78
+ * > **Note**: Palette menus are only supported in submenus.
79
+ *
22
80
  * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayaspalette) for more information.
23
81
  */
24
82
  palette?: boolean;
25
83
  /**
26
- * If `true`, the menu item will be displayed as destructive.
84
+ * Whether to separate the background of this item from other header items.
27
85
  *
28
- * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.
86
+ * @default false
29
87
  */
30
- destructive?: boolean;
88
+ separateBackground?: boolean;
89
+ /**
90
+ * Style for the label of the header item.
91
+ */
92
+ style?: StackHeaderItemSharedProps['style'];
93
+ /**
94
+ * The tint color to apply to the button item
95
+ *
96
+ * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/tintcolor) for more information.
97
+ */
98
+ tintColor?: StackHeaderItemSharedProps['tintColor'];
99
+ /**
100
+ * Optional title to show on top of the menu.
101
+ */
102
+ title?: string;
103
+ /**
104
+ * @default 'plain'
105
+ */
106
+ variant?: StackHeaderItemSharedProps['variant'];
31
107
  }
32
108
  /**
33
109
  * Component representing menu for `Stack.Header.Right` or `Stack.Header.Left`.
@@ -104,7 +180,7 @@ export interface StackHeaderMenuProps extends StackHeaderItemSharedProps {
104
180
  * @platform ios
105
181
  */
106
182
  export declare const StackHeaderMenu: React.FC<StackHeaderMenuProps>;
107
- export declare function convertStackHeaderMenuPropsToRNHeaderItem(props: StackHeaderMenuProps): NativeStackHeaderItemMenu;
183
+ export declare function convertStackHeaderMenuPropsToRNHeaderItem(props: StackHeaderMenuProps): NativeStackHeaderItemMenu | undefined;
108
184
  export interface StackHeaderMenuActionProps {
109
185
  /**
110
186
  * Can be an Icon, Label or string title.
@@ -1 +1 @@
1
- {"version":3,"file":"StackHeaderMenu.d.ts","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,+BAA+B,EAEhC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,UAAU,CAAC;AAIlB,MAAM,WAAW,oBAAqB,SAAQ,0BAA0B;IACtE;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyEG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAAQ,CAAC;AAEpE,wBAAgB,yCAAyC,CACvD,KAAK,EAAE,oBAAoB,GAC1B,yBAAyB,CAsB3B;AAiDD,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,GAAG,mBAAmB,CAAC;IACtC;;;;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAAc,CAAC;AAEtF,wBAAgB,+CAA+C,CAC7D,KAAK,EAAE,0BAA0B,GAChC,+BAA+B,CAwBjC"}
1
+ {"version":3,"file":"StackHeaderMenu.d.ts","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,+BAA+B,EAEhC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,UAAU,CAAC;AAIlB,MAAM,WAAW,oBAAoB;IACnC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;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;CACjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyEG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAAQ,CAAC;AAEpE,wBAAgB,yCAAyC,CACvD,KAAK,EAAE,oBAAoB,GAC1B,yBAAyB,GAAG,SAAS,CA2BvC;AAsDD,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,QAAQ,GAAG,mBAAmB,CAAC;IACtC;;;;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAAc,CAAC;AAEtF,wBAAgB,+CAA+C,CAC7D,KAAK,EAAE,0BAA0B,GAChC,+BAA+B,CAwBjC"}
@@ -83,18 +83,23 @@ const children_1 = require("../../utils/children");
83
83
  */
84
84
  exports.StackHeaderMenu = primitives_1.Menu;
85
85
  function convertStackHeaderMenuPropsToRNHeaderItem(props) {
86
+ if (props.hidden) {
87
+ return undefined;
88
+ }
86
89
  const { title, ...rest } = props;
87
90
  const actions = react_1.Children.toArray(props.children).filter((child) => (0, children_1.isChildOfType)(child, exports.StackHeaderMenuAction) || (0, children_1.isChildOfType)(child, exports.StackHeaderMenu));
88
91
  const item = {
89
92
  ...(0, shared_1.convertStackHeaderSharedPropsToRNSharedHeaderItem)(rest),
90
93
  type: 'menu',
91
94
  menu: {
92
- items: actions.map((action) => {
95
+ items: actions
96
+ .map((action) => {
93
97
  if ((0, children_1.isChildOfType)(action, exports.StackHeaderMenu)) {
94
98
  return convertStackHeaderSubmenuMenuPropsToRNHeaderItem(action.props);
95
99
  }
96
100
  return convertStackHeaderMenuActionPropsToRNHeaderItem(action.props);
97
- }),
101
+ })
102
+ .filter((i) => !!i),
98
103
  },
99
104
  };
100
105
  if (title) {
@@ -103,6 +108,9 @@ function convertStackHeaderMenuPropsToRNHeaderItem(props) {
103
108
  return item;
104
109
  }
105
110
  function convertStackHeaderSubmenuMenuPropsToRNHeaderItem(props) {
111
+ if (props.hidden) {
112
+ return undefined;
113
+ }
106
114
  // Removing children. Otherwise the buttons will be broken
107
115
  const sharedProps = (0, shared_1.convertStackHeaderSharedPropsToRNSharedHeaderItem)(props);
108
116
  const actions = react_1.Children.toArray(props.children).filter((child) => (0, children_1.isChildOfType)(child, exports.StackHeaderMenuAction) || (0, children_1.isChildOfType)(child, exports.StackHeaderMenu));
@@ -110,12 +118,14 @@ function convertStackHeaderSubmenuMenuPropsToRNHeaderItem(props) {
110
118
  // https://github.com/react-navigation/react-navigation/pull/12895
111
119
  const item = {
112
120
  type: 'submenu',
113
- items: actions.map((action) => {
121
+ items: actions
122
+ .map((action) => {
114
123
  if ((0, children_1.isChildOfType)(action, exports.StackHeaderMenu)) {
115
124
  return convertStackHeaderSubmenuMenuPropsToRNHeaderItem(action.props);
116
125
  }
117
126
  return convertStackHeaderMenuActionPropsToRNHeaderItem(action.props);
118
- }),
127
+ })
128
+ .filter((i) => !!i),
119
129
  label: sharedProps.label || props.title || '',
120
130
  };
121
131
  if (props.inline !== undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"StackHeaderMenu.js","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {\n NativeStackHeaderItemMenu,\n NativeStackHeaderItemMenuAction,\n NativeStackHeaderItemMenuSubmenu,\n} from '@react-navigation/native-stack';\nimport { Children, type ReactNode } from 'react';\nimport type { ImageSourcePropType } from 'react-native';\nimport type { HeaderBarButtonItemSubmenu } from 'react-native-screens';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport {\n convertStackHeaderSharedPropsToRNSharedHeaderItem,\n type StackHeaderItemSharedProps,\n} from './shared';\nimport { Menu, MenuAction } from '../../primitives';\nimport { isChildOfType } from '../../utils/children';\n\nexport interface StackHeaderMenuProps extends StackHeaderItemSharedProps {\n /**\n * Optional title to show on top of the menu.\n */\n title?: string;\n /**\n * If `true`, the menu will be displayed inline.\n * This means that the menu will not be collapsed\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 * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayaspalette) for more information.\n */\n palette?: boolean;\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\n/**\n * Component representing menu for `Stack.Header.Right` or `Stack.Header.Left`.\n *\n * Use as `Stack.Header.Menu` to provide top-level menus on iOS header bars.\n * It accepts `Stack.Header.MenuAction` and nested `Stack.Header.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 Screen() {\n * return (\n * <>\n * <ScreenContent />\n * <Stack.Screen>\n * <Stack.Header>\n * <Stack.Header.Right>\n * <Stack.Header.Menu>\n * <Stack.Header.Label>Menu</Stack.Header.Label>\n * <Stack.Header.Icon sf=\"ellipsis.circle\" />\n * <Stack.Header.MenuAction onPress={() => Alert.alert('Action 1 pressed!')}>\n * Action 1\n * </Stack.Header.MenuAction>\n * <Stack.Header.MenuAction isOn icon=\"star.fill\">\n * Action 2\n * </Stack.Header.MenuAction>\n * <Stack.Header.Menu inline>\n * <Stack.Header.MenuAction isOn>Sub Action</Stack.Header.MenuAction>\n * </Stack.Header.Menu>\n * </Stack.Header.Menu>\n * </Stack.Header.Right>\n * </Stack.Header>\n * </Stack.Screen>\n * </>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n * import { Text } from 'react-native';\n *\n * export default function Screen() {\n * return (\n * <>\n * <ScreenContent />\n * <Stack.Screen>\n * <Stack.Header>\n * <Stack.Header.Left>\n * <Stack.Header.Menu>\n * <Stack.Header.MenuAction onPress={() => Alert.alert('Action 1 pressed!')}>\n * Action 1\n * </Stack.Header.MenuAction>\n * <Stack.Header.Menu inline palette title=\"Icons\">\n * <Stack.Header.MenuAction isOn icon=\"star.fill\" />\n * <Stack.Header.MenuAction icon=\"heart.fill\" />\n * </Stack.Header.Menu>\n * </Stack.Header.Menu>\n * </Stack.Header.Left>\n * </Stack.Header>\n * </Stack.Screen>\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 StackHeaderMenu: React.FC<StackHeaderMenuProps> = Menu;\n\nexport function convertStackHeaderMenuPropsToRNHeaderItem(\n props: StackHeaderMenuProps\n): NativeStackHeaderItemMenu {\n const { title, ...rest } = props;\n const actions = Children.toArray(props.children).filter(\n (child) => isChildOfType(child, StackHeaderMenuAction) || isChildOfType(child, StackHeaderMenu)\n );\n const item: NativeStackHeaderItemMenu = {\n ...convertStackHeaderSharedPropsToRNSharedHeaderItem(rest),\n type: 'menu',\n menu: {\n items: actions.map((action) => {\n if (isChildOfType(action, StackHeaderMenu)) {\n return convertStackHeaderSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackHeaderMenuActionPropsToRNHeaderItem(action.props);\n }),\n },\n };\n if (title) {\n item.menu.title = title;\n }\n\n return item;\n}\n\nfunction convertStackHeaderSubmenuMenuPropsToRNHeaderItem(\n props: StackHeaderMenuProps\n): NativeStackHeaderItemMenuSubmenu {\n // Removing children. Otherwise the buttons will be broken\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const actions = Children.toArray(props.children).filter(\n (child) => isChildOfType(child, StackHeaderMenuAction) || isChildOfType(child, StackHeaderMenu)\n );\n\n // TODO: Remove Pick<HeaderBarButtonItemSubmenu> when this PR is merged and released in react-navigation:\n // https://github.com/react-navigation/react-navigation/pull/12895\n const item: NativeStackHeaderItemMenuSubmenu &\n Pick<HeaderBarButtonItemSubmenu, 'displayAsPalette' | 'displayInline' | 'destructive'> = {\n type: 'submenu',\n items: actions.map((action) => {\n if (isChildOfType(action, StackHeaderMenu)) {\n return convertStackHeaderSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackHeaderMenuActionPropsToRNHeaderItem(action.props);\n }),\n label: sharedProps.label || props.title || '',\n };\n\n if (props.inline !== undefined) {\n item.displayInline = props.inline;\n }\n if (props.palette !== undefined) {\n item.displayAsPalette = props.palette;\n }\n if (props.destructive !== undefined) {\n item.destructive = props.destructive;\n }\n\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Header.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 StackHeaderMenuActionProps {\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 /**\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.Header.Menu`.\n *\n * @example\n * ```tsx\n * import React from 'react';\n * import { Alert } from 'react-native';\n * import { Stack, Label, Icon } from 'expo-router';\n *\n * export default function ExampleScreen() {\n * return (\n * <>\n * <ScreenContent />\n * <Stack.Screen>\n * <Stack.Header>\n * <Stack.Header.Right>\n * <Stack.Header.Menu icon=\"ellipsis.circle\">\n * <Stack.Header.MenuAction onPress={() => Alert.alert('Action 1 pressed!')}>\n * Action 1\n * </Stack.Header.MenuAction>\n * <Stack.Header.MenuAction isOn onPress={() => Alert.alert('Action 2 pressed!')}>\n * <Label>Action 2</Label>\n * <Icon sf=\"star.fill\" />\n * </Stack.Header.MenuAction>\n * </Stack.Header.Menu>\n * </Stack.Header.Right>\n * </Stack.Header>\n * </Stack.Screen>\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 StackHeaderMenuAction: React.FC<StackHeaderMenuActionProps> = MenuAction;\n\nexport function convertStackHeaderMenuActionPropsToRNHeaderItem(\n props: StackHeaderMenuActionProps\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 action icons\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Header.Menu.Action, 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":"StackHeaderMenu.js","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {\n NativeStackHeaderItemMenu,\n NativeStackHeaderItemMenuAction,\n NativeStackHeaderItemMenuSubmenu,\n} from '@react-navigation/native-stack';\nimport { Children, type ReactNode } from 'react';\nimport type { ImageSourcePropType } from 'react-native';\nimport type { HeaderBarButtonItemSubmenu } from 'react-native-screens';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport {\n convertStackHeaderSharedPropsToRNSharedHeaderItem,\n type StackHeaderItemSharedProps,\n} from './shared';\nimport { Menu, MenuAction } from '../../primitives';\nimport { isChildOfType } from '../../utils/children';\n\nexport interface StackHeaderMenuProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n /**\n * There are two ways to specify the content of the menu header item - using props or child components:\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * ...\n * <Stack.Header.Menu icon=\"star.fill\" title=\"As props\">\n * <Stack.Header.MenuAction>Action 1</Stack.Header.MenuAction>\n * </Stack.Header.Menu>\n * ```\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n *\n * ...\n * <Stack.Header.Menu>\n * <Stack.Header.Icon sf=\"star.fill\" />\n * <Stack.Header.Label>As components</Stack.Header.Label>\n * <Stack.Header.Badge>3</Stack.Header.Badge>\n * <Stack.Header.MenuAction>Action 1</Stack.Header.MenuAction>\n * </Stack.Header.Menu>\n * ```\n *\n * **Note**: When icon is used, the label will not be shown and will be used for accessibility purposes only.\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 /**\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 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}\n\n/**\n * Component representing menu for `Stack.Header.Right` or `Stack.Header.Left`.\n *\n * Use as `Stack.Header.Menu` to provide top-level menus on iOS header bars.\n * It accepts `Stack.Header.MenuAction` and nested `Stack.Header.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 Screen() {\n * return (\n * <>\n * <ScreenContent />\n * <Stack.Screen>\n * <Stack.Header>\n * <Stack.Header.Right>\n * <Stack.Header.Menu>\n * <Stack.Header.Label>Menu</Stack.Header.Label>\n * <Stack.Header.Icon sf=\"ellipsis.circle\" />\n * <Stack.Header.MenuAction onPress={() => Alert.alert('Action 1 pressed!')}>\n * Action 1\n * </Stack.Header.MenuAction>\n * <Stack.Header.MenuAction isOn icon=\"star.fill\">\n * Action 2\n * </Stack.Header.MenuAction>\n * <Stack.Header.Menu inline>\n * <Stack.Header.MenuAction isOn>Sub Action</Stack.Header.MenuAction>\n * </Stack.Header.Menu>\n * </Stack.Header.Menu>\n * </Stack.Header.Right>\n * </Stack.Header>\n * </Stack.Screen>\n * </>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * import { Stack } from 'expo-router';\n * import { Text } from 'react-native';\n *\n * export default function Screen() {\n * return (\n * <>\n * <ScreenContent />\n * <Stack.Screen>\n * <Stack.Header>\n * <Stack.Header.Left>\n * <Stack.Header.Menu>\n * <Stack.Header.MenuAction onPress={() => Alert.alert('Action 1 pressed!')}>\n * Action 1\n * </Stack.Header.MenuAction>\n * <Stack.Header.Menu inline palette title=\"Icons\">\n * <Stack.Header.MenuAction isOn icon=\"star.fill\" />\n * <Stack.Header.MenuAction icon=\"heart.fill\" />\n * </Stack.Header.Menu>\n * </Stack.Header.Menu>\n * </Stack.Header.Left>\n * </Stack.Header>\n * </Stack.Screen>\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 StackHeaderMenu: React.FC<StackHeaderMenuProps> = Menu;\n\nexport function convertStackHeaderMenuPropsToRNHeaderItem(\n props: StackHeaderMenuProps\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) => isChildOfType(child, StackHeaderMenuAction) || isChildOfType(child, StackHeaderMenu)\n );\n const item: NativeStackHeaderItemMenu = {\n ...convertStackHeaderSharedPropsToRNSharedHeaderItem(rest),\n type: 'menu',\n menu: {\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackHeaderMenu)) {\n return convertStackHeaderSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackHeaderMenuActionPropsToRNHeaderItem(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 convertStackHeaderSubmenuMenuPropsToRNHeaderItem(\n props: StackHeaderMenuProps\n): NativeStackHeaderItemMenuSubmenu | undefined {\n if (props.hidden) {\n return undefined;\n }\n // Removing children. Otherwise the buttons will be broken\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props);\n const actions = Children.toArray(props.children).filter(\n (child) => isChildOfType(child, StackHeaderMenuAction) || isChildOfType(child, StackHeaderMenu)\n );\n\n // TODO: Remove Pick<HeaderBarButtonItemSubmenu> when this PR is merged and released in react-navigation:\n // https://github.com/react-navigation/react-navigation/pull/12895\n const item: NativeStackHeaderItemMenuSubmenu &\n Pick<HeaderBarButtonItemSubmenu, 'displayAsPalette' | 'displayInline' | 'destructive'> = {\n type: 'submenu',\n items: actions\n .map((action) => {\n if (isChildOfType(action, StackHeaderMenu)) {\n return convertStackHeaderSubmenuMenuPropsToRNHeaderItem(action.props);\n }\n return convertStackHeaderMenuActionPropsToRNHeaderItem(action.props);\n })\n .filter((i) => !!i),\n label: sharedProps.label || props.title || '',\n };\n\n if (props.inline !== undefined) {\n item.displayInline = props.inline;\n }\n if (props.palette !== undefined) {\n item.displayAsPalette = props.palette;\n }\n if (props.destructive !== undefined) {\n item.destructive = props.destructive;\n }\n\n if (sharedProps.icon) {\n // Only SF Symbols are supported in submenu icons\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Header.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 StackHeaderMenuActionProps {\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 /**\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.Header.Menu`.\n *\n * @example\n * ```tsx\n * import React from 'react';\n * import { Alert } from 'react-native';\n * import { Stack, Label, Icon } from 'expo-router';\n *\n * export default function ExampleScreen() {\n * return (\n * <>\n * <ScreenContent />\n * <Stack.Screen>\n * <Stack.Header>\n * <Stack.Header.Right>\n * <Stack.Header.Menu icon=\"ellipsis.circle\">\n * <Stack.Header.MenuAction onPress={() => Alert.alert('Action 1 pressed!')}>\n * Action 1\n * </Stack.Header.MenuAction>\n * <Stack.Header.MenuAction isOn onPress={() => Alert.alert('Action 2 pressed!')}>\n * <Label>Action 2</Label>\n * <Icon sf=\"star.fill\" />\n * </Stack.Header.MenuAction>\n * </Stack.Header.Menu>\n * </Stack.Header.Right>\n * </Stack.Header>\n * </Stack.Screen>\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 StackHeaderMenuAction: React.FC<StackHeaderMenuActionProps> = MenuAction;\n\nexport function convertStackHeaderMenuActionPropsToRNHeaderItem(\n props: StackHeaderMenuActionProps\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 action icons\n if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n console.warn(\n 'When Icon is used inside Stack.Header.Menu.Action, only sfSymbol icons are supported. This is a limitation of React Native Screens.'\n );\n }\n }\n return item;\n}\n"]}
@@ -1,5 +1,11 @@
1
1
  import type { NativeStackHeaderItemSpacing } from '@react-navigation/native-stack';
2
2
  export interface StackHeaderSpacerProps {
3
+ /**
4
+ * Whether the spacer should be hidden.
5
+ *
6
+ * @default false
7
+ */
8
+ hidden?: boolean;
3
9
  /**
4
10
  * The width of the spacing element.
5
11
  *
@@ -36,5 +42,5 @@ export interface StackHeaderSpacerProps {
36
42
  * @platform ios
37
43
  */
38
44
  export declare const StackHeaderSpacer: React.FC<StackHeaderSpacerProps>;
39
- export declare function convertStackHeaderSpacerPropsToRNHeaderItem(props: StackHeaderSpacerProps): NativeStackHeaderItemSpacing;
45
+ export declare function convertStackHeaderSpacerPropsToRNHeaderItem({ hidden, width, }: StackHeaderSpacerProps): NativeStackHeaderItemSpacing | undefined;
40
46
  //# sourceMappingURL=StackHeaderSpacer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StackHeaderSpacer.d.ts","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderSpacer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAEnF,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAc,CAAC;AAE9E,wBAAgB,2CAA2C,CACzD,KAAK,EAAE,sBAAsB,GAC5B,4BAA4B,CAK9B"}
1
+ {"version":3,"file":"StackHeaderSpacer.d.ts","sourceRoot":"","sources":["../../../src/layouts/stack-utils/StackHeaderSpacer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAEnF,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;CAIf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAc,CAAC;AAE9E,wBAAgB,2CAA2C,CAAC,EAC1D,MAAM,EACN,KAAK,GACN,EAAE,sBAAsB,GAAG,4BAA4B,GAAG,SAAS,CAQnE"}
@@ -32,10 +32,13 @@ exports.convertStackHeaderSpacerPropsToRNHeaderItem = convertStackHeaderSpacerPr
32
32
  */
33
33
  const StackHeaderSpacer = () => null;
34
34
  exports.StackHeaderSpacer = StackHeaderSpacer;
35
- function convertStackHeaderSpacerPropsToRNHeaderItem(props) {
35
+ function convertStackHeaderSpacerPropsToRNHeaderItem({ hidden, width, }) {
36
+ if (hidden) {
37
+ return undefined;
38
+ }
36
39
  return {
37
40
  type: 'spacing',
38
- spacing: props.width,
41
+ spacing: width,
39
42
  };
40
43
  }
41
44
  //# sourceMappingURL=StackHeaderSpacer.js.map