Skip to content

Commit e921fe5

Browse files
authored
Update TabList Test Page with More Examples (#2988)
* Add examples to test page * Add dev warning for duplicate tabKeys * Change files * Use imported icon props
1 parent ee6c10d commit e921fe5

File tree

4 files changed

+169
-73
lines changed

4 files changed

+169
-73
lines changed

apps/fluent-tester/src/TestComponents/TabList/TabListTest.tsx

Lines changed: 151 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,209 @@
11
import React from 'react';
2-
import { View, StyleSheet } from 'react-native';
2+
import { View } from 'react-native';
33

4+
import { ButtonV1 as Button } from '@fluentui-react-native/button';
45
import { Divider } from '@fluentui-react-native/divider';
6+
import { Menu, MenuTrigger, MenuList, MenuItem, MenuPopover } from '@fluentui-react-native/menu';
57
import { TabList, Tab } from '@fluentui-react-native/tablist';
68
import { TextV1 as Text } from '@fluentui-react-native/text';
79

10+
import { svgProps, fontProps } from '../Common/iconExamples';
11+
import { stackStyle } from '../Common/styles';
812
import type { PlatformStatus, TestSection } from '../Test';
913
import { Test } from '../Test';
1014

11-
const Header = Text.customize({ variant: 'subheaderStandard' });
15+
const SubHeader = Text.customize({ variant: 'subheaderStandard' });
16+
const Header = Text.customize({ variant: 'headerStandard' });
1217
const Line = Divider.customize({ paddingVertical: 4 });
1318
const PaddedTabList = TabList.customize({
1419
paddingVertical: 4,
1520
});
1621

17-
const styles = StyleSheet.create({
18-
container: {
19-
paddingVertical: 8,
20-
},
21-
});
22-
23-
const TabListSizeTest: React.FunctionComponent = () => {
22+
const TabListDefaultTest: React.FunctionComponent = () => {
23+
const [key, setKey] = React.useState('tab1');
2424
return (
25-
<View style={styles.container}>
26-
<Header>Small</Header>
27-
<PaddedTabList size="small">
28-
<Tab tabKey="hello">Tab 1</Tab>
29-
<Tab tabKey="world">Tab 2</Tab>
30-
</PaddedTabList>
25+
<View style={stackStyle}>
26+
<Header>Uncontrolled Component</Header>
3127
<Line />
32-
<Header>Medium (default)</Header>
33-
<PaddedTabList size="medium">
34-
<Tab tabKey="hello">Tab 1</Tab>
35-
<Tab tabKey="world">Tab 2</Tab>
28+
<PaddedTabList defaultSelectedKey={'tab1'}>
29+
<Tab tabKey="tab1">Tab 1</Tab>
30+
<Tab tabKey="tab2">Tab 2</Tab>
31+
<Tab tabKey="tab3">Tab 3</Tab>
3632
</PaddedTabList>
33+
<Header>Controlled Component</Header>
3734
<Line />
38-
<Header>Large</Header>
39-
<PaddedTabList size="large">
40-
<Tab tabKey="hello">Tab 1</Tab>
41-
<Tab tabKey="world">Tab 2</Tab>
35+
<Text>Selected Key: {key}</Text>
36+
<PaddedTabList
37+
selectedKey={key}
38+
onTabSelect={(val) => {
39+
console.log('New key:', val);
40+
setKey(val);
41+
}}
42+
>
43+
<Tab tabKey="tab1">Tab 1</Tab>
44+
<Tab tabKey="tab2">Tab 2</Tab>
45+
<Tab tabKey="tab3">Tab 3</Tab>
4246
</PaddedTabList>
4347
</View>
4448
);
4549
};
4650

47-
const TabListVerticalTest: React.FunctionComponent = () => {
51+
const TabListDisabledTest: React.FunctionComponent = () => {
4852
return (
49-
<TabList vertical>
50-
<Tab tabKey="hello">Tab 1</Tab>
51-
<Tab tabKey="world">Tab 2</Tab>
52-
</TabList>
53+
<View style={stackStyle}>
54+
<PaddedTabList defaultSelectedKey="tab2">
55+
<Tab disabled tabKey="tab1">
56+
Tab 1
57+
</Tab>
58+
<Tab tabKey="tab2">Tab 2</Tab>
59+
<Tab disabled tabKey="tab3">
60+
Tab 3
61+
</Tab>
62+
<Tab tabKey="tab4">Tab 4</Tab>
63+
</PaddedTabList>
64+
<PaddedTabList disabled>
65+
<Tab tabKey="tab1">Tab 1</Tab>
66+
<Tab tabKey="tab2">Tab 2</Tab>
67+
<Tab tabKey="tab3">Tab 3</Tab>
68+
</PaddedTabList>
69+
</View>
5370
);
5471
};
5572

56-
const TabListAppearanceTest: React.FunctionComponent = () => {
73+
const TabListVariantsTest: React.FunctionComponent = () => {
5774
return (
58-
<View style={styles.container}>
59-
<Header>Transparent Appearance</Header>
60-
<PaddedTabList appearance="transparent">
61-
<Tab tabKey="hello">Tab 1</Tab>
62-
<Tab tabKey="world">Tab 2</Tab>
75+
<View style={stackStyle}>
76+
<Header>Size Variants</Header>
77+
<Line />
78+
<SubHeader>Small</SubHeader>
79+
<PaddedTabList defaultSelectedKey="sm1" size="small">
80+
<Tab tabKey="sm1">Small Tab 1</Tab>
81+
<Tab tabKey="sm2">Small Tab 2</Tab>
82+
<Tab tabKey="sm3">Small Tab 3</Tab>
83+
</PaddedTabList>
84+
<SubHeader>Medium (default)</SubHeader>
85+
<PaddedTabList defaultSelectedKey="m1" size="medium">
86+
<Tab tabKey="m1">Medium Tab 1</Tab>
87+
<Tab tabKey="m2">Medium Tab 2</Tab>
88+
<Tab tabKey="m3">Medium Tab 3</Tab>
89+
</PaddedTabList>
90+
<SubHeader>Large</SubHeader>
91+
<PaddedTabList defaultSelectedKey="lg1" size="large">
92+
<Tab tabKey="lg1">Large Tab 1</Tab>
93+
<Tab tabKey="lg2">Large Tab 2</Tab>
94+
<Tab tabKey="lg3">Large Tab 3</Tab>
6395
</PaddedTabList>
64-
<Header>Subtle Appearance</Header>
65-
<PaddedTabList appearance="subtle">
66-
<Tab tabKey="hello">Tab 1</Tab>
67-
<Tab tabKey="world">Tab 2</Tab>
96+
<Header>Appearance</Header>
97+
<Line />
98+
<SubHeader>Transparent Appearance</SubHeader>
99+
<PaddedTabList defaultSelectedKey="tab1" appearance="transparent">
100+
<Tab tabKey="tab1">Tab 1</Tab>
101+
<Tab tabKey="tab2">Tab 2</Tab>
102+
<Tab tabKey="tab3">Tab 3</Tab>
103+
</PaddedTabList>
104+
<SubHeader>Subtle Appearance</SubHeader>
105+
<PaddedTabList defaultSelectedKey="tab1" appearance="subtle">
106+
<Tab tabKey="tab1">Tab 1</Tab>
107+
<Tab tabKey="tab2">Tab 2</Tab>
108+
<Tab tabKey="tab3">Tab 3</Tab>
109+
</PaddedTabList>
110+
<Header>Vertical Orientation</Header>
111+
<Line />
112+
<PaddedTabList defaultSelectedKey="tab1" vertical>
113+
<Tab tabKey="tab1">Tab 1</Tab>
114+
<Tab tabKey="tab2">Tab 2</Tab>
115+
<Tab tabKey="tab3">Tab 3</Tab>
68116
</PaddedTabList>
69117
</View>
70118
);
71119
};
72120

73-
const TabListDisabledTest: React.FunctionComponent = () => {
121+
const TabListIconTest: React.FunctionComponent = () => {
74122
return (
75-
<View>
76-
<PaddedTabList>
77-
<Tab disabled tabKey="hello">
78-
Tab 1
123+
<View style={stackStyle}>
124+
<TabList defaultSelectedKey="fontIcon">
125+
<Tab icon={{ fontSource: fontProps }} tabKey="fontIcon">
126+
Font Icon
79127
</Tab>
80-
<Tab tabKey="world">Tab 2</Tab>
81-
</PaddedTabList>
82-
<PaddedTabList disabled>
83-
<Tab tabKey="hello">Tab 1</Tab>
84-
<Tab tabKey="world">Tab 2</Tab>
85-
</PaddedTabList>
128+
<Tab icon={{ fontSource: fontProps }} tabKey="fontIconOnly" />
129+
<Tab icon={{ svgSource: svgProps }} tabKey="svgIcon">
130+
SVG Icon
131+
</Tab>
132+
<Tab icon={{ svgSource: svgProps }} tabKey="svgIconOnly" />
133+
</TabList>
86134
</View>
87135
);
88136
};
89137

90-
const TabListIconTest: React.FunctionComponent = () => {
91-
const iconProp = {
92-
fontSource: {
93-
fontFamily: 'Arial',
94-
codepoint: 0x2663,
95-
},
96-
};
138+
const TabListViewTest: React.FunctionComponent = () => {
139+
const [key, setKey] = React.useState('a');
140+
const views = React.useMemo(
141+
() => ({
142+
a: (
143+
<View>
144+
<SubHeader>This is View 1</SubHeader>
145+
<Text variant="body1">Here is some text.</Text>
146+
</View>
147+
),
148+
b: (
149+
<View>
150+
<SubHeader>This is View 2</SubHeader>
151+
<Button>Button 1</Button>
152+
</View>
153+
),
154+
c: (
155+
<View>
156+
<SubHeader>This is View 3</SubHeader>
157+
<Menu>
158+
<MenuTrigger>
159+
<Button>Menu</Button>
160+
</MenuTrigger>
161+
<MenuPopover>
162+
<MenuList>
163+
<MenuItem>Item 1</MenuItem>
164+
<MenuItem>Item 2</MenuItem>
165+
<MenuItem>Item 3</MenuItem>
166+
</MenuList>
167+
</MenuPopover>
168+
</Menu>
169+
</View>
170+
),
171+
}),
172+
[],
173+
);
97174
return (
98-
<TabList>
99-
<Tab icon={iconProp} tabKey="withIcon">
100-
Tab Item
101-
</Tab>
102-
<Tab icon={iconProp} tabKey="iconOnly" />
103-
</TabList>
175+
<View style={stackStyle}>
176+
<TabList selectedKey={key} onTabSelect={setKey}>
177+
<Tab tabKey="a">View 1</Tab>
178+
<Tab tabKey="b">View 2</Tab>
179+
<Tab tabKey="c">View 3</Tab>
180+
</TabList>
181+
{views[key]}
182+
</View>
104183
);
105184
};
106185

107186
const sections: TestSection[] = [
108187
{
109-
name: 'Size',
110-
component: TabListSizeTest,
111-
},
112-
{
113-
name: 'Vertical',
114-
component: TabListVerticalTest,
115-
},
116-
{
117-
name: 'Appearance',
118-
component: TabListAppearanceTest,
188+
name: 'TabList Controlled vs Uncontrolled',
189+
component: TabListDefaultTest,
119190
},
120191
{
121192
name: 'Disabled',
122193
component: TabListDisabledTest,
123194
},
195+
{
196+
name: 'Variants',
197+
component: TabListVariantsTest,
198+
},
124199
{
125200
name: 'Icon',
126201
component: TabListIconTest,
127202
},
203+
{
204+
name: 'Rendering Content Separately',
205+
component: TabListViewTest,
206+
},
128207
];
129208

130209
export const TabListTest: React.FunctionComponent = () => {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Add dev warning for duplicate tabKeys",
4+
"packageName": "@fluentui-react-native/tablist",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "Add examples to test page",
4+
"packageName": "@fluentui-react-native/tester",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

packages/experimental/TabList/src/TabList/useTabList.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@ export const useTabList = (props: TabListProps): TabListInfo => {
3838

3939
const addTabKey = React.useCallback(
4040
(tabKey: string) => {
41+
if (__DEV__ && tabKeys.includes(tabKey)) {
42+
console.warn(`Tab Key "${tabKey}" already exists in the TabList. Duplicate keys are not supported.`);
43+
}
4144
setTabKeys((keys) => [...keys, tabKey]);
4245
},
43-
[setTabKeys],
46+
[tabKeys, setTabKeys],
4447
);
4548

4649
const removeTabKey = React.useCallback(

0 commit comments

Comments
 (0)