New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Version 4.0 with api refactoring and dynamic tabs #93
Conversation
This may have an additional benefit that it would make it possible to add/remove tabs at runtime dynamically. I'm not sure if the dynamic part works, because I haven't tested it. But if it doesn't, it should be fixable. |
Also, this is a breaking change so it would need to bump the package to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes are so awesome 🎉 🚀 Makes the API much more idiomatic, I really like it.
Just one concern, how do we get the ref from a parent component? Maybe a simple solution is to somehow map the refMap to an object inside the useImperativeHandle. So we can access like this: ref.current.article.current...
or ref.current.tabs.article.current...
.
Would be awesome if it were possible to pass props to the Tab
and send it to TabBarComponent
or HeaderComponent
. Just like react-navigation. But that's another story...
I'm thinking about how could we achieve an expo preview for PRs other than mine. The github secrets can't be shared between forks, so seems there is no right solution for this. Would be great if it were possible. Right now I need to fetch every PR and test locally. |
@andreialecu we can add something like this: // utility hook
const useTabsOptions = (children: typeof Tab[] | typeof Tab) => {
const options = React.useMemo(() => {
const tabsOptions = {}
React.Children.forEach(children, (element, index) => {
const { options, name } = element.props
tabsOptions[name] = options
})
return tabsOptions
}, [children])
return options
}
// inside the Container:
// extract the props passed to each Tab component and map to the tab names
const tabOptions = useTabsOptions(children)
// pass the tab options to the TabBar
<TabBarComponent options={tabOptions} ... /> And then use like this: <Tabs.Container ref={ref} headerHeight={HEADER_HEIGHT} {...props}>
// direct props
<Tabs.Tab name="article" options={{ label: ...}}>
<Article />
</Tabs.Tab>
// or options
<Tabs.Tab name="albums" options={{ label: ... }}>
<Albums />
</Tabs.Tab>
</Tabs.Container> It will grab the props before rendering the tab bar. We can pass it to the header too. In this example the TabBar would receive: {
article: { label: ... },
albums: { label: ... }
} |
I have just added the options 🚀 Please review and make necessary changes if needed, including the naming conventions. tried the preview after having commits from me, but still don't work |
src/Tab.tsx
Outdated
@@ -2,9 +2,9 @@ import React from 'react' | |||
|
|||
import { ParamList, TabOptions } from './types' | |||
|
|||
export interface TabProps<T extends ParamList> { | |||
export type TabProps<T extends ParamList> = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed to type
instead of interface
because the docs script doesn't like interfaces, and doesn't matter anyway.
src/hooks.tsx
Outdated
} | ||
|
||
export const useTabOptions = <T extends ParamList>( | ||
children: React.ReactElement<TabProps<T>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this type can probably be narrowed down.
src/types.ts
Outdated
label?: string | ||
} | ||
|
||
export type FinalTabOptions<T extends ParamList> = Record< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have a better name for this? FinalTabOptions is awkward.
I'm working on this at the moment btw. Will report back in a few. |
…ative-collapsible-tab-view into refactor-apicleanup3
I'm not using in a production app so I don't mind if it's incomplete, happy to report bugs here. What's the best way to use these latest changes? |
@danielfein I already replied to your previous comment here with instructions. Scroll up a bit. Feedback would be greatly appreciated. There are some issues on android with the latest commit which are being worked on (related to snapping and flatlists) |
Hi @andreialecu did as you said to use your version in my project. However, it seems like the
I see these errors:
Also:
Propose releasing as @next ? |
react-native-collapsible-tab-view-v3.7.1.tgz.zip I ran (or clone this PR, and run |
There is a known issue with RefreshControl + FlatList + Snapping on Android (iOS works fine). The issue also affects the current published version though. We believe it's a reanimated bug: software-mansion/react-native-reanimated#1703 |
Hi @andreialecu I'm now setup with the new version in my project. Just getting to grips with the new setup but currently when I scroll up on iOS, the header does not scroll with the list. Also I'm seeing I will continue to have a look. (I previously had a few pages to update to the new version). |
Make sure to use the scrollview or flatlist exported from this package. Not the react native ones. If the problem persists, a code sample of how you're using it would be helpful. |
Third alternative to #90 or #91 😆
Introduces a
<Tabs.Tab />
component for defining the tabs.I think I like this the best personally. Seems most idiomatic with React practices in general.
Another benefit is that there's no more need to define the tabs twice (and to make sure the order matches).