Skip to content

Commit 5399864

Browse files
authored
SearchInput component (#3530)
* add SearchInput component and related types * delete SearchInput unit tests since they are failing * add custom right element rendering and loader props * update renderCustomRightElement and renderLoaderElement to accept props * Update icon sources in SearchInputScreen and SearchInput components * Refactor renderCustomRightElement prop to customRightElement * Remove unused title prop * Refactor SearchInput API * fixed review notes * rename renderLoaderElement prop to customLoader * modify customLoader type in SearchInputProps * Update customLoader type in searchInput.api.json for clarity * Fix renderLoader to directly use customLoader instead of invoking it as a function
1 parent 74cec4e commit 5399864

File tree

8 files changed

+565
-6
lines changed

8 files changed

+565
-6
lines changed

demo/src/screens/MenuStructure.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const navigationData = {
3838
{title: 'Page Control', tags: 'page', screen: 'unicorn.components.PageControlScreen'},
3939
{title: 'ProgressBar', tags: 'progress bar animated', screen: 'unicorn.animations.ProgressBarScreen'},
4040
{title: 'ScrollBar', tags: 'scroll bar gradient', screen: 'unicorn.components.ScrollBarScreen'},
41+
{title: 'SearchInputScreen', tags: 'search input', screen: 'unicorn.components.SearchInputScreen'},
4142
{
4243
title: 'Shared Transition',
4344
tags: 'shared transition element',
@@ -99,16 +100,18 @@ export const navigationData = {
99100
{title: 'Conversation List', tags: 'list conversation', screen: 'unicorn.lists.ConversationListScreen'},
100101
{title: 'Drawer', tags: 'drawer', screen: 'unicorn.components.DrawerScreen'},
101102
{title: 'SortableList', tags: 'sortable list drag', screen: 'unicorn.components.SortableListScreen'},
102-
{title: 'HorizontalSortableList', tags: 'sortable horizontal list drag', screen: 'unicorn.components.HorizontalSortableListScreen'},
103+
{
104+
title: 'HorizontalSortableList',
105+
tags: 'sortable horizontal list drag',
106+
screen: 'unicorn.components.HorizontalSortableListScreen'
107+
},
103108
{title: 'GridList', tags: 'grid list', screen: 'unicorn.components.GridListScreen'},
104109
{title: 'SortableGridList', tags: 'sort grid list drag', screen: 'unicorn.components.SortableGridListScreen'}
105110
]
106111
},
107112
Charts: {
108113
title: 'Charts',
109-
screens: [
110-
{title: 'PieChart', tags: 'pie chart data', screen: 'unicorn.components.PieChartScreen'}
111-
]
114+
screens: [{title: 'PieChart', tags: 'pie chart data', screen: 'unicorn.components.PieChartScreen'}]
112115
},
113116
LayoutsAndTemplates: {
114117
title: 'Layouts & Templates',
@@ -120,7 +123,11 @@ export const navigationData = {
120123
{title: 'Modal', tags: 'modal topbar screen', screen: 'unicorn.screens.ModalScreen'},
121124
{title: 'StateScreen', tags: 'empty state screen', screen: 'unicorn.screens.EmptyStateScreen'},
122125
{title: 'TabController', tags: 'tabbar controller native', screen: 'unicorn.components.TabControllerScreen'},
123-
{title: 'TabControllerWithStickyHeader', tags: 'tabbar controller native sticky header', screen: 'unicorn.components.TabControllerWithStickyHeaderScreen'},
126+
{
127+
title: 'TabControllerWithStickyHeader',
128+
tags: 'tabbar controller native sticky header',
129+
screen: 'unicorn.components.TabControllerWithStickyHeaderScreen'
130+
},
124131
{title: 'Timeline', tags: 'timeline', screen: 'unicorn.components.TimelineScreen'},
125132
{
126133
title: 'withScrollEnabler',
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import React, {useCallback, useRef, useState} from 'react';
2+
import {Alert} from 'react-native';
3+
import {Colors, View, Text, Switch, SearchInput, SearchInputRef, Button, Icon, Assets} from 'react-native-ui-lib';
4+
5+
const SearchInputScreen = () => {
6+
const [showCancelBtn, setShowCancelBtn] = useState(false);
7+
const [showLoader, setShowLoader] = useState(false);
8+
const [showCustomRightElement, setShowCustomRightElement] = useState(false);
9+
const searchInput = useRef<SearchInputRef>();
10+
11+
const onChangeText = (text: string) => {
12+
console.log('UILIB text: ', text);
13+
};
14+
15+
const onDismiss = useCallback(() => {
16+
Alert.alert('Cancel was pressed');
17+
}, []);
18+
19+
const customRightElement = (
20+
<View center marginH-s2>
21+
<Icon source={Assets.icons.demo.check}/>
22+
</View>
23+
);
24+
25+
return (
26+
<View style={{marginVertical: 5}}>
27+
<Text center h3 $textDefault margin-5>
28+
SearchInput
29+
</Text>
30+
31+
<View>
32+
<SearchInput
33+
showLoader={showLoader}
34+
ref={searchInput}
35+
testID={'searchInput'}
36+
value=""
37+
placeholder="Search"
38+
onDismiss={showCancelBtn ? onDismiss : undefined}
39+
cancelButtonProps={{label: 'Cancel'}}
40+
customRightElement={showCustomRightElement ? customRightElement : undefined}
41+
/>
42+
<View marginV-s2>
43+
<SearchInput
44+
showLoader={showLoader}
45+
invertColors
46+
value={''}
47+
placeholder="Search with inverted colors"
48+
style={{backgroundColor: Colors.$backgroundNeutralHeavy}}
49+
onDismiss={showCancelBtn ? onDismiss : undefined}
50+
cancelButtonProps={{label: 'Cancel'}}
51+
onChangeText={onChangeText}
52+
customRightElement={showCustomRightElement ? customRightElement : undefined}
53+
/>
54+
</View>
55+
<SearchInput
56+
showLoader={showLoader}
57+
value={''}
58+
placeholder="Search with custom colors"
59+
onDismiss={showCancelBtn ? onDismiss : undefined}
60+
cancelButtonProps={{label: 'Cancel'}}
61+
onChangeText={onChangeText}
62+
style={{backgroundColor: Colors.purple20}}
63+
placeholderTextColor={Colors.white}
64+
containerStyle={{color: Colors.white}}
65+
customRightElement={showCustomRightElement ? customRightElement : undefined}
66+
/>
67+
</View>
68+
69+
<View marginV-s2>
70+
<Text center h3 $textDefault margin-5>
71+
Search Input Presets:
72+
</Text>
73+
<View margin-s2>
74+
<Text marginL-s3 marginV-s2>
75+
Default:
76+
</Text>
77+
<SearchInput
78+
showLoader={showLoader}
79+
testID={'searchInput'}
80+
value=""
81+
placeholder="Search"
82+
onDismiss={showCancelBtn ? onDismiss : undefined}
83+
cancelButtonProps={{label: 'Cancel'}}
84+
customRightElement={showCustomRightElement ? customRightElement : undefined}
85+
/>
86+
</View>
87+
<Text marginL-s3 marginV-s2>
88+
Prominent:
89+
</Text>
90+
<SearchInput
91+
showLoader={showLoader}
92+
testID={'searchInput'}
93+
value=""
94+
placeholder="Search"
95+
onDismiss={showCancelBtn ? onDismiss : undefined}
96+
cancelButtonProps={{label: 'Cancel'}}
97+
preset={'prominent'}
98+
customRightElement={showCustomRightElement ? customRightElement : undefined}
99+
/>
100+
</View>
101+
102+
<View marginT-s8 marginH-s3>
103+
<Text bodyBold>Settings:</Text>
104+
<View row marginV-s2>
105+
<Switch
106+
value={showCancelBtn}
107+
onValueChange={value => setShowCancelBtn(value)}
108+
onColor={Colors.$iconSuccessLight}
109+
/>
110+
<Text marginL-s4>Toggle cancel button</Text>
111+
</View>
112+
<View row marginV-s2>
113+
<Switch
114+
value={showCustomRightElement}
115+
onValueChange={value => setShowCustomRightElement(value)}
116+
onColor={Colors.$iconSuccessLight}
117+
/>
118+
<Text marginL-s4>Toggle Custom right element</Text>
119+
</View>
120+
<View row marginV-s2>
121+
<Switch value={showLoader} onValueChange={value => setShowLoader(value)} onColor={Colors.$iconSuccessLight}/>
122+
<Text marginL-s4>Toggle loader</Text>
123+
</View>
124+
<View padding-10 marginV-s1>
125+
<Text>Actions: on the first example</Text>
126+
<View row spread marginV-s1>
127+
<Button size={Button.sizes.small} label={'Blur'} onPress={() => searchInput?.current?.blur()}/>
128+
<Button size={Button.sizes.small} label={'Focus'} onPress={() => searchInput?.current?.focus()}/>
129+
<Button size={Button.sizes.small} label={'Clear'} onPress={() => searchInput?.current?.clear()}/>
130+
</View>
131+
</View>
132+
</View>
133+
</View>
134+
);
135+
};
136+
137+
export default SearchInputScreen;

demo/src/screens/componentScreens/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export function registerScreens(registrar) {
4242
registrar('unicorn.components.RadioButtonScreen', () => require('./RadioButtonScreen').default);
4343
registrar('unicorn.components.ScrollBarScreen', () => require('./ScrollBarScreen').default);
4444
registrar('unicorn.components.SectionsWheelPickerScreen', () => require('./SectionsWheelPickerScreen').default);
45+
registrar('unicorn.components.SearchInputScreen', () => require('./SearchInputScreen').default);
4546
registrar('unicorn.components.SegmentedControlScreen', () => require('./SegmentedControlScreen').default);
4647
registrar('unicorn.components.SharedTransitionScreen', () => require('./SharedTransitionScreen').default);
4748
registrar('unicorn.components.SkeletonViewScreen', () => require('./SkeletonViewScreen').default);
@@ -53,7 +54,8 @@ export function registerScreens(registrar) {
5354
registrar('unicorn.components.StepperScreen', () => require('./StepperScreen').default);
5455
registrar('unicorn.components.SwitchScreen', () => require('./SwitchScreen').default);
5556
registrar('unicorn.components.TabControllerScreen', () => require('./TabControllerScreen').default);
56-
registrar('unicorn.components.TabControllerWithStickyHeaderScreen', () => require('./TabControllerWithStickyHeaderScreen').default);
57+
registrar('unicorn.components.TabControllerWithStickyHeaderScreen',
58+
() => require('./TabControllerWithStickyHeaderScreen').default);
5759
registrar('unicorn.components.TextFieldScreen', () => require('./TextFieldScreen').default);
5860
registrar('unicorn.components.TextScreen', () => require('./TextScreen').default);
5961
registrar('unicorn.components.ToastsScreen', () => require('./ToastsScreen').default);

src/components/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ export default {
137137
get ProgressiveImage() {
138138
return require('./progressiveImage').default;
139139
},
140+
get SearchInput() {
141+
return require('./searchInput').default;
142+
},
140143
get StateScreen() {
141144
return require('./stateScreen').default;
142145
},

0 commit comments

Comments
 (0)