@fluentui-react-native/tester 0.59.1 → 0.59.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui-react-native/tester",
3
- "version": "0.59.1",
3
+ "version": "0.59.4",
4
4
  "description": "A test app to test FluentUI React Native Components during development",
5
5
  "license": "MIT",
6
6
  "author": "Microsoft <fluentuinativeowners@microsoft.com>",
@@ -25,32 +25,32 @@
25
25
  "directory": "apps/fluent-tester"
26
26
  },
27
27
  "dependencies": {
28
- "@fluentui-react-native/android-theme": ">=0.5.6 <1.0.0",
29
- "@fluentui-react-native/apple-theme": ">=0.9.15 <1.0.0",
30
- "@fluentui-react-native/badge": ">=0.0.21 <1.0.0",
31
- "@fluentui-react-native/button": ">=0.22.11 <1.0.0",
32
- "@fluentui-react-native/default-theme": ">=0.9.13 <1.0.0",
33
- "@fluentui-react-native/experimental-activity-indicator": ">=0.5.18 <1.0.0",
34
- "@fluentui-react-native/experimental-avatar": ">=0.14.10 <1.0.0",
35
- "@fluentui-react-native/experimental-button": "0.15.11",
36
- "@fluentui-react-native/experimental-checkbox": "0.10.8",
37
- "@fluentui-react-native/experimental-drawer": ">=0.1.1 <1.0.0",
28
+ "@fluentui-react-native/android-theme": ">=0.7.0 <1.0.0",
29
+ "@fluentui-react-native/apple-theme": ">=0.11.0 <1.0.0",
30
+ "@fluentui-react-native/badge": ">=0.0.23 <1.0.0",
31
+ "@fluentui-react-native/button": ">=0.22.13 <1.0.0",
32
+ "@fluentui-react-native/default-theme": ">=0.9.15 <1.0.0",
33
+ "@fluentui-react-native/experimental-activity-indicator": ">=0.5.20 <1.0.0",
34
+ "@fluentui-react-native/experimental-avatar": ">=0.14.12 <1.0.0",
35
+ "@fluentui-react-native/experimental-button": "0.15.13",
36
+ "@fluentui-react-native/experimental-checkbox": "0.10.10",
37
+ "@fluentui-react-native/experimental-drawer": ">=0.1.3 <1.0.0",
38
38
  "@fluentui-react-native/experimental-native-date-picker": ">=0.4.1 <1.0.0",
39
- "@fluentui-react-native/experimental-expander": "0.3.20",
40
- "@fluentui-react-native/experimental-menu-button": ">=0.3.23 <1.0.0",
41
- "@fluentui-react-native/experimental-shimmer": "0.6.22",
42
- "@fluentui-react-native/experimental-tabs": "0.4.32",
43
- "@fluentui-react-native/experimental-text": ">=0.7.19 <1.0.0",
44
- "@fluentui-react-native/framework": ">=0.7.19 <1.0.0",
45
- "@fluentui-react-native/icon": "0.11.14",
46
- "@fluentui-react-native/interactive-hooks": ">=0.14.6 <1.0.0",
47
- "@fluentui-react-native/stack": ">=0.6.19 <1.0.0",
39
+ "@fluentui-react-native/experimental-expander": "0.3.22",
40
+ "@fluentui-react-native/experimental-menu-button": ">=0.3.25 <1.0.0",
41
+ "@fluentui-react-native/experimental-shimmer": "0.6.24",
42
+ "@fluentui-react-native/experimental-tabs": "0.4.34",
43
+ "@fluentui-react-native/experimental-text": ">=0.7.21 <1.0.0",
44
+ "@fluentui-react-native/framework": ">=0.7.21 <1.0.0",
45
+ "@fluentui-react-native/icon": "0.11.16",
46
+ "@fluentui-react-native/interactive-hooks": ">=0.14.8 <1.0.0",
47
+ "@fluentui-react-native/stack": ">=0.6.21 <1.0.0",
48
48
  "@fluentui-react-native/theme": ">=0.6.6 <1.0.0",
49
49
  "@fluentui-react-native/theme-types": ">=0.14.1 <1.0.0",
50
50
  "@fluentui-react-native/themed-stylesheet": "^1.3.3",
51
- "@fluentui-react-native/theming-utils": ">=0.9.2 <1.0.0",
52
- "@fluentui-react-native/win32-theme": ">=0.14.15 <1.0.0",
53
- "@fluentui/react-native": ">=0.28.1 <1.0.0",
51
+ "@fluentui-react-native/theming-utils": ">=0.9.4 <1.0.0",
52
+ "@fluentui-react-native/win32-theme": ">=0.16.0 <1.0.0",
53
+ "@fluentui/react-native": ">=0.28.3 <1.0.0",
54
54
  "@react-native-community/slider": "^4.2.0",
55
55
  "@react-native-menu/menu": "^0.1.2",
56
56
  "@react-native-picker/picker": "^2.2.1",
@@ -1,129 +1,148 @@
1
1
  import * as React from 'react';
2
- import { View, Picker, Switch } from 'react-native';
3
- import { FocusZone, Button, Text, FocusZoneDirection, Checkbox } from '@fluentui/react-native';
2
+ import { View, Switch } from 'react-native';
3
+ import { FocusZone, Text, FocusZoneDirection, Checkbox } from '@fluentui/react-native';
4
+ import { ButtonV1 as Button, ButtonProps } from '@fluentui-react-native/button';
4
5
  import { Test, TestSection, PlatformStatus } from '../Test';
5
6
  import { FOCUSZONE_TESTPAGE } from './consts';
6
- import { focusZoneTestStyles, stackStyleFocusZone } from './styles';
7
+ import { focusZoneTestStyles, GridButton, stackStyleFocusZone, SubheaderText } from './styles';
7
8
  import { commonTestStyles } from '../Common/styles';
8
9
  import { Stack } from '@fluentui-react-native/stack';
10
+ import { MenuButton, MenuButtonItemProps } from '@fluentui-react-native/experimental-menu-button';
11
+
12
+ const ListOfCheckboxes: React.FunctionComponent = () => {
13
+ return (
14
+ <React.Fragment>
15
+ <Checkbox label="Option A" />
16
+ <Checkbox label="Option B" />
17
+ <Checkbox label="Option C" />
18
+ <Checkbox label="Option D" />
19
+ </React.Fragment>
20
+ );
21
+ };
22
+
23
+ const FocusZoneListWrapper: React.FunctionComponent = (props) => {
24
+ const buttonProps: ButtonProps = { children: 'Click to Focus', style: { marginVertical: 10 } };
25
+ return (
26
+ <React.Fragment>
27
+ <Button {...buttonProps} />
28
+ {React.Children.map(props.children, (child) => {
29
+ return (
30
+ <React.Fragment>
31
+ {child}
32
+ <Button {...buttonProps} />
33
+ </React.Fragment>
34
+ );
35
+ })}
36
+ </React.Fragment>
37
+ );
38
+ };
39
+
40
+ const FocusZoneDirections: FocusZoneDirection[] = ['bidirectional', 'horizontal', 'vertical', 'none'];
9
41
 
10
42
  const DirectionalFocusZone: React.FunctionComponent = () => {
11
43
  return (
12
- <View>
13
- <Button content="Outside FocusZone" />
14
- <Text variant="headerSemibold">FocusZone with Bidirectional arrow key navigation</Text>
15
- <FocusZone focusZoneDirection="bidirectional">
16
- <Checkbox label="Option A" />
17
- <Checkbox label="Option B" />
18
- <Checkbox label="Option C" />
19
- <Checkbox label="Option D" />
20
- </FocusZone>
21
- <Button content="Outside FocusZone" />
22
- <Text variant="headerSemibold">FocusZone with Vertical arrow key navigation</Text>
23
- <FocusZone focusZoneDirection="vertical">
24
- <Checkbox label="Option A" />
25
- <Checkbox label="Option B" />
26
- <Checkbox label="Option C" />
27
- <Checkbox label="Option D" />
28
- </FocusZone>
29
- <Button content="Outside FocusZone" />
30
- <Text variant="headerSemibold">FocusZone with Horizontal arrow key navigation</Text>
31
- <FocusZone focusZoneDirection="horizontal">
32
- <Checkbox label="Option A" />
33
- <Checkbox label="Option B" />
34
- <Checkbox label="Option C" />
35
- <Checkbox label="Option D" />
36
- </FocusZone>
37
- <Button content="Outside FocusZone" />
38
- <Text variant="headerSemibold">FocusZone with No arrow key navigation</Text>
39
- <FocusZone focusZoneDirection="none">
40
- <Checkbox label="Option A" />
41
- <Checkbox label="Option B" />
42
- <Checkbox label="Option C" />
43
- <Checkbox label="Option D" />
44
- </FocusZone>
45
- <Button content="Outside FocusZone" />
46
- <Text variant="headerSemibold">FocusZone with no props set</Text>
44
+ <FocusZoneListWrapper>
47
45
  <FocusZone>
48
- <Checkbox label="Option A" />
49
- <Checkbox label="Option B" />
50
- <Checkbox label="Option C" />
51
- <Checkbox label="Option D" />
46
+ <SubheaderText>FocusZone with no props set</SubheaderText>
47
+ <ListOfCheckboxes />
52
48
  </FocusZone>
53
- <Button content="Outside FocusZone" />
54
- </View>
49
+ {FocusZoneDirections.map((direction, index) => (
50
+ <FocusZone key={index} focusZoneDirection={direction}>
51
+ <SubheaderText>FocusZone with arrow key navigation: {direction}</SubheaderText>
52
+ <ListOfCheckboxes />
53
+ </FocusZone>
54
+ ))}
55
+ </FocusZoneListWrapper>
55
56
  );
56
57
  };
57
58
 
58
59
  const CommonUsageFocusZone: React.FunctionComponent = () => {
59
60
  return (
60
- <View>
61
- <Button content="Outside FocusZone" />
62
- <Text variant="headerSemibold">FocusZone with Circular Navigation</Text>
61
+ <FocusZoneListWrapper>
63
62
  <FocusZone isCircularNavigation={true}>
64
- <Checkbox label="Option A" />
65
- <Checkbox label="Option B" />
66
- <Checkbox label="Option C" />
67
- <Checkbox label="Option D" />
63
+ <SubheaderText>FocusZone with Circular Navigation</SubheaderText>
64
+ <ListOfCheckboxes />
68
65
  </FocusZone>
69
- <Button content="Outside FocusZone" />
70
- <Text variant="headerSemibold">Disabled FocusZone</Text>
71
66
  <FocusZone disabled={true}>
72
- <Checkbox label="Option A" />
73
- <Checkbox label="Option B" />
74
- <Checkbox label="Option C" />
75
- <Checkbox label="Option D" />
67
+ <SubheaderText>Disabled FocusZone</SubheaderText>
68
+ <ListOfCheckboxes />
76
69
  </FocusZone>
77
- <Button content="Outside FocusZone" />
78
- </View>
70
+ </FocusZoneListWrapper>
79
71
  );
80
72
  };
81
73
 
82
- const Navigation2DFocusZone: React.FunctionComponent = () => {
83
- const buttonRefs = [];
84
- const [defaultTabbableElementIndex, setDefaultTabbableElementIndex] = React.useState<number>(5);
85
- const onClick = React.useCallback(
86
- (i: number) => {
87
- setDefaultTabbableElementIndex(i);
88
- },
89
- [setDefaultTabbableElementIndex],
90
- );
91
-
92
- for (let i = 0; i <= 9; i++) {
93
- // eslint-disable-next-line react-hooks/rules-of-hooks
94
- const ref = React.useRef<View>(null);
95
- buttonRefs.push(i == 0 ? undefined : ref);
96
- }
74
+ type GridOfButtonsProps = {
75
+ gridWidth: number;
76
+ gridHeight: number;
77
+ buttonRefs?: React.RefObject<View>[];
78
+ onClick?: (index: number) => void;
79
+ };
97
80
 
81
+ const GridOfButtons: React.FunctionComponent<GridOfButtonsProps> = (props: GridOfButtonsProps) => {
98
82
  return (
99
- <View>
100
- <View>
101
- <Button content="Outside FocusZone" />
102
- <Button content="Clear default tabble element" onClick={() => onClick(0)} />
103
- </View>
104
- <FocusZone use2DNavigation={true} defaultTabbableElement={buttonRefs[defaultTabbableElementIndex]} isCircularNavigation={true}>
105
- <View style={focusZoneTestStyles.focusZoneContainer}>
106
- <View style={focusZoneTestStyles.focusZoneViewStyle}>
107
- <Button content="#1" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[1]} onClick={() => onClick(1)} />
108
- <Button content="#2" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[2]} onClick={() => onClick(2)} />
109
- <Button content="#3" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[3]} onClick={() => onClick(3)} />
110
- </View>
111
- <View style={focusZoneTestStyles.focusZoneViewStyle}>
112
- <Button content="#4" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[4]} onClick={() => onClick(4)} />
113
- <Button content="#5" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[5]} onClick={() => onClick(5)} />
114
- <Button content="#6" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[6]} onClick={() => onClick(6)} />
83
+ <React.Fragment>
84
+ {[...Array(props.gridHeight)].map((_value, heightIndex: number) => {
85
+ return (
86
+ <View key={heightIndex} style={focusZoneTestStyles.focusZoneViewStyle}>
87
+ {[...Array(props.gridWidth)].map((_value, widthIndex: number) => {
88
+ const gridIndex = heightIndex * props.gridWidth + widthIndex + 1;
89
+ return (
90
+ <GridButton
91
+ key={widthIndex}
92
+ style={focusZoneTestStyles.focusZoneButton}
93
+ componentRef={props?.buttonRefs?.[gridIndex]}
94
+ onClick={() => {
95
+ props?.onClick?.(gridIndex);
96
+ }}
97
+ >
98
+ <Text>{gridIndex}</Text>
99
+ </GridButton>
100
+ );
101
+ })}
115
102
  </View>
116
- <View style={focusZoneTestStyles.focusZoneViewStyle}>
117
- <Button content="#7" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[7]} onClick={() => onClick(7)} />
118
- <Button content="#8" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[8]} onClick={() => onClick(8)} />
119
- <Button content="#9" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[9]} onClick={() => onClick(9)} />
103
+ );
104
+ })}
105
+ </React.Fragment>
106
+ );
107
+ };
108
+
109
+ const Navigation2DFocusZone: React.FunctionComponent = () => {
110
+ const [defaultTabbableElementIndex, setDefaultTabbableElementIndex] = React.useState<number | null>(5);
111
+ const gridWidth = 3,
112
+ gridHeight = 4;
113
+
114
+ const refMemo = React.useMemo(
115
+ () =>
116
+ Array(gridWidth * gridHeight)
117
+ .fill(null)
118
+ .map(() => React.createRef<View>()),
119
+ [gridWidth, gridHeight],
120
+ );
121
+ const buttonRefs = React.useRef(refMemo);
122
+ const defaultTextNote = 'The defaultTabbableElement is ' + defaultTabbableElementIndex;
123
+ return (
124
+ <React.Fragment>
125
+ <Text>{defaultTextNote}</Text>
126
+ <Button onClick={() => setDefaultTabbableElementIndex(null)} style={{ marginTop: 10 }}>
127
+ Clear defaultTabbableElement
128
+ </Button>
129
+ <FocusZoneListWrapper>
130
+ <FocusZone
131
+ use2DNavigation={true}
132
+ defaultTabbableElement={defaultTabbableElementIndex ? buttonRefs.current[defaultTabbableElementIndex] : undefined}
133
+ isCircularNavigation={true}
134
+ >
135
+ <View style={focusZoneTestStyles.focusZoneContainer}>
136
+ {GridOfButtons({
137
+ gridWidth: 3,
138
+ gridHeight: 4,
139
+ buttonRefs: buttonRefs.current,
140
+ onClick: (index: number) => setDefaultTabbableElementIndex(index),
141
+ })}
120
142
  </View>
121
- </View>
122
- </FocusZone>
123
- <View>
124
- <Button content="Outside FocusZone" />
125
- </View>
126
- </View>
143
+ </FocusZone>
144
+ </FocusZoneListWrapper>
145
+ </React.Fragment>
127
146
  );
128
147
  };
129
148
 
@@ -143,14 +162,12 @@ function SwitchWithLabel(props: ISwitchWithLabelProps): React.ReactElement {
143
162
  );
144
163
  }
145
164
 
146
- const focusZoneDirectionStrings = ['Bidirectional', 'Horizontal', 'Vertical', 'None'];
147
-
148
165
  const CustomizableFocusZone: React.FunctionComponent = () => {
149
166
  const [is2DNav, set2dNav] = React.useState(false);
150
167
  const [isDisabled, setDisabled] = React.useState(false);
151
168
  const [isCircularNav, setIsCircularNav] = React.useState(false);
152
-
153
- const [isFocusZoneDirection, setFocusZoneDirection] = React.useState<FocusZoneDirection>('bidirectional');
169
+ const [focusZoneDirection, setFocusZoneDirection] = React.useState<FocusZoneDirection>('bidirectional');
170
+ const menuItems: MenuButtonItemProps[] = FocusZoneDirections.map((direction) => ({ itemKey: direction, text: direction }));
154
171
 
155
172
  return (
156
173
  <View style={commonTestStyles.root}>
@@ -159,63 +176,27 @@ const CustomizableFocusZone: React.FunctionComponent = () => {
159
176
  <SwitchWithLabel label="2D Navigation" value={is2DNav} onValueChange={set2dNav} />
160
177
  <SwitchWithLabel label="Disabled" value={isDisabled} onValueChange={setDisabled} />
161
178
  <SwitchWithLabel label="Circular Navigation" value={isCircularNav} onValueChange={setIsCircularNav} />
162
- <Picker
163
- prompt="Direction"
164
- style={commonTestStyles.header}
165
- selectedValue="Bidirectional"
166
- onValueChange={(direction) => {
167
- switch (direction) {
168
- case 'Bidirectional':
169
- setFocusZoneDirection('bidirectional');
170
- break;
171
- case 'Horizontal':
172
- setFocusZoneDirection('horizontal');
173
- break;
174
- case 'Vertical':
175
- setFocusZoneDirection('vertical');
176
- break;
177
- case 'None':
178
- setFocusZoneDirection('none');
179
- break;
180
- }
179
+ <MenuButton
180
+ content={focusZoneDirection}
181
+ menuItems={menuItems}
182
+ onItemClick={(direction) => setFocusZoneDirection(direction as FocusZoneDirection)}
183
+ contextualMenu={{
184
+ shouldFocusOnMount: true,
185
+ shouldFocusOnContainer: true,
181
186
  }}
182
- >
183
- {focusZoneDirectionStrings.map((direction, index) => (
184
- <Picker.Item label={direction} key={index} value={direction} />
185
- ))}
186
- </Picker>
187
+ />
187
188
  </View>
188
189
 
189
- <View>
190
- <Button content="Outside FocusZone" />
191
- </View>
192
- <FocusZone
193
- disabled={isDisabled}
194
- use2DNavigation={is2DNav}
195
- focusZoneDirection={isFocusZoneDirection}
196
- isCircularNavigation={isCircularNav}
197
- >
198
- <View style={focusZoneTestStyles.focusZoneContainer}>
199
- <View style={focusZoneTestStyles.focusZoneViewStyle}>
200
- <Button content="#1" style={focusZoneTestStyles.focusZoneButton} />
201
- <Button content="#2" style={focusZoneTestStyles.focusZoneButton} />
202
- <Button content="#3" style={focusZoneTestStyles.focusZoneButton} />
203
- </View>
204
- <View style={focusZoneTestStyles.focusZoneViewStyle}>
205
- <Button content="#4" style={focusZoneTestStyles.focusZoneButton} />
206
- <Button content="#5" style={focusZoneTestStyles.focusZoneButton} />
207
- <Button content="#6" style={focusZoneTestStyles.focusZoneButton} />
208
- </View>
209
- <View style={focusZoneTestStyles.focusZoneViewStyle}>
210
- <Button content="#7" style={focusZoneTestStyles.focusZoneButton} />
211
- <Button content="#8" style={focusZoneTestStyles.focusZoneButton} />
212
- <Button content="#9" style={focusZoneTestStyles.focusZoneButton} />
213
- </View>
214
- </View>
215
- </FocusZone>
216
- <View>
217
- <Button content="Outside FocusZone" />
218
- </View>
190
+ <FocusZoneListWrapper>
191
+ <FocusZone
192
+ disabled={isDisabled}
193
+ use2DNavigation={is2DNav}
194
+ focusZoneDirection={focusZoneDirection}
195
+ isCircularNavigation={isCircularNav}
196
+ >
197
+ <View style={focusZoneTestStyles.focusZoneContainer}>{GridOfButtons({ gridWidth: 3, gridHeight: 3 })}</View>
198
+ </FocusZone>
199
+ </FocusZoneListWrapper>
219
200
  </Stack>
220
201
  </View>
221
202
  );
@@ -232,7 +213,7 @@ const focusZoneSections: TestSection[] = [
232
213
  component: CommonUsageFocusZone,
233
214
  },
234
215
  {
235
- name: '2D Navigation with Default Tabbable Element (#5) FocusZone Usage',
216
+ name: '2D Navigation',
236
217
  component: Navigation2DFocusZone,
237
218
  },
238
219
  {
@@ -250,7 +231,5 @@ export const FocusZoneTest: React.FunctionComponent = () => {
250
231
  androidStatus: 'Backlog',
251
232
  };
252
233
 
253
- const description = 'No description.';
254
-
255
- return <Test name="FocusZone Test" description={description} sections={focusZoneSections} status={status}></Test>;
234
+ return <Test name="FocusZone Test" description={'No description.'} sections={focusZoneSections} status={status} />;
256
235
  };
@@ -1,12 +1,14 @@
1
- import { StyleSheet } from 'react-native';
1
+ import { StyleSheet, View } from 'react-native';
2
2
  import { IStackProps } from '@fluentui-react-native/stack';
3
+ import { Text } from '@fluentui/react-native';
4
+ import { ButtonV1 as Button } from '@fluentui-react-native/button';
5
+ import { Icon } from '@fluentui-react-native/icon';
3
6
 
4
7
  export const focusZoneTestStyles = StyleSheet.create({
5
8
  focusZoneViewStyle: {
6
9
  flexDirection: 'row',
7
10
  alignContent: 'flex-start',
8
11
  alignItems: 'flex-start',
9
- marginTop: 10,
10
12
  },
11
13
  focusZoneContainer: {
12
14
  flexDirection: 'column',
@@ -14,14 +16,27 @@ export const focusZoneTestStyles = StyleSheet.create({
14
16
  padding: 4,
15
17
  },
16
18
  focusZoneButton: {
17
- marginRight: 60,
18
19
  height: 50,
19
20
  width: 50,
20
21
  },
21
- focusZoneButton0: {
22
- height: 50,
23
- width: 50,
22
+ });
23
+
24
+ export const GridButton = Button.compose({
25
+ slots: {
26
+ root: View,
27
+ icon: Icon,
28
+ content: Text,
24
29
  },
30
+ slotProps: {
31
+ content: {
32
+ style: { aspectRatio: 1, alignItems: 'center', justifyContent: 'center' },
33
+ },
34
+ },
35
+ });
36
+
37
+ export const SubheaderText = Text.customize({
38
+ tokens: { variant: 'subheaderSemibold' },
39
+ root: { style: { textDecorationLine: 'underline' } },
25
40
  });
26
41
 
27
42
  export const stackStyleFocusZone: IStackProps['style'] = {