Skip to content

Commit b5a9fde

Browse files
authored
Publish Initial Tooltip Package (#3237)
* new tooltip folders * updated package.json * added props * added native tooltip view * js changes * added test page * updated platform status * adding tooltip test page * added more tooltip enabled components in test file * code cleanup and test positioning prop * test description * updated prop comments and removed empty tokens * remove comments * changed jest to win32 * updated dependencies * set importHelper * update dependency versions * tentatively updating yarn.lock * Change files * fixing dependencies * capabilities * update yarn.lock * update dependencies * update yarn.lock * fixed import orders * update target type * add capabilities * add dependency and remove unused capabilities * update yarn.lock * update snapshots * add style prop to Tooltip to avoid layout issues * add separate position test * testing comment * fixing comments * fixing more comments * removed useTooltip and changed to stagedComponent * fixing more comments * fixed pr comments * updated button import
1 parent a9d39e9 commit b5a9fde

26 files changed

+445
-1
lines changed

apps/E2E/src/Tooltip/consts.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const HOMEPAGE_TOOLTIP_BUTTON = 'Homepage_Tooltip_Button';
2+
export const TOOLTIP_TESTPAGE = 'Tooltip_TestPage';

apps/E2E/src/index.consts.ts

+1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@ export * from './TabsV1/consts';
4040
export * from './TextLegacy/consts';
4141
export * from './TextV1/consts';
4242
export * from './Theme/consts';
43+
export * from './Tooltip/consts';
4344
export * from './VibrancyView/consts';

apps/fluent-tester/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"@fluentui-react-native/theme-types": ">=0.33.0 <1.0.0",
7979
"@fluentui-react-native/themed-stylesheet": "^1.6.0",
8080
"@fluentui-react-native/theming-utils": ">=0.25.0 <1.0.0",
81+
"@fluentui-react-native/tooltip": "0.1.0",
8182
"@fluentui-react-native/vibrancy-view": ">=0.1.0 <1.0.0",
8283
"@fluentui-react-native/win32-theme": ">=0.28.0 <1.0.0",
8384
"@fluentui/react-native": ">=0.39.1 <1.0.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as React from 'react';
2+
import { View } from 'react-native';
3+
4+
import { ButtonV1 } from '@fluentui-react-native/button';
5+
import { Tooltip } from '@fluentui-react-native/tooltip';
6+
7+
export const TooltipDefault: React.FunctionComponent = () => {
8+
return (
9+
<View>
10+
<Tooltip content="Tooltip should show under mouse cursor">
11+
<ButtonV1>Test</ButtonV1>
12+
</Tooltip>
13+
</View>
14+
);
15+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import * as React from 'react';
2+
import { View } from 'react-native';
3+
4+
import { ButtonV1 } from '@fluentui-react-native/button';
5+
import { Tooltip } from '@fluentui-react-native/tooltip';
6+
7+
export const TooltipPosition: React.FunctionComponent = () => {
8+
const topCenterRef = React.useRef<View>(null);
9+
10+
return (
11+
<View>
12+
<Tooltip content="Test" positioning="topCenter">
13+
<ButtonV1>No Target + TopCenter</ButtonV1>
14+
</Tooltip>
15+
<Tooltip content="Test" positioning="topCenter" target={topCenterRef}>
16+
<ButtonV1 componentRef={topCenterRef}>Target + TopCenter</ButtonV1>
17+
</Tooltip>
18+
{/* Adding more tests as follow-up*/}
19+
</View>
20+
);
21+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as React from 'react';
2+
3+
import { TooltipDefault } from './TooltipDefault';
4+
import { TooltipPosition } from './TooltipPosition';
5+
import { TOOLTIP_TESTPAGE } from '../../../../E2E/src/Tooltip/consts';
6+
import { Test } from '../Test';
7+
import type { TestSection, PlatformStatus } from '../Test';
8+
9+
const tooltipSections: TestSection[] = [
10+
{
11+
name: 'Default',
12+
testID: TOOLTIP_TESTPAGE,
13+
component: TooltipDefault,
14+
},
15+
{
16+
name: 'Target + Positioning',
17+
component: TooltipPosition,
18+
},
19+
];
20+
21+
export const TooltipTest: React.FunctionComponent = () => {
22+
const status: PlatformStatus = {
23+
win32Status: 'Experimental',
24+
uwpStatus: 'Backlog',
25+
iosStatus: 'Backlog',
26+
macosStatus: 'Backlog',
27+
androidStatus: 'Backlog',
28+
};
29+
30+
const description =
31+
'A Tooltip component displays additional information about another component. Tooltip is not expected to handle interactive content.';
32+
33+
return <Test name="Tooltip Test" description={description} sections={tooltipSections} status={status} />;
34+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './TooltipTest';

apps/fluent-tester/src/testPages.ts

+7
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import { TabsV1Test } from './TestComponents/TabsV1';
4444
import { TextLegacyTest } from './TestComponents/TextLegacy';
4545
import { TextV1Test } from './TestComponents/TextV1';
4646
import { ThemeTest } from './TestComponents/Theme';
47+
import { TooltipTest } from './TestComponents/Tooltip';
4748
import { VibrancyViewTest } from './TestComponents/VibrancyView';
4849
import * as Constants from '../../E2E/src/index.consts';
4950

@@ -331,6 +332,12 @@ export const tests: TestDescription[] = [
331332
testPageButton: Constants.HOMEPAGE_THEME_BUTTON,
332333
platforms: ['android', 'ios', 'macos', 'win32', 'windows'],
333334
},
335+
{
336+
name: 'Tooltip',
337+
component: TooltipTest,
338+
testPageButton: Constants.HOMEPAGE_TOOLTIP_BUTTON,
339+
platforms: ['win32'],
340+
},
334341
{
335342
name: 'Vibrancy View',
336343
component: VibrancyViewTest,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "adding package",
4+
"packageName": "@fluentui-react-native/e2e-testing",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "adding tests for new component",
4+
"packageName": "@fluentui-react-native/tester",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "adding new package",
4+
"packageName": "@fluentui-react-native/tooltip",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
extends: ['@fluentui-react-native/eslint-config-rules'],
3+
};

packages/experimental/Tooltip/CHANGELOG.json

Whitespace-only changes.

packages/experimental/Tooltip/CHANGELOG.md

Whitespace-only changes.

packages/experimental/Tooltip/SPEC.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Tooltip
2+
3+
## Background
4+
5+
Please write here you documentation...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('@fluentui-react-native/scripts/babel.config');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const { configureReactNativeJest } = require('@fluentui-react-native/scripts');
2+
module.exports = configureReactNativeJest('win32');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const { preset } = require('@fluentui-react-native/scripts');
2+
3+
preset();
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"name": "@fluentui-react-native/tooltip",
3+
"version": "0.1.0",
4+
"description": "A cross-platform Tooltip component for React Native.",
5+
"main": "src/index.ts",
6+
"module": "src/index.ts",
7+
"typings": "lib/index.d.ts",
8+
"onPublish": {
9+
"main": "lib-commonjs/index.js",
10+
"module": "lib/index.js"
11+
},
12+
"scripts": {
13+
"build": "fluentui-scripts build",
14+
"clean": "fluentui-scripts clean",
15+
"depcheck": "fluentui-scripts depcheck",
16+
"just": "fluentui-scripts",
17+
"lint": "fluentui-scripts eslint",
18+
"test": "fluentui-scripts jest",
19+
"update-snapshots": "fluentui-scripts jest -u",
20+
"prettier": "fluentui-scripts prettier",
21+
"prettier-fix": "fluentui-scripts prettier --fix true"
22+
},
23+
"repository": {
24+
"type": "git",
25+
"url": "https://github.com/microsoft/fluentui-react-native.git",
26+
"directory": "packages/experimental/Tooltip"
27+
},
28+
"dependencies": {
29+
"@fluentui-react-native/callout": "^0.25.0",
30+
"@fluentui-react-native/component-cache": "^1.6.0",
31+
"@fluentui-react-native/framework": "0.12.0",
32+
"tslib": "^2.3.1"
33+
},
34+
"devDependencies": {
35+
"@fluentui-react-native/button": "^0.36.1",
36+
"@fluentui-react-native/eslint-config-rules": "^0.1.1",
37+
"@fluentui-react-native/scripts": "^0.1.1",
38+
"@fluentui-react-native/test-tools": ">=0.1.1 <1.0.0",
39+
"@office-iss/react-native-win32": "^0.72.0",
40+
"@react-native/metro-config": "^0.72.0",
41+
"react": "18.2.0",
42+
"react-native": "^0.72.0"
43+
},
44+
"peerDependencies": {
45+
"react": "18.2.0",
46+
"react-native": "^0.72.0"
47+
},
48+
"author": "",
49+
"license": "MIT",
50+
"rnx-kit": {
51+
"kitType": "library",
52+
"alignDeps": {
53+
"presets": [
54+
"microsoft/react-native"
55+
],
56+
"requirements": [
57+
58+
],
59+
"capabilities": [
60+
"core",
61+
"react"
62+
]
63+
}
64+
}
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/** @jsxRuntime classic */
2+
import * as React from 'react';
3+
4+
import { ensureNativeComponent } from '@fluentui-react-native/component-cache';
5+
import { mergeProps, stagedComponent } from '@fluentui-react-native/framework';
6+
7+
import type { TooltipProps } from './Tooltip.types';
8+
import { tooltipName } from './Tooltip.types';
9+
10+
const NativeTooltipView = ensureNativeComponent('RCTTooltip');
11+
12+
/**
13+
* A function which determines if a set of styles should be applied to the component given the current state and props of the tooltip.
14+
*
15+
* @param layer The name of the state that is being checked for
16+
* @param userProps The props that were passed into the tooltip
17+
* @returns Whether the styles that are assigned to the layer should be applied to the tooltip
18+
*/
19+
export const tooltipLookup = (layer: string, userProps: TooltipProps): boolean => {
20+
return userProps[layer];
21+
};
22+
23+
export const Tooltip = stagedComponent((props: TooltipProps) => {
24+
return (rest: TooltipProps, children: React.ReactNode) => {
25+
return <NativeTooltipView {...mergeProps(props, rest)}>{children}</NativeTooltipView>;
26+
};
27+
});
28+
29+
Tooltip.displayName = tooltipName;
30+
31+
export default Tooltip;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type * as React from 'react';
2+
import type { ViewStyle } from 'react-native';
3+
4+
import type { DirectionalHint } from '@fluentui-react-native/callout';
5+
6+
export const tooltipName = 'Tooltip';
7+
8+
export type TooltipProps = React.PropsWithChildren<{
9+
/**
10+
* The text of the tooltip.
11+
*/
12+
content: string;
13+
14+
/**
15+
* Notification when the visibility of the tooltip is changed.
16+
*/
17+
onVisibleChange?: (event, data) => void;
18+
19+
/**
20+
* Positioning of the tooltip relative to the target element.
21+
*
22+
* @default topCenter
23+
*/
24+
positioning?: DirectionalHint;
25+
26+
/**
27+
* Allow consumers to pass in Style props
28+
*/
29+
style?: ViewStyle;
30+
31+
/**
32+
* Target anchor that tooltip uses for relative positioning. Certain components may proffer a string as an anchor target, such as
33+
* anchoring to a point inside the component.
34+
*
35+
* If not provided, will anchor to the wrapper element.
36+
*/
37+
target?: React.RefObject<React.Component> | string;
38+
39+
/**
40+
* Controls the tooltip visibility and can be used in conjunction with onVisibleChange to modify show/hide behavior. If not provided, will be updated based on hover/focus events on target element.
41+
*
42+
* @default false
43+
*/
44+
visible?: boolean;
45+
}>;
46+
47+
export interface TooltipSlotProps {
48+
root: TooltipProps;
49+
}
50+
51+
export interface TooltipType {
52+
props: TooltipProps;
53+
slotProps: TooltipSlotProps;
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import * as React from 'react';
2+
3+
import { ButtonV1 } from '@fluentui-react-native/button';
4+
import { checkRenderConsistency, checkReRender } from '@fluentui-react-native/test-tools';
5+
import * as renderer from 'react-test-renderer';
6+
7+
import { Tooltip } from '../Tooltip';
8+
9+
describe('Tooltip component tests', () => {
10+
it('Tooltip default', () => {
11+
const tree = renderer
12+
.create(
13+
<Tooltip content="Your component">
14+
<ButtonV1>Your component</ButtonV1>
15+
</Tooltip>,
16+
)
17+
.toJSON();
18+
expect(tree).toMatchSnapshot();
19+
});
20+
21+
it('Tooltip simple rendering does not invalidate styling', () => {
22+
checkRenderConsistency(
23+
() => (
24+
<Tooltip content="Default Tooltip">
25+
<ButtonV1>Default Tooltip</ButtonV1>
26+
</Tooltip>
27+
),
28+
2,
29+
);
30+
});
31+
32+
it('Tooltip re-renders correctly', () => {
33+
checkReRender(
34+
() => (
35+
<Tooltip content="Render twice">
36+
<ButtonV1>Render twice</ButtonV1>
37+
</Tooltip>
38+
),
39+
2,
40+
);
41+
});
42+
43+
// Feel free to add more tests here
44+
});

0 commit comments

Comments
 (0)