Bump eslint-plugin to 0.2.11 and fix hook-related errors (#1494)

* Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11

Bumps [@rnx-kit/eslint-plugin](https://github.com/microsoft/rnx-kit/tree/HEAD/packages/eslint-plugin) from 0.2.10 to 0.2.11.
- [Release notes](https://github.com/microsoft/rnx-kit/releases)
- [Changelog](https://github.com/microsoft/rnx-kit/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/microsoft/rnx-kit/commits/@rnx-kit/eslint-plugin@0.2.11/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@rnx-kit/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix build

* Fix build again

* Update doc

* Fix menubutton hooks

* Fix MenuButton component

* Tabs

* Change files

* Fix tester

* Change files

* Fix build

* Fix dependency

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
Ruriko Araki 2022-03-04 14:12:14 -08:00 коммит произвёл GitHub
Родитель 8f5f61c4e6
Коммит 051e390caa
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
68 изменённых файлов: 403 добавлений и 275 удалений

Просмотреть файл

@ -7,7 +7,7 @@ import { Test, TestSection, PlatformStatus } from '../Test';
import { ACTIVITY_INDICATOR_TESTPAGE } from './consts';
import { View, Switch } from 'react-native';
const basicActivityIndicator: React.FunctionComponent = () => {
const BasicActivityIndicator: React.FunctionComponent = () => {
const [animating, setAnimating] = React.useState(true);
const [hidesWhenStopped, setHidesWhenStopped] = React.useState(true);
@ -30,7 +30,7 @@ const basicActivityIndicator: React.FunctionComponent = () => {
);
};
const activityIndicatorTest: React.FunctionComponent = () => {
const ActivityIndicatorMainTest: React.FunctionComponent = () => {
return (
<Stack style={stackStyle}>
<Text>Extra Small</Text>
@ -57,7 +57,7 @@ const CustomizedActivityIndicator = ActivityIndicator.customize({
size: 'large',
});
const customizedActivityIndicatorTest: React.FunctionComponent = () => {
const CustomizedActivityIndicatorTest: React.FunctionComponent = () => {
return (
<Stack style={stackStyle}>
<Text>Customized Activity Indicator</Text>
@ -70,17 +70,17 @@ const activityIndicatorSections: TestSection[] = [
{
name: 'Base ActivityIndicator',
testID: ACTIVITY_INDICATOR_TESTPAGE,
component: basicActivityIndicator,
component: BasicActivityIndicator,
},
{
name: 'ActivityIndicator',
testID: ACTIVITY_INDICATOR_TESTPAGE,
component: activityIndicatorTest,
component: ActivityIndicatorMainTest,
},
{
name: 'Customized ActivityIndicator',
testID: ACTIVITY_INDICATOR_TESTPAGE,
component: customizedActivityIndicatorTest,
component: CustomizedActivityIndicatorTest,
},
];

Просмотреть файл

@ -6,7 +6,7 @@ import { Test, TestSection, PlatformStatus } from '../Test';
import { E2ECalloutTest } from './CalloutE2ETest';
import { fluentTesterStyles } from '../Common/styles';
const standardCallout: React.FunctionComponent = () => {
const StandardCallout: React.FunctionComponent = () => {
const [showStandardCallout, setShowStandardCallout] = React.useState(false);
const [isStandardCalloutVisible, setIsStandardCalloutVisible] = React.useState(false);
@ -23,29 +23,35 @@ const standardCallout: React.FunctionComponent = () => {
const [preventDismissOnClickOutside, setPreventDismissOnClickOutside] = React.useState(false);
const [calloutDismissBehaviors, setDismissBehaviors] = React.useState<DismissBehaviors[]>([]);
const onPreventDismissOnKeyDownChange = React.useCallback((value) => {
setPreventDismissOnKeyDown(value);
if (value) {
setDismissBehaviors(calloutDismissBehaviors.concat('preventDismissOnKeyDown'));
} else {
const newDismissBehaviors = calloutDismissBehaviors.filter((value) => {
value != 'preventDismissOnKeyDown';
});
setDismissBehaviors(newDismissBehaviors);
}
}, []);
const onPreventDismissOnKeyDownChange = React.useCallback(
(value) => {
setPreventDismissOnKeyDown(value);
if (value) {
setDismissBehaviors(calloutDismissBehaviors.concat('preventDismissOnKeyDown'));
} else {
const newDismissBehaviors = calloutDismissBehaviors.filter((value) => {
value != 'preventDismissOnKeyDown';
});
setDismissBehaviors(newDismissBehaviors);
}
},
[calloutDismissBehaviors],
);
const onPreventDismissOnClickOutsideChange = React.useCallback((value) => {
setPreventDismissOnClickOutside(value);
if (value) {
setDismissBehaviors(calloutDismissBehaviors.concat('preventDismissOnClickOutside'));
} else {
const newDismissBehaviors = calloutDismissBehaviors.filter((value) => {
value != 'preventDismissOnClickOutside';
});
setDismissBehaviors(newDismissBehaviors);
}
}, []);
const onPreventDismissOnClickOutsideChange = React.useCallback(
(value) => {
setPreventDismissOnClickOutside(value);
if (value) {
setDismissBehaviors(calloutDismissBehaviors.concat('preventDismissOnClickOutside'));
} else {
const newDismissBehaviors = calloutDismissBehaviors.filter((value) => {
value != 'preventDismissOnClickOutside';
});
setDismissBehaviors(newDismissBehaviors);
}
},
[calloutDismissBehaviors],
);
const redTargetRef = React.useRef<View>(null);
const blueTargetRef = React.useRef<View>(null);
@ -113,7 +119,7 @@ const standardCallout: React.FunctionComponent = () => {
const addButton = React.useCallback(() => {
setScrollviewContents((arr) => [...arr, 1]);
}, [setScrollviewContents, scrollviewContents]);
}, [setScrollviewContents]);
return (
<View>
@ -245,7 +251,7 @@ const standardCallout: React.FunctionComponent = () => {
);
};
const customCallout: React.FunctionComponent = () => {
const CustomCallout: React.FunctionComponent = () => {
const [showCustomizedCallout, setShowCustomizedCallout] = React.useState(false);
const [isCustomizedCalloutVisible, setIsCustomizedCalloutVisible] = React.useState(false);
@ -304,11 +310,11 @@ const calloutSections: TestSection[] = [
{
name: 'Standard Usage',
testID: CALLOUT_TESTPAGE,
component: standardCallout,
component: StandardCallout,
},
{
name: 'Customized Usage',
component: customCallout,
component: CustomCallout,
},
{
name: 'E2E Testing Callout',

Просмотреть файл

@ -11,7 +11,7 @@ function onChangeUncontrolled(isChecked: boolean) {
console.log(isChecked);
}
const basicCheckbox: React.FunctionComponent = () => {
const BasicCheckbox: React.FunctionComponent = () => {
return (
<View>
<Checkbox label="Unchecked checkbox (undefined)" onChange={onChangeUncontrolled} />
@ -29,7 +29,7 @@ const basicCheckbox: React.FunctionComponent = () => {
);
};
const otherCheckbox: React.FunctionComponent = () => {
const OtherCheckbox: React.FunctionComponent = () => {
const [isCheckedControlled1, setCheckedControlled1] = React.useState(false);
const onChangeControlled1 = React.useCallback((checked) => {
setCheckedControlled1(checked);
@ -87,7 +87,7 @@ const HoverCheckbox = Checkbox.customize({
},
});
const tokenCheckbox: React.FunctionComponent = () => {
const TokenCheckbox: React.FunctionComponent = () => {
const [checkboxColor, setCheckboxColor] = React.useState('blue');
const [checkmarkColor, setCheckmarkColor] = React.useState('white');
@ -148,15 +148,15 @@ const checkboxSections: TestSection[] = [
{
name: 'Basic Checkboxes',
testID: CHECKBOX_TESTPAGE,
component: basicCheckbox,
component: BasicCheckbox,
},
{
name: 'Other Implementations',
component: otherCheckbox,
component: OtherCheckbox,
},
{
name: 'Token Customized Checkboxes',
component: tokenCheckbox,
component: TokenCheckbox,
},
{
name: 'Checkbox for E2E Testing',

Просмотреть файл

@ -12,7 +12,7 @@ function onChangeUncontrolled(_e: InteractionEvent, isChecked: boolean) {
console.log(isChecked);
}
const basicCheckbox: React.FunctionComponent = () => {
const BasicCheckbox: React.FunctionComponent = () => {
return (
<View>
<Checkbox label="Unchecked checkbox (undefined)" onChange={onChangeUncontrolled} />
@ -28,7 +28,7 @@ const basicCheckbox: React.FunctionComponent = () => {
);
};
const sizeCheckbox: React.FunctionComponent = () => {
const SizeCheckbox: React.FunctionComponent = () => {
return (
<View>
<Checkbox tooltip="Medium checkbox" size="medium" />
@ -39,7 +39,7 @@ const sizeCheckbox: React.FunctionComponent = () => {
);
};
const otherCheckbox: React.FunctionComponent = () => {
const OtherCheckbox: React.FunctionComponent = () => {
const [isCheckedControlled1, setCheckedControlled1] = React.useState(false);
const onChangeControlled1 = React.useCallback((checked) => {
setCheckedControlled1(checked);
@ -86,7 +86,7 @@ const HoverCheckbox = Checkbox.customize({
},
});
const tokenCheckbox: React.FunctionComponent = () => {
const TokenCheckbox: React.FunctionComponent = () => {
const [checkboxColor, setCheckboxColor] = React.useState('blue');
const [checkmarkColor, setCheckmarkColor] = React.useState('white');
@ -147,19 +147,19 @@ const checkboxSections: TestSection[] = [
{
name: 'Basic Checkboxes',
testID: EXPERIMENTAL_CHECKBOX_TESTPAGE,
component: basicCheckbox,
component: BasicCheckbox,
},
{
name: 'Size Checkboxes',
component: sizeCheckbox,
component: SizeCheckbox,
},
{
name: 'Other Implementations',
component: otherCheckbox,
component: OtherCheckbox,
},
{
name: 'Token Customized Checkboxes',
component: tokenCheckbox,
component: TokenCheckbox,
},
{
name: 'E2E Testing for Experimental Checkbox',

Просмотреть файл

@ -121,7 +121,7 @@ export const Slider: React.FunctionComponent<ISliderProps> = (props: ISliderProp
setThumbLocation(initialThumbLocation);
});
}
}, [ref.current, initialValue, maximum, minimum]);
}, [ref, initialValue, maximum, minimum]);
return (
<View style={[userStyle, styles.root]}>

Просмотреть файл

@ -16,7 +16,7 @@ import { Test, TestSection, PlatformStatus } from '../Test';
import { svgProps, fontProps, testImage } from '../Common/iconExamples';
import { E2EContextualMenuTest } from './E2EContextualMenuTest';
const contextualMenu: React.FunctionComponent = () => {
const ContextualMenuMainTest: React.FunctionComponent = () => {
const stdBtnRef = React.useRef(null);
const [showContextualMenu, setShowContextualMenu] = React.useState(false);
@ -114,7 +114,7 @@ const contextualMenu: React.FunctionComponent = () => {
);
};
const nestedContextualMenu: React.FunctionComponent = () => {
const NestedContextualMenu: React.FunctionComponent = () => {
const stdBtnRef = React.useRef(null);
const [showContextualMenu, setShowContextualMenu] = React.useState(false);
@ -472,11 +472,11 @@ const contextualMenuSections: TestSection[] = [
{
name: 'Standard ContextualMenu',
testID: CONTEXTUALMENU_TESTPAGE,
component: contextualMenu,
component: ContextualMenuMainTest,
},
{
name: 'Nested ContextualMenu',
component: nestedContextualMenu,
component: NestedContextualMenu,
},
{
name: 'IconButton with Customized ContextualMenu',

Просмотреть файл

@ -30,7 +30,7 @@ const CustomizedExpander = Expander.customize({
chevronBorderThickness: 2,
});
const expanderTest: React.FunctionComponent = () => {
const ExpanderMainTest: React.FunctionComponent = () => {
/** This test page has not yet been tested and does not currently build because
* the react-native-test-app does not yet support WinUI 2.6
* Filed issue in react-native-test-app: https://github.com/microsoft/react-native-test-app/issues/444
@ -87,7 +87,7 @@ const expanderTest: React.FunctionComponent = () => {
);
};
const basicExpander: React.FunctionComponent = () => {
const BasicExpander: React.FunctionComponent = () => {
return (
<Stack style={stackStyle}>
<View style={commonStyles.root}>
@ -104,12 +104,12 @@ const expanderSections: TestSection[] = [
{
name: 'BaseExpander',
testID: EXPANDER_TESTPAGE,
component: basicExpander,
component: BasicExpander,
},
{
name: 'Expander',
testID: EXPANDER_TESTPAGE,
component: expanderTest,
component: ExpanderMainTest,
},
];

Просмотреть файл

@ -52,7 +52,7 @@ export const ComponentTwiddler: React.FunctionComponent<IComponentTwiddlerProps>
);
};
const basicFocusTrapZone: React.FunctionComponent = () => {
const BasicFocusTrapZone: React.FunctionComponent = () => {
const [state, setState] = React.useState({
useTrapZone: false,
renderTrapZone: true,
@ -133,7 +133,7 @@ const focusTrapZoneSections: TestSection[] = [
{
name: 'Basic FocusTrapZone Usage',
testID: FOCUSTRAPZONE_TESTPAGE,
component: basicFocusTrapZone,
component: BasicFocusTrapZone,
},
];

Просмотреть файл

@ -7,7 +7,7 @@ import { focusZoneTestStyles, stackStyleFocusZone } from './styles';
import { commonTestStyles } from '../Common/styles';
import { Stack } from '@fluentui-react-native/stack';
const directionalFocusZone: React.FunctionComponent = () => {
const DirectionalFocusZone: React.FunctionComponent = () => {
return (
<View>
<Button content="Outside FocusZone" />
@ -55,7 +55,7 @@ const directionalFocusZone: React.FunctionComponent = () => {
);
};
const commonUsageFocusZone: React.FunctionComponent = () => {
const CommonUsageFocusZone: React.FunctionComponent = () => {
return (
<View>
<Button content="Outside FocusZone" />
@ -79,42 +79,44 @@ const commonUsageFocusZone: React.FunctionComponent = () => {
);
};
const navigation2DFocusZone: React.FunctionComponent = () => {
const Navigation2DFocusZone: React.FunctionComponent = () => {
const buttonRefs = [];
const onClicks = [];
const [defaultTabbableElementIndex, setDefaultTabbableElementIndex] = React.useState<number>(5);
const onClick = React.useCallback(
(i: number) => {
setDefaultTabbableElementIndex(i);
},
[setDefaultTabbableElementIndex],
);
for (let i = 0; i <= 9; i++) {
buttonRefs.push(i == 0 ? undefined : React.useRef<View>(null));
onClicks.push(
React.useCallback(() => {
setDefaultTabbableElementIndex(i);
}, [setDefaultTabbableElementIndex]),
);
// eslint-disable-next-line react-hooks/rules-of-hooks
const ref = React.useRef<View>(null);
buttonRefs.push(i == 0 ? undefined : ref);
}
return (
<View>
<View>
<Button content="Outside FocusZone" />
<Button content="Clear default tabble element" onClick={onClicks[0]} />
<Button content="Clear default tabble element" onClick={() => onClick(0)} />
</View>
<FocusZone use2DNavigation={true} defaultTabbableElement={buttonRefs[defaultTabbableElementIndex]} isCircularNavigation={true}>
<View style={focusZoneTestStyles.focusZoneContainer}>
<View style={focusZoneTestStyles.focusZoneViewStyle}>
<Button content="#1" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[1]} onClick={onClicks[1]} />
<Button content="#2" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[2]} onClick={onClicks[2]} />
<Button content="#3" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[3]} onClick={onClicks[3]} />
<Button content="#1" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[1]} onClick={() => onClick(1)} />
<Button content="#2" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[2]} onClick={() => onClick(2)} />
<Button content="#3" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[3]} onClick={() => onClick(3)} />
</View>
<View style={focusZoneTestStyles.focusZoneViewStyle}>
<Button content="#4" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[4]} onClick={onClicks[4]} />
<Button content="#5" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[5]} onClick={onClicks[5]} />
<Button content="#6" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[6]} onClick={onClicks[6]} />
<Button content="#4" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[4]} onClick={() => onClick(4)} />
<Button content="#5" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[5]} onClick={() => onClick(5)} />
<Button content="#6" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[6]} onClick={() => onClick(6)} />
</View>
<View style={focusZoneTestStyles.focusZoneViewStyle}>
<Button content="#7" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[7]} onClick={onClicks[7]} />
<Button content="#8" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[8]} onClick={onClicks[8]} />
<Button content="#9" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[9]} onClick={onClicks[9]} />
<Button content="#7" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[7]} onClick={() => onClick(7)} />
<Button content="#8" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[8]} onClick={() => onClick(8)} />
<Button content="#9" style={focusZoneTestStyles.focusZoneButton} componentRef={buttonRefs[9]} onClick={() => onClick(9)} />
</View>
</View>
</FocusZone>
@ -143,7 +145,7 @@ function SwitchWithLabel(props: ISwitchWithLabelProps): React.ReactElement {
const focusZoneDirectionStrings = ['Bidirectional', 'Horizontal', 'Vertical', 'None'];
const customizableFocusZone: React.FunctionComponent = () => {
const CustomizableFocusZone: React.FunctionComponent = () => {
const [is2DNav, set2dNav] = React.useState(false);
const [isDisabled, setDisabled] = React.useState(false);
const [isCircularNav, setIsCircularNav] = React.useState(false);
@ -223,19 +225,19 @@ const focusZoneSections: TestSection[] = [
{
name: 'Directional FocusZone Usage',
testID: FOCUSZONE_TESTPAGE,
component: directionalFocusZone,
component: DirectionalFocusZone,
},
{
name: 'Common FocusZone Usage',
component: commonUsageFocusZone,
component: CommonUsageFocusZone,
},
{
name: '2D Navigation with Default Tabbable Element (#5) FocusZone Usage',
component: navigation2DFocusZone,
component: Navigation2DFocusZone,
},
{
name: 'Customizable FocusZone',
component: customizableFocusZone,
component: CustomizableFocusZone,
},
];

Просмотреть файл

@ -11,7 +11,7 @@ const testImage = require('./../../../../assets/testicon.png');
const testTtf = require('./../../../../assets/Font_Awesome_900.otf');
import TestSvg from './assets/test.svg';
const icons: React.FunctionComponent = () => {
const Icons: React.FunctionComponent = () => {
const fontCustomFontProps: FontIconProps = {
fontFamily: 'Font Awesome 5 Free',
fontSrcFile: testTtf,
@ -94,7 +94,7 @@ const iconSections: TestSection[] = [
{
name: 'Icon',
testID: ICON_TESTPAGE,
component: icons,
component: Icons,
},
{
name: 'Icon for E2E Testing',

Просмотреть файл

@ -7,7 +7,7 @@ import { LINK_TESTPAGE } from './consts';
import { Test, TestSection, PlatformStatus } from '../Test';
import { LinkE2ETest } from './E2ELinkTest';
const links: React.FunctionComponent = () => {
const Links: React.FunctionComponent = () => {
const doPress = (): void => {
Alert.alert('Alert.', 'You have been alerted.');
};
@ -24,7 +24,7 @@ const linkSections: TestSection[] = [
{
name: 'Navigation and Alert',
testID: LINK_TESTPAGE,
component: links,
component: Links,
},
{
name: 'Link E2E Test',

Просмотреть файл

@ -7,7 +7,7 @@ import { Stack } from '@fluentui-react-native/stack';
import { stackStyle } from '../Common/styles';
import { Text } from '@fluentui/react-native';
const nativeDatePicker: React.FunctionComponent = () => {
const NativeDatePickerMainTest: React.FunctionComponent = () => {
const [startDate, setStartDate] = React.useState<Date>(new Date());
const [endDate, setEndDate] = React.useState<Date>(null);
@ -109,7 +109,7 @@ const nativeDatePickerSections: TestSection[] = [
{
name: 'Native Date Picker',
testID: NATIVEDATEPICKER_TESTPAGE,
component: nativeDatePicker,
component: NativeDatePickerMainTest,
},
];

Просмотреть файл

@ -73,7 +73,7 @@ export const CustomizeUsage: React.FunctionComponent = () => {
iconStrokeWidth: iconStrokeWidth,
};
return PersonaCoin.customize({ tokens });
}, [coinColor, textColor, showRings, coinSize, iconSize, iconStrokeWidth]);
}, [coinColor, textColor, coinSize, iconSize, iconStrokeWidth]);
return (
<View style={{ flexDirection: 'column', padding: 10, backgroundColor: showColoredBackground ? 'gray' : 'transparent' }}>

Просмотреть файл

@ -92,7 +92,7 @@ const PressComponent: React.FunctionComponent<ViewProps> = (props: ViewProps) =>
);
};
const pressable: React.FunctionComponent = () => {
const PressableMainTest: React.FunctionComponent = () => {
const [hoverProps, hoverState] = useHoverState({});
return (
@ -126,7 +126,7 @@ const pressableSections: TestSection[] = [
{
name: 'Pressable Components',
testID: PRESSABLE_TESTPAGE,
component: pressable,
component: PressableMainTest,
},
];

Просмотреть файл

@ -5,7 +5,7 @@ import { RADIOGROUP_TESTPAGE } from './consts';
import { Test, TestSection, PlatformStatus } from '../Test';
import { E2ERadioGroupTest } from './RadioGroupE2ETest';
const basicRadioGroup: React.FunctionComponent = () => {
const BasicRadioGroup: React.FunctionComponent = () => {
// Client's example onChange function
const onChange = (key: string) => {
console.log(key);
@ -56,7 +56,7 @@ const radioGroupSections: TestSection[] = [
{
name: 'Basic RadioGroup Usage',
testID: RADIOGROUP_TESTPAGE,
component: basicRadioGroup,
component: BasicRadioGroup,
},
{
name: 'RadioGroup for E2E Testing',

Просмотреть файл

@ -9,7 +9,7 @@ import { Test, TestSection, PlatformStatus } from '../Test';
const BlueSeparator = Separator.customize({ color: 'blue' });
const RedSeparator = Separator.customize({ color: 'red' });
const separator: React.FunctionComponent = () => {
const SeparatorMainTest: React.FunctionComponent = () => {
return (
<Stack style={stackStyle} gap={5}>
<Stack gap={4} style={separatorStackStyle}>
@ -31,7 +31,7 @@ const separatorSections: TestSection[] = [
{
name: 'Basic Button',
testID: SEPARATOR_TESTPAGE,
component: separator,
component: SeparatorMainTest,
},
];

Просмотреть файл

@ -13,7 +13,7 @@ const styles = StyleSheet.create({
},
});
const rect: React.FunctionComponent = () => {
const RectTest: React.FunctionComponent = () => {
const [useColorA, setUseColorA] = React.useState(false);
const colorA = 'red';
const colorB = 'green';
@ -36,7 +36,7 @@ const rect: React.FunctionComponent = () => {
);
};
const circle: React.FunctionComponent = () => {
const CircleTest: React.FunctionComponent = () => {
return (
<Svg width="50" height="50">
<Circle cx="25" cy="25" r="20" fill="red" stroke="black" />
@ -44,7 +44,7 @@ const circle: React.FunctionComponent = () => {
);
};
const line: React.FunctionComponent = () => {
const LineTest: React.FunctionComponent = () => {
return (
<Svg width="50" height="50">
<Line x1="10" y1="10" x2="20" y2="20" fill="red" stroke="black" />
@ -52,7 +52,7 @@ const line: React.FunctionComponent = () => {
);
};
const path: React.FunctionComponent = () => {
const PathTest: React.FunctionComponent = () => {
return (
<Svg width="100" height="100">
<Path d="M 0 0 A 10 10 0 0,1 0 100" fill="magenta" stroke="purple" id="path" />
@ -60,7 +60,7 @@ const path: React.FunctionComponent = () => {
);
};
const polygon: React.FunctionComponent = () => {
const PolygonTest: React.FunctionComponent = () => {
return (
<Svg height="100" width="100">
<Polygon points="40,5 70,80 25,95" fill="lime" stroke="purple" strokeWidth="1" />
@ -68,7 +68,7 @@ const polygon: React.FunctionComponent = () => {
);
};
const linearGradient: React.FunctionComponent = () => {
const LinearGradientTest: React.FunctionComponent = () => {
return (
<Svg height="100" width="100" style={{ backgroundColor: 'black' }} viewBox="0 0 10 10" color="yellow">
<Defs>
@ -82,7 +82,7 @@ const linearGradient: React.FunctionComponent = () => {
);
};
const radialGradient: React.FunctionComponent = () => {
const RadialGradientTest: React.FunctionComponent = () => {
return (
<Svg height="100" width="100" style={{ backgroundColor: 'black' }} viewBox="0 0 10 10" color="yellow">
<Defs>
@ -96,7 +96,7 @@ const radialGradient: React.FunctionComponent = () => {
);
};
const rectCircle: React.FunctionComponent = () => {
const RectCircleTest: React.FunctionComponent = () => {
return (
<Svg height="200" width="200">
<Defs>
@ -113,11 +113,11 @@ const rectCircle: React.FunctionComponent = () => {
);
};
const bundledSvg: React.FunctionComponent = () => {
const BundledSvgTest: React.FunctionComponent = () => {
return <TestSvg width={200} height={200} color="red" />;
};
const remoteSvg: React.FunctionComponent = () => {
const RemoteSvgTest: React.FunctionComponent = () => {
return (
<View>
<SvgCssUri
@ -144,43 +144,43 @@ const svgSections: TestSection[] = [
{
name: 'Rect',
testID: SVG_TESTPAGE,
component: rect,
component: RectTest,
},
{
name: 'Circle',
component: circle,
component: CircleTest,
},
{
name: 'Line',
component: line,
component: LineTest,
},
{
name: 'Path',
component: path,
component: PathTest,
},
{
name: 'Polygon',
component: polygon,
component: PolygonTest,
},
{
name: 'Linear Gradient',
component: linearGradient,
component: LinearGradientTest,
},
{
name: 'Radial Gradient',
component: radialGradient,
component: RadialGradientTest,
},
{
name: 'Rect and Circle via Defs and Use',
component: rectCircle,
component: RectCircleTest,
},
{
name: 'Bundled Svg',
component: bundledSvg,
component: BundledSvgTest,
},
{
name: 'Remotely Retrieved Svgs',
component: remoteSvg,
component: RemoteSvgTest,
},
];

Просмотреть файл

@ -7,7 +7,7 @@ import { Test, TestSection, PlatformStatus } from '../Test';
import { E2ETabsTest } from './TabsE2ETest';
import TestSvg from './test.svg';
const tabs: React.FunctionComponent = () => {
const TabsMainTest: React.FunctionComponent = () => {
return (
<View style={stackStyle}>
<Tabs label="Tabs">
@ -25,7 +25,7 @@ const tabs: React.FunctionComponent = () => {
);
};
const disabledTabs: React.FunctionComponent = () => {
const DisabledTabs: React.FunctionComponent = () => {
return (
<View style={stackStyle}>
<Tabs label="Tabs">
@ -43,7 +43,7 @@ const disabledTabs: React.FunctionComponent = () => {
);
};
const tabsCountIcon: React.FunctionComponent = () => {
const TabsCountIcon: React.FunctionComponent = () => {
const svgExample = {
svgSource: {
src: TestSvg,
@ -70,7 +70,7 @@ const tabsCountIcon: React.FunctionComponent = () => {
);
};
const onTabsClickEvent: React.FunctionComponent = () => {
const TabsClickEventTest: React.FunctionComponent = () => {
const [selectedKey, setSelectedKey] = React.useState('home_key');
const onTabsClick = (key: string) => {
@ -95,7 +95,7 @@ const onTabsClickEvent: React.FunctionComponent = () => {
);
};
const tabsChangingViews: React.FunctionComponent = () => {
const TabsChangingViews: React.FunctionComponent = () => {
// If user wants to control what gets rendered example.
const [selectedKey, setSelectedKey] = React.useState('Tabs #1');
@ -117,7 +117,7 @@ const tabsChangingViews: React.FunctionComponent = () => {
);
};
const tabsRenderSeparately: React.FunctionComponent = () => {
const TabsRenderSeparately: React.FunctionComponent = () => {
const [selectedKey, setSelectedKey] = React.useState('rectangleRed');
const onTabsClick = (key: string) => {
@ -149,7 +149,7 @@ const tabsRenderSeparately: React.FunctionComponent = () => {
);
};
const tabsSettingSelectedKey: React.FunctionComponent = () => {
const TabsSettingSelectedKey: React.FunctionComponent = () => {
// If user wants to programmatically set the tab's selectedKey with a button example.
const [selectedKey, setSelectedKey] = React.useState('home');
const [currTabItemIndex, setCurrTabItemIndex] = React.useState(0);
@ -179,7 +179,7 @@ const tabsSettingSelectedKey: React.FunctionComponent = () => {
);
};
const tabsShowHideItem: React.FunctionComponent = () => {
const TabsShowHideItem: React.FunctionComponent = () => {
const [showFirstItem, setshowFirstItem] = React.useState(true);
const toggleShowFirstItem = React.useCallback(() => {
@ -208,7 +208,7 @@ const tabsShowHideItem: React.FunctionComponent = () => {
);
};
const tabsWithFlexibility: React.FunctionComponent = () => {
const TabsWithFlexibility: React.FunctionComponent = () => {
const [selectedKey, setSelectedKey] = React.useState('home');
const goHomeTab = () => {
@ -241,35 +241,35 @@ const tabsSections: TestSection[] = [
{
name: 'Default Tabs',
testID: TABS_TESTPAGE,
component: tabs,
component: TabsMainTest,
},
{
name: 'Tabs with disabled',
component: disabledTabs,
component: DisabledTabs,
},
{
name: 'Trigger onTabsClick event',
component: onTabsClickEvent,
component: TabsClickEventTest,
},
{
name: 'User Custom Render',
component: tabsChangingViews,
component: TabsChangingViews,
},
{
name: 'Render Content Separately',
component: tabsRenderSeparately,
component: TabsRenderSeparately,
},
{
name: 'Override Selected Key',
component: tabsSettingSelectedKey,
component: TabsSettingSelectedKey,
},
{
name: 'Show/Hide Tabs item',
component: tabsShowHideItem,
component: TabsShowHideItem,
},
{
name: 'More Flexibility',
component: tabsWithFlexibility,
component: TabsWithFlexibility,
},
{
name: 'E2E Tabs Test',
@ -280,7 +280,7 @@ const tabsSections: TestSection[] = [
if (Platform.OS !== 'windows') {
tabsSections.push({
name: 'Count and Icon',
component: tabsCountIcon,
component: TabsCountIcon,
});
}

Просмотреть файл

@ -10,7 +10,7 @@ import { SvgIconProps } from '@fluentui-react-native/icon';
import TestSvg from './test.svg';
import { E2ETestExperimentalTabs } from './TabsExperimentalE2ETest';
const tabs: React.FunctionComponent = () => {
const TabsMainTest: React.FunctionComponent = () => {
return (
<View style={stackStyle}>
<Tabs label="Tabs">
@ -28,7 +28,7 @@ const tabs: React.FunctionComponent = () => {
);
};
const disabledTabs: React.FunctionComponent = () => {
const DisabledTabs: React.FunctionComponent = () => {
return (
<View style={stackStyle}>
<Tabs label="Tabs">
@ -46,7 +46,7 @@ const disabledTabs: React.FunctionComponent = () => {
);
};
const tabsCountIcon: React.FunctionComponent = () => {
const TabsCountIcon: React.FunctionComponent = () => {
const svgProps: SvgIconProps = {
src: TestSvg,
viewBox: '0 0 500 500',
@ -69,7 +69,7 @@ const tabsCountIcon: React.FunctionComponent = () => {
);
};
const onTabsClickEvent: React.FunctionComponent = () => {
const TabsClickEventTest: React.FunctionComponent = () => {
const [selectedKey, setSelectedKey] = React.useState('home_key');
const onTabsClick = React.useCallback(
@ -97,7 +97,7 @@ const onTabsClickEvent: React.FunctionComponent = () => {
);
};
const tabsChangingViews: React.FunctionComponent = () => {
const TabsChangingViews: React.FunctionComponent = () => {
// If User wants to control what gets rendered example
const [selectedKey, setSelectedKey] = React.useState('home');
@ -124,7 +124,7 @@ const tabsChangingViews: React.FunctionComponent = () => {
);
};
const tabsRenderSeparately: React.FunctionComponent = () => {
const TabsRenderSeparately: React.FunctionComponent = () => {
const [selectedKey, setSelectedKey] = React.useState('rectangleRed');
const onTabsClick = React.useCallback(
@ -159,7 +159,7 @@ const tabsRenderSeparately: React.FunctionComponent = () => {
);
};
const tabsSettingSelectedKey: React.FunctionComponent = () => {
const TabsSettingSelectedKey: React.FunctionComponent = () => {
// If user wants to programmatically set the selectedKey to control the view
const [selectedKey, setSelectedKey] = React.useState('home');
const [currTabItemIndex, setCurrTabItemIndex] = React.useState(0);
@ -189,7 +189,7 @@ const tabsSettingSelectedKey: React.FunctionComponent = () => {
);
};
const tabsWithFlexibility: React.FunctionComponent = () => {
const TabsWithFlexibility: React.FunctionComponent = () => {
const [selectedKey, setSelectedKey] = React.useState('home');
const goHomeTab = React.useCallback(() => {
@ -225,31 +225,31 @@ const tabsSections: TestSection[] = [
{
name: 'Default Tabs',
testID: EXPERIMENTAL_TABS_TESTPAGE,
component: tabs,
component: TabsMainTest,
},
{
name: 'Tabs with disabled',
component: disabledTabs,
component: DisabledTabs,
},
{
name: 'Trigger onTabsClick event',
component: onTabsClickEvent,
component: TabsClickEventTest,
},
{
name: 'User Custom Render',
component: tabsChangingViews,
component: TabsChangingViews,
},
{
name: 'Render Content Separately',
component: tabsRenderSeparately,
component: TabsRenderSeparately,
},
{
name: 'Override Selected Key',
component: tabsSettingSelectedKey,
component: TabsSettingSelectedKey,
},
{
name: 'More Flexibility',
component: tabsWithFlexibility,
component: TabsWithFlexibility,
},
{
name: 'E2E Testing Experimental Tabs',
@ -260,7 +260,7 @@ const tabsSections: TestSection[] = [
if (Platform.OS !== 'windows') {
tabsSections.push({
name: 'Count and Icon',
component: tabsCountIcon,
component: TabsCountIcon,
});
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/badge",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/button",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/composition",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/experimental-activity-indicator",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/experimental-avatar",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/experimental-checkbox",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/experimental-drawer",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/experimental-expander",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/experimental-menu-button",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/experimental-shimmer",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/experimental-tabs",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/menu-button",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/separator",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/tabs",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@fluentui-react-native/tester",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Bump @rnx-kit/eslint-plugin from 0.2.10 to 0.2.11",
"packageName": "@uifabricshared/theming-react-native",
"email": "ruaraki@microsoft.com",
"dependentChangeType": "patch"
}

Просмотреть файл

@ -34,7 +34,7 @@ export const Foo = compose<TabItemType>({
['color', ...fontStyles.keys],
),
},
render: (userProps: TProps, useSlots: UseSlots<TType>) => {
useRender: (userProps: TProps, useSlots: UseSlots<TType>) => {
// Grab the styled slots.
const Slots = useSlots(userProps);
// Return the handler to finish render.

Просмотреть файл

@ -41,7 +41,7 @@ export const Button = compose<ButtonType>({
icon: Icon,
content: Text,
},
render: (userProps: ButtonProps, useSlots: UseSlots<ButtonType>) => {
useRender: (userProps: ButtonProps, useSlots: UseSlots<ButtonType>) => {
const button = useButton(userProps);
const iconProps = createIconProps(userProps.icon);
// grab the styled slots

Просмотреть файл

@ -21,7 +21,7 @@ export const CompoundButton = compose<CompoundButtonType>({
secondaryContent: Text,
contentContainer: View,
},
render: (userProps: CompoundButtonProps, useSlots: UseSlots<CompoundButtonType>) => {
useRender: (userProps: CompoundButtonProps, useSlots: UseSlots<CompoundButtonType>) => {
const button = useButton(userProps);
const iconProps = createIconProps(userProps.icon);

Просмотреть файл

@ -14,7 +14,7 @@ export const FAB = compose<FABType>({
icon: Icon,
content: Text,
},
render: (_userProps: ButtonCoreProps, _useSlots: UseSlots<FABType>) => {
useRender: (_userProps: ButtonCoreProps, _useSlots: UseSlots<FABType>) => {
return (_final: ButtonCoreProps, ..._children: React.ReactNode[]) => {
return null; // Only implemented for mobile endpoints
};

Просмотреть файл

@ -32,7 +32,7 @@ export const FAB = compose<FABType>({
icon: Icon,
content: Text,
},
render: (userProps: ButtonCoreProps, useSlots: UseSlots<FABType>) => {
useRender: (userProps: ButtonCoreProps, useSlots: UseSlots<FABType>) => {
const { icon, onClick, ...rest } = userProps;
const iconProps = createIconProps(userProps.icon);

Просмотреть файл

@ -19,7 +19,7 @@ export const ToggleButton = compose<ToggleButtonType>({
icon: Icon,
content: Text,
},
render: (userProps: ToggleButtonProps, useSlots: UseSlots<ToggleButtonType>) => {
useRender: (userProps: ToggleButtonProps, useSlots: UseSlots<ToggleButtonType>) => {
const iconProps = createIconProps(userProps.icon);
const toggleButton = useToggleButton(userProps);

Просмотреть файл

@ -16,6 +16,7 @@ import {
MenuButtonType,
MenuButtonRenderData,
MenuButtonState,
MenuButtonItemProps,
} from './MenuButton.types';
export const MenuButton = compose<MenuButtonType>({
@ -34,30 +35,6 @@ export const MenuButton = compose<MenuButtonType>({
setShowContextualMenu(!showContextualMenu);
}, [showContextualMenu, setShowContextualMenu]);
const menuItemsUpdated = menuItems.map((item) => {
if (item.hasSubmenu) {
const [showSubmenu, setShowSubmenu] = useState(false);
const toggleShowSubmenu = React.useCallback(() => {
setShowSubmenu(!showSubmenu);
}, [showSubmenu, setShowSubmenu]);
const onDismissSubmenu = React.useCallback(() => {
setShowSubmenu(false);
}, [setShowSubmenu]);
const { onHoverIn = toggleShowSubmenu, submenuProps = {}, ...restItems } = item;
const { onDismiss = onDismissSubmenu, setShowMenu = toggleShowSubmenu, ...restSubmenuProps } = submenuProps;
const menuItemUpdated = {
...restItems,
onHoverIn,
showSubmenu: item.showSubmenu ? showSubmenu : undefined,
submenuProps: { ...restSubmenuProps, onDismiss, setShowMenu },
};
return menuItemUpdated;
}
return item;
});
const state: MenuButtonState = {
context: {
showContextualMenu: !!showContextualMenu,
@ -87,7 +64,7 @@ export const MenuButton = compose<MenuButtonType>({
...contextualMenu,
},
contextualMenuItems: {
menuItems: menuItemsUpdated,
menuItems,
},
});
@ -132,21 +109,12 @@ export const MenuButton = compose<MenuButtonType>({
{context.showContextualMenu && (
<Slots.contextualMenu>
{menuItems.map((menuItem) => {
const { hasSubmenu, submenuProps, showSubmenu, componentRef, submenuItems, ...items } = menuItem;
return hasSubmenu && submenuItems ? (
return menuItem.hasSubmenu && menuItem.submenuItems ? (
<Slots.contextualMenuItems>
<SubmenuItem componentRef={componentRef} {...items} />
{showSubmenu && (
<Submenu target={componentRef} {...submenuProps}>
{submenuItems.map((submenuItem) => (
<ContextualMenuItem key={submenuItem.itemKey} {...submenuItem} />
))}
</Submenu>
)}
<SubMenuItem {...menuItem} />
</Slots.contextualMenuItems>
) : (
<ContextualMenuItem key={items.itemKey} {...items} />
<ContextualMenuItem key={menuItem.itemKey} {...menuItem} />
);
})}
</Slots.contextualMenu>
@ -156,4 +124,30 @@ export const MenuButton = compose<MenuButtonType>({
},
});
const SubMenuItem: React.FunctionComponent<MenuButtonItemProps> = (props: MenuButtonItemProps): JSX.Element => {
const [showSubmenuState, setShowSubmenu] = React.useState(false);
const toggleShowSubmenu = React.useCallback(() => {
setShowSubmenu(!showSubmenuState);
}, [showSubmenuState, setShowSubmenu]);
const onDismissSubmenu = React.useCallback(() => {
setShowSubmenu(false);
}, [setShowSubmenu]);
const { showSubmenu = showSubmenuState, submenuProps, componentRef, submenuItems, onHoverIn = toggleShowSubmenu, ...restItems } = props;
const { onDismiss = onDismissSubmenu, setShowMenu = toggleShowSubmenu, ...restSubmenuProps } = submenuProps;
return (
<React.Fragment>
<SubmenuItem componentRef={componentRef} onHoverIn={onHoverIn} {...restItems} />
{showSubmenu && (
<Submenu target={componentRef} onDismiss={onDismiss} setShowMenu={setShowMenu} {...restSubmenuProps}>
{submenuItems?.map((submenuItem) => (
<ContextualMenuItem key={submenuItem.itemKey} {...submenuItem} />
))}
</Submenu>
)}
</React.Fragment>
);
};
export default MenuButton;

Просмотреть файл

@ -22,7 +22,7 @@ export const Separator = compose<SeparatorType>({
),
},
slots: { root: View },
render: (props: SeparatorProps, useSlots: UseSlots<SeparatorType>) => {
useRender: (props: SeparatorProps, useSlots: UseSlots<SeparatorType>) => {
const Root = useSlots(props).root;
return (rest: SeparatorProps, children: React.ReactNode) => <Root {...mergeProps(props, rest, propMask)}>{children}</Root>;
},

Просмотреть файл

@ -71,16 +71,20 @@ export const TabsItem = compose<TabsItemType>({
headerText: !!headerText || itemCount !== undefined,
},
};
const refWithFocus = useViewCommandFocus(componentRef);
const buttonRef = Platform.OS === 'macos' ? componentRef : refWithFocus;
const buttonRef = Platform.OS === 'macos' ? componentRef : useViewCommandFocus(componentRef);
/* We use the componentRef of the currently selected tabsItem to maintain the default tabbable
element in Tabs. Since the componentRef isn't generated until after initial render,
we must update it once here. */
/**
* We use the componentRef of the currently selected tabsItem to maintain the default tabbable
* element in Tabs. Since the componentRef isn't generated until after initial render,
* we must update it once here.
* Since this is meant to only be run once, surpressing lint error
*/
React.useEffect(() => {
if (itemKey == info.selectedKey) {
info.updateSelectedTabsItemRef && componentRef && info.updateSelectedTabsItemRef(componentRef);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Grab the styling information from the userProps, referencing the state as well as the props.
@ -95,7 +99,7 @@ export const TabsItem = compose<TabsItemType>({
break;
}
},
[info, itemKey],
[changeSelection],
);
const countText = itemCount !== undefined ? ` (${itemCount})` : '';
@ -123,6 +127,7 @@ export const TabsItem = compose<TabsItemType>({
render: (Slots: ISlots<TabsItemSlotProps>, renderData: TabsItemRenderData, ...children: React.ReactNode[]) => {
const info = renderData.state!.info;
// eslint-disable-next-line react-hooks/rules-of-hooks
const context = React.useContext(TabsContext);
// Sets the view that belongs to a TabItem.
context.views.set(info.key, children);

Просмотреть файл

@ -58,13 +58,17 @@ export const TabsItem = compose<TabsItemType>({
const buttonRef = useViewCommandFocus(componentRef);
/* We use the componentRef of the currently selected tabsItem to maintain the default tabbable
element in Tabs. Since the componentRef isn't generated until after initial render,
we must update it once here. */
/**
* We use the componentRef of the currently selected tabsItem to maintain the default tabbable
* element in Tabs. Since the componentRef isn't generated until after initial render,
* we must update it once here.
* Since this is meant to only be run once, surpressing lint error
*/
React.useEffect(() => {
if (itemKey == info.selectedKey) {
info.updateSelectedTabsItemRef && componentRef && info.updateSelectedTabsItemRef(componentRef);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
// Grab the styling information from the userProps, referencing the state as well as the props.
@ -79,7 +83,7 @@ export const TabsItem = compose<TabsItemType>({
break;
}
},
[info, itemKey],
[changeSelection],
);
const countText = itemCount !== undefined ? ` (${itemCount})` : '';
@ -107,6 +111,7 @@ export const TabsItem = compose<TabsItemType>({
render: (Slots: ISlots<TabsItemSlotProps>, renderData: TabsItemRenderData, ...children: React.ReactNode[]) => {
const info = renderData.state!.info;
// eslint-disable-next-line react-hooks/rules-of-hooks
const context = React.useContext(TabsContext);
// Sets the view that belongs to a TabItem.
context.views.set(info.key, children);

Просмотреть файл

@ -7,7 +7,8 @@ import { ThemeContext } from '@uifabricshared/theming-ramp';
export const ThemeProvider: React.FunctionComponent<IThemeProviderProps> = (props: IThemeProviderProps) => {
const { registry: registryFromProps, theme: themeName = '', children } = props;
const registryToUse = registryFromProps || useThemeRegistry() || getThemeRegistry();
const defaultRegistry = useThemeRegistry();
const registryToUse = registryFromProps || defaultRegistry || getThemeRegistry();
const [theme, setThemeState] = React.useState(registryToUse.getTheme(themeName));
React.useEffect(() => {

Просмотреть файл

@ -26,7 +26,7 @@ export const ActivityIndicator = compose<FluentActivityIndicatorType>({
root: View,
svg: AnimatedSvg,
},
render: (props: ActivityIndicatorProps, useSlots: UseSlots<FluentActivityIndicatorType>) => {
useRender: (props: ActivityIndicatorProps, useSlots: UseSlots<FluentActivityIndicatorType>) => {
const Slots = useSlots(props);
const slotProps = useStyling(props);

Просмотреть файл

@ -15,7 +15,7 @@ export const ActivityIndicator = compose<CoreActivityIndicatorType>({
slots: {
root: CoreActivityIndicator,
},
render: (props: ActivityIndicatorProps, useSlots: UseSlots<CoreActivityIndicatorType>) => {
useRender: (props: ActivityIndicatorProps, useSlots: UseSlots<CoreActivityIndicatorType>) => {
const Slots = useSlots(props);
return () => <Slots.root />;
},

Просмотреть файл

@ -126,7 +126,7 @@ export const Avatar = compose<AvatarType>({
['size'],
),
},
render: (props: AvatarProps, useSlots: UseSlots<AvatarType>) => {
useRender: (props: AvatarProps, useSlots: UseSlots<AvatarType>) => {
const Root = useSlots(props).root;
return (rest: AvatarProps) => <Root {...mergeProps(props, rest)} />;

Просмотреть файл

@ -35,7 +35,7 @@ export const JSAvatar = compose<JSAvatarType>({
ring: View,
glow: View,
},
render: (userProps: JSAvatarProps, useSlots: UseSlots<JSAvatarType>) => {
useRender: (userProps: JSAvatarProps, useSlots: UseSlots<JSAvatarType>) => {
const avatar = useAvatar(userProps);
const Slots = useSlots(userProps, (layer) => avatarLookup(layer, avatar.state, userProps));

Просмотреть файл

@ -40,7 +40,7 @@ export const Badge = compose<BadgeType>({
icon: Icon,
text: Text,
},
render: (userProps: BadgeProps, useSlots: UseSlots<BadgeType>) => {
useRender: (userProps: BadgeProps, useSlots: UseSlots<BadgeType>) => {
const iconProps = createIconProps(userProps.icon);
const badge = useBadge(userProps);

Просмотреть файл

@ -48,7 +48,7 @@ export const PresenceBadge = compose<PresenceBadgeType>({
slots: {
badge: Badge,
},
render: (userProps: PresenceBadgeProps) => {
useRender: (userProps: PresenceBadgeProps) => {
const badge = useBadge(userProps);
const size = getIconSize(userProps.size || 'medium');
const iconXml = `<svg width="${size}" height="${size}" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">

Просмотреть файл

@ -29,7 +29,7 @@ export const Checkbox = compose<CheckboxTypeMacOS>({
},
})),
},
render: (props: CheckboxProps, useSlots: UseSlots<CheckboxTypeMacOS>) => {
useRender: (props: CheckboxProps, useSlots: UseSlots<CheckboxTypeMacOS>) => {
const { onChange, ...restOfUserProps } = props;
const onPress = (e: any) => {
if (onChange != null) {

Просмотреть файл

@ -18,7 +18,7 @@ export const Checkbox = compose<CheckboxType>({
label: Text,
required: Text,
},
render: (userProps: CheckboxProps, useSlots: UseSlots<CheckboxType>) => {
useRender: (userProps: CheckboxProps, useSlots: UseSlots<CheckboxType>) => {
// configure props and state for checkbox based on user props
const Checkbox = useCheckbox(userProps);
// grab the styled slots

Просмотреть файл

@ -16,7 +16,7 @@ export const Drawer = compose<DrawerType>({
style: {},
})),
},
render: (props: DrawerProps, useSlots: UseSlots<DrawerType>) => {
useRender: (props: DrawerProps, useSlots: UseSlots<DrawerType>) => {
const { target, ...rest } = props;
const [nativeTarget, setNativeTarget] = React.useState<number | null>(null);

Просмотреть файл

@ -17,7 +17,7 @@ export const Expander = compose<ExpanderType>({
root: buildProps((tokens) => ({ ...tokens })),
},
slots: { root: ExpanderComponent },
render: (userProps: ExpanderProps, useSlots: UseSlots<ExpanderType>) => {
useRender: (userProps: ExpanderProps, useSlots: UseSlots<ExpanderType>) => {
const Root = useSlots(userProps).root;
const [expandedState, setExpandedState] = React.useState(userProps.expanded);
const expanderHeight = expandedState ? userProps.expandedHeight : userProps.collapsedHeight;

Просмотреть файл

@ -21,7 +21,7 @@ export const MenuButton = compose<MenuButtonType>({
slotProps: {
root: {},
},
render: (props: MenuButtonProps, useSlots: UseSlots<MenuButtonType>) => {
useRender: (props: MenuButtonProps, useSlots: UseSlots<MenuButtonType>) => {
const { menuItems, content, icon, disabled, onItemClick, contextualMenu, style, appearance, ...rest } = props;
const stdBtnRef = useRef(null);
@ -52,28 +52,6 @@ export const MenuButton = compose<MenuButtonType>({
...contextualMenu,
};
const menuItemsUpdated = menuItems?.map((item) => {
if (item.hasSubmenu) {
const [showSubmenu, setShowSubmenu] = useState(false);
const toggleShowSubmenu = useCallback(() => {
setShowSubmenu(!showSubmenu);
}, [showSubmenu, setShowSubmenu]);
const onDismissSubmenu = useCallback(() => {
setShowSubmenu(false);
}, [setShowSubmenu]);
const { onHoverIn = toggleShowSubmenu, submenuProps = {}, ...restItems } = item;
const { onDismiss = onDismissSubmenu, setShowMenu = toggleShowSubmenu, ...restSubmenuProps } = submenuProps;
const menuItemUpdated = {
...restItems,
onHoverIn,
showSubmenu: item.showSubmenu ?? showSubmenu,
submenuProps: { ...restSubmenuProps, onDismiss, setShowMenu },
};
return menuItemUpdated;
}
return item;
});
const Slots = useSlots(props);
return () => {
@ -89,7 +67,7 @@ export const MenuButton = compose<MenuButtonType>({
{content}
<Slots.chevronIcon xml={chevronXml} />
</Button>
{showContextualMenu && renderContextualMenu(contextualMenuProps, menuItemsUpdated)}
{showContextualMenu && renderContextualMenu(contextualMenuProps, menuItems)}
</Slots.root>
);
};

Просмотреть файл

@ -1,5 +1,5 @@
/* @jsxFrag React.Fragment */
import React from 'react';
import * as React from 'react';
import { ContextualMenu, ContextualMenuItem, SubmenuItem, Submenu, ContextualMenuProps } from '@fluentui-react-native/contextual-menu';
import { MenuButtonItemProps } from './MenuButton.types';
@ -7,22 +7,34 @@ export const renderContextualMenu = (contextualMenu: ContextualMenuProps, menuIt
return (
<ContextualMenu {...contextualMenu}>
{menuItems?.map((menuItem) => {
const { hasSubmenu, submenuProps, showSubmenu, componentRef, submenuItems, ...items } = menuItem;
return hasSubmenu ? (
<>
<SubmenuItem componentRef={componentRef} {...items} />
{showSubmenu && (
<Submenu target={componentRef} {...submenuProps}>
{submenuItems?.map((submenuItem) => (
<ContextualMenuItem key={submenuItem.itemKey} {...submenuItem} />
))}
</Submenu>
)}
</>
) : (
<ContextualMenuItem key={items.itemKey} {...items} />
);
return menuItem.hasSubmenu ? <SubMenuItem {...menuItem} /> : <ContextualMenuItem key={menuItem.itemKey} {...menuItem} />;
})}
</ContextualMenu>
);
};
const SubMenuItem: React.FunctionComponent<MenuButtonItemProps> = (props: MenuButtonItemProps): JSX.Element => {
const [showSubmenuState, setShowSubmenu] = React.useState(false);
const toggleShowSubmenu = React.useCallback(() => {
setShowSubmenu(!showSubmenuState);
}, [showSubmenuState, setShowSubmenu]);
const onDismissSubmenu = React.useCallback(() => {
setShowSubmenu(false);
}, [setShowSubmenu]);
const { showSubmenu = showSubmenuState, submenuProps, componentRef, submenuItems, onHoverIn = toggleShowSubmenu, ...restItems } = props;
const { onDismiss = onDismissSubmenu, setShowMenu = toggleShowSubmenu, ...restSubmenuProps } = submenuProps;
return (
<>
<SubmenuItem componentRef={componentRef} onHoverIn={onHoverIn} {...restItems} />
{showSubmenu && (
<Submenu target={componentRef} onDismiss={onDismiss} setShowMenu={setShowMenu} {...restSubmenuProps}>
{submenuItems?.map((submenuItem) => (
<ContextualMenuItem key={submenuItem.itemKey} {...submenuItem} />
))}
</Submenu>
)}
</>
);
};

Просмотреть файл

@ -14,7 +14,7 @@ export const Shimmer = compose<ShimmerType>({
slots: {
root: Svg,
},
render: (props: ShimmerProps, useSlots: UseSlots<ShimmerType>) => {
useRender: (props: ShimmerProps, useSlots: UseSlots<ShimmerType>) => {
const Slots = useSlots(props);
const AnimatedLinearGradient = Animated.createAnimatedComponent(LinearGradient);
const tokens = useStyling(props).root;

Просмотреть файл

@ -81,7 +81,7 @@ export const Shimmer = compose<ShimmerType>({
shimmerWaveContainer: waveContainer,
},
render: (props: ShimmerProps, useSlots: UseSlots<ShimmerType>) => {
useRender: (props: ShimmerProps, useSlots: UseSlots<ShimmerType>) => {
return (rest: ShimmerProps) => {
const { elements, ...mergedProps } = mergeProps(props, rest);
const Slots = useSlots(mergedProps);

Просмотреть файл

@ -47,7 +47,7 @@ export const Stack = compose<StackType>({
filters: {
root: filterViewProps,
},
render: (props: StackProps, useSlots: UseSlots<StackType>) => {
useRender: (props: StackProps, useSlots: UseSlots<StackType>) => {
const { gap, horizontal, wrap, ...rest } = props;
const Slots = useSlots(props);
return (final: StackProps, ...children: React.ReactNode[]) => {

Просмотреть файл

@ -9,7 +9,7 @@ export const StackItem = compose<StackItemType>({
displayName: stackItemName,
...stylingSettings,
slots: { root: View },
render: (props: StackItemProps, useSlots: UseSlots<StackItemType>) => {
useRender: (props: StackItemProps, useSlots: UseSlots<StackItemType>) => {
const Root = useSlots(props).root;
return (final: StackItemProps, ...children: React.ReactNode[]) => <Root {...mergeProps(props, final)}>{children}</Root>;
},

Просмотреть файл

@ -33,17 +33,19 @@ export const Tabs = compose<TabsType>({
stack: View,
tabPanel: View,
},
render: (userProps: TabsProps, useSlots: UseSlots<TabsType>) => {
useRender: (userProps: TabsProps, useSlots: UseSlots<TabsType>) => {
// configure props and state for tabs based on user props
const tabs = useTabs(userProps);
if (!tabs.state) return null;
// Grab the styled slots.
const Slots = useSlots(userProps, (layer) => tabs.state[layer] || userProps[layer]);
// Return the handler to finish render.
return (final: TabsProps, ...children: React.ReactNode[]) => {
if (!tabs.state) {
return null;
}
const { label, defaultTabbableElement, isCircularNavigation, ...mergedProps } = mergeProps(tabs.props, final);
// Populate the tabsItemKeys array.

Просмотреть файл

@ -32,12 +32,10 @@ export const Tabs = compose<TabsType>({
stack: View,
tabPanel: View,
},
render: (userProps: TabsProps, useSlots: UseSlots<TabsType>) => {
useRender: (userProps: TabsProps, useSlots: UseSlots<TabsType>) => {
// configure props and state for tabs based on user props
const tabs = useTabs(userProps);
if (!tabs.state) return null;
// Grab the styled slots.
const Slots = useSlots(userProps, (layer) => tabs.state[layer] || userProps[layer]);
@ -70,6 +68,10 @@ export const Tabs = compose<TabsType>({
// Return the handler to finish render.
return (final: TabsProps, ...children: React.ReactNode[]) => {
if (!tabs.state) {
return null;
}
const { label, ...mergedProps } = mergeProps(tabs.props, final);
// Populate the tabsItemKeys array

Просмотреть файл

@ -20,17 +20,20 @@ export const TabsItem = compose<TabItemType>({
indicator: View,
content: Text,
},
render: (userProps: TabsItemProps, useSlots: UseSlots<TabItemType>) => {
useRender: (userProps: TabsItemProps, useSlots: UseSlots<TabItemType>) => {
const tabsItem = useTabsItem(userProps);
if (!tabsItem.state) return null;
const iconProps = createIconProps(userProps.icon);
const context = React.useContext(TabsContext);
// Grab the styled slots.
const Slots = useSlots(userProps, (layer) => tabsItem.state[layer] || userProps[layer]);
// Return the handler to finish render.
return (final: TabsItemProps, ...children: React.ReactNode[]) => {
const context = React.useContext(TabsContext);
if (!tabsItem.state) {
return null;
}
const { icon, itemKey, itemCount, headerText, ...mergedProps } = mergeProps(tabsItem.props, final);
let containerText = headerText;

Просмотреть файл

@ -60,7 +60,7 @@ const Base = composeFactory<ViewProps, SlotProps, Tokens, Theme>(
outer: View,
content: Text,
},
render: (props: ViewProps, useSlots: UseStyledSlots<ViewProps, SlotProps>) => {
useRender: (props: ViewProps, useSlots: UseStyledSlots<ViewProps, SlotProps>) => {
const Slots = useSlots(props);
return (extra: ViewProps) => (
<Slots.outer {...mergeProps(props, extra)}>

Просмотреть файл

@ -21,7 +21,7 @@ export type ComposeFactoryOptions<TProps, TSlotProps, TTokens, TTheme, TStatics
/**
* staged render function that takes props and a useSlots hook as an input
*/
render: (props: TProps, useSlots: UseStyledSlots<TProps, TSlotProps>) => React.FunctionComponent<TProps>;
useRender: (props: TProps, useSlots: UseStyledSlots<TProps, TSlotProps>) => React.FunctionComponent<TProps>;
/**
* optional statics to attach to the component
@ -64,7 +64,7 @@ export function composeFactory<TProps, TSlotProps, TTokens, TTheme, TStatics ext
const useSlots = buildUseSlots(options) as UseStyledSlots<TProps, TSlotProps>;
// build the staged component
const component = stagedComponent<TProps>((props) => options.render(props, useSlots)) as LocalComponent;
const component = stagedComponent<TProps>((props) => options.useRender(props, useSlots)) as LocalComponent;
// attach additional props to the returned component
component.displayName = options.displayName;

Просмотреть файл

@ -2505,14 +2505,15 @@
"@rnx-kit/tools-node" "^1.2.6"
"@rnx-kit/eslint-plugin@^0.2.8":
version "0.2.10"
resolved "https://registry.yarnpkg.com/@rnx-kit/eslint-plugin/-/eslint-plugin-0.2.10.tgz#c7d88cd3f98a96d740e5f33a520b19a86def74d0"
integrity sha512-ZKOF4N814dDOY2qE7BwwYvr4F8Ebe+SCDihf8azRpc/yhGUKAFzYf9jIv8bO0TUf3GPhOzgQoRGRYclTRFXgKw==
version "0.2.11"
resolved "https://registry.yarnpkg.com/@rnx-kit/eslint-plugin/-/eslint-plugin-0.2.11.tgz#ff49840e520f5401a7d61e0cbb9bc6e9c42c61d7"
integrity sha512-43N6mQYVwSUZJMEpeovVsXq8acpz2e7BWAkNg59FJA90VfBd8oMyfJ3/B9d9emCSSMCKWJra+aPSF182GlDx2Q==
dependencies:
"@typescript-eslint/eslint-plugin" "^5.0.0"
"@typescript-eslint/parser" "^5.0.0"
enhanced-resolve "^5.8.3"
eslint-plugin-react "^7.26.0"
eslint-plugin-react-hooks "^4.3.0"
"@rnx-kit/jest-preset@^0.1.9":
version "0.1.9"
@ -7012,6 +7013,11 @@ eslint-plugin-jest@^25.0.0:
dependencies:
"@typescript-eslint/experimental-utils" "^5.0.0"
eslint-plugin-react-hooks@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172"
integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==
eslint-plugin-react@^7.26.0:
version "7.28.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz#8f3ff450677571a659ce76efc6d80b6a525adbdf"