UNPKG

react-native-stack-tabview

Version:

react-native-stack-tabview

299 lines (267 loc) 15.8 kB
# react-native-stack-tabview Based on pure `JS` scripts, without relying on native, no need for `react-native link`,`Title` / `Header` / `Tabs` / `Sticky` / `Screen` components can be flexibly configured, among which `Tabs` / `Sticky` can slide When it reaches the top, it will be topped; what we support is to independently manage its own `Sticky` / `Screen` / `Badge` / `tabLabel` configuration in the form of a stack, and inject the `Screen` [lifecycle](#InjectionLifecycle) `onRefresh` / `onEndReached` They will be triggered when the pull-down refresh and the scroll bar hit the bottom, and finally inject more into `Screen` / `Sticky` [props](#InjectionScreenProps) ##### Table of Contents * [Features](#features) * [Installation](#installation) * [Usage](#usage) * [Props](#props) * [Method](#method) * [Stack Property](#StackProperty) * [Badge Property](#BadgeProperty) * [Injection lifecycle to Screen](#InjectionLifecycle) * [Injection props to Screen](#InjectionScreenProps) * [Injection props to Sticky](#InjectionStickyProps) * [Known Issues](#KnownIssues) ## <a name="features"/>Features * Support to individually set pull-down refresh and up-slide load for each screen (Lifecycle injection or props injection) * Flex Tabs and multiple Tabs horizontal scrolling support configuration method * Allow to set up each Screen’s own Sticky component * Custom badges can be configured for each Tab * Support pull down to refresh and slide up to load more pre-functions `onBeforeRefresh` / `onBeforeEndReached` * Support animation title, can support animation as `interpolate.opacity` and `interpolate.height` ## <a name="installation"/>Installation ```shell npm i react-native-stack-tabview ``` or ```shell yarn add react-native-stack-tabview ``` ## <a name="usage"/>Usage ```jsx import React from 'react'; import ScrollableTabView from 'react-native-stack-tabview'; function App() { return ( <ScrollableTabView ref={rf => (this.scrollableTabView = rf)} mappingProps={{ fromRootEst: this.state.est, }} badges={[ null, [ <View style={{ position: 'absolute', zIndex: 100, top: 10, right: 0, }} > <Text>new</Text> </View>, <View style={{ position: 'absolute', width: 150, height: 50, zIndex: 100, marginTop: 35, right: 0, opacity: 0.6, backgroundColor: 'pink', justifyContent: 'center', alignItems: 'center', }} > <Text>Three Tips</Text> </View>, ], ]} stacks={[ { screen: One, sticky: Sticky, tabLabel: 'OneTab', tabLabelRender: tabLabel => { return `--- ${tabLabel} ---`; }, badge: [<Text>one</Text>, <Text>two</Text>], toProps: { xx: 123, }, }, { screen: ({ layoutHeight, refresh, scrollTo, toTabView, initScreen, onRefresh, onEndReached, }) => { // The code is required initScreen(); const [datetime, setDatetime] = useState(Date.now()); useEffect(() => { setInterval(() => { setDatetime(Date.now()); }, 1000); }, []); onRefresh((toggled) => { toggled(true); alert("onRefresh start"); setTimeout(() => { toggled(false); alert("onRefresh stop"); }, 3000); }); onEndReached(() => { alert("onEndReached"); }); return ( <View style={{ flex: 1, backgroundColor: "#151723", justifyContent: "center", alignItems: "center", }} > <Text style={{ color: "#ffffff" }}> Test function component {datetime} </Text> </View> ); }, tabLabel: "TestFunctionComponent", } ]} tabsStyle={{}} tabWrapStyle={{}} tabInnerStyle={{}} tabActiveOpacity={0.6} tabStyle={{}} textStyle={{}} textActiveStyle={{}} tabUnderlineStyle={{}} firstIndex={0} syncToSticky={true} onEndReachedThreshold={0.1} onBeforeRefresh={(next, toggled) => { toggled(); next(); }} onBeforeEndReached={next => { next(); }} onTabviewChanged={(index, tabLabel, isFirst) => { alert(index); }} header={() => { return <View style={{ backgroundColor: 'pink', height: 120 }}></View>; }} oneTabHidden={true} enableCachePage={true} carouselProps={{}} sectionListProps={{}} toHeaderOnTab={true} toTabsOnTab={true} tabsShown={false} fixedTabs={false} fixedHeader={false} useScroll={false} fillScreen={true} ></ScrollableTabView> ); } ``` ## <a name="props"/>Props All props are optional Prop | Type | Default | Description ----------------- | -------- | ----------- | ----------- **`stacks`** | Array | [] | Page Stack < [Read Stack Property](#StackProperty) > **`mappingProps`** | Object | {} | Associate mapping data to Stack / Sticky **`badges`** | Array | [] | Badges for each Tab < [Read Badge Property](#BadgeProperty) > **`tabsStyle`** | Object | {} | The entire Tabs style **`tabWrapStyle`** | Object / Function | {} | Single Tab wrap style (The function parameters provide item, index, and need to return the style object, eg. **`return index == 1 && {zIndex: 10}`**) **`tabInnerStyle`** | Object | {} | Single Tab inner style **`tabActiveOpacity`** | Number | 0.6 | Transparency after Tab button click **`tabStyle`** | Object | {} | Single Tab style **`textStyle`** | Object | {} | Text style in Tab **`textActiveStyle`** | Object | {} | Select the active text style **`tabUnderlineStyle`** | Object | {} | Select the active underline style **`firstIndex`** | Number / Null | null | Set the stack of **`firstIndex`** to active (make sure that the number of **`stacks`** is greater than to **`firstIndex`** when setting the **`firstIndex`** value) **`syncToSticky`** | Boolean | true | Whether it is synchronized (**`render`** triggered in the Screen **`componentDidUpdate`** will update Sticky) **`onEndReachedThreshold`** | Number | 0.2 | Bottom callback threshold **`onBeforeRefresh`** | Function | null | Pull down to refresh the pre-functions, execute **`next`** to execute **`onRefresh`** function in Screen, execute **`toggled`** to switch system loading, you can pass true / false to specify (callback contains **`next`**, **`toggled`** two formal parameters) **`onBeforeEndReached`** | Function | null | Slide up to load more pre-functions, execute next will execute the **`onEndReached`** function in the Screen (callback contains **`next`** formal parameters) **`onTabviewChanged`** | Function | null | Tab switch completion callback (callback contains **`index`**, **`tabLabel`**, **`isFirst`** parameters) **`screenScrollThrottle`** | Number | 60 | **`Screen`** Throttle parameters during lateral sliding, Unit (ms) **`header`** | Function / JSX Element / Class Component | null | Top component (if the function needs to return Element) **`stickyHeader`** | Function / JSX Element / Class Component | null | Top component (if the function needs to return Element) for sticky **`oneTabHidden`** | Boolean | false | Hide itself when there is only one Tab **`enableCachePage`** | Boolean | true | Whether the persistent page will not be destroyed after switching **`carouselProps`** | Object | {} | The remaining attributes passed to Carousel < [Read Carousel](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md) > **`sectionListProps`** | Object | {} | Remaining attributes passed to SectionList < [Read SectionList](https://reactnative.dev/docs/sectionlist) > **`toHeaderOnTab`** | Boolean | false | Click to trigger the activated Tab will scroll to Header (high priority) **`toTabsOnTab`** | Boolean | false | Click to trigger the activated Tab will scroll to Tabs **`tabsShown`** | Boolean | true | Configure Tabs display and hide **`fixedTabs`** | Boolean | false | When **`enableCachePage`** is true, slide to switch Screen to set the minimum height to ensure that the Header and Tabs will not bounce **`fixedHeader`** | Boolean | false | Render together with Tabs, fix the top Header, do not follow the scroll **`useScroll`** | Boolean | false | Does Tabs support horizontal scrolling (it needs to be enabled when there are multiple category Tabs, it is recommended that **`tabStyle`** pass in a fixed width) **`useScrollStyle`** | Object | {} | Set **`contentContainerStyle`** for scrolling **`Tabs`**, usually add margins to the left and right sides **`paddingLeft`** **`paddingHorizontal`** **`fillScreen`** | Boolean | true | Fill the entire Screen **`title`** | Function / JSX Element / Class Component | null | Animation title **`titleArgs`** | Object | **`{ style: {}, interpolateOpacity: {}, interpolateHeight: {} }`** | Title parameter configuration < [Read interpolate](https://reactnative.dev/docs/animations#interpolation) > **`onScroll`** | Function | null | Scroll event monitoring **`onScroll2Horizontal`** | Function | null | Scroll event monitoring for orizontal **`tabsEnableAnimated`** | Boolean | false | Enable sliding effect for Tabs, Need to specify **`width`** for **`tabStyle`** **`tabsEnableAnimatedUnderlineWidth`** | Number | 0 | To set a fixed width for the Tabs Underline and add a jumping animation, you need to enable **`tabsEnableAnimated=true`**. (It is recommended to pass in one third of **`tabStyle.width`** or a fixed 30px) **`errorToThrow`** | Boolean | false | **`console.error`** will throw an error **`throw new Error()`** ## <a name="method"/>Method ``` javascript <ScrollableTabView ref={rf => (this.scrollableTabView = rf)} > </ScrollableTabView> this.scrollableTabView.getCurrentRef(); this.scrollableTabView.toTabView(1); this.scrollableTabView.scrollTo(0); this.scrollableTabView.clearStacks(()=>alert('done')); ``` Name | Type | Description ----------------- | -------- | ----------- **`getCurrentRef(index: number.optional)`** | Function | Get the instance of the currently active view, you can pass **`index`** to get the specified instance **`toTabView(index: number.required / label: string.required)`** | Function | Jump to the specified Screen **`scrollTo(index: number.required)`** | Function | Swipe up and down to the specified position (passing in 0 is the default positioning to tabs / passing in a negative number is set to the top) **`clearStacks(callback: function.optional)`** | Function | Clear the Stacks and related state (Tabs / Badge / Stacks)) ## <a name="StackProperty"/>Stack Property Name | Type | Description ----------------- | -------- | ----------- **`screen`** | Class / Function Component | Screen components ( If the function component must call initScreen ) **`sticky`** | Class Component | Sticky component, The context of this type of component will be returned in the instance **`tabLabel`** | String | Tab display name **`tabLabelRender`** | Function | Custom Tab rendering function, priority is higher than **`tabLabel`** **`badge`** | Array | For the current Tab badge, it is mutually exclusive with the **`badges`** attribute, and has a higher priority than the outermost attribute **`badges`** < [Read Badge Property](#BadgeProperty) > **`toProps`** | Object | **`toProps`** Only pass to Screen without data association ## <a name="BadgeProperty"/>Badge Property Type | Description -------- | ----------- JSX Element | Badges/Hovering Tips, etc. rendered based on the current Tab ## <a name="InjectionLifecycle"/>Injection lifecycle to Screen (On Class Component) Name | Type | Description ----------------- | -------- | ----------- **`onRefresh`** | Function | Triggered when pull-down refresh, the formal parameter **`toggled`** function is used to switch the display of the native loading state, if the user switches the tab during loading, it will be forced to hide and reset the state **`onEndReached`** | Function | Swipe up to load more triggers ## <a name="InjectionScreenProps"/>Injection props to Screen Name | Type | Description ----------------- | -------- | ----------- **`refresh()`** | Function | Manually trigger refresh and synchronize Screen status to Sticky **`scrollTo(index: number.required)`** | Function | Swipe up and down to the specified position (passing in 0 is the default positioning to tabs / passing in a negative number is set to the top) **`toTabView(index: number.required / label: string.required)`** | Function | Jump to the specified Screen **`layoutHeight.container`** | Number | Total height of the Container **`layoutHeight.header`** | Number | Total height of the Header **`layoutHeight.tabs`** | Number | Total height of the Tabs **`layoutHeight.screen`** | Number | Total height of the Screen **`initScreen`** | Function | (On Function Component) If it is a function component, it must be called **`onRefresh`** | Function | (On Function Component) < [Read onRefresh description](#InjectionLifecycle) > **`onEndReached`** | Function | (On Function Component) < [Read onEndReached description](#InjectionLifecycle) > ## <a name="InjectionStickyProps"/>Injection props to Sticky Name | Type | Description ----------------- | -------- | ----------- **`screenContext`** | Object | Get Screen context ## <a name="KnownIssues"/>Known Issues - If you just add a `Stack`, you can `Push`, but if you need to update or delete a `Stack`, please use [clearStacks](#Method) and then add the `Stacks` you need **MIT Licensed**