Skip to content

Commit 2cd8d7b

Browse files
committed
feat(tooltip): add tooltip component
1 parent bfa2c45 commit 2cd8d7b

23 files changed

+1446
-76
lines changed

Diff for: .storybook/preview.js renamed to .storybook/preview.tsx

+22-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';
22
import React from 'react';
33
import { ScrollView } from 'react-native';
44
import { SafeAreaProvider } from 'react-native-safe-area-context';
5-
import { PortalProvider, ThemeProvider, Toast, theme } from '../src';
5+
import { Parameters, Story } from '@storybook/react-native';
6+
import {
7+
PortalProvider,
8+
ThemeProvider,
9+
TooltipProvider,
10+
Toast,
11+
theme,
12+
} from '../src';
613

714
theme.fonts = {
815
light: 'Rubik-Light',
@@ -14,25 +21,28 @@ theme.fonts = {
1421

1522
export const decorators = [
1623
withBackgrounds,
17-
Story => (
24+
(Story: Story) => (
1825
<ThemeProvider theme={theme}>
19-
<PortalProvider>
20-
<SafeAreaProvider>
21-
<ScrollView style={{ backgroundColor: theme.colors.neutralFull }}>
22-
<Story />
23-
</ScrollView>
24-
<Toast ignoreKeyboard extraPaddingBottom={16} />
25-
</SafeAreaProvider>
26-
</PortalProvider>
26+
<TooltipProvider>
27+
<PortalProvider>
28+
<SafeAreaProvider>
29+
<ScrollView style={{ backgroundColor: theme.colors.neutralFull }}>
30+
<Story />
31+
</ScrollView>
32+
<Toast ignoreKeyboard extraPaddingBottom={16} />
33+
</SafeAreaProvider>
34+
</PortalProvider>
35+
</TooltipProvider>
2736
</ThemeProvider>
2837
),
2938
];
3039

31-
export const parameters = {
40+
export const parameters: Parameters = {
3241
backgrounds: [
3342
{ name: 'plain', value: theme.colors.neutralFull, default: true },
3443
{ name: 'warm', value: '#f1f2f7' },
3544
],
45+
layout: 'fullscreen',
3646
options: {
3747
storySort: {
3848
order: [
@@ -48,6 +58,7 @@ export const parameters = {
4858
'Text',
4959
'TextArea',
5060
'Toast',
61+
'Tooltip',
5162
'Switch',
5263
'Modal',
5364
],

Diff for: .storybook/storybook.requires.js

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const getStories = () => {
3838
require('../src/components/TextArea/TextArea.stories.tsx'),
3939
require('../src/components/TextLink/TextLink.stories.tsx'),
4040
require('../src/components/Toast/Toast.stories.tsx'),
41+
require('../src/components/Tooltip/Tooltip.stories.tsx'),
4142
require('../src/components/Spinner/Spinner.stories.tsx'),
4243
require('../src/components/Modal/Modal.stories.tsx'),
4344
];

Diff for: __mocks__/react-native-safe-area-context.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// __mocks__/react-native-safe-area-context.js
2+
import React from 'react';
3+
import { View } from 'react-native';
4+
5+
const inset = {
6+
top: 62,
7+
right: 0,
8+
bottom: 32,
9+
left: 0,
10+
};
11+
12+
export const SafeAreaProvider = ({ children }) => children;
13+
14+
export const SafeAreaConsumer = ({ children }) => children(inset);
15+
16+
export const SafeAreaView = ({ children }) => (
17+
<View style={inset}>{children}</View>
18+
);
19+
20+
export const useSafeAreaInsets = () => inset;

Diff for: package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
"react-dom": "18.2.0",
103103
"react-native": "0.74.5",
104104
"react-native-builder-bob": "^0.35.2",
105-
"react-native-safe-area-context": "4.3.4",
105+
"react-native-safe-area-context": "^5.1.0",
106106
"react-native-svg": "^15.11.1",
107107
"react-test-renderer": "^18.2.0",
108108
"typescript": "5.0.4"

Diff for: src/components/Button/Button.test.tsx

+8-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ describe('Button', () => {
2727
test('should render given kind and color correctly', () => {
2828
// when
2929
const { getByTestId } = render(<Button testID="button" kind="success" />);
30-
const buttonComponent = getByTestId('button').children[0];
30+
const buttonComponent = getByTestId('button')
31+
.children[0] as ReactTestInstance;
3132

3233
// then
3334
expect(buttonComponent.props.kind).toBe('success');
@@ -40,7 +41,8 @@ describe('Button', () => {
4041
const { getByTestId } = render(
4142
<Button testID="button" size="l" label="test" />,
4243
);
43-
const buttonComponent = getByTestId('button').children[0];
44+
const buttonComponent = getByTestId('button')
45+
.children[0] as ReactTestInstance;
4446

4547
// then
4648
const textComponent = buttonComponent.props
@@ -132,7 +134,8 @@ describe('Button', () => {
132134
const { getByTestId } = render(
133135
<Button testID="button" label="testtesttest" />,
134136
);
135-
const buttonComponent = getByTestId('button').children[0];
137+
const buttonComponent = getByTestId('button')
138+
.children[0] as ReactTestInstance;
136139

137140
// then
138141
expect(buttonComponent.props.variant).toBe('primary');
@@ -182,7 +185,8 @@ describe('Button', () => {
182185
filled={true}
183186
/>,
184187
);
185-
const buttonComponent = getByTestId('button').children[0];
188+
const buttonComponent = getByTestId('button')
189+
.children[0] as ReactTestInstance;
186190

187191
// then
188192
expect(buttonComponent.props.alignSelf).toBe('stretch');

Diff for: src/components/Spinner/Spinner.test.tsx

+16-26
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Animated } from 'react-native';
33
import { render } from '../../test-utils';
44
import theme from '../../theme';
55
import Spinner from './Spinner';
6+
import { ReactTestInstance } from 'react-test-renderer';
67

78
describe('Spinner', () => {
89
test('should render Spinner correctly', () => {
@@ -19,16 +20,15 @@ describe('Spinner', () => {
1920
<Spinner testID="spinner" color="successKey" />,
2021
);
2122

22-
const spinnerComponent = getByTestId('spinner');
23+
const spinnerComponent = getByTestId('spinner')
24+
.children[0] as ReactTestInstance;
2325

2426
// then
25-
expect(spinnerComponent.children[0].props.children[0].props.fill).toBe(
27+
expect(spinnerComponent.props.children[0].props.fill).toBe(
2628
theme.colors.successKey,
2729
);
28-
expect(spinnerComponent.children[0].props.children[0].props.opacity).toBe(
29-
0.3,
30-
);
31-
expect(spinnerComponent.children[0].props.children[1].props.fill).toBe(
30+
expect(spinnerComponent.props.children[0].props.opacity).toBe(0.3);
31+
expect(spinnerComponent.props.children[1].props.fill).toBe(
3232
theme.colors.successKey,
3333
);
3434
});
@@ -37,18 +37,13 @@ describe('Spinner', () => {
3737
// when
3838
const { getByTestId } = render(<Spinner testID="spinner" color="pink" />);
3939

40-
const spinnerComponent = getByTestId('spinner');
40+
const spinnerComponent = getByTestId('spinner')
41+
.children[0] as ReactTestInstance;
4142

4243
// then
43-
expect(spinnerComponent.children[0].props.children[0].props.fill).toBe(
44-
'pink',
45-
);
46-
expect(spinnerComponent.children[0].props.children[0].props.opacity).toBe(
47-
0.3,
48-
);
49-
expect(spinnerComponent.children[0].props.children[1].props.fill).toBe(
50-
'pink',
51-
);
44+
expect(spinnerComponent.props.children[0].props.fill).toBe('pink');
45+
expect(spinnerComponent.props.children[0].props.opacity).toBe(0.3);
46+
expect(spinnerComponent.props.children[1].props.fill).toBe('pink');
5247
});
5348

5449
test('should render hex color', () => {
@@ -57,18 +52,13 @@ describe('Spinner', () => {
5752
<Spinner testID="spinner" color="#5C8984" />,
5853
);
5954

60-
const spinnerComponent = getByTestId('spinner');
55+
const spinnerComponent = getByTestId('spinner')
56+
.children[0] as ReactTestInstance;
6157

6258
// then
63-
expect(spinnerComponent.children[0].props.children[0].props.fill).toBe(
64-
'#5C8984',
65-
);
66-
expect(spinnerComponent.children[0].props.children[0].props.opacity).toBe(
67-
0.3,
68-
);
69-
expect(spinnerComponent.children[0].props.children[1].props.fill).toBe(
70-
'#5C8984',
71-
);
59+
expect(spinnerComponent.props.children[0].props.fill).toBe('#5C8984');
60+
expect(spinnerComponent.props.children[0].props.opacity).toBe(0.3);
61+
expect(spinnerComponent.props.children[1].props.fill).toBe('#5C8984');
7262
});
7363

7464
test('should start spin animation', () => {

Diff for: src/components/Toast/Toast.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import Box from '../Box/Box';
33
import ToastView from './ToastView';
44
import { ShowMethodParams, ToastDataWithId, ToastDurations } from './types';
5-
import { uuid } from './utils';
5+
import { uuid } from '../../utils/uuid';
66
import { useSafeAreaInsets } from 'react-native-safe-area-context';
77
import { useKeyboard } from './hooks';
88
import theme from '../../theme';

Diff for: src/components/Toast/utils.test.ts

+1-19
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
import {
2-
capitalizeFirstLetter,
3-
getFirstNChar,
4-
pausableTimer,
5-
uuid,
6-
} from './utils';
1+
import { capitalizeFirstLetter, getFirstNChar, pausableTimer } from './utils';
72

83
describe('Toast Utils', () => {
94
describe('capitalizeFirstLetter', () => {
@@ -140,17 +135,4 @@ describe('Toast Utils', () => {
140135
expect(mockCallback).not.toBeCalled();
141136
});
142137
});
143-
144-
describe('uuid', () => {
145-
test('Should return a N-character string', () => {
146-
// given
147-
const n = 1 + Math.floor(Math.random() * 32);
148-
149-
// when
150-
const result = uuid(n);
151-
152-
// then
153-
expect(result.length).toBe(n);
154-
});
155-
});
156138
});

Diff for: src/components/Toast/utils.ts

-9
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
export function uuid(digits: number) {
2-
let str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXZ';
3-
let id = [];
4-
for (let i = 0; i < digits; i++) {
5-
id.push(str[Math.floor(Math.random() * str.length)]);
6-
}
7-
return id.join('');
8-
}
9-
101
export function capitalizeFirstLetter(str?: string) {
112
if (!str || typeof str !== 'string') {
123
return '';

0 commit comments

Comments
 (0)