Last Updated on : 2024-06-05 03:14:34download
Tabs is written by pure gestures, which solves the problem of mutual nesting caused by ScrollView implementation. In addition, through the new lazy loading function, the TabContent component is split out for users to use alone.
Note: for more information, see Demo.
One screen displays four tabs by default. The number of tabs displayed on one screen can be customized through maxItem.
Note: if the length of
dataSource
exceeds maxItem, it will automatically become split-screen.
import React from "react";
import { View } from "react-native";
import { Tabs } from "tuya-panel-kit";
import TesterTitle from "../../components/TesterTitle";
export default class OnlyTabsScene extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
activeKey1: "1",
activeKey2: "3",
d1: [
{ value: "1", label: "Sensor" },
{ value: "2", label: "Remote control" },
{ value: "3", label: "RFID" },
{ value: "4", label: "Limited sensor" },
],
d2: [
{ value: "1", label: "1" },
{ value: "2", label: "22" },
{ value: "3", label: "333" },
{ value: "4", label: "Limited sensor" },
{ value: "5", label: "55555" },
{ value: "6", label: "666666" },
{ value: "7", label: "7777777" },
{ value: "8", label: "88888888" },
],
};
}
_handleD1Change = (tab) => {
this.setState({ activeKey1: tab.value });
};
_handleD2Change = (tab) => {
this.setState({ activeKey2: tab.value });
};
render() {
return (
<View style={{ flex: 1 }}>
<TesterTitle title="Basic Tabs" />
<Tabs
activeKey={this.state.activeKey1}
dataSource={this.state.d1}
onChange={this._handleD1Change}
/>
<TesterTitle title="Split-screen Tabs" />
<Tabs
activeKey={this.state.activeKey2}
dataSource={this.state.d2}
onChange={this._handleD2Change}
/>
<TesterTitle title="Basic Tabs (stateless components)" />
<Tabs dataSource={this.state.d1} />
<TesterTitle title="Split-screen Tabs (stateless components)" />
<Tabs dataSource={this.state.d2} />
<TesterTitle title="Tabs with fixed underline width" />
<Tabs underlineWidth={30} dataSource={this.state.d2} />
</View>
);
}
}
It can be used in scenarios that do not require tabs, such as simulating page switching.
/* eslint-disable react/no-array-index-key */
import _ from "lodash";
import React from "react";
import { View } from "react-native";
import { Tabs } from "tuya-panel-kit";
import TesterTitle from "../../components/TesterTitle";
import Panel from "./components/Panel";
export default class OnlyContentTabsScene extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
activeIndex: 0,
d1: [
{ value: "1", label: "111" },
{ value: "2", label: "222" },
{ value: "3", label: "333" },
{ value: "4", label: "444" },
],
};
}
_handleRelease = (gestureState, index) => {
this.setState({ activeIndex: index });
};
render() {
return (
<View style={{ flex: 1 }}>
<TesterTitle title="My content is very lightweight and does not require preloading" /> <Tabs.TabContent
preload={false}
activeIndex={this.state.activeIndex}
onRelease={this._handleRelease}
>
{this.state.d1.map((data, idx) => (
<Panel key={idx} title={`${idx}`} />
))}
</Tabs.TabContent>
<TesterTitle title="Separate TabContent" />
<Tabs.TabContent
activeIndex={this.state.activeIndex}
onRelease={this._handleRelease}
>
{this.state.d1.map((data, idx) => (
<Panel key={idx} largeData={idx === 1} title={data.label} />
))}
</Tabs.TabContent>
</View>
);
}
}
import _ from "lodash";
import React from "react";
import { View, ScrollView } from "react-native";
import { Tabs, TYListItem } from "tuya-panel-kit";
import TesterTitle from "../../components/TesterTitle";
import Panel from "./components/Panel";
export default class WithContentTabsScene extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
activeKey1: "1",
activeKey2: "3",
d1: [
{ value: "1", label: "Sensor" },
{ value: "2", label: "Remote control" },
{ value: "3", label: "RFID" },
{ value: "4", label: "Limited sensor" },
],
d2: [
{ value: "1", label: "1" },
{ value: "2", label: "22" },
{ value: "3", label: "333" },
{ value: "4", label: "Limited sensor" },
{ value: "5", label: "55555" },
{ value: "6", label: "666666" },
{ value: "7", label: "7777777" },
{ value: "8", label: "88888888" },
],
};
}
_handleD1Change = (tab) => {
this.setState({ activeKey1: tab.value });
};
_handleD2Change = (tab) => {
this.setState({ activeKey2: tab.value });
};
render() {
return (
<View style={{ flex: 1 }}>
{/* https://github.com/facebook/react-native/issues/11206 */}
<TesterTitle title="There are Tabs with scrollable content on one screen" />
<Tabs
activeKey={this.state.activeKey1}
dataSource={this.state.d1}
swipeable={true}
onChange={this._handleD1Change}
>
<Tabs.TabPanel>
<ScrollView>
{_.times(10, (n) => (
<TYListItem key={n} title={`Test_${n}`} />
// <TYText key={n} text={`Test_${n}`} />
))}
</ScrollView>
</Tabs.TabPanel>
<Tabs.TabPanel>
<TYListItem title="Page 2" />
</Tabs.TabPanel>
<Tabs.TabPanel>
<TYListItem title="Page 3" />
</Tabs.TabPanel>
<Tabs.TabPanel>
<TYListItem title="Page 4" />
</Tabs.TabPanel>
</Tabs>
<TesterTitle title="Tabs with content on split screens" /> <Tabs
activeKey={this.state.activeKey2}
dataSource={this.state.d2}
onChange={this._handleD2Change}
>
{this.state.d2.map((data, idx) => (
<Panel key={idx} title={data.label} />
))}
</Tabs>
<TesterTitle title="Split screens have content tabs that are located below" />
<Tabs
tabPosition="bottom"
activeKey={this.state.activeKey2}
dataSource={this.state.d2}
onChange={this._handleD2Change}
>
{this.state.d2.map((data, idx) => (
<Panel key={idx} title={data.label} />
))}
</Tabs>
</View>
);
}
}
import React from "react";
import { View } from "react-native";
import { Tabs, TYListItem } from "tuya-panel-kit";
import TesterTitle from "../../components/TesterTitle";
import Panel from "./components/Panel";
export default class NestedTabsScene extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
activeKey1: "1",
activeKey2: "3",
d1: [
{ value: "1", label: "Sensor" },
{ value: "2", label: "Remote control" },
{ value: "3", label: "RFID" },
{ value: "4", label: "Limited sensor" },
],
d2: [
{ value: "1", label: "1" },
{ value: "2", label: "22" },
{ value: "3", label: "333" },
{ value: "4", label: "4444" },
{ value: "5", label: "55555" },
{ value: "6", label: "666666" },
{ value: "7", label: "7777777" },
{ value: "8", label: "88888888" },
],
};
}
_handleD1Change = (tab) => {
this.setState({ activeKey1: tab.value });
};
_handleD2Change = (tab) => {
this.setState({ activeKey2: tab.value });
};
render() {
return (
<View style={{ flex: 1 }}>
<TesterTitle title="Nested Tabs" />
<Tabs
tabPosition="bottom"
underlineStyle={{ backgroundColor: "transparent" }}
activeKey={this.state.activeKey1}
dataSource={this.state.d1}
swipeable={false}
onChange={this._handleD1Change}
>
<Tabs.TabPanel background="#fff">
<Tabs
activeKey={this.state.activeKey2}
dataSource={this.state.d2}
onChange={this._handleD2Change}
>
{this.state.d2.map((data, idx) => (
<Panel key={idx} title={data.label} />
))}
</Tabs>
</Tabs.TabPanel>
<Tabs.TabPanel background="#fff">
<TYListItem title="Page 2" />
</Tabs.TabPanel>
<Tabs.TabPanel background="#fff">
<TYListItem title="Page 3" />
</Tabs.TabPanel>
<Tabs.TabPanel background="#fff">
<TYListItem title="Page 4" />
</Tabs.TabPanel>
</Tabs>
</View>
);
}
}
The style of Tabs
.
Type | Required | Default value |
---|---|---|
ViewPropTypes.style | No | null |
The container style that wraps Tabs
and TabContent
. It only takes effect when TabContent
is configured.
Type | Required | Default value |
---|---|---|
ViewPropTypes.style | No | null |
The style of TabContent
. It only takes effect when TabContent
is configured.
Type | Required | Default value |
---|---|---|
ViewPropTypes.style | No | null |
The style of the selected tab.
Type | Required | Default value |
---|---|---|
ViewPropTypes.style | No | null |
The text style of the unselected Tab
.
Type | Required | Default value |
---|---|---|
ViewPropTypes.style | No | null |
The selected text style.
Type | Required | Default value |
---|---|---|
ViewPropTypes.style | No | null |
Style of the underline.
Type | Required | Default value |
---|---|---|
ViewPropTypes.style | No | null |
The width of the underline. If not set, it will follow the text width by default.
Type | Required | Default value |
---|---|---|
number |
No | null |
The default activation value. It is used when it is set to uncontrolled components.
Type | Required | Default value |
---|---|---|
number | string |
No | 0 |
Activation value. If the parameter value is set, it becomes a controlled component. It needs to be used with onChange
.
Type | Required | Default value |
---|---|---|
number | string |
No | null |
Data source.
Type | Required | Default value |
---|---|---|
ITabsDataSource | Yes | null |
interface ITabsDataSource {
value: string; // Label value
label? : string; // Label text
renderTab? : (
isActive: boolean,
state: ITabState,
props: ITabProps
) => React.Element; // Custom rendering tab label }
Whether to disable the Tabs
page.
Note: only
Tabs
can be disabled, andTabContent
cannot be disabled.
Type | Required | Default value |
---|---|---|
boolean |
No | false |
Whether TabContent
supports scrolling.
Type | Required | Default value |
---|---|---|
boolean |
No | true |
The maximum number of Tab
labels supported on a screen.
Type | Required | Default value |
---|---|---|
number |
No | 4 |
When Tab
and TabContent
exist at the same time, the arrangement position of Tab
.
Type | Required | Default value |
---|---|---|
top| bottom |
No | top ’ |
The color when activated.
Type | Required | Default value |
---|---|---|
ColorPropType | No | Theme color |
The background color of Tab
page.
Type | Required | Default value |
---|---|---|
ColorPropType | No | #fff |
Whether TabContent
needs to be preloaded.
Type | Required | Default value |
---|---|---|
boolean |
No | true |
The preload delay time of TabContent
.
Type | Required | Default value |
---|---|---|
number |
No | null |
Custom rendering of the placeholder container in the preload.
Type | Required | Default value |
---|---|---|
(activeIndex, children) => React.Element |
No | null |
Callback for tab change.
Type | Required | Default value |
---|---|---|
(tab, index) => void |
No | null |
The child element of Tab
, generally TabContent
.
Type | Required | Default value |
---|---|---|
array |
No | null |
The extra white space on the right, in px.
This property is added in the @2.0.0-rc.2 version.
Type | Required | Default value |
---|---|---|
number |
No | 0.5 |
The acceleration threshold of TabContent
in px. If the sliding rate exceeds the threshold, it is directly judged as the next page.
This property is added in the @2.0.0-rc.2 version.
Type | Required | Default value |
---|---|---|
number |
No | 0.5 |
Animation configuration.
Type | Required | Default value |
---|---|---|
IAnimationConfig |
No |
|
Gradient example:
interface IAnimationConfig {
duration? : number;
easing? : EasingFunction;
delay? : number;
isInteraction? : bool;
useNativeDriver? : bool; // tabs are always false, width animation is not supported }
// Default value
{
duration: 200,
easing: Easing.linear,
delay: 0,
isInteraction: true,
useNativeDriver: false,
}
The style of TabContent
.
Type | Required | Default value |
---|---|---|
ViewPropTypes.style | No | null |
The currently activated index.
Type | Required | Default value |
---|---|---|
number |
Yes | 0 |
Whether to disable TabContent
.
Type | Required | Default value |
---|---|---|
boolean |
No | false |
Whether TabContent
needs to be preloaded.
Type | Required | Default value |
---|---|---|
boolean |
No | true |
The preload delay time of TabContent
.
Type | Required | Default value |
---|---|---|
number |
No | null |
TabContent
sliding callback.
Type | Required | Default value |
---|---|---|
(gestureState, index, percent) => void |
No | null |
Callback of TabContent
sliding end.
Type | Required | Default value |
---|---|---|
(gestureState, index, percent) => void |
No | null |
Custom rendering of the placeholder container in the preload.
Type | Required | Default value |
---|---|---|
(activeIndex, children) => React.Element |
No | null |
Child element of TabContent
.
Type | Required | Default value |
---|---|---|
array |
No | null |
The acceleration threshold of TabContent
in px. If the sliding rate exceeds the threshold, it is directly judged as the next page.
This property is added in the @2.0.0-rc.2 version.
Type | Required | Default value |
---|---|---|
number |
No | 0.5 |
Animation configuration.
Type | Required | Default value |
---|---|---|
IAnimationConfig |
No |
|
Gradient example:
interface IAnimationConfig {
duration? : number;
easing? : EasingFunction;
delay? : number;
isInteraction? : bool;
useNativeDriver? : bool;
}
// Default value
{
duration: 200,
easing: Easing.linear,
delay: 0,
isInteraction: true,
useNativeDriver: true,
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback