diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2f9bcf..f3f31f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,11 +11,12 @@ jobs: lint: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup - uses: ./.github/actions/setup + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - run: yarn install --frozen-lockfile + - run: yarn install --cwd example --frozen-lockfile - name: Lint files run: yarn lint diff --git a/README.md b/README.md index 00e439e..03bd07b 100644 --- a/README.md +++ b/README.md @@ -111,10 +111,10 @@ Version >= 11 requires React Native 0.71 / Expo 48 or newer. Use version 10 if y 2. Wrap your root component in a `HeaderButtons` Provider and pass the `stackType` prop (`'native' | 'js'`), as seen in [example's App.tsx](https://github.com/vonovak/react-navigation-header-buttons/blob/master/example/src/App.tsx). -There are 3 providers to choose from - but don't worry about it now, you'll get an actionable warning if you don't do it right: +There are 3 providers to choose from - it's recommended you use `HeaderButtonsProvider`, and you'll get an actionable warning if you're trying to do something that requires a different provider. -- `HeaderButtonsProvider` - the default, which assumes you will use `overflowMenuPressHandlerDropdownMenu` on Android but not iOS (because that's the default behavior that the library ships with). -- `HeaderButtonsProviderPlain` - use it if you're not planning to use `overflowMenuPressHandlerDropdownMenu`. It will shave a few kB off your bundle and Hermes won't have to parse the code that would not run in the end. +- `HeaderButtonsProvider` - assumes you will use `overflowMenuPressHandlerDropdownMenu` on Android but not iOS (because that's the default behavior that the library ships with). +- `HeaderButtonsProviderPlain` - use it if you're not planning to use `overflowMenuPressHandlerDropdownMenu`. It will shave a few kB off your bundle and Hermes won't have to parse extra code that would not run in the end. - `HeaderButtonsProviderDropdownMenu` - use it if you're planning to use `overflowMenuPressHandlerDropdownMenu` on all platforms. Importing: `import { your_chosen_provider } from 'react-navigation-header-buttons/your_chosen_provider'`. @@ -128,9 +128,11 @@ Importing: `import { your_chosen_provider } from 'react-navigation-header-button Is a wrapper over all the visible header buttons (those can be text-buttons, icon-button, or any custom react elements). -You should provide the `HeaderButtonComponent` prop that encapsulates how all buttons rendered in children will look. Typically, you'll want to provide a component that wraps [`HeaderButton`](#headerbutton) as seen in the example. However, you're free to use your own component (see `HeaderButton.tsx` for reference). +You should provide the `HeaderButtonComponent` prop that encapsulates how all buttons rendered in `children` will look. -In particular, it allows setting `IconComponent`, `size` and `color` in one place so that you don't need to repeat it for each icon-button - but you can override those for each `Item` if you like. +This allows setting `IconComponent`, `size` and `color` in one place so that you don't need to repeat it for each icon-button - but you can override those for each `Item` if you like. + +Typically, you'll want to provide a component that wraps [`HeaderButton`](#headerbutton) as seen in the example above. However, you're free to use your own component (see `HeaderButton.tsx` for reference). `HeaderButtons` accepts: @@ -158,17 +160,17 @@ Renders text, or icon inside a [PlatformPressable](https://reactnavigation.org/d `Item` also accepts other props that you'll typically not need to pass because `HeaderButtonComponent` already knows them (eg. `iconSize`) or because they are pulled from the React Navigation's theme object (`color`). -| additional props and type | description | note | -| -------------------------------------------------------- | --------------------------------------------------------------------------------------- | ---- | -| IconComponent?: ComponentType | component to use for the icons, for example from `react-native-vector-icons` | | -| iconSize?: number | iconSize | | -| color?: string | color of icons and buttons | | -| renderButton?: (params: VisibleButtonProps) => ReactNode | renders the body of the button (text or icon), defaults to `defaultRenderVisibleButton` | | +| additional props and type | description | note | +| -------------------------------------------------------- |------------------------------------------------------------------------------------------------| ---- | +| IconComponent?: ComponentType | component to use for the icons, for example from `react-native-vector-icons` | | +| iconSize?: number | iconSize | | +| color?: string | color of icons and buttons | | +| renderButton?: (params: VisibleButtonProps) => ReactNode | renders the body of the button (text or icon), defaults to `defaultRenderVisibleButton` | | ### `OverflowMenu` Defines the behavior for overflow button (if there is one). You can render `OverflowMenu` only by itself too, you do not need to wrap it in `HeaderButtons`. -The most important prop is `onPress` which defines what kind of overflow menu we should show. +The most important (but optional) prop is `onPress` which defines what kind of overflow menu we should show. The package exports common handlers you can use, but you can provide your own too (via the `onPress` prop): @@ -269,15 +271,11 @@ const HiddenItemWrappedTwice = ()=> ### `HeaderButtonsProvider` / `HeaderButtonsProviderPlain` / `HeaderButtonsProviderDropdownMenu` -You need to wrap your root component with a HeaderButtons Provider. `stackType` is a required prop, which indicates whether you're using a native or JS stack. - Importing: `import { your_chosen_provider } from 'react-navigation-header-buttons/your_chosen_provider'`. -There are 3 providers to choose from. You'll get an actionable warning if you don't use the right one. +You need to wrap your root component with a HeaderButtons Provider. `stackType` is a required prop, which indicates whether you're using a native or JS stack. -- `HeaderButtonsProvider` - the default, which assumes you will use `overflowMenuPressHandlerDropdownMenu` on Android but not iOS (because that's the default behavior that the library ships with). -- `HeaderButtonsProviderPlain` - use it if you're not planning to use `overflowMenuPressHandlerDropdownMenu`. It will shave a few kB off your bundle and Hermes won't have to parse the code that would not run in the end. -- `HeaderButtonsProviderDropdownMenu` - use it if you're planning to use `overflowMenuPressHandlerDropdownMenu` on all platforms. +There are 3 providers to choose from, see [Setup](#setup) for more info. Optional `spaceAboveMenu` prop can be used to set the distance between the top of the screen and the top of the overflow menu when using `overflowMenuPressHandlerDropdownMenu`. @@ -285,7 +283,7 @@ Optional `spaceAboveMenu` prop can be used to set the distance between the top o `HeaderButton` is where all the `onPress`, `title` and Icon-related props (color, size) meet to render actual button. -You can fully customize what it renders inside of the `PlatformPressable` using the `renderButton?: (params: VisibleButtonProps) => ReactNode` prop. +You can fully customize what it renders inside the `PlatformPressable` using the `renderButton?: (params: VisibleButtonProps) => ReactNode` prop. ## Recipes diff --git a/src/overflowMenu/__tests__/OverflowMenuProvider.test.tsx b/src/overflowMenu/__tests__/OverflowMenuProvider.test.tsx index b856dfe..fcd3d0c 100644 --- a/src/overflowMenu/__tests__/OverflowMenuProvider.test.tsx +++ b/src/overflowMenu/__tests__/OverflowMenuProvider.test.tsx @@ -162,11 +162,6 @@ describe('HeaderButtonsProvider renders', () => { return path.split('/').pop(); }); - expect(filteredIos).not.toContain('Menu.tsx'); - expect(filteredIos).not.toContain('HeaderButtonsProviderDropdownMenu.tsx'); - expect(filteredAndroid).toContain('HeaderButtonsProviderDropdownMenu.tsx'); - expect(filteredAndroid).toContain('Menu.tsx'); - expect(filteredIos).toMatchInlineSnapshot(` [ "HeaderButtonsProvider.tsx", @@ -186,5 +181,10 @@ describe('HeaderButtonsProvider renders', () => { "Divider.tsx", ] `); + + expect(filteredIos).not.toContain('Menu.tsx'); + expect(filteredIos).not.toContain('HeaderButtonsProviderDropdownMenu.tsx'); + expect(filteredAndroid).toContain('HeaderButtonsProviderDropdownMenu.tsx'); + expect(filteredAndroid).toContain('Menu.tsx'); }, 20000); });