Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(searchbar): 多端适配 #2657

Merged
merged 15 commits into from
Nov 10, 2024
Merged
2 changes: 1 addition & 1 deletion src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@
"author": "dsj"
},
{
"version": "2.0.0",
"version": "3.0.0",
"name": "SearchBar",
"type": "component",
"cName": "搜索栏",
Expand Down
12 changes: 10 additions & 2 deletions src/packages/searchbar/demo.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Taro from '@tarojs/taro'
import { ScrollView, View } from '@tarojs/components'
import { useTranslate } from '@/sites/assets/locale/taro'
import Header from '@/sites/components/header'
import { harmony } from '@/utils/platform-taro'

import Demo1 from './demos/taro/demo1'
import Demo2 from './demos/taro/demo2'
Expand Down Expand Up @@ -66,8 +67,15 @@ const SearchBarDemo = () => {
<Demo4 />
<View className="h2">{translated.title5}</View>
<Demo5 />
<View className="h2">{translated.title7}</View>
<Demo6 />
{/* 组件引入Popover组件,带Popover组件适配harmony后验证 */}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个简化一下。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个简化一下。

已修改

{harmony() ? (
<></>
) : (
<>
<View className="h2">{translated.title7}</View>
<Demo6 />
</>
)}
<View className="h2">{translated.title6}</View>
<Demo7 />
</ScrollView>
Expand Down
60 changes: 41 additions & 19 deletions src/packages/searchbar/demos/taro/demo5.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,57 @@ import {
Close,
Star,
} from '@nutui/icons-react-taro'
import { Icon } from '@tarojs/components'
import { harmony } from '@/utils/platform-taro'

const Demo5 = () => {
// TODO:harmony 下图标为了适配展示使用,待icon适配之后统一移除
const isHarmony = harmony()
return (
<>
<SearchBar
left={
<>
<ArrowLeft size={20} />
<Close size={20} />
</>
isHarmony ? (
<>
<Icon type="waiting" size={20} />
<Icon type="cancel" size={20} color="#c2c4cc" />
</>
) : (
<>
<ArrowLeft size={20} />
<Close size={20} />
</>
)
}
right={
<>
<Star
size={20}
style={{
color: 'var(--nutui-color-primary)',
}}
/>
<More size={20} />
</>
isHarmony ? (
<>
<Icon type="cancel" size={20} />
<Icon type="info" size={20} />
</>
) : (
<>
<Star
size={20}
style={{
color: 'var(--nutui-color-primary)',
}}
/>
<More size={20} />
</>
)
}
rightIn={
<Photograph
size={16}
onClick={() => {
console.log('Photograph right in')
}}
/>
isHarmony ? (
<Icon type="download" size={20} />
) : (
<Photograph
size={16}
onClick={() => {
console.log('Photograph right in')
}}
/>
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

点击事件处理需要适配鸿蒙平台

鸿蒙平台下的图标点击事件处理缺失,需要保持与其他平台行为一致。

建议修改为:

rightIn={
  isHarmony ? (
-   <Icon type="download" size={20} />
+   <Icon 
+     type="download" 
+     size={20} 
+     onClick={() => {
+       console.log('Photograph right in')
+     }}
+   />
  ) : (
    <Photograph
      size={16}
      onClick={() => {
        console.log('Photograph right in')
      }}
    />
  )
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
isHarmony ? (
<Icon type="download" size={20} />
) : (
<Photograph
size={16}
onClick={() => {
console.log('Photograph right in')
}}
/>
)
isHarmony ? (
<Icon
type="download"
size={20}
onClick={() => {
console.log('Photograph right in')
}}
/>
) : (
<Photograph
size={16}
onClick={() => {
console.log('Photograph right in')
}}
/>
)

}
/>
</>
Expand Down
7 changes: 4 additions & 3 deletions src/packages/searchbar/demos/taro/demo7.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useState } from 'react'
import { View } from '@tarojs/components'
import { SearchBar } from '@nutui/nutui-react-taro'
import pxTransform from '@/utils/px-transform'

const Demo7 = () => {
const [value, setValue] = useState('')
Expand All @@ -9,10 +10,10 @@ const Demo7 = () => {
<SearchBar onChange={(val: string) => setValue(val)} maxLength={10} />
<View
style={{
height: '40px',
lineHeight: '40px',
height: pxTransform(40),
lineHeight: pxTransform(40),
color: '#666',
fontSize: '14px',
fontSize: pxTransform(14),
}}
>
{value}
Expand Down
19 changes: 9 additions & 10 deletions src/packages/searchbar/searchbar.harmony.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
align-items: center;
width: 100%;
padding: 6px 16px;
background: #F7F8FC;
color: #1A1A1A;
background: #f5f6fa;
color: #1a1a1a;
font-size: 14px;
box-sizing: border-box;
justify-content: center;
Expand All @@ -27,15 +27,16 @@
.nut-searchbar-clear {
width: 16px;
height: 16px;
color: undefined;
color: rgba(0, 0, 0, 0.2);
}
.nut-searchbar-rightin {
width: 16px;
height: 16px;
color: undefined;
color: rgba(0, 0, 0, 0.2);
}
.nut-searchbar-left, .nut-searchbar-right {
display: flex;
display: inline-flex;
align-items: center;
}
.nut-searchbar-left.nut-icon, .nut-searchbar-right.nut-icon {
width: 20px;
Expand Down Expand Up @@ -89,7 +90,7 @@
.nut-searchbar-right > text:first-child, .nut-searchbar-right > view:first-child {
margin-left: 0;
}
.nut-searchbar-input-box {
.nut-searchbar-input-box, .nut-searchbar-input {
display: flex;
align-items: center;
flex: 1;
Expand All @@ -99,12 +100,10 @@
outline: 0;
box-sizing: border-box;
width: 100%;
height: 32px;
line-height: 32px;
padding: 0 4px;
font-size: 14px;
color: #1A1A1A;
caret-color: #1A1A1A;
color: #1a1a1a;
caret-color: #1a1a1a;
background: transparent;
text-align: left;
}
Expand Down
8 changes: 4 additions & 4 deletions src/packages/searchbar/searchbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@

&-left,
&-right {
display: flex;
display: inline-flex;
align-items: center;

&.nut-icon {
width: 20px;
Expand Down Expand Up @@ -89,7 +90,8 @@
}
}

&-input-box {
&-input-box,
&-input {
display: flex;
align-items: center;
flex: 1;
Expand All @@ -100,8 +102,6 @@
outline: 0;
box-sizing: border-box;
width: 100%;
height: $searchbar-input-height;
line-height: $searchbar-input-height;
padding: $searchbar-input-padding;
font-size: $searchbar-font-size;
color: $searchbar-input-text-color;
Expand Down
75 changes: 43 additions & 32 deletions src/packages/searchbar/searchbar.taro.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { FunctionComponent, useEffect, useRef, useState } from 'react'
import type { ChangeEvent, FocusEvent, MouseEvent } from 'react'
import { View, ITouchEvent } from '@tarojs/components'
import { View, ITouchEvent, Input as TaroInput, Icon } from '@tarojs/components'
import { MaskClose, Search, ArrowLeft } from '@nutui/icons-react-taro'
import { useConfig } from '@/packages/configprovider/configprovider.taro'
import { BasicComponent, ComponentDefaults } from '@/utils/typings'
import { harmony } from '@/utils/platform-taro'

export interface SearchBarProps extends BasicComponent {
value?: number | string
value?: string
placeholder?: string
shape?: 'square' | 'round'
disabled?: boolean
Expand All @@ -27,6 +28,9 @@ export interface SearchBarProps extends BasicComponent {
onInputClick?: (event: MouseEvent<HTMLInputElement>) => void
}

// TODO:harmony 下图标为了适配展示使用,待icon适配之后统一移除
const isHarmony = harmony()

const defaultProps = {
...ComponentDefaults,
placeholder: '',
Expand All @@ -40,7 +44,7 @@ const defaultProps = {
left: '',
right: '',
rightIn: '',
leftIn: <Search size="16" />,
leftIn: isHarmony ? <Icon type="search" size={16} /> : <Search size="16" />,
} as SearchBarProps
export const SearchBar: FunctionComponent<
Partial<SearchBarProps> &
Expand Down Expand Up @@ -87,21 +91,20 @@ export const SearchBar: FunctionComponent<
const searchSelf: HTMLInputElement | null = searchRef.current
searchSelf && searchSelf.focus()
}
const change = (event: ChangeEvent<HTMLInputElement>) => {
if (value === event.target.value) return
onChange && onChange?.(event.target.value, event)
setValue(event.target.value)
event.target.value === '' && forceFocus()
const onInput = (event: any) => {
const eventValue = event?.detail?.value
if (value === eventValue) return
onChange && onChange?.(eventValue, event)
setValue(eventValue)
eventValue === '' && forceFocus()
Comment on lines +90 to +95
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

优化事件处理和空值检查

建议使用可选链操作符来简化代码并提高可读性:

  const onInput = (event: any) => {
    const eventValue = event?.detail?.value
    if (value === eventValue) return
-   onChange && onChange?.(eventValue, event)
+   onChange?.(eventValue, event)
    setValue(eventValue)
    eventValue === '' && forceFocus()
  }

另外,建议添加对 event 参数的类型定义:

const onInput = (event: ITouchEvent) => {
🧰 Tools
🪛 Biome

[error] 93-93: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

}
const focus = (event: FocusEvent<HTMLInputElement>) => {
const { value } = event.target
onFocus && onFocus?.(value, event)
const focus = (event: any) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any 类型处理下~

onFocus && onFocus?.(event?.detail?.value, event)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

都判断过了,是不是不需要在写? 了。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

都判断过了,是不是不需要在写? 了。

已修改

}
const blur = (event: FocusEvent<HTMLInputElement>) => {
const blur = (event: any) => {
const searchSelf: HTMLInputElement | null = searchRef.current
searchSelf && searchSelf.blur()
const { value } = event.target
onBlur && onBlur?.(value, event)
onBlur && onBlur?.(event?.detail?.value, event)
}
useEffect(() => {
setValue(outerValue || '')
Expand All @@ -111,26 +114,27 @@ export const SearchBar: FunctionComponent<
}, [autoFocus])
const renderField = () => {
return (
<input
<TaroInput
className={`${classPrefix}-input ${
clearable ? `${classPrefix}-input-clear` : ''
}`}
ref={searchRef}
style={style}
value={value || ''}
placeholder={placeholder || locale.placeholder}
disabled={disabled}
readOnly={readOnly}
maxLength={maxLength}
onKeyPress={onKeypress}
onChange={(e) => change(e)}
onFocus={(e) => focus(e)}
onBlur={(e) => blur(e)}
onClick={(e) => clickInput(e)}
disabled={disabled || readOnly}
maxlength={maxLength}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readonly 和 disabled 在表现上样式不一样~~ 这个怎么区分呢

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readonly 和 disabled 在表现上样式不一样~~ 这个怎么区分呢

taro的input只支持disabled, 我参考我们已适配的input组件处理的

// @ts-ignore
// onKeyDown={onKeypress}
onInput={onInput}
onFocus={focus}
onBlur={blur}
onClick={clickInput}
onConfirm={onConfirm}
/>
)
}
const clickInput = (e: MouseEvent<HTMLInputElement>) => {
const clickInput = (e: any) => {
onInputClick && onInputClick(e)
}
const renderLeftIn = () => {
Expand Down Expand Up @@ -167,7 +171,11 @@ export const SearchBar: FunctionComponent<
className={`${classPrefix}-clear ${classPrefix}-icon`}
onClick={(e: any) => clearaVal(e)}
>
<MaskClose size={16} />
{isHarmony ? (
<Icon type="cancel" size={16} color="#c2c4cc" />
) : (
<MaskClose size={16} />
)}
</View>
)
}
Expand All @@ -182,13 +190,16 @@ export const SearchBar: FunctionComponent<
onChange && onChange?.('')
onClear && onClear(event)
}
const onKeypress = (e: any) => {
if (e.key === 'Enter' || e.keyCode === 13) {
if (typeof e.cancelable !== 'boolean' || e.cancelable) {
e.preventDefault()
}
onSearch && onSearch(value as string)
}
// const onKeypress = (event: any) => {
// if (event?.detail?.keyCode === 13) {
// if (typeof event.cancelable !== 'boolean' || event.cancelable) {
// event.preventDefault()
// }
// onSearch && onSearch(value as string)
// }
// }
const onConfirm = () => {
onSearch && onSearch(value as string)
Comment on lines +185 to +194
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

搜索确认逻辑优化

  1. 使用可选链简化代码
  2. 补充 onConfirm 的类型定义
- const onConfirm = () => {
-   onSearch && onSearch(value as string)
+ const onConfirm = (event: ITouchEvent) => {
+   onSearch?.(value as string)
  }

注释说明:移除已注释的 onKeypress 相关代码,因为在 Taro 环境下统一使用 onConfirm 处理搜索事件。

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// const onKeypress = (event: any) => {
// if (event?.detail?.keyCode === 13) {
// if (typeof event.cancelable !== 'boolean' || event.cancelable) {
// event.preventDefault()
// }
// onSearch && onSearch(value as string)
// }
// }
const onConfirm = () => {
onSearch && onSearch(value as string)
// const onKeypress = (event: any) => {
// if (event?.detail?.keyCode === 13) {
// if (typeof event.cancelable !== 'boolean' || event.cancelable) {
// event.preventDefault()
// }
// onSearch && onSearch(value as string)
// }
// }
const onConfirm = (event: ITouchEvent) => {
onSearch?.(value as string)
🧰 Tools
🪛 Biome

[error] 194-194: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

}
return (
<View
Expand Down