expo-router 57.0.1 → 57.0.3

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 (70) hide show
  1. package/android/build.gradle +2 -2
  2. package/build/layouts/stack-utils/toolbar/StackToolbarButton/native.android.d.ts.map +1 -1
  3. package/build/layouts/stack-utils/toolbar/StackToolbarButton/native.android.js +3 -1
  4. package/build/layouts/stack-utils/toolbar/StackToolbarButton/native.android.js.map +1 -1
  5. package/build/layouts/stack-utils/toolbar/StackToolbarButton/types.d.ts +4 -0
  6. package/build/layouts/stack-utils/toolbar/StackToolbarButton/types.d.ts.map +1 -1
  7. package/build/layouts/stack-utils/toolbar/StackToolbarButton/types.js.map +1 -1
  8. package/build/layouts/stack-utils/toolbar/StackToolbarMenu/index.d.ts.map +1 -1
  9. package/build/layouts/stack-utils/toolbar/StackToolbarMenu/index.js +2 -2
  10. package/build/layouts/stack-utils/toolbar/StackToolbarMenu/index.js.map +1 -1
  11. package/build/layouts/stack-utils/toolbar/StackToolbarMenu/native.android.d.ts.map +1 -1
  12. package/build/layouts/stack-utils/toolbar/StackToolbarMenu/native.android.js +6 -1
  13. package/build/layouts/stack-utils/toolbar/StackToolbarMenu/native.android.js.map +1 -1
  14. package/build/layouts/stack-utils/toolbar/StackToolbarMenu/types.d.ts +4 -0
  15. package/build/layouts/stack-utils/toolbar/StackToolbarMenu/types.d.ts.map +1 -1
  16. package/build/layouts/stack-utils/toolbar/StackToolbarMenu/types.js.map +1 -1
  17. package/build/layouts/stack-utils/toolbar/ToolbarItemBadge.android.d.ts +21 -0
  18. package/build/layouts/stack-utils/toolbar/ToolbarItemBadge.android.d.ts.map +1 -0
  19. package/build/layouts/stack-utils/toolbar/ToolbarItemBadge.android.js +41 -0
  20. package/build/layouts/stack-utils/toolbar/ToolbarItemBadge.android.js.map +1 -0
  21. package/build/layouts/stack-utils/toolbar/ToolbarItemBadge.d.ts +11 -0
  22. package/build/layouts/stack-utils/toolbar/ToolbarItemBadge.d.ts.map +1 -0
  23. package/build/layouts/stack-utils/toolbar/ToolbarItemBadge.js +14 -0
  24. package/build/layouts/stack-utils/toolbar/ToolbarItemBadge.js.map +1 -0
  25. package/build/react-navigation/native-stack/views/NativeStackView.native.d.ts.map +1 -1
  26. package/build/react-navigation/native-stack/views/NativeStackView.native.js +2 -1
  27. package/build/react-navigation/native-stack/views/NativeStackView.native.js.map +1 -1
  28. package/build/testing-library/index.d.ts.map +1 -1
  29. package/build/testing-library/index.js +8 -0
  30. package/build/testing-library/index.js.map +1 -1
  31. package/build/utils/font.d.ts +2 -0
  32. package/build/utils/font.d.ts.map +1 -1
  33. package/build/utils/font.js +27 -0
  34. package/build/utils/font.js.map +1 -1
  35. package/expo-module.config.json +1 -1
  36. package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1.module → 57.0.3/expo.modules.router-57.0.3.module} +7 -7
  37. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.3/expo.modules.router-57.0.3.module.md5 +1 -0
  38. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.3/expo.modules.router-57.0.3.module.sha1 +1 -0
  39. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.3/expo.modules.router-57.0.3.module.sha256 +1 -0
  40. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.3/expo.modules.router-57.0.3.module.sha512 +1 -0
  41. package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1.pom → 57.0.3/expo.modules.router-57.0.3.pom} +1 -1
  42. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.3/expo.modules.router-57.0.3.pom.md5 +1 -0
  43. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.3/expo.modules.router-57.0.3.pom.sha1 +1 -0
  44. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.3/expo.modules.router-57.0.3.pom.sha256 +1 -0
  45. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.3/expo.modules.router-57.0.3.pom.sha512 +1 -0
  46. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml +4 -4
  47. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.md5 +1 -1
  48. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha1 +1 -1
  49. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha256 +1 -1
  50. package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha512 +1 -1
  51. package/package.json +9 -9
  52. package/plugin/tsconfig.tsbuildinfo +1 -0
  53. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.1/expo.modules.router-57.0.1.module.md5 +0 -1
  54. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.1/expo.modules.router-57.0.1.module.sha1 +0 -1
  55. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.1/expo.modules.router-57.0.1.module.sha256 +0 -1
  56. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.1/expo.modules.router-57.0.1.module.sha512 +0 -1
  57. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.1/expo.modules.router-57.0.1.pom.md5 +0 -1
  58. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.1/expo.modules.router-57.0.1.pom.sha1 +0 -1
  59. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.1/expo.modules.router-57.0.1.pom.sha256 +0 -1
  60. package/local-maven-repo/expo/modules/router/expo.modules.router/57.0.1/expo.modules.router-57.0.1.pom.sha512 +0 -1
  61. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1-sources.jar → 57.0.3/expo.modules.router-57.0.3-sources.jar} +0 -0
  62. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1-sources.jar.md5 → 57.0.3/expo.modules.router-57.0.3-sources.jar.md5} +0 -0
  63. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1-sources.jar.sha1 → 57.0.3/expo.modules.router-57.0.3-sources.jar.sha1} +0 -0
  64. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1-sources.jar.sha256 → 57.0.3/expo.modules.router-57.0.3-sources.jar.sha256} +0 -0
  65. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1-sources.jar.sha512 → 57.0.3/expo.modules.router-57.0.3-sources.jar.sha512} +0 -0
  66. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1.aar → 57.0.3/expo.modules.router-57.0.3.aar} +0 -0
  67. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1.aar.md5 → 57.0.3/expo.modules.router-57.0.3.aar.md5} +0 -0
  68. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1.aar.sha1 → 57.0.3/expo.modules.router-57.0.3.aar.sha1} +0 -0
  69. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1.aar.sha256 → 57.0.3/expo.modules.router-57.0.3.aar.sha256} +0 -0
  70. /package/local-maven-repo/expo/modules/router/expo.modules.router/{57.0.1/expo.modules.router-57.0.1.aar.sha512 → 57.0.3/expo.modules.router-57.0.3.aar.sha512} +0 -0
@@ -4,13 +4,13 @@ plugins {
4
4
  }
5
5
 
6
6
  group = 'expo.modules.router'
7
- version = '57.0.1'
7
+ version = '57.0.3'
8
8
 
9
9
  android {
10
10
  namespace "expo.modules.router"
11
11
  defaultConfig {
12
12
  versionCode 1
13
- versionName "57.0.1"
13
+ versionName "57.0.3"
14
14
  }
15
15
  lintOptions {
16
16
  abortOnError false
@@ -1 +1 @@
1
- {"version":3,"file":"native.android.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarButton/native.android.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAKxD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAgClE,CAAC"}
1
+ {"version":3,"file":"native.android.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarButton/native.android.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAMxD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAsClE,CAAC"}
@@ -5,6 +5,7 @@ exports.NativeToolbarButton = void 0;
5
5
  const jsx_runtime_1 = require("react/jsx-runtime");
6
6
  const jetpack_compose_1 = require("@expo/ui/jetpack-compose");
7
7
  const AnimatedItemContainer_1 = require("../../../../toolbar/AnimatedItemContainer");
8
+ const ToolbarItemBadge_1 = require("../ToolbarItemBadge");
8
9
  const context_1 = require("../context");
9
10
  const defaults_1 = require("../defaults");
10
11
  /**
@@ -25,7 +26,8 @@ const NativeToolbarButton = (props) => {
25
26
  const tintColor = props.imageRenderingMode === 'original'
26
27
  ? null
27
28
  : (props.tintColor ?? toolbarColors.tintColor ?? (0, defaults_1.DEFAULT_TOOLBAR_TINT_COLOR)());
28
- return ((0, jsx_runtime_1.jsx)(AnimatedItemContainer_1.AnimatedItemContainer, { visible: !props.hidden, children: (0, jsx_runtime_1.jsx)(jetpack_compose_1.IconButton, { onClick: props.onPress, enabled: !props.disabled, children: (0, jsx_runtime_1.jsx)(jetpack_compose_1.Icon, { source: props.source, tint: tintColor, size: 24, contentDescription: props.accessibilityLabel }) }) }));
29
+ const button = ((0, jsx_runtime_1.jsx)(jetpack_compose_1.IconButton, { onClick: props.onPress, enabled: !props.disabled, children: (0, jsx_runtime_1.jsx)(jetpack_compose_1.Icon, { source: props.source, tint: tintColor, size: 24, contentDescription: (0, ToolbarItemBadge_1.getBadgeContentDescription)(props.accessibilityLabel, props.badge) }) }));
30
+ return ((0, jsx_runtime_1.jsx)(AnimatedItemContainer_1.AnimatedItemContainer, { visible: !props.hidden, children: (0, jsx_runtime_1.jsx)(ToolbarItemBadge_1.ToolbarItemBadge, { badge: props.badge, disabled: props.disabled, children: button }) }));
29
31
  };
30
32
  exports.NativeToolbarButton = NativeToolbarButton;
31
33
  //# sourceMappingURL=native.android.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"native.android.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarButton/native.android.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;AACb,8DAA4D;AAG5D,qFAAkF;AAClF,wCAA8C;AAC9C,0CAAyD;AAEzD;;;GAGG;AACI,MAAM,mBAAmB,GAAuC,CAAC,KAAK,EAAE,EAAE;IAC/E,MAAM,aAAa,GAAG,IAAA,0BAAgB,GAAE,CAAC;IAEzC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CACV,wNAAwN,CACzN,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0EAA0E;IAC1E,4EAA4E;IAC5E,wCAAwC;IACxC,MAAM,SAAS,GACb,KAAK,CAAC,kBAAkB,KAAK,UAAU;QACrC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,aAAa,CAAC,SAAS,IAAI,IAAA,qCAA0B,GAAE,CAAC,CAAC;IAEnF,OAAO,CACL,uBAAC,6CAAqB,IAAC,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,YAC3C,uBAAC,4BAAU,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,YAC1D,uBAAC,sBAAI,IACH,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,EAAE,EACR,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,GAC5C,GACS,GACS,CACzB,CAAC;AACJ,CAAC,CAAC;AAhCW,QAAA,mBAAmB,uBAgC9B","sourcesContent":["'use client';\nimport { IconButton, Icon } from '@expo/ui/jetpack-compose';\n\nimport type { NativeToolbarButtonProps } from './types';\nimport { AnimatedItemContainer } from '../../../../toolbar/AnimatedItemContainer';\nimport { useToolbarColors } from '../context';\nimport { DEFAULT_TOOLBAR_TINT_COLOR } from '../defaults';\n\n/**\n * Native toolbar button component for Android bottom toolbar.\n * Renders as an IconButton with animated visibility.\n */\nexport const NativeToolbarButton: React.FC<NativeToolbarButtonProps> = (props) => {\n const toolbarColors = useToolbarColors();\n\n if (!props.source) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Stack.Toolbar.Button on Android requires an ImageSourcePropType icon. SF Symbols and xcasset icons are not supported. Use the `icon` prop with a require() or { uri } source, or use <Stack.Toolbar.Icon src={...} />.'\n );\n }\n return null;\n }\n\n // `tint={null}` tells `<Icon>` to draw the source in its original colors.\n // `undefined` would fall back to `LocalContentColor`, i.e. the IconButton's\n // content color, which is still a tint.\n const tintColor =\n props.imageRenderingMode === 'original'\n ? null\n : (props.tintColor ?? toolbarColors.tintColor ?? DEFAULT_TOOLBAR_TINT_COLOR());\n\n return (\n <AnimatedItemContainer visible={!props.hidden}>\n <IconButton onClick={props.onPress} enabled={!props.disabled}>\n <Icon\n source={props.source}\n tint={tintColor}\n size={24}\n contentDescription={props.accessibilityLabel}\n />\n </IconButton>\n </AnimatedItemContainer>\n );\n};\n"]}
1
+ {"version":3,"file":"native.android.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarButton/native.android.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;AACb,8DAA4D;AAG5D,qFAAkF;AAClF,0DAAmF;AACnF,wCAA8C;AAC9C,0CAAyD;AAEzD;;;GAGG;AACI,MAAM,mBAAmB,GAAuC,CAAC,KAAK,EAAE,EAAE;IAC/E,MAAM,aAAa,GAAG,IAAA,0BAAgB,GAAE,CAAC;IAEzC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CACV,wNAAwN,CACzN,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0EAA0E;IAC1E,4EAA4E;IAC5E,wCAAwC;IACxC,MAAM,SAAS,GACb,KAAK,CAAC,kBAAkB,KAAK,UAAU;QACrC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,aAAa,CAAC,SAAS,IAAI,IAAA,qCAA0B,GAAE,CAAC,CAAC;IAEnF,MAAM,MAAM,GAAG,CACb,uBAAC,4BAAU,IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,KAAK,CAAC,QAAQ,YAC1D,uBAAC,sBAAI,IACH,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,EAAE,EACR,kBAAkB,EAAE,IAAA,6CAA0B,EAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,KAAK,CAAC,GACrF,GACS,CACd,CAAC;IAEF,OAAO,CACL,uBAAC,6CAAqB,IAAC,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,YAC3C,uBAAC,mCAAgB,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,YAC3D,MAAM,GACU,GACG,CACzB,CAAC;AACJ,CAAC,CAAC;AAtCW,QAAA,mBAAmB,uBAsC9B","sourcesContent":["'use client';\nimport { Icon, IconButton } from '@expo/ui/jetpack-compose';\n\nimport type { NativeToolbarButtonProps } from './types';\nimport { AnimatedItemContainer } from '../../../../toolbar/AnimatedItemContainer';\nimport { getBadgeContentDescription, ToolbarItemBadge } from '../ToolbarItemBadge';\nimport { useToolbarColors } from '../context';\nimport { DEFAULT_TOOLBAR_TINT_COLOR } from '../defaults';\n\n/**\n * Native toolbar button component for Android bottom toolbar.\n * Renders as an IconButton with animated visibility.\n */\nexport const NativeToolbarButton: React.FC<NativeToolbarButtonProps> = (props) => {\n const toolbarColors = useToolbarColors();\n\n if (!props.source) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Stack.Toolbar.Button on Android requires an ImageSourcePropType icon. SF Symbols and xcasset icons are not supported. Use the `icon` prop with a require() or { uri } source, or use <Stack.Toolbar.Icon src={...} />.'\n );\n }\n return null;\n }\n\n // `tint={null}` tells `<Icon>` to draw the source in its original colors.\n // `undefined` would fall back to `LocalContentColor`, i.e. the IconButton's\n // content color, which is still a tint.\n const tintColor =\n props.imageRenderingMode === 'original'\n ? null\n : (props.tintColor ?? toolbarColors.tintColor ?? DEFAULT_TOOLBAR_TINT_COLOR());\n\n const button = (\n <IconButton onClick={props.onPress} enabled={!props.disabled}>\n <Icon\n source={props.source}\n tint={tintColor}\n size={24}\n contentDescription={getBadgeContentDescription(props.accessibilityLabel, props.badge)}\n />\n </IconButton>\n );\n\n return (\n <AnimatedItemContainer visible={!props.hidden}>\n <ToolbarItemBadge badge={props.badge} disabled={props.disabled}>\n {button}\n </ToolbarItemBadge>\n </AnimatedItemContainer>\n );\n};\n"]}
@@ -2,6 +2,7 @@ import { SharedRef } from 'expo';
2
2
  import type { ReactNode } from 'react';
3
3
  import type { ColorValue, ImageSourcePropType, StyleProp, TextStyle } from 'react-native';
4
4
  import type { SFSymbol } from 'sf-symbols-typescript';
5
+ import type { NativeStackHeaderItemButton } from '../../../../react-navigation/native-stack';
5
6
  import type { BasicTextStyle } from '../../../../utils/font';
6
7
  import type { StackHeaderItemSharedProps } from '../shared';
7
8
  export interface StackToolbarButtonProps {
@@ -179,5 +180,8 @@ export interface NativeToolbarButtonProps {
179
180
  variant?: 'plain' | 'done' | 'prominent';
180
181
  label?: string;
181
182
  source?: ImageSourcePropType;
183
+ /** Badge overlay on the icon. Only rendered in left/right placements.
184
+ * @platform android */
185
+ badge?: NativeStackHeaderItemButton['badge'];
182
186
  }
183
187
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarButton/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AAE5D,MAAM,WAAW,uBAAuB;IACtC;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAE1C;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAChD;;;;;;;;;;;;;;;;;;OAkBG;IACH,iBAAiB,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACpD;;;OAGG;IACH,OAAO,CAAC,EAAE,0BAA0B,CAAC,SAAS,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAChD,kBAAkB,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,WAAW,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarButton/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AAC7F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AAE5D,MAAM,WAAW,uBAAuB;IACtC;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAE1C;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAChD;;;;;;;;;;;;;;;;;;OAkBG;IACH,iBAAiB,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACpD;;;OAGG;IACH,OAAO,CAAC,EAAE,0BAA0B,CAAC,SAAS,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAChD,kBAAkB,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,WAAW,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B;2BACuB;IACvB,KAAK,CAAC,EAAE,2BAA2B,CAAC,OAAO,CAAC,CAAC;CAC9C"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarButton/types.ts"],"names":[],"mappings":"","sourcesContent":["import { SharedRef } from 'expo';\nimport type { ReactNode } from 'react';\nimport type { ColorValue, ImageSourcePropType, StyleProp, TextStyle } from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport type { BasicTextStyle } from '../../../../utils/font';\nimport type { StackHeaderItemSharedProps } from '../shared';\n\nexport interface StackToolbarButtonProps {\n /**\n * Accessibility label spoken by screen readers (TalkBack/VoiceOver).\n *\n * @see [Android — Compose accessibility for graphic elements](https://developer.android.com/develop/ui/compose/accessibility/api-defaults#graphic-elements) and [Apple — Supporting VoiceOver in your app](https://developer.apple.com/documentation/uikit/supporting-voiceover-in-your-app#Update-your-apps-accessibility) for more information.\n *\n * @platform android\n * @platform ios\n */\n accessibilityLabel?: string;\n /**\n * @platform ios\n */\n accessibilityHint?: string;\n /**\n * There are two ways to specify the content of the button:\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=\"star.fill\">As text passed as children</Stack.Toolbar.Button>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\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>\n * <Stack.Toolbar.Icon sf=\"star.fill\" />\n * <Stack.Toolbar.Label>As components</Stack.Toolbar.Label>\n * <Stack.Toolbar.Badge>3</Stack.Toolbar.Badge>\n * </Stack.Toolbar.Button>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * > **Note**: When icon is used, the label will not be shown and will be used for accessibility purposes only. Badge is only supported in left/right placements, not in bottom (iOS toolbar limitation).\n */\n children?: ReactNode;\n /**\n * @platform android\n * @platform ios\n */\n disabled?: boolean;\n /**\n * Whether the button should be hidden.\n *\n * @default false\n *\n * @platform android\n * @platform ios\n */\n hidden?: boolean;\n /**\n * Whether to hide the shared background.\n *\n * @platform iOS 26+\n */\n hidesSharedBackground?: boolean;\n /**\n * Icon to display in the button.\n *\n * On Android, only image source is supported.\n *\n * On iOS, it can be a string representing an SFSymbol, an image source or xcasset.\n *\n * > **Note**: When used in `placement=\"bottom\"` on iOS, only string SFSymbols are supported. Use the `image` prop to provide custom images.\n *\n * @platform android\n * @platform ios\n */\n icon?: StackHeaderItemSharedProps['icon'];\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display in the button.\n *\n * > **Note**: This prop is only supported in toolbar with `placement=\"bottom\"`.\n *\n * @platform ios\n */\n image?: InstanceType<SharedRef<'image'>> | null;\n /**\n * Controls how image-based icons are rendered.\n *\n * - `'template'`: applies tint color to the icon\n * - `'original'`: preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior on iOS:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * **On Android:** defaults to `'template'`.\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform android\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\n onPress?: () => void;\n /**\n * Whether to separate the background of this item from other header items.\n *\n * @default false\n * @platform ios\n */\n separateBackground?: boolean;\n /**\n * Whether the button is in a selected state\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/isselected) for more information\n *\n * @platform ios\n */\n selected?: boolean;\n /**\n * Style for the label of the header item.\n *\n * @platform android\n * @platform ios\n */\n style?: StyleProp<TextStyle>;\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 * @see [Android documentation](https://developer.android.com/develop/ui/compose/graphics/images/customize#tint-image) for more information.\n *\n * @platform android\n * @platform ios\n */\n tintColor?: StackHeaderItemSharedProps['tintColor'];\n /**\n * @default 'plain'\n * @platform ios\n */\n variant?: StackHeaderItemSharedProps['variant'];\n}\n\nexport interface NativeToolbarButtonProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n disabled?: boolean;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n icon?: SFSymbol;\n xcassetName?: string;\n image?: InstanceType<SharedRef<'image'>> | null;\n imageRenderingMode?: 'template' | 'original';\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 label?: string;\n /* @platform android */\n source?: ImageSourcePropType;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarButton/types.ts"],"names":[],"mappings":"","sourcesContent":["import { SharedRef } from 'expo';\nimport type { ReactNode } from 'react';\nimport type { ColorValue, ImageSourcePropType, StyleProp, TextStyle } from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport type { NativeStackHeaderItemButton } from '../../../../react-navigation/native-stack';\nimport type { BasicTextStyle } from '../../../../utils/font';\nimport type { StackHeaderItemSharedProps } from '../shared';\n\nexport interface StackToolbarButtonProps {\n /**\n * Accessibility label spoken by screen readers (TalkBack/VoiceOver).\n *\n * @see [Android — Compose accessibility for graphic elements](https://developer.android.com/develop/ui/compose/accessibility/api-defaults#graphic-elements) and [Apple — Supporting VoiceOver in your app](https://developer.apple.com/documentation/uikit/supporting-voiceover-in-your-app#Update-your-apps-accessibility) for more information.\n *\n * @platform android\n * @platform ios\n */\n accessibilityLabel?: string;\n /**\n * @platform ios\n */\n accessibilityHint?: string;\n /**\n * There are two ways to specify the content of the button:\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=\"star.fill\">As text passed as children</Stack.Toolbar.Button>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\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>\n * <Stack.Toolbar.Icon sf=\"star.fill\" />\n * <Stack.Toolbar.Label>As components</Stack.Toolbar.Label>\n * <Stack.Toolbar.Badge>3</Stack.Toolbar.Badge>\n * </Stack.Toolbar.Button>\n * </Stack.Toolbar>\n * <ScreenContent />\n * </>\n * );\n * }\n * ```\n *\n * > **Note**: When icon is used, the label will not be shown and will be used for accessibility purposes only. Badge is only supported in left/right placements, not in bottom (iOS toolbar limitation).\n */\n children?: ReactNode;\n /**\n * @platform android\n * @platform ios\n */\n disabled?: boolean;\n /**\n * Whether the button should be hidden.\n *\n * @default false\n *\n * @platform android\n * @platform ios\n */\n hidden?: boolean;\n /**\n * Whether to hide the shared background.\n *\n * @platform iOS 26+\n */\n hidesSharedBackground?: boolean;\n /**\n * Icon to display in the button.\n *\n * On Android, only image source is supported.\n *\n * On iOS, it can be a string representing an SFSymbol, an image source or xcasset.\n *\n * > **Note**: When used in `placement=\"bottom\"` on iOS, only string SFSymbols are supported. Use the `image` prop to provide custom images.\n *\n * @platform android\n * @platform ios\n */\n icon?: StackHeaderItemSharedProps['icon'];\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display in the button.\n *\n * > **Note**: This prop is only supported in toolbar with `placement=\"bottom\"`.\n *\n * @platform ios\n */\n image?: InstanceType<SharedRef<'image'>> | null;\n /**\n * Controls how image-based icons are rendered.\n *\n * - `'template'`: applies tint color to the icon\n * - `'original'`: preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior on iOS:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * **On Android:** defaults to `'template'`.\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform android\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\n onPress?: () => void;\n /**\n * Whether to separate the background of this item from other header items.\n *\n * @default false\n * @platform ios\n */\n separateBackground?: boolean;\n /**\n * Whether the button is in a selected state\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uibarbuttonitem/isselected) for more information\n *\n * @platform ios\n */\n selected?: boolean;\n /**\n * Style for the label of the header item.\n *\n * @platform android\n * @platform ios\n */\n style?: StyleProp<TextStyle>;\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 * @see [Android documentation](https://developer.android.com/develop/ui/compose/graphics/images/customize#tint-image) for more information.\n *\n * @platform android\n * @platform ios\n */\n tintColor?: StackHeaderItemSharedProps['tintColor'];\n /**\n * @default 'plain'\n * @platform ios\n */\n variant?: StackHeaderItemSharedProps['variant'];\n}\n\nexport interface NativeToolbarButtonProps {\n accessibilityLabel?: string;\n accessibilityHint?: string;\n disabled?: boolean;\n hidden?: boolean;\n hidesSharedBackground?: boolean;\n icon?: SFSymbol;\n xcassetName?: string;\n image?: InstanceType<SharedRef<'image'>> | null;\n imageRenderingMode?: 'template' | 'original';\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 label?: string;\n /* @platform android */\n source?: ImageSourcePropType;\n /** Badge overlay on the icon. Only rendered in left/right placements.\n * @platform android */\n badge?: NativeStackHeaderItemButton['badge'];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAClF,OAAO,KAAK,EACV,yBAAyB,EACzB,+BAA+B,EAEhC,MAAM,2CAA2C,CAAC;AAcnD,YAAY,EACV,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,SAAS,CAAC;AAqBjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA2D5D,CAAC;AAEF,wBAAgB,0CAA0C,CACxD,KAAK,EAAE,qBAAqB,EAC5B,iBAAiB,GAAE,OAAe,GACjC,yBAAyB,GAAG,SAAS,CAsCvC;AAiED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAmBxE,CAAC;AAEF,wBAAgB,gDAAgD,CAC9D,KAAK,EAAE,2BAA2B,GACjC,+BAA+B,CAwBjC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/index.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAClF,OAAO,KAAK,EACV,yBAAyB,EACzB,+BAA+B,EAEhC,MAAM,2CAA2C,CAAC;AAcnD,YAAY,EACV,qBAAqB,EACrB,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,SAAS,CAAC;AAqBjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA4D5D,CAAC;AAEF,wBAAgB,0CAA0C,CACxD,KAAK,EAAE,qBAAqB,EAC5B,iBAAiB,GAAE,OAAe,GACjC,yBAAyB,GAAG,SAAS,CAsCvC;AAiED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAmBxE,CAAC;AAEF,wBAAgB,gDAAgD,CAC9D,KAAK,EAAE,2BAA2B,GACjC,+BAA+B,CAwBjC"}
@@ -85,14 +85,14 @@ const StackToolbarMenu = (props) => {
85
85
  throw new Error(`Stack.Toolbar.Menu only accepts Stack.Toolbar.Menu, Stack.Toolbar.MenuAction, Stack.Toolbar.Label, Stack.Toolbar.Icon, and Stack.Toolbar.Badge as its children.`);
86
86
  }
87
87
  }
88
- if (process.env.NODE_ENV !== 'production') {
88
+ if (process.env.NODE_ENV !== 'production' && placement === 'bottom') {
89
89
  const hasBadge = (0, children_1.getFirstChildOfType)(props.children, toolbar_primitives_1.StackToolbarBadge);
90
90
  if (hasBadge) {
91
91
  console.warn('Stack.Toolbar.Badge is not supported in bottom toolbar (iOS limitation). The badge will be ignored.');
92
92
  }
93
93
  }
94
94
  // TODO(@ubax): Handle image loading using useImage in a follow-up PR.
95
- return ((0, jsx_runtime_1.jsx)(native_1.NativeToolbarMenu, { ...props, icon: icon, source: source, xcassetName: xcassetName, image: props.image, imageRenderingMode: imageRenderingMode, label: computedLabel, title: computedMenuTitle, children: validChildren }));
95
+ return ((0, jsx_runtime_1.jsx)(native_1.NativeToolbarMenu, { ...props, icon: icon, source: source, xcassetName: xcassetName, image: props.image, imageRenderingMode: imageRenderingMode, label: computedLabel, title: computedMenuTitle, badge: sharedProps?.badge, children: validChildren }));
96
96
  };
97
97
  exports.StackToolbarMenu = StackToolbarMenu;
98
98
  function convertStackToolbarMenuPropsToRNHeaderItem(props, isBottomPlacement = false) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/index.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport { Children, useMemo, type ReactNode } from 'react';\nimport type { ImageSourcePropType } from 'react-native';\nimport type { PlatformIconIOS } from 'react-native-screens';\n\nimport { NativeToolbarMenu, NativeToolbarMenuAction } from './native';\nimport type { StackToolbarMenuProps, StackToolbarMenuActionProps } from './types';\nimport type {\n NativeStackHeaderItemMenu,\n NativeStackHeaderItemMenuAction,\n NativeStackHeaderItemMenuSubmenu,\n} from '../../../../react-navigation/native-stack';\nimport {\n filterAllowedChildrenElements,\n getFirstChildOfType,\n isChildOfType,\n} from '../../../../utils/children';\nimport { useToolbarPlacement } from '../context';\nimport {\n convertStackHeaderSharedPropsToRNSharedHeaderItem,\n extractIconRenderingMode,\n extractXcassetName,\n} from '../shared';\nimport { StackToolbarLabel, StackToolbarIcon, StackToolbarBadge } from '../toolbar-primitives';\n\nexport type {\n StackToolbarMenuProps,\n NativeToolbarMenuProps,\n StackToolbarMenuActionProps,\n NativeToolbarMenuActionProps,\n} from './types';\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\n/**\n * Use as `Stack.Toolbar.Menu` to provide menus in the 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 * > **Note (Android):** The root `icon` must be an `ImageSourcePropType` (use a\n * > `require()` or `{ uri }` source, or `<Stack.Toolbar.Icon src={...} />`); SF Symbols\n * > and `xcasset` icons are silently dropped.\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 android\n * @platform ios\n */\nexport const StackToolbarMenu: React.FC<StackToolbarMenuProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if ((process.env.EXPO_OS === 'ios' && placement !== 'bottom') || placement == null) {\n // On ios, 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 validChildren = useMemo(\n () => filterAllowedChildrenElements(props.children, ALLOWED_CHILDREN),\n [props.children]\n );\n\n // Use shared conversion that doesn't bail on hidden, so source is always computed\n // and NativeToolbarMenu always renders — letting AnimatedItemContainer handle visibility.\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props, true);\n const { label: computedLabel, menuTitle: computedMenuTitle } = computeMenuLabelAndTitle(\n props.children,\n props.title\n );\n const icon = sharedProps?.icon?.type === 'sfSymbol' ? sharedProps.icon.name : undefined;\n const source = sharedProps?.icon?.type === 'image' ? sharedProps.icon.source : undefined;\n const xcassetName = extractXcassetName(props);\n const imageRenderingMode = extractIconRenderingMode(props) ?? props.iconRenderingMode;\n\n if (process.env.NODE_ENV !== 'production') {\n const allChildren = Children.toArray(props.children);\n if (allChildren.length !== validChildren.length) {\n throw new Error(\n `Stack.Toolbar.Menu only accepts Stack.Toolbar.Menu, Stack.Toolbar.MenuAction, Stack.Toolbar.Label, Stack.Toolbar.Icon, and Stack.Toolbar.Badge as its children.`\n );\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n const hasBadge = getFirstChildOfType(props.children, StackToolbarBadge);\n if (hasBadge) {\n console.warn(\n 'Stack.Toolbar.Badge is not supported in bottom toolbar (iOS limitation). The badge will be ignored.'\n );\n }\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n return (\n <NativeToolbarMenu\n {...props}\n icon={icon}\n source={source}\n xcassetName={xcassetName}\n image={props.image}\n imageRenderingMode={imageRenderingMode}\n label={computedLabel}\n title={computedMenuTitle}\n children={validChildren}\n />\n );\n};\n\nexport function convertStackToolbarMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps,\n isBottomPlacement: boolean = false\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, isBottomPlacement);\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\n// Custom menu action icons are not supported in react-navigation yet\n// But they are supported in react-native-screens\n// TODO(@ubax): Remove this workaround once react-navigation supports custom icons for menu actions.\n// https://linear.app/expo/issue/ENG-19853/remove-custom-conversion-logic-for-icon-from-packagesexpo\nfunction convertImageIconToPlatformIcon(icon: {\n source: ImageSourcePropType;\n tinted?: boolean;\n}): PlatformIconIOS {\n return icon.tinted\n ? { type: 'templateSource', templateSource: icon.source }\n : { type: 'imageSource', imageSource: icon.source };\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 if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n item.icon = convertImageIconToPlatformIcon(\n sharedProps.icon\n ) as unknown as NativeStackHeaderItemMenuSubmenu['icon'];\n }\n }\n\n return item;\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 android\n * @platform ios\n */\nexport const StackToolbarMenuAction: React.FC<StackToolbarMenuActionProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if (process.env.EXPO_OS === 'ios' && placement !== 'bottom') {\n throw new Error('Stack.Toolbar.MenuAction must be used inside a Stack.Toolbar.Menu');\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n const icon = typeof props.icon === 'string' ? props.icon : undefined;\n const source = typeof props.icon !== 'string' ? props.icon : undefined;\n return (\n <NativeToolbarMenuAction\n {...props}\n icon={icon}\n source={source}\n image={props.image}\n imageRenderingMode={props.iconRenderingMode}\n />\n );\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 description: props.subtitle,\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 if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n item.icon = convertImageIconToPlatformIcon(\n sharedProps.icon\n ) as unknown as NativeStackHeaderItemMenuAction['icon'];\n }\n }\n return item;\n}\n\nconst ALLOWED_CHILDREN = [\n StackToolbarMenu,\n StackToolbarMenuAction,\n NativeToolbarMenu,\n NativeToolbarMenuAction,\n StackToolbarLabel,\n StackToolbarIcon,\n StackToolbarBadge,\n];\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/index.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport { Children, useMemo, type ReactNode } from 'react';\nimport type { ImageSourcePropType } from 'react-native';\nimport type { PlatformIconIOS } from 'react-native-screens';\n\nimport { NativeToolbarMenu, NativeToolbarMenuAction } from './native';\nimport type { StackToolbarMenuProps, StackToolbarMenuActionProps } from './types';\nimport type {\n NativeStackHeaderItemMenu,\n NativeStackHeaderItemMenuAction,\n NativeStackHeaderItemMenuSubmenu,\n} from '../../../../react-navigation/native-stack';\nimport {\n filterAllowedChildrenElements,\n getFirstChildOfType,\n isChildOfType,\n} from '../../../../utils/children';\nimport { useToolbarPlacement } from '../context';\nimport {\n convertStackHeaderSharedPropsToRNSharedHeaderItem,\n extractIconRenderingMode,\n extractXcassetName,\n} from '../shared';\nimport { StackToolbarLabel, StackToolbarIcon, StackToolbarBadge } from '../toolbar-primitives';\n\nexport type {\n StackToolbarMenuProps,\n NativeToolbarMenuProps,\n StackToolbarMenuActionProps,\n NativeToolbarMenuActionProps,\n} from './types';\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\n/**\n * Use as `Stack.Toolbar.Menu` to provide menus in the 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 * > **Note (Android):** The root `icon` must be an `ImageSourcePropType` (use a\n * > `require()` or `{ uri }` source, or `<Stack.Toolbar.Icon src={...} />`); SF Symbols\n * > and `xcasset` icons are silently dropped.\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 android\n * @platform ios\n */\nexport const StackToolbarMenu: React.FC<StackToolbarMenuProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if ((process.env.EXPO_OS === 'ios' && placement !== 'bottom') || placement == null) {\n // On ios, 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 validChildren = useMemo(\n () => filterAllowedChildrenElements(props.children, ALLOWED_CHILDREN),\n [props.children]\n );\n\n // Use shared conversion that doesn't bail on hidden, so source is always computed\n // and NativeToolbarMenu always renders — letting AnimatedItemContainer handle visibility.\n const sharedProps = convertStackHeaderSharedPropsToRNSharedHeaderItem(props, true);\n const { label: computedLabel, menuTitle: computedMenuTitle } = computeMenuLabelAndTitle(\n props.children,\n props.title\n );\n const icon = sharedProps?.icon?.type === 'sfSymbol' ? sharedProps.icon.name : undefined;\n const source = sharedProps?.icon?.type === 'image' ? sharedProps.icon.source : undefined;\n const xcassetName = extractXcassetName(props);\n const imageRenderingMode = extractIconRenderingMode(props) ?? props.iconRenderingMode;\n\n if (process.env.NODE_ENV !== 'production') {\n const allChildren = Children.toArray(props.children);\n if (allChildren.length !== validChildren.length) {\n throw new Error(\n `Stack.Toolbar.Menu only accepts Stack.Toolbar.Menu, Stack.Toolbar.MenuAction, Stack.Toolbar.Label, Stack.Toolbar.Icon, and Stack.Toolbar.Badge as its children.`\n );\n }\n }\n\n if (process.env.NODE_ENV !== 'production' && placement === 'bottom') {\n const hasBadge = getFirstChildOfType(props.children, StackToolbarBadge);\n if (hasBadge) {\n console.warn(\n 'Stack.Toolbar.Badge is not supported in bottom toolbar (iOS limitation). The badge will be ignored.'\n );\n }\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n return (\n <NativeToolbarMenu\n {...props}\n icon={icon}\n source={source}\n xcassetName={xcassetName}\n image={props.image}\n imageRenderingMode={imageRenderingMode}\n label={computedLabel}\n title={computedMenuTitle}\n badge={sharedProps?.badge}\n children={validChildren}\n />\n );\n};\n\nexport function convertStackToolbarMenuPropsToRNHeaderItem(\n props: StackToolbarMenuProps,\n isBottomPlacement: boolean = false\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, isBottomPlacement);\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\n// Custom menu action icons are not supported in react-navigation yet\n// But they are supported in react-native-screens\n// TODO(@ubax): Remove this workaround once react-navigation supports custom icons for menu actions.\n// https://linear.app/expo/issue/ENG-19853/remove-custom-conversion-logic-for-icon-from-packagesexpo\nfunction convertImageIconToPlatformIcon(icon: {\n source: ImageSourcePropType;\n tinted?: boolean;\n}): PlatformIconIOS {\n return icon.tinted\n ? { type: 'templateSource', templateSource: icon.source }\n : { type: 'imageSource', imageSource: icon.source };\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 if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n item.icon = convertImageIconToPlatformIcon(\n sharedProps.icon\n ) as unknown as NativeStackHeaderItemMenuSubmenu['icon'];\n }\n }\n\n return item;\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 android\n * @platform ios\n */\nexport const StackToolbarMenuAction: React.FC<StackToolbarMenuActionProps> = (props) => {\n const placement = useToolbarPlacement();\n\n if (process.env.EXPO_OS === 'ios' && placement !== 'bottom') {\n throw new Error('Stack.Toolbar.MenuAction must be used inside a Stack.Toolbar.Menu');\n }\n\n // TODO(@ubax): Handle image loading using useImage in a follow-up PR.\n const icon = typeof props.icon === 'string' ? props.icon : undefined;\n const source = typeof props.icon !== 'string' ? props.icon : undefined;\n return (\n <NativeToolbarMenuAction\n {...props}\n icon={icon}\n source={source}\n image={props.image}\n imageRenderingMode={props.iconRenderingMode}\n />\n );\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 description: props.subtitle,\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 if (sharedProps.icon.type === 'sfSymbol') {\n item.icon = sharedProps.icon;\n } else {\n item.icon = convertImageIconToPlatformIcon(\n sharedProps.icon\n ) as unknown as NativeStackHeaderItemMenuAction['icon'];\n }\n }\n return item;\n}\n\nconst ALLOWED_CHILDREN = [\n StackToolbarMenu,\n StackToolbarMenuAction,\n NativeToolbarMenu,\n NativeToolbarMenuAction,\n StackToolbarLabel,\n StackToolbarIcon,\n StackToolbarBadge,\n];\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"native.android.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/native.android.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAqBpF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA+G9D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CA4C1E,CAAC"}
1
+ {"version":3,"file":"native.android.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/native.android.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,4BAA4B,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAsBpF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA2H9D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CA4C1E,CAAC"}
@@ -9,6 +9,7 @@ const react_1 = require("react");
9
9
  const primitives_1 = require("../../../../primitives");
10
10
  const AnimatedItemContainer_1 = require("../../../../toolbar/AnimatedItemContainer");
11
11
  const children_1 = require("../../../../utils/children");
12
+ const ToolbarItemBadge_1 = require("../ToolbarItemBadge");
12
13
  const context_1 = require("../context");
13
14
  const defaults_1 = require("../defaults");
14
15
  const arrowRightIcon = require('../../../../../assets/arrow_right.xml');
@@ -40,6 +41,9 @@ const NativeToolbarMenu = (props) => {
40
41
  setExpanded(false);
41
42
  parentClose?.();
42
43
  }, [parentClose]);
44
+ if (process.env.NODE_ENV !== 'production' && isNested && props.badge) {
45
+ console.warn('Stack.Toolbar.Badge on a nested Stack.Toolbar.Menu is not supported on Android; it is only rendered on a root menu. The badge will be ignored.');
46
+ }
43
47
  // Inline nested: render children directly with a divider separator
44
48
  if (isNested && props.inline) {
45
49
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(jetpack_compose_1.HorizontalDivider, {}), props.children] }));
@@ -62,7 +66,8 @@ const NativeToolbarMenu = (props) => {
62
66
  }
63
67
  return null;
64
68
  }
65
- return ((0, jsx_runtime_1.jsx)(AnimatedItemContainer_1.AnimatedItemContainer, { visible: !props.hidden, children: (0, jsx_runtime_1.jsxs)(jetpack_compose_1.DropdownMenu, { expanded: expanded, onDismissRequest: () => setExpanded(false), color: backgroundColor, children: [(0, jsx_runtime_1.jsx)(jetpack_compose_1.DropdownMenu.Trigger, { children: (0, jsx_runtime_1.jsx)(jetpack_compose_1.IconButton, { onClick: () => setExpanded(true), enabled: !props.disabled, modifiers: [(0, modifiers_1.background)(backgroundColor)], children: (0, jsx_runtime_1.jsx)(jetpack_compose_1.Icon, { source: props.source, tint: sourceTint, size: 24, contentDescription: props.accessibilityLabel }) }) }), (0, jsx_runtime_1.jsx)(jetpack_compose_1.DropdownMenu.Items, { children: (0, jsx_runtime_1.jsx)(ToolbarMenuCloseContext, { value: closeMenu, children: props.children }) })] }) }));
69
+ const iconButton = ((0, jsx_runtime_1.jsx)(jetpack_compose_1.IconButton, { onClick: () => setExpanded(true), enabled: !props.disabled, modifiers: [(0, modifiers_1.background)(backgroundColor)], children: (0, jsx_runtime_1.jsx)(jetpack_compose_1.Icon, { source: props.source, tint: sourceTint, size: 24, contentDescription: (0, ToolbarItemBadge_1.getBadgeContentDescription)(props.accessibilityLabel, props.badge) }) }));
70
+ return ((0, jsx_runtime_1.jsx)(AnimatedItemContainer_1.AnimatedItemContainer, { visible: !props.hidden, children: (0, jsx_runtime_1.jsxs)(jetpack_compose_1.DropdownMenu, { expanded: expanded, onDismissRequest: () => setExpanded(false), color: backgroundColor, children: [(0, jsx_runtime_1.jsx)(jetpack_compose_1.DropdownMenu.Trigger, { children: (0, jsx_runtime_1.jsx)(ToolbarItemBadge_1.ToolbarItemBadge, { badge: props.badge, disabled: props.disabled, children: iconButton }) }), (0, jsx_runtime_1.jsx)(jetpack_compose_1.DropdownMenu.Items, { children: (0, jsx_runtime_1.jsx)(ToolbarMenuCloseContext, { value: closeMenu, children: props.children }) })] }) }));
66
71
  };
67
72
  exports.NativeToolbarMenu = NativeToolbarMenu;
68
73
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"native.android.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/native.android.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport {\n DropdownMenu,\n DropdownMenuItem,\n HorizontalDivider,\n Icon,\n IconButton,\n Text as ComposeText,\n} from '@expo/ui/jetpack-compose';\nimport { background } from '@expo/ui/jetpack-compose/modifiers';\nimport { createContext, use, useCallback, useState } from 'react';\n\nimport type { NativeToolbarMenuActionProps, NativeToolbarMenuProps } from './types';\nimport { Label } from '../../../../primitives';\nimport { AnimatedItemContainer } from '../../../../toolbar/AnimatedItemContainer';\nimport { getFirstChildOfType } from '../../../../utils/children';\nimport { useToolbarColors } from '../context';\nimport {\n DEFAULT_DESTRUCTIVE_COLOR,\n DEFAULT_TOOLBAR_BACKGROUND_COLOR,\n DEFAULT_TOOLBAR_TINT_COLOR,\n} from '../defaults';\n\nconst arrowRightIcon = require('../../../../../assets/arrow_right.xml');\nconst checkmarkIcon = require('../../../../../assets/checkmark.xml');\n\n/**\n * Context for propagating menu close callbacks from root to nested menus.\n * - `null` means root level (no parent menu)\n * - A function means nested level (call to close entire menu chain)\n */\nconst ToolbarMenuCloseContext = createContext<(() => void) | null>(null);\n\n/**\n * Native toolbar menu component for Android bottom toolbar.\n * Renders as a DropdownMenu with IconButton trigger (root) or DropdownMenuItem trigger (nested).\n */\nexport const NativeToolbarMenu: React.FC<NativeToolbarMenuProps> = (props) => {\n const [expanded, setExpanded] = useState(false);\n const parentClose = use(ToolbarMenuCloseContext);\n const isNested = parentClose !== null;\n const toolbarColors = useToolbarColors();\n\n const tintColor = props.tintColor ?? toolbarColors.tintColor ?? DEFAULT_TOOLBAR_TINT_COLOR();\n // `tint={null}` tells `<Icon>` to draw the source in its original colors.\n // `undefined` would fall back to `LocalContentColor` (i.e. still a tint).\n // Only the user-provided source respects `imageRenderingMode`; internal\n // ornaments (submenu arrow, action checkmark) are always tinted.\n const sourceTint = props.imageRenderingMode === 'original' ? null : tintColor;\n\n const backgroundColor = (toolbarColors.backgroundColor ??\n DEFAULT_TOOLBAR_BACKGROUND_COLOR()) as string;\n\n const closeMenu = useCallback(() => {\n setExpanded(false);\n parentClose?.();\n }, [parentClose]);\n\n // Inline nested: render children directly with a divider separator\n if (isNested && props.inline) {\n return (\n <>\n <HorizontalDivider />\n {props.children}\n </>\n );\n }\n\n // Non-inline nested: DropdownMenu with DropdownMenuItem trigger\n if (isNested) {\n const trailingIcon = (\n <DropdownMenuItem.TrailingIcon>\n <Icon source={arrowRightIcon} tint={tintColor} size={24} />\n </DropdownMenuItem.TrailingIcon>\n );\n const leadingIcon = props.source ? (\n <DropdownMenuItem.LeadingIcon>\n <Icon source={props.source} tint={sourceTint} size={24} />\n </DropdownMenuItem.LeadingIcon>\n ) : null;\n return (\n <DropdownMenu\n expanded={expanded}\n onDismissRequest={() => setExpanded(false)}\n color={backgroundColor}>\n <DropdownMenu.Trigger>\n <DropdownMenuItem\n onClick={() => {\n if (!props.disabled) setExpanded(true);\n }}\n modifiers={[background(backgroundColor)]}\n enabled={!props.disabled}>\n {leadingIcon}\n <DropdownMenuItem.Text>\n <ComposeText\n color={\n typeof props.tintColor === 'string'\n ? props.tintColor\n : ((toolbarColors.tintColor ?? DEFAULT_TOOLBAR_TINT_COLOR()) as string)\n }>\n {props.label}\n </ComposeText>\n </DropdownMenuItem.Text>\n {trailingIcon}\n </DropdownMenuItem>\n </DropdownMenu.Trigger>\n <DropdownMenu.Items>\n <ToolbarMenuCloseContext value={closeMenu}>{props.children}</ToolbarMenuCloseContext>\n </DropdownMenu.Items>\n </DropdownMenu>\n );\n }\n\n // Root: AnimatedItemContainer + IconButton trigger + DropdownMenu\n if (!props.source) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Stack.Toolbar.Menu on Android requires an ImageSourcePropType icon. SF Symbols and xcasset icons are not supported. Use the `icon` prop with a require() or { uri } source, or use <Stack.Toolbar.Icon src={...} />.'\n );\n }\n return null;\n }\n\n return (\n <AnimatedItemContainer visible={!props.hidden}>\n <DropdownMenu\n expanded={expanded}\n onDismissRequest={() => setExpanded(false)}\n color={backgroundColor}>\n <DropdownMenu.Trigger>\n <IconButton\n onClick={() => setExpanded(true)}\n enabled={!props.disabled}\n modifiers={[background(backgroundColor)]}>\n <Icon\n source={props.source}\n tint={sourceTint}\n size={24}\n contentDescription={props.accessibilityLabel}\n />\n </IconButton>\n </DropdownMenu.Trigger>\n <DropdownMenu.Items>\n <ToolbarMenuCloseContext value={closeMenu}>{props.children}</ToolbarMenuCloseContext>\n </DropdownMenu.Items>\n </DropdownMenu>\n </AnimatedItemContainer>\n );\n};\n\n/**\n * Native toolbar menu action component for Android.\n * Renders as a DropdownMenuItem.\n */\nexport const NativeToolbarMenuAction: React.FC<NativeToolbarMenuActionProps> = (props) => {\n const closeMenu = use(ToolbarMenuCloseContext);\n const toolbarColors = useToolbarColors();\n const tintColor = props.destructive\n ? (DEFAULT_DESTRUCTIVE_COLOR() as string)\n : ((toolbarColors.tintColor ?? DEFAULT_TOOLBAR_TINT_COLOR()) as string);\n\n const backgroundColor = (toolbarColors.backgroundColor ??\n DEFAULT_TOOLBAR_BACKGROUND_COLOR()) as string;\n\n const handleClick = useCallback(() => {\n props.onPress?.();\n if (!props.unstable_keepPresented) {\n closeMenu?.();\n }\n }, [props.onPress, props.unstable_keepPresented, closeMenu]);\n\n const areChildrenString = typeof props.children === 'string';\n const label = areChildrenString\n ? props.children\n : (getFirstChildOfType(props.children, Label)?.props.children ?? '');\n\n if (props.hidden) return null;\n\n return (\n <DropdownMenuItem\n onClick={handleClick}\n modifiers={[background(backgroundColor)]}\n enabled={!props.disabled}>\n <DropdownMenuItem.Text>\n <ComposeText color={tintColor}>{label}</ComposeText>\n </DropdownMenuItem.Text>\n {props.source && (\n <DropdownMenuItem.LeadingIcon>\n <Icon source={props.source} tint={tintColor} size={24} />\n </DropdownMenuItem.LeadingIcon>\n )}\n {props.isOn && (\n <DropdownMenuItem.TrailingIcon>\n <Icon source={checkmarkIcon} tint={tintColor} size={24} />\n </DropdownMenuItem.TrailingIcon>\n )}\n </DropdownMenuItem>\n );\n};\n"]}
1
+ {"version":3,"file":"native.android.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/native.android.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport {\n DropdownMenu,\n DropdownMenuItem,\n HorizontalDivider,\n Icon,\n IconButton,\n Text as ComposeText,\n} from '@expo/ui/jetpack-compose';\nimport { background } from '@expo/ui/jetpack-compose/modifiers';\nimport { createContext, use, useCallback, useState } from 'react';\n\nimport type { NativeToolbarMenuActionProps, NativeToolbarMenuProps } from './types';\nimport { Label } from '../../../../primitives';\nimport { AnimatedItemContainer } from '../../../../toolbar/AnimatedItemContainer';\nimport { getFirstChildOfType } from '../../../../utils/children';\nimport { getBadgeContentDescription, ToolbarItemBadge } from '../ToolbarItemBadge';\nimport { useToolbarColors } from '../context';\nimport {\n DEFAULT_DESTRUCTIVE_COLOR,\n DEFAULT_TOOLBAR_BACKGROUND_COLOR,\n DEFAULT_TOOLBAR_TINT_COLOR,\n} from '../defaults';\n\nconst arrowRightIcon = require('../../../../../assets/arrow_right.xml');\nconst checkmarkIcon = require('../../../../../assets/checkmark.xml');\n\n/**\n * Context for propagating menu close callbacks from root to nested menus.\n * - `null` means root level (no parent menu)\n * - A function means nested level (call to close entire menu chain)\n */\nconst ToolbarMenuCloseContext = createContext<(() => void) | null>(null);\n\n/**\n * Native toolbar menu component for Android bottom toolbar.\n * Renders as a DropdownMenu with IconButton trigger (root) or DropdownMenuItem trigger (nested).\n */\nexport const NativeToolbarMenu: React.FC<NativeToolbarMenuProps> = (props) => {\n const [expanded, setExpanded] = useState(false);\n const parentClose = use(ToolbarMenuCloseContext);\n const isNested = parentClose !== null;\n const toolbarColors = useToolbarColors();\n\n const tintColor = props.tintColor ?? toolbarColors.tintColor ?? DEFAULT_TOOLBAR_TINT_COLOR();\n // `tint={null}` tells `<Icon>` to draw the source in its original colors.\n // `undefined` would fall back to `LocalContentColor` (i.e. still a tint).\n // Only the user-provided source respects `imageRenderingMode`; internal\n // ornaments (submenu arrow, action checkmark) are always tinted.\n const sourceTint = props.imageRenderingMode === 'original' ? null : tintColor;\n\n const backgroundColor = (toolbarColors.backgroundColor ??\n DEFAULT_TOOLBAR_BACKGROUND_COLOR()) as string;\n\n const closeMenu = useCallback(() => {\n setExpanded(false);\n parentClose?.();\n }, [parentClose]);\n\n if (process.env.NODE_ENV !== 'production' && isNested && props.badge) {\n console.warn(\n 'Stack.Toolbar.Badge on a nested Stack.Toolbar.Menu is not supported on Android; it is only rendered on a root menu. The badge will be ignored.'\n );\n }\n\n // Inline nested: render children directly with a divider separator\n if (isNested && props.inline) {\n return (\n <>\n <HorizontalDivider />\n {props.children}\n </>\n );\n }\n\n // Non-inline nested: DropdownMenu with DropdownMenuItem trigger\n if (isNested) {\n const trailingIcon = (\n <DropdownMenuItem.TrailingIcon>\n <Icon source={arrowRightIcon} tint={tintColor} size={24} />\n </DropdownMenuItem.TrailingIcon>\n );\n const leadingIcon = props.source ? (\n <DropdownMenuItem.LeadingIcon>\n <Icon source={props.source} tint={sourceTint} size={24} />\n </DropdownMenuItem.LeadingIcon>\n ) : null;\n return (\n <DropdownMenu\n expanded={expanded}\n onDismissRequest={() => setExpanded(false)}\n color={backgroundColor}>\n <DropdownMenu.Trigger>\n <DropdownMenuItem\n onClick={() => {\n if (!props.disabled) setExpanded(true);\n }}\n modifiers={[background(backgroundColor)]}\n enabled={!props.disabled}>\n {leadingIcon}\n <DropdownMenuItem.Text>\n <ComposeText\n color={\n typeof props.tintColor === 'string'\n ? props.tintColor\n : ((toolbarColors.tintColor ?? DEFAULT_TOOLBAR_TINT_COLOR()) as string)\n }>\n {props.label}\n </ComposeText>\n </DropdownMenuItem.Text>\n {trailingIcon}\n </DropdownMenuItem>\n </DropdownMenu.Trigger>\n <DropdownMenu.Items>\n <ToolbarMenuCloseContext value={closeMenu}>{props.children}</ToolbarMenuCloseContext>\n </DropdownMenu.Items>\n </DropdownMenu>\n );\n }\n\n // Root: AnimatedItemContainer + IconButton trigger + DropdownMenu\n if (!props.source) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn(\n 'Stack.Toolbar.Menu on Android requires an ImageSourcePropType icon. SF Symbols and xcasset icons are not supported. Use the `icon` prop with a require() or { uri } source, or use <Stack.Toolbar.Icon src={...} />.'\n );\n }\n return null;\n }\n\n const iconButton = (\n <IconButton\n onClick={() => setExpanded(true)}\n enabled={!props.disabled}\n modifiers={[background(backgroundColor)]}>\n <Icon\n source={props.source}\n tint={sourceTint}\n size={24}\n contentDescription={getBadgeContentDescription(props.accessibilityLabel, props.badge)}\n />\n </IconButton>\n );\n\n return (\n <AnimatedItemContainer visible={!props.hidden}>\n <DropdownMenu\n expanded={expanded}\n onDismissRequest={() => setExpanded(false)}\n color={backgroundColor}>\n <DropdownMenu.Trigger>\n <ToolbarItemBadge badge={props.badge} disabled={props.disabled}>\n {iconButton}\n </ToolbarItemBadge>\n </DropdownMenu.Trigger>\n <DropdownMenu.Items>\n <ToolbarMenuCloseContext value={closeMenu}>{props.children}</ToolbarMenuCloseContext>\n </DropdownMenu.Items>\n </DropdownMenu>\n </AnimatedItemContainer>\n );\n};\n\n/**\n * Native toolbar menu action component for Android.\n * Renders as a DropdownMenuItem.\n */\nexport const NativeToolbarMenuAction: React.FC<NativeToolbarMenuActionProps> = (props) => {\n const closeMenu = use(ToolbarMenuCloseContext);\n const toolbarColors = useToolbarColors();\n const tintColor = props.destructive\n ? (DEFAULT_DESTRUCTIVE_COLOR() as string)\n : ((toolbarColors.tintColor ?? DEFAULT_TOOLBAR_TINT_COLOR()) as string);\n\n const backgroundColor = (toolbarColors.backgroundColor ??\n DEFAULT_TOOLBAR_BACKGROUND_COLOR()) as string;\n\n const handleClick = useCallback(() => {\n props.onPress?.();\n if (!props.unstable_keepPresented) {\n closeMenu?.();\n }\n }, [props.onPress, props.unstable_keepPresented, closeMenu]);\n\n const areChildrenString = typeof props.children === 'string';\n const label = areChildrenString\n ? props.children\n : (getFirstChildOfType(props.children, Label)?.props.children ?? '');\n\n if (props.hidden) return null;\n\n return (\n <DropdownMenuItem\n onClick={handleClick}\n modifiers={[background(backgroundColor)]}\n enabled={!props.disabled}>\n <DropdownMenuItem.Text>\n <ComposeText color={tintColor}>{label}</ComposeText>\n </DropdownMenuItem.Text>\n {props.source && (\n <DropdownMenuItem.LeadingIcon>\n <Icon source={props.source} tint={tintColor} size={24} />\n </DropdownMenuItem.LeadingIcon>\n )}\n {props.isOn && (\n <DropdownMenuItem.TrailingIcon>\n <Icon source={checkmarkIcon} tint={tintColor} size={24} />\n </DropdownMenuItem.TrailingIcon>\n )}\n </DropdownMenuItem>\n );\n};\n"]}
@@ -3,6 +3,7 @@ import type { ReactNode } from 'react';
3
3
  import type { ColorValue, ImageSourcePropType, StyleProp, TextStyle } from 'react-native';
4
4
  import type { SFSymbol } from 'sf-symbols-typescript';
5
5
  import type { LinkMenuActionProps } from '../../../../link/elements';
6
+ import type { NativeStackHeaderItemButton } from '../../../../react-navigation/native-stack';
6
7
  import type { StackHeaderItemSharedProps } from '../shared';
7
8
  export interface StackToolbarMenuProps {
8
9
  /**
@@ -205,6 +206,9 @@ export interface NativeToolbarMenuProps {
205
206
  elementSize?: 'auto' | 'small' | 'medium' | 'large';
206
207
  /** @platform android */
207
208
  source?: ImageSourcePropType;
209
+ /** Badge overlay on the menu icon. Only rendered at the root (left/right placements).
210
+ * @platform android */
211
+ badge?: NativeStackHeaderItemButton['badge'];
208
212
  }
209
213
  export interface StackToolbarMenuActionProps {
210
214
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/types.ts"],"names":[],"mappings":"","sourcesContent":["import { SharedRef } from 'expo';\nimport type { ReactNode } from 'react';\nimport type { ColorValue, ImageSourcePropType, StyleProp, TextStyle } from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport type { LinkMenuActionProps } from '../../../../link/elements';\nimport type { StackHeaderItemSharedProps } from '../shared';\n\nexport interface StackToolbarMenuProps {\n /**\n * Accessibility label spoken by screen readers (TalkBack/VoiceOver).\n *\n * @see [Android — Compose accessibility for graphic elements](https://developer.android.com/develop/ui/compose/accessibility/api-defaults#graphic-elements) and [Apple — Supporting VoiceOver in your app](https://developer.apple.com/documentation/uikit/supporting-voiceover-in-your-app#Update-your-apps-accessibility) for more information.\n *\n * @platform android\n * @platform ios\n */\n accessibilityLabel?: string;\n /**\n * @platform ios\n */\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 * @platform android\n * @platform ios\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 * @platform ios\n */\n destructive?: boolean;\n /**\n * @platform android\n * @platform ios\n */\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 * @platform ios\n */\n image?: InstanceType<SharedRef<'image'>> | null;\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 * @platform android\n * @platform ios\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\"` on iOS, only string SFSymbols are supported. Use the `image` prop to provide custom images.\n *\n * > **Note (Android)**: Only `ImageSourcePropType` icons are rendered at the menu root.\n * > SF Symbols and `xcasset` names are silently dropped — provide a `require()` or\n * > `{ uri }` source.\n *\n * @platform android\n * @platform ios\n */\n icon?: StackHeaderItemSharedProps['icon'];\n /**\n * Controls how image-based icons are rendered.\n *\n * - `'template'`: applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior on iOS:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * **On Android:** defaults to `'template'`.\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform android\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\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 * @platform android\n * @platform ios\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 * @platform ios\n */\n palette?: boolean;\n /**\n * Whether to separate the background of this item from other header items.\n *\n * @default false\n * @platform ios\n */\n separateBackground?: boolean;\n /**\n * Style for the label of the header item.\n *\n * @platform android\n * @platform ios\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 * @see [Android documentation](https://developer.android.com/develop/ui/compose/graphics/images/customize#tint-image) for more information.\n *\n * @platform android\n * @platform ios\n */\n tintColor?: StackHeaderItemSharedProps['tintColor'];\n /**\n * Optional title to show on top of the menu.\n *\n * @platform android\n * @platform ios\n */\n title?: string;\n /**\n * @default 'plain'\n *\n * @platform ios\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\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;\n xcassetName?: string;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n */\n image?: InstanceType<SharedRef<'image'>> | null;\n imageRenderingMode?: 'template' | 'original';\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 /** @platform android */\n source?: ImageSourcePropType;\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 /**\n * Icon for the menu action.\n *\n * Can be an SF Symbol name or an image source.\n *\n * > **Note (Android)**: Only `ImageSourcePropType` icons are rendered. SF Symbols are\n * > silently dropped. Provide a `require()` or `{ uri }` source.\n */\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 * @platform ios\n */\n image?: InstanceType<SharedRef<'image'>> | null;\n /**\n * Controls how image-based icons are rendered on iOS.\n *\n * - `'template'`: iOS applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: Preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\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 * @platform android\n * @platform ios\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 on iOS it will recreate\n * the menu, 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 * @platform android\n * @platform ios\n */\n unstable_keepPresented?: boolean;\n /**\n * If `true`, the menu item will be displayed as selected.\n *\n * @platform android\n * @platform ios\n */\n isOn?: boolean;\n onPress?: () => void;\n /**\n * An elaborated title that explains the purpose of the action.\n *\n * @platform ios\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 * @platform ios\n */\n subtitle?: string;\n hidden?: boolean;\n}\n\nexport interface NativeToolbarMenuActionProps extends LinkMenuActionProps {\n /** @platform android */\n source?: ImageSourcePropType;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/layouts/stack-utils/toolbar/StackToolbarMenu/types.ts"],"names":[],"mappings":"","sourcesContent":["import { SharedRef } from 'expo';\nimport type { ReactNode } from 'react';\nimport type { ColorValue, ImageSourcePropType, StyleProp, TextStyle } from 'react-native';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport type { LinkMenuActionProps } from '../../../../link/elements';\nimport type { NativeStackHeaderItemButton } from '../../../../react-navigation/native-stack';\nimport type { StackHeaderItemSharedProps } from '../shared';\n\nexport interface StackToolbarMenuProps {\n /**\n * Accessibility label spoken by screen readers (TalkBack/VoiceOver).\n *\n * @see [Android — Compose accessibility for graphic elements](https://developer.android.com/develop/ui/compose/accessibility/api-defaults#graphic-elements) and [Apple — Supporting VoiceOver in your app](https://developer.apple.com/documentation/uikit/supporting-voiceover-in-your-app#Update-your-apps-accessibility) for more information.\n *\n * @platform android\n * @platform ios\n */\n accessibilityLabel?: string;\n /**\n * @platform ios\n */\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 * @platform android\n * @platform ios\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 * @platform ios\n */\n destructive?: boolean;\n /**\n * @platform android\n * @platform ios\n */\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 * @platform ios\n */\n image?: InstanceType<SharedRef<'image'>> | null;\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 * @platform android\n * @platform ios\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\"` on iOS, only string SFSymbols are supported. Use the `image` prop to provide custom images.\n *\n * > **Note (Android)**: Only `ImageSourcePropType` icons are rendered at the menu root.\n * > SF Symbols and `xcasset` names are silently dropped — provide a `require()` or\n * > `{ uri }` source.\n *\n * @platform android\n * @platform ios\n */\n icon?: StackHeaderItemSharedProps['icon'];\n /**\n * Controls how image-based icons are rendered.\n *\n * - `'template'`: applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior on iOS:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * **On Android:** defaults to `'template'`.\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform android\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\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 * @platform android\n * @platform ios\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 * @platform ios\n */\n palette?: boolean;\n /**\n * Whether to separate the background of this item from other header items.\n *\n * @default false\n * @platform ios\n */\n separateBackground?: boolean;\n /**\n * Style for the label of the header item.\n *\n * @platform android\n * @platform ios\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 * @see [Android documentation](https://developer.android.com/develop/ui/compose/graphics/images/customize#tint-image) for more information.\n *\n * @platform android\n * @platform ios\n */\n tintColor?: StackHeaderItemSharedProps['tintColor'];\n /**\n * Optional title to show on top of the menu.\n *\n * @platform android\n * @platform ios\n */\n title?: string;\n /**\n * @default 'plain'\n *\n * @platform ios\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\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;\n xcassetName?: string;\n // TODO(@ubax): Add useImage support in a follow-up PR.\n /**\n * Image to display for the menu item.\n */\n image?: InstanceType<SharedRef<'image'>> | null;\n imageRenderingMode?: 'template' | 'original';\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 /** @platform android */\n source?: ImageSourcePropType;\n /** Badge overlay on the menu icon. Only rendered at the root (left/right placements).\n * @platform android */\n badge?: NativeStackHeaderItemButton['badge'];\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 /**\n * Icon for the menu action.\n *\n * Can be an SF Symbol name or an image source.\n *\n * > **Note (Android)**: Only `ImageSourcePropType` icons are rendered. SF Symbols are\n * > silently dropped. Provide a `require()` or `{ uri }` source.\n */\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 * @platform ios\n */\n image?: InstanceType<SharedRef<'image'>> | null;\n /**\n * Controls how image-based icons are rendered on iOS.\n *\n * - `'template'`: iOS applies tint color to the icon (useful for monochrome icons)\n * - `'original'`: Preserves original icon colors (useful for multi-color icons)\n *\n * **Default behavior:**\n * - If `tintColor` is specified, defaults to `'template'`\n * - If no `tintColor`, defaults to `'original'`\n *\n * This prop only affects image-based icons (not SF Symbols).\n *\n * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiimage/renderingmode-swift.enum) for more information.\n *\n * @platform ios\n */\n iconRenderingMode?: 'template' | 'original';\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 * @platform android\n * @platform ios\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 on iOS it will recreate\n * the menu, 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 * @platform android\n * @platform ios\n */\n unstable_keepPresented?: boolean;\n /**\n * If `true`, the menu item will be displayed as selected.\n *\n * @platform android\n * @platform ios\n */\n isOn?: boolean;\n onPress?: () => void;\n /**\n * An elaborated title that explains the purpose of the action.\n *\n * @platform ios\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 * @platform ios\n */\n subtitle?: string;\n hidden?: boolean;\n}\n\nexport interface NativeToolbarMenuActionProps extends LinkMenuActionProps {\n /** @platform android */\n source?: ImageSourcePropType;\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import type { ReactElement, ReactNode } from 'react';
2
+ import type { NativeStackHeaderItemButton } from '../../../react-navigation/native-stack';
3
+ type ToolbarBadge = NativeStackHeaderItemButton['badge'];
4
+ /**
5
+ * Builds the spoken description for a badged icon so TalkBack announces the
6
+ * badge value (e.g. an unread count) alongside the label.
7
+ */
8
+ export declare function getBadgeContentDescription(accessibilityLabel: string | undefined, badge: ToolbarBadge): string | undefined;
9
+ /**
10
+ * Overlays a Material 3 Badge on the top-end corner of a toolbar item's icon.
11
+ * Compose anchors a badge to a single child, so the icon is wrapped in a Box.
12
+ * Renders the anchor unchanged when there's no badge, and a dot (no text) when
13
+ * the badge has no value. Shared by Stack.Toolbar.Button and Stack.Toolbar.Menu.
14
+ */
15
+ export declare function ToolbarItemBadge({ badge, disabled, children, }: {
16
+ badge: ToolbarBadge;
17
+ disabled?: boolean;
18
+ children: ReactNode;
19
+ }): ReactElement;
20
+ export {};
21
+ //# sourceMappingURL=ToolbarItemBadge.android.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarItemBadge.android.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/ToolbarItemBadge.android.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAErD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,wCAAwC,CAAC;AAG1F,KAAK,YAAY,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;AAOzD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,KAAK,EAAE,YAAY,GAClB,MAAM,GAAG,SAAS,CAKpB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,YAAY,CAyBf"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.getBadgeContentDescription = getBadgeContentDescription;
5
+ exports.ToolbarItemBadge = ToolbarItemBadge;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
7
+ const jetpack_compose_1 = require("@expo/ui/jetpack-compose");
8
+ const modifiers_1 = require("@expo/ui/jetpack-compose/modifiers");
9
+ const font_1 = require("../../../utils/font");
10
+ /** A badge shows text when its value is neither null nor empty; otherwise it's a bare dot. */
11
+ function badgeHasValue(badge) {
12
+ return badge?.value != null && badge.value !== '';
13
+ }
14
+ /**
15
+ * Builds the spoken description for a badged icon so TalkBack announces the
16
+ * badge value (e.g. an unread count) alongside the label.
17
+ */
18
+ function getBadgeContentDescription(accessibilityLabel, badge) {
19
+ if (!accessibilityLabel) {
20
+ return undefined;
21
+ }
22
+ return badgeHasValue(badge) ? `${accessibilityLabel}, ${badge.value}` : accessibilityLabel;
23
+ }
24
+ /**
25
+ * Overlays a Material 3 Badge on the top-end corner of a toolbar item's icon.
26
+ * Compose anchors a badge to a single child, so the icon is wrapped in a Box.
27
+ * Renders the anchor unchanged when there's no badge, and a dot (no text) when
28
+ * the badge has no value. Shared by Stack.Toolbar.Button and Stack.Toolbar.Menu.
29
+ */
30
+ function ToolbarItemBadge({ badge, disabled, children, }) {
31
+ if (!badge) {
32
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children });
33
+ }
34
+ return ((0, jsx_runtime_1.jsxs)(jetpack_compose_1.Box, { contentAlignment: "topEnd", children: [children, (0, jsx_runtime_1.jsx)(jetpack_compose_1.Badge, { containerColor: badge.style?.backgroundColor, contentColor: badge.style?.color, modifiers: disabled ? [(0, modifiers_1.alpha)(0.38)] : undefined, children: badgeHasValue(badge) ? ((0, jsx_runtime_1.jsx)(jetpack_compose_1.Text, { style: {
35
+ typography: 'labelSmall',
36
+ fontWeight: (0, font_1.convertFontWeightToComposeFontWeight)(badge.style?.fontWeight),
37
+ fontSize: badge.style?.fontSize,
38
+ fontFamily: badge.style?.fontFamily,
39
+ }, children: String(badge.value) })) : null })] }));
40
+ }
41
+ //# sourceMappingURL=ToolbarItemBadge.android.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarItemBadge.android.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/ToolbarItemBadge.android.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAmBb,gEAQC;AAQD,4CAiCC;;AAnED,8DAA2E;AAC3E,kEAA4E;AAI5E,8CAA2E;AAI3E,8FAA8F;AAC9F,SAAS,aAAa,CAAC,KAAmB;IACxC,OAAO,KAAK,EAAE,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;AACpD,CAAC;AAED;;;GAGG;AACH,SAAgB,0BAA0B,CACxC,kBAAsC,EACtC,KAAmB;IAEnB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,kBAAkB,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAC7F,CAAC;AAED;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,QAAQ,GAKT;IACC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,2DAAG,QAAQ,GAAI,CAAC;IACzB,CAAC;IACD,OAAO,CACL,wBAAC,qBAAG,IAAC,gBAAgB,EAAC,QAAQ,aAC3B,QAAQ,EACT,uBAAC,uBAAK,IACJ,cAAc,EAAE,KAAK,CAAC,KAAK,EAAE,eAAe,EAC5C,YAAY,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,EAChC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAA,iBAAa,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,YACtD,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CACtB,uBAAC,sBAAW,IACV,KAAK,EAAE;wBACL,UAAU,EAAE,YAAY;wBACxB,UAAU,EAAE,IAAA,2CAAoC,EAAC,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC;wBACzE,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ;wBAC/B,UAAU,EAAE,KAAK,CAAC,KAAK,EAAE,UAAU;qBACpC,YACA,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GACR,CACf,CAAC,CAAC,CAAC,IAAI,GACF,IACJ,CACP,CAAC;AACJ,CAAC","sourcesContent":["'use client';\nimport { Badge, Box, Text as ComposeText } from '@expo/ui/jetpack-compose';\nimport { alpha as alphaModifier } from '@expo/ui/jetpack-compose/modifiers';\nimport type { ReactElement, ReactNode } from 'react';\n\nimport type { NativeStackHeaderItemButton } from '../../../react-navigation/native-stack';\nimport { convertFontWeightToComposeFontWeight } from '../../../utils/font';\n\ntype ToolbarBadge = NativeStackHeaderItemButton['badge'];\n\n/** A badge shows text when its value is neither null nor empty; otherwise it's a bare dot. */\nfunction badgeHasValue(badge: ToolbarBadge): badge is NonNullable<ToolbarBadge> {\n return badge?.value != null && badge.value !== '';\n}\n\n/**\n * Builds the spoken description for a badged icon so TalkBack announces the\n * badge value (e.g. an unread count) alongside the label.\n */\nexport function getBadgeContentDescription(\n accessibilityLabel: string | undefined,\n badge: ToolbarBadge\n): string | undefined {\n if (!accessibilityLabel) {\n return undefined;\n }\n return badgeHasValue(badge) ? `${accessibilityLabel}, ${badge.value}` : accessibilityLabel;\n}\n\n/**\n * Overlays a Material 3 Badge on the top-end corner of a toolbar item's icon.\n * Compose anchors a badge to a single child, so the icon is wrapped in a Box.\n * Renders the anchor unchanged when there's no badge, and a dot (no text) when\n * the badge has no value. Shared by Stack.Toolbar.Button and Stack.Toolbar.Menu.\n */\nexport function ToolbarItemBadge({\n badge,\n disabled,\n children,\n}: {\n badge: ToolbarBadge;\n disabled?: boolean;\n children: ReactNode;\n}): ReactElement {\n if (!badge) {\n return <>{children}</>;\n }\n return (\n <Box contentAlignment=\"topEnd\">\n {children}\n <Badge\n containerColor={badge.style?.backgroundColor}\n contentColor={badge.style?.color}\n modifiers={disabled ? [alphaModifier(0.38)] : undefined}>\n {badgeHasValue(badge) ? (\n <ComposeText\n style={{\n typography: 'labelSmall',\n fontWeight: convertFontWeightToComposeFontWeight(badge.style?.fontWeight),\n fontSize: badge.style?.fontSize,\n fontFamily: badge.style?.fontFamily,\n }}>\n {String(badge.value)}\n </ComposeText>\n ) : null}\n </Badge>\n </Box>\n );\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { NativeStackHeaderItemButton } from '../../../react-navigation/native-stack';
3
+ type ToolbarBadge = NativeStackHeaderItemButton['badge'];
4
+ export declare function getBadgeContentDescription(_accessibilityLabel: string | undefined, _badge: ToolbarBadge): string | undefined;
5
+ export declare function ToolbarItemBadge(_props: {
6
+ badge: ToolbarBadge;
7
+ disabled?: boolean;
8
+ children: ReactNode;
9
+ }): null;
10
+ export {};
11
+ //# sourceMappingURL=ToolbarItemBadge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarItemBadge.d.ts","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/ToolbarItemBadge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,wCAAwC,CAAC;AAE1F,KAAK,YAAY,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;AAMzD,wBAAgB,0BAA0B,CACxC,mBAAmB,EAAE,MAAM,GAAG,SAAS,EACvC,MAAM,EAAE,YAAY,GACnB,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,IAAI,CAEP"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBadgeContentDescription = getBadgeContentDescription;
4
+ exports.ToolbarItemBadge = ToolbarItemBadge;
5
+ // Toolbar badges are only rendered through Jetpack Compose on Android
6
+ // (see ToolbarItemBadge.android.tsx). On other platforms these are no-ops —
7
+ // iOS badge support flows through native header items instead.
8
+ function getBadgeContentDescription(_accessibilityLabel, _badge) {
9
+ return undefined;
10
+ }
11
+ function ToolbarItemBadge(_props) {
12
+ return null;
13
+ }
14
+ //# sourceMappingURL=ToolbarItemBadge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolbarItemBadge.js","sourceRoot":"","sources":["../../../../src/layouts/stack-utils/toolbar/ToolbarItemBadge.tsx"],"names":[],"mappings":";;AAUA,gEAKC;AAED,4CAMC;AAjBD,sEAAsE;AACtE,4EAA4E;AAC5E,+DAA+D;AAE/D,SAAgB,0BAA0B,CACxC,mBAAuC,EACvC,MAAoB;IAEpB,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,gBAAgB,CAAC,MAIhC;IACC,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["import type { ReactNode } from 'react';\n\nimport type { NativeStackHeaderItemButton } from '../../../react-navigation/native-stack';\n\ntype ToolbarBadge = NativeStackHeaderItemButton['badge'];\n\n// Toolbar badges are only rendered through Jetpack Compose on Android\n// (see ToolbarItemBadge.android.tsx). On other platforms these are no-ops —\n// iOS badge support flows through native header items instead.\n\nexport function getBadgeContentDescription(\n _accessibilityLabel: string | undefined,\n _badge: ToolbarBadge\n): string | undefined {\n return undefined;\n}\n\nexport function ToolbarItemBadge(_props: {\n badge: ToolbarBadge;\n disabled?: boolean;\n children: ReactNode;\n}): null {\n return null;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"NativeStackView.native.d.ts","sourceRoot":"","sources":["../../../../src/react-navigation/native-stack/views/NativeStackView.native.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,EAC7B,MAAM,UAAU,CAAC;AAElB,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,SAAS,EAEd,KAAK,oBAAoB,EAG1B,MAAM,cAAc,CAAC;AAgatB,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,oBAAoB,CAAC,aAAa,CAAC,CAAC;IAC3C,UAAU,EAAE,4BAA4B,CAAC;IACzC,WAAW,EAAE,wBAAwB,CAAC;IACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,aAAa,CAAC,EAAE,WAAW,EAAE,OAAO,KAAK,qBAAqB,CAAC;CAC5F,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,KAAK,2CA2HlF"}
1
+ {"version":3,"file":"NativeStackView.native.d.ts","sourceRoot":"","sources":["../../../../src/react-navigation/native-stack/views/NativeStackView.native.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EACxB,4BAA4B,EAC7B,MAAM,UAAU,CAAC;AAElB,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,SAAS,EAEd,KAAK,oBAAoB,EAG1B,MAAM,cAAc,CAAC;AAgatB,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,oBAAoB,CAAC,aAAa,CAAC,CAAC;IAC3C,UAAU,EAAE,4BAA4B,CAAC;IACzC,WAAW,EAAE,wBAAwB,CAAC;IACtC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,aAAa,CAAC,EAAE,WAAW,EAAE,OAAO,KAAK,qBAAqB,CAAC;CAC5F,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,KAAK,2CA8HlF"}
@@ -240,6 +240,7 @@ const SceneView = ({ index, focused, shouldFreeze, descriptor, previousDescripto
240
240
  }) })) : null, (0, jsx_runtime_1.jsx)(elements_1.HeaderShownContext.Provider, { value: isParentHeaderShown || headerShown !== false, children: (0, jsx_runtime_1.jsx)(elements_1.HeaderBackContext.Provider, { value: headerBack, children: render() }) })] }) }) }) }));
241
241
  };
242
242
  function NativeStackView({ state, navigation, descriptors, describe }) {
243
+ const { colors } = (0, native_1.useTheme)();
243
244
  const { setNextDismissedKey } = (0, useDismissedRouteError_1.useDismissedRouteError)(state);
244
245
  (0, useInvalidPreventRemoveError_1.useInvalidPreventRemoveError)(descriptors);
245
246
  const modalRouteKeys = (0, getModalRoutesKeys_1.getModalRouteKeys)(state.routes, descriptors);
@@ -247,7 +248,7 @@ function NativeStackView({ state, navigation, descriptors, describe }) {
247
248
  acc[route.key] = acc[route.key] || describe(route, true);
248
249
  return acc;
249
250
  }, {});
250
- return ((0, jsx_runtime_1.jsx)(elements_1.SafeAreaProviderCompat, { children: (0, jsx_runtime_1.jsx)(react_native_screens_1.ScreenStack, { style: styles.container, children: state.routes.concat(state.preloadedRoutes).map((route, index) => {
251
+ return ((0, jsx_runtime_1.jsx)(elements_1.SafeAreaProviderCompat, { children: (0, jsx_runtime_1.jsx)(react_native_screens_1.ScreenStack, { nativeContainerStyle: { backgroundColor: colors.background }, style: styles.container, children: state.routes.concat(state.preloadedRoutes).map((route, index) => {
251
252
  const descriptor = (descriptors[route.key] ?? preloadedDescriptors[route.key]);
252
253
  const isFocused = state.index === index;
253
254
  const isBelowFocused = state.index - 1 === index;