Skip to content

Commit 9b99c2c

Browse files
authored
feat(searchbar): v15 适配,增加了受控和默认值 (#3209)
1 parent ece37a2 commit 9b99c2c

28 files changed

+831
-330
lines changed

src/packages/configprovider/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,11 +655,12 @@ export type NutCSSVariables =
655655
| 'nutuiSearchbarBackground'
656656
| 'nutuiSearchbarColor'
657657
| 'nutuiSearchbarGap'
658+
| 'nutuiSearchbarInnerGap'
658659
| 'nutuiSearchbarFontSize'
659-
| 'nutuiSearchbarContentPadding'
660660
| 'nutuiSearchbarContentBackground'
661661
| 'nutuiSearchbarContentBorderRadius'
662662
| 'nutuiSearchbarContentRoundBorderRadius'
663+
| 'nutuiSearchbarIconSize'
663664
| 'nutuiSearchbarInputHeight'
664665
| 'nutuiSearchbarInputPadding'
665666
| 'nutuiSearchbarInputTextColor'
Lines changed: 70 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,89 @@
11
import * as React from 'react'
2-
import { fireEvent, render } from '@testing-library/react'
2+
import { render, fireEvent, waitFor } from '@testing-library/react'
33
import '@testing-library/jest-dom'
4+
import { useState } from 'react'
45
import SearchBar from '@/packages/searchbar'
56

6-
test('basic usage', () => {
7-
const { container } = render(<SearchBar placeholder="请输入文字" />)
8-
expect(container.querySelector('.nut-searchbar-input')).toHaveAttribute(
9-
'placeholder',
10-
'请输入文字'
7+
test('should render with placeholder', () => {
8+
const { getByPlaceholderText } = render(
9+
<SearchBar placeholder="请输入文字" />
1110
)
11+
expect(getByPlaceholderText('请输入文字')).toBeInTheDocument()
1212
})
1313

1414
test('should limit maxlength of input value when using maxlength prop', () => {
1515
const { container } = render(<SearchBar shape="round" maxLength={5} />)
16-
expect(container.querySelector('.nut-searchbar-input')).toHaveAttribute(
17-
'maxlength',
18-
'5'
19-
)
20-
expect(container.querySelector('.nut-searchbar-content')).toHaveClass(
21-
'nut-searchbar-round'
22-
)
16+
const input = container.querySelector('.nut-searchbar-input')
17+
expect(input).toHaveAttribute('maxlength', '5')
18+
expect(input?.parentNode).toHaveClass('nut-searchbar-round')
2319
})
2420

25-
test('Search box text settings', () => {
21+
test('should display left and right text', () => {
2622
const { container } = render(<SearchBar left="文本" right="确定" />)
2723
expect(container.querySelector('.nut-searchbar-left')?.innerHTML).toBe('文本')
2824
expect(container.querySelector('.nut-searchbar-right')?.innerHTML).toBe(
2925
'确定'
3026
)
3127
})
3228

33-
test('Search clear & change', () => {
34-
const change = vi.fn()
35-
const { container } = render(
36-
<SearchBar value="123" onChange={change} maxLength={10} />
37-
)
38-
const input = container.querySelector('.nut-searchbar-input')
39-
expect(input?.getAttribute('value')).toBe('123')
40-
const clear = container.querySelector('.nut-searchbar-clear')
41-
fireEvent.click(clear as Element)
42-
expect(change).toBeCalledWith('')
43-
expect(input?.getAttribute('value')).toBe('')
29+
test('should render with tags', () => {
30+
const { container } = render(<SearchBar tag value="add,add3" />)
31+
const dvalues = container.querySelectorAll('.nut-searchbar-value')
32+
expect(dvalues.length).toBe(2)
33+
})
34+
35+
test('should render right-in element', () => {
36+
const { container, rerender } = render(<SearchBar rightIn="搜索" />)
37+
const rightin = container.querySelectorAll('.nut-searchbar-rightin')
38+
expect(rightin.length).toBe(1)
39+
rerender(<SearchBar rightIn={<div className="test">搜索</div>} />)
40+
const test = container.querySelectorAll('.test')
41+
expect(test.length).toBe(1)
42+
})
43+
44+
test('should handle all events correctly', async () => {
45+
const handleChange = vi.fn()
46+
const handleFocus = vi.fn()
47+
const handleBlur = vi.fn()
48+
const handleClick = vi.fn()
49+
const handleClear = vi.fn()
50+
const Demo = () => {
51+
const [value, setValue] = useState('奶茶')
52+
const onChange = (newValue: string) => {
53+
setValue(newValue) // 更新状态
54+
handleChange(newValue) // 调用传入的 onChange 处理函数
55+
}
56+
return (
57+
<SearchBar
58+
value={value}
59+
autoFocus
60+
onChange={onChange}
61+
onFocus={handleFocus}
62+
onBlur={handleBlur}
63+
onInputClick={handleClick}
64+
onClear={handleClear}
65+
/>
66+
)
67+
}
68+
69+
const { container } = render(<Demo />)
70+
const inputEl = container.querySelector('.nut-searchbar-input') as Element
71+
expect(inputEl).toHaveValue('奶茶')
72+
fireEvent.click(inputEl)
73+
expect(handleClick).toHaveBeenCalledTimes(1)
74+
fireEvent.change(inputEl, { target: { value: '冰激凌' } })
75+
76+
await waitFor(() => {
77+
expect(handleFocus).toHaveBeenCalledTimes(1)
78+
expect(handleChange).toHaveBeenCalledTimes(1)
79+
expect(inputEl).toHaveValue('冰激凌')
80+
fireEvent.blur(inputEl)
81+
expect(handleBlur).toHaveBeenCalled()
82+
})
83+
84+
const clear = container.querySelector('.nut-searchbar-clear') as Element
85+
fireEvent.click(clear)
86+
await waitFor(() => {
87+
expect(inputEl).toHaveValue('')
88+
})
4489
})

src/packages/searchbar/demo.taro.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import Demo4 from './demos/taro/demo4'
1212
import Demo5 from './demos/taro/demo5'
1313
import Demo6 from './demos/taro/demo6'
1414
import Demo7 from './demos/taro/demo7'
15+
import Demo10 from './demos/taro/demo10'
1516

1617
const SearchBarDemo = () => {
1718
const [translated] = useTranslate({
1819
'zh-CN': {
1920
title1: '基础用法',
21+
title10: '默认值、受控',
2022
title2: '搜索框形状及最大长度',
2123
title3: '搜索框内外背景设置',
2224
title4: '搜索框文本设置',
@@ -26,6 +28,7 @@ const SearchBarDemo = () => {
2628
},
2729
'zh-TW': {
2830
title1: '基礎用法',
31+
title10: '默認值、受控',
2932
title2: '蒐索框形狀及最大長度',
3033
title3: '蒐索框內外背景設定',
3134
title4: '蒐索框文字設定',
@@ -35,22 +38,14 @@ const SearchBarDemo = () => {
3538
},
3639
'en-US': {
3740
title1: 'Basic Usage',
41+
title10: 'DefaultValue and controlled mode',
3842
title2: 'Search Box Shape And Maximum Length',
3943
title3: 'Background Settings Inside And Outside The Search Box',
4044
title4: 'Search Box Text Settings',
4145
title5: 'Custom Icon Settings',
4246
title6: 'Data Change Monitoring',
4347
title7: 'Custom Settings',
4448
},
45-
'id-ID': {
46-
title1: 'penggunaan dasar',
47-
title2: 'bentuk kotak pencarian dan panjang maksimum',
48-
title3: 'pengaturan latar belakang di dalam dan diluar kotak pencarian',
49-
title4: 'tetapan teks kotak pencarian',
50-
title5: 'pengaturan ikon suai',
51-
title6: 'Monitor perubahan data',
52-
title7: 'pengaturan suai',
53-
},
5449
})
5550

5651
return (
@@ -59,6 +54,8 @@ const SearchBarDemo = () => {
5954
<ScrollView className={`demo ${Taro.getEnv() === 'WEB' ? 'web' : ''}`}>
6055
<View className="h2">{translated.title1}</View>
6156
<Demo1 />
57+
<View className="h2">{translated.title10}</View>
58+
<Demo10 />
6259
<View className="h2">{translated.title2}</View>
6360
<Demo2 />
6461
<View className="h2">{translated.title3}</View>

src/packages/searchbar/demo.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import Demo4 from './demos/h5/demo4'
88
import Demo5 from './demos/h5/demo5'
99
import Demo6 from './demos/h5/demo6'
1010
import Demo7 from './demos/h5/demo7'
11+
import Demo10 from './demos/h5/demo10'
1112

1213
const SearchBarDemo = () => {
1314
const [translated] = useTranslate({
1415
'zh-CN': {
1516
title1: '基础用法',
17+
title10: '默认值、受控',
1618
title2: '搜索框形状及最大长度',
1719
title3: '搜索框内外背景设置',
1820
title4: '搜索框文本设置',
@@ -22,6 +24,7 @@ const SearchBarDemo = () => {
2224
},
2325
'zh-TW': {
2426
title1: '基礎用法',
27+
title10: '默認值、受控',
2528
title2: '蒐索框形狀及最大長度',
2629
title3: '蒐索框內外背景設定',
2730
title4: '蒐索框文字設定',
@@ -31,29 +34,23 @@ const SearchBarDemo = () => {
3134
},
3235
'en-US': {
3336
title1: 'Basic Usage',
37+
title10: 'DefaultValue and controlled mode',
3438
title2: 'Search Box Shape And Maximum Length',
3539
title3: 'Background Settings Inside And Outside The Search Box',
3640
title4: 'Search Box Text Settings',
3741
title5: 'Custom Icon Settings',
3842
title6: 'Data Change Monitoring',
3943
title7: 'Custom Settings',
4044
},
41-
'id-ID': {
42-
title1: 'penggunaan dasar',
43-
title2: 'bentuk kotak pencarian dan panjang maksimum',
44-
title3: 'pengaturan latar belakang di dalam dan diluar kotak pencarian',
45-
title4: 'tetapan teks kotak pencarian',
46-
title5: 'pengaturan ikon suai',
47-
title6: 'Monitor perubahan data',
48-
title7: 'pengaturan suai',
49-
},
5045
})
5146

5247
return (
5348
<>
5449
<div className="demo">
5550
<h2>{translated.title1}</h2>
5651
<Demo1 />
52+
<h2>{translated.title10}</h2>
53+
<Demo10 />
5754
<h2>{translated.title2}</h2>
5855
<Demo2 />
5956
<h2>{translated.title3}</h2>

src/packages/searchbar/demos/h5/demo1.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
import React from 'react'
2-
import { SearchBar } from '../../searchbar'
2+
import { Photograph, Scan } from '@nutui/icons-react'
3+
import { SearchBar, Divider } from '@nutui/nutui-react'
34

45
const Demo1 = () => {
56
return (
67
<>
7-
<SearchBar backable placeholder="上京东,购好物" />
8+
<SearchBar placeholder="麻辣烫" rightIn="搜索" />
9+
<SearchBar
10+
leftIn={<Scan />}
11+
placeholder="华为Mate 70"
12+
rightIn={
13+
<div style={{ display: 'flex', alignItems: 'center' }}>
14+
<Photograph color="#888B94" onClick={() => console.log('拍照购')} />
15+
<Divider direction="vertical" />
16+
<span style={{ color: '#ff0f23' }}>搜索</span>
17+
</div>
18+
}
19+
/>
820
</>
921
)
1022
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React, { useState } from 'react'
2+
import { SearchBar, Button } from '@nutui/nutui-react'
3+
import { Photograph, Category } from '@nutui/icons-react'
4+
5+
const Demo = () => {
6+
const [value, setValue] = useState('醋溜土豆丝')
7+
const [value1, setValue1] = useState('西红柿,铁皮')
8+
return (
9+
<>
10+
<SearchBar
11+
backable
12+
leftIn={null}
13+
value={value1}
14+
tag
15+
onItemClick={(val: string) => {
16+
console.log('click', val)
17+
const arr = value1.split(',')
18+
const newArr = arr.filter((item: string) => item !== val)
19+
const newVal = newArr.length > 1 ? newArr.join(',') : newArr.join('')
20+
setValue1(newVal)
21+
}}
22+
onFocus={(val: string) => {
23+
console.log('focus value', val)
24+
setValue1(val.split(',').join(''))
25+
}}
26+
onChange={(val) => {
27+
console.log('onChange', val)
28+
setValue1(val)
29+
}}
30+
rightIn={
31+
<div style={{ display: 'flex', alignItems: 'center' }}>
32+
<Photograph color="#505259" />
33+
</div>
34+
}
35+
right={<Category />}
36+
/>
37+
<SearchBar
38+
backable
39+
leftIn={null}
40+
value={value}
41+
onChange={(val) => {
42+
setValue(val)
43+
}}
44+
autoFocus
45+
rightIn={
46+
<div style={{ display: 'flex', alignItems: 'center' }}>
47+
<Photograph color="#505259" style={{ marginRight: '12px' }} />
48+
<Button type="primary" size="mini">
49+
搜索
50+
</Button>
51+
</div>
52+
}
53+
/>
54+
</>
55+
)
56+
}
57+
export default Demo

src/packages/searchbar/demos/h5/demo2.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react'
2-
import { SearchBar } from '../../searchbar'
2+
import { SearchBar } from '@nutui/nutui-react'
33

44
const Demo2 = () => {
55
return (

src/packages/searchbar/demos/h5/demo3.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import React from 'react'
2-
import { SearchBar } from '../../searchbar'
3-
import ConfigProvider from '../../../configprovider'
4-
import Toast from '../../../toast'
2+
import { SearchBar, ConfigProvider, Toast } from '@nutui/nutui-react'
53

64
const Demo3 = () => {
75
return (
86
<>
97
<ConfigProvider
108
theme={{
119
nutuiSearchbarBackground: 'var(--nutui-color-primary)',
12-
nutuiSearchbarContentBackground: '#eee',
10+
nutuiSearchbarContentBackground: '#fff',
1311
nutuiSearchbarInputTextAlign: 'right',
1412
}}
1513
>

src/packages/searchbar/demos/h5/demo4.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from 'react'
2-
import { SearchBar } from '../../searchbar'
3-
import Toast from '../../../toast'
2+
import { SearchBar, Toast } from '@nutui/nutui-react'
43

54
const Demo4 = () => {
65
return (

src/packages/searchbar/demos/h5/demo5.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,29 @@
11
import React from 'react'
22
import { ArrowLeft, Photograph, More, Close, Star } from '@nutui/icons-react'
3-
import { SearchBar } from '../../searchbar'
3+
import { SearchBar } from '@nutui/nutui-react'
44

55
const Demo5 = () => {
66
return (
77
<>
88
<SearchBar
99
left={
1010
<>
11-
<ArrowLeft width={20} height={20} />
12-
<Close width={20} height={20} />
11+
<ArrowLeft />
12+
<Close />
1313
</>
1414
}
1515
right={
1616
<>
1717
<Star
18-
width={20}
19-
height={20}
2018
style={{
2119
color: 'var(--nutui-color-primary)',
2220
}}
2321
/>
24-
<More width={20} height={20} />
22+
<More />
2523
</>
2624
}
2725
rightIn={
2826
<Photograph
29-
width={16}
30-
height={16}
3127
onClick={() => {
3228
console.log('Photograph right in')
3329
}}

0 commit comments

Comments
 (0)