feat(searchbar): v15 适配,增加了受控和默认值#3209
Conversation
Suggested reviewers
Poem
|
There was a problem hiding this comment.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
src/packages/searchbar/searchbar.tsx (1)
178-193:⚠️ Potential issue
clearaVal中onChange参数缺失导致类型与语义不一致
onChange约定签名为(value: string, event: ChangeEvent<HTMLInputElement>),
但这里仅传入了字符串,可能触发 TS 警告甚至上层逻辑错误。- onChange && onChange('') + // 将 div 事件转换为虚假的 ChangeEvent 以符合签名,或改为可选链并传 `undefined` + onChange?.('', undefined as unknown as ChangeEvent<HTMLInputElement>)如果不想构造伪事件,建议在此处 不要调用
onChange,改为让调用方依赖onClear。🧰 Tools
🪛 Biome (1.9.4)
[error] 192-192: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 193-193: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🧹 Nitpick comments (8)
src/packages/searchbar/demo.tsx (1)
17-17: 多语言支持完善添加了新示例的标题翻译,确保在不同语言环境下都能正确显示。中文和繁体中文翻译看起来正确,但英文翻译似乎没有进行本地化,仍保留中文内容。
建议将英文翻译更新为对应的英文描述:
- title10: '默认值、受控', + title10: 'Default Value & Controlled Mode',Also applies to: 27-27, 37-37
src/packages/searchbar/demos/h5/demo10.tsx (1)
11-25: 默认值(非受控)模式示例这个示例很好地展示了:
- 使用
defaultValue属性设置默认值- 通过
onItemClick处理默认值项的点击事件- 自定义图标和右侧内容
注意到在
onItemClick回调中,将dvalue设置为了固定值"黄瓜"而非基于当前值的动态更新。这种实现可能不符合实际使用场景的需求。考虑改进
onItemClick的处理方式,使其能动态更新值:onItemClick={(value: string) => { console.log('click', value) - setDvalue('黄瓜') + // 从默认值中移除被点击的项 + setDvalue(dvalue.split(',').filter(item => item !== value).join(',')) }}src/packages/searchbar/doc.taro.md (1)
120-121: 更新CSS变量默认值更新了多个CSS变量的默认值:
- 减小了padding值(从
6px 16px到1px 8px)- 更新了背景色为
$color-background-sunken- 区分了外部大间距和内部元素间距
- 增加了内容区圆角和round模式下的圆角值
- 调整了输入区高度和内边距
这些更新使组件样式更加精细和现代化。
注意:文档中有一处小错误,在
\--nutui-searchbar-input-padding描述中,"搜索框输入区padding"包含了重复的英文单词,可以考虑改为中文表述以保持一致性。-| \--nutui-searchbar-input-padding | 搜索框输入区padding | `0 0 0 8px` | +| \--nutui-searchbar-input-padding | 搜索框输入区内边距 | `0 0 0 8px` |Also applies to: 123-124, 127-130
🧰 Tools
🪛 LanguageTool
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 |1px 8px| | --nutui-searchbar-background | 搜索框背景色 |$color-background-sunken|...(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 |$color-background-sunken| | --nutui-searchbar-color | ...(GL_BARBARISM_REPLACE)
src/packages/searchbar/searchbar.tsx (1)
207-214:focus状态样式判断条件过于宽泛
当前根据left || backable判定是否添加-focus,意味着只要存在左侧内容就会触发,
与“聚焦”语义不符。建议改为监听input的实际 focus/blur 状态或autoFocus。src/packages/searchbar/searchbar.scss (2)
12-16: 全局 icon 尺寸统一可能影响自定义大小
.nut-searchbar .nut-icon统一设置width/height/font-size,
会覆盖用户在left/right/rightIn等插槽自定义的 icon 大小。
可以只对leftIn/rightIn/clear等特定内置 icon 设定,避免误伤。// 示例:限定作用域而非通配 .nut-searchbar-icon { width: $searchbar-icon-size; height: $searchbar-icon-size; font-size: $searchbar-icon-size; }
82-105: 默认值列表位置写死,缺乏适配性
.nut-searchbar-values使用top: 9px; left: 6px;会在不同尺寸主题下产生错位,
建议改为使用padding-left或flex + gap方案,或暴露 CSS 变量方便业务方覆盖。src/packages/searchbar/doc.md (1)
99-101: 文字排版错误 – “搜搜框”
| right | 搜搜框右侧区域 → 应为 搜索框
请修正以保持专业性。src/packages/searchbar/doc.zh-TW.md (1)
99-101: 排版錯誤 – 「搜搜框」
| right | 搜搜框右側區域 → 應為 搜索框 / 搜尋框
請修正以避免文字錯誤。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
src/packages/searchbar/demo.tsx(3 hunks)src/packages/searchbar/demos/h5/demo1.tsx(1 hunks)src/packages/searchbar/demos/h5/demo10.tsx(1 hunks)src/packages/searchbar/demos/h5/demo3.tsx(1 hunks)src/packages/searchbar/demos/h5/demo5.tsx(1 hunks)src/packages/searchbar/doc.md(3 hunks)src/packages/searchbar/doc.taro.md(3 hunks)src/packages/searchbar/doc.zh-TW.md(2 hunks)src/packages/searchbar/searchbar.scss(2 hunks)src/packages/searchbar/searchbar.tsx(8 hunks)src/sites/sites-react/doc/docs/react/migrate-from-v2.md(1 hunks)src/styles/variables.scss(1 hunks)src/types/spec/searchbar/base.ts(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/packages/searchbar/demos/h5/demo1.tsx (1)
src/packages/searchbar/searchbar.tsx (1)
SearchBar(25-233)
src/packages/searchbar/demos/h5/demo10.tsx (1)
src/packages/searchbar/searchbar.tsx (1)
SearchBar(25-233)
src/packages/searchbar/demos/h5/demo5.tsx (1)
src/packages/calendarcard/icon.taro.tsx (1)
ArrowLeft(44-44)
🪛 LanguageTool
src/packages/searchbar/doc.md
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 | 1px 8px | | --nutui-searchbar-background | 搜索框背景色 | $color-background-sunken |...
(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 | $color-background-sunken | | --nutui-searchbar-color | ...
(GL_BARBARISM_REPLACE)
[locale-violation] ~123-~123: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...| $color-title | | --nutui-searchbar-gap | 搜索框外部/大间距 | 12px | | --nutui-searc...
(GL_BARBARISM_REPLACE)
[locale-violation] ~124-~124: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 | 12px | | --nutui-searchbar-inner-gap | 搜索框内部元素间的间距 | 12px | | --nutui-sea...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ze-base| | \--nutui-searchbar-content-background | 搜索框中间内容区的背景色 |$color-background-ove...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...bar-content-background | 搜索框中间内容区的背景色 | $color-background-overlay | | --nutui-searchbar-content...
(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圆角 | 19px | | --nutui-searchbar-input-height | 搜索框输入区高度 | 38px | | --nutui...
(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框输入区高度 | 38px | | --nutui-searchbar-input-padding | 搜索框输入区padding | 0 0 0 8px |...
(GL_BARBARISM_REPLACE)
[duplication] ~130-~130: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框输入区padding | 0 0 0 8px | | --nutui-searchbar-input-tex...
(WORD_REPETITION)
src/packages/searchbar/doc.zh-TW.md
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 | 1px 8px | | --nutui-searchbar-background | 搜索框背景色 | $color-background-sunken |...
(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 | $color-background-sunken | | --nutui-searchbar-color | ...
(GL_BARBARISM_REPLACE)
[locale-violation] ~123-~123: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...| $color-title | | --nutui-searchbar-gap | 搜索框外部/大間距 | 12px | | --nutui-searc...
(GL_BARBARISM_REPLACE)
[locale-violation] ~124-~124: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 | 12px | | --nutui-searchbar-inner-gap | 搜索框內部元素間的間距 | 12px | | --nutui-sea...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ze-base| | \--nutui-searchbar-content-background | 搜索框中間內容區的背景色 |$color-background-ove...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...bar-content-background | 搜索框中間內容區的背景色 | $color-background-overlay | | --nutui-searchbar-content...
(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圓角 | 19px | | --nutui-searchbar-input-height | 搜索框輸入區高度 | 38px | | --nutui...
(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框輸入區高度 | 38px | | --nutui-searchbar-input-padding | 搜索框輸入區padding | 0 0 0 8px |...
(GL_BARBARISM_REPLACE)
[duplication] ~130-~130: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框輸入區padding | 0 0 0 8px | | --nutui-searchbar-input-tex...
(WORD_REPETITION)
src/packages/searchbar/doc.taro.md
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 | 1px 8px | | --nutui-searchbar-background | 搜索框背景色 | $color-background-sunken |...
(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 | $color-background-sunken | | --nutui-searchbar-color | ...
(GL_BARBARISM_REPLACE)
[locale-violation] ~123-~123: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...| $color-title | | --nutui-searchbar-gap | 搜索框外部/大间距 | 12px | | --nutui-searc...
(GL_BARBARISM_REPLACE)
[locale-violation] ~124-~124: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 | 12px | | --nutui-searchbar-inner-gap | 搜索框内部元素间的间距 | 12px | | --nutui-sea...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ze-base| | \--nutui-searchbar-content-background | 搜索框中间内容区的背景色 |$color-background-ove...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...bar-content-background | 搜索框中间内容区的背景色 | $color-background-overlay | | --nutui-searchbar-content...
(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圆角 | 19px | | --nutui-searchbar-input-height | 搜索框输入区高度 | 38px | | --nutui...
(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框输入区高度 | 38px | | --nutui-searchbar-input-padding | 搜索框输入区padding | 0 0 0 8px |...
(GL_BARBARISM_REPLACE)
[duplication] ~130-~130: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框输入区padding | 0 0 0 8px | | --nutui-searchbar-input-tex...
(WORD_REPETITION)
🪛 Biome (1.9.4)
src/packages/searchbar/searchbar.tsx
[error] 78-78: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 83-83: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 89-89: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 94-94: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 96-96: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 192-192: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (21)
src/styles/variables.scss (6)
1929-1929: 更新了SearchBar的内边距,使其更紧凑将SearchBar的内边距从
6px 16px调整为1px 8px,使组件布局更加紧凑,这与SearchBar的受控和默认值特性更新相匹配。
1932-1932: 更新了SearchBar的背景色,提高可辨识度将背景色从
$color-background更改为$color-background-sunken,增强了SearchBar与周围元素的视觉区分度。
1935-1936: 优化了SearchBar的间距设置
- 将主间距从
16px缩小至12px- 新增了
$searchbar-inner-gap变量设为8px,用于内部元素间距这种差异化间距设置使组件层次结构更清晰,外部元素间距稍大,内部元素间距稍小,符合设计规范。
1947-1947: 增加了SearchBar的圆角半径,提升现代感将内容圆角从
4px增加至8px,圆形搜索框圆角从18px增加至19px,使组件更加现代化,视觉效果更佳。Also applies to: 1951-1951
1953-1958: 新增了SearchBar的图标和输入框样式变量新增了3个重要变量:
$searchbar-icon-size: 20px- 统一图标尺寸$searchbar-input-height: 38px- 定义输入框高度$searchbar-input-padding: 0 0 0 8px- 输入框内边距这些变量增强了组件的一致性和可配置性,支持新的受控和默认值功能所需的UI布局。
1965-1965: 更新了输入光标颜色,增强品牌一致性将输入框光标颜色从
$color-title更改为$color-primary,使其与品牌主色保持一致,提升用户体验。src/packages/searchbar/demos/h5/demo3.tsx (1)
12-12: 更新了主题配置中的内容背景色将搜索框内容区背景色从灰色(
#eee)调整为白色(#fff),使搜索框在自定义主题下视觉效果更加清爽。此修改与组件整体样式更新保持一致。src/packages/searchbar/demos/h5/demo5.tsx (2)
11-12: 移除了图标组件的尺寸属性移除了
ArrowLeft、Close和More图标的尺寸属性,改为使用全局样式统一控制。这与变量文件中新增的$searchbar-icon-size相对应,提高了组件样式的一致性和可维护性。Also applies to: 22-22
26-31: 保留了Photograph图标的点击事件处理移除了
Photograph图标的尺寸属性,但保留了点击事件处理,确保功能不受样式调整影响。这是一个良好的优化,既统一了样式又保持了交互功能。src/sites/sites-react/doc/docs/react/migrate-from-v2.md (1)
183-188: 新增了SearchBar组件的迁移指南清晰地补充了SearchBar组件的新特性说明,包括:
value属性支持受控模式- 新增
defaultValue属性,支持默认值和多默认值(以逗号分隔)- 新增
onItemClick回调,用于处理点击默认值项目的关闭图标事件文档更新全面且准确,有助于用户理解并使用这些新功能。
src/types/spec/searchbar/base.ts (1)
7-7: 扩展了BaseSearchBar接口,增加新属性支持在BaseSearchBar接口中新增了两个属性:
defaultValue: string- 用于支持非受控模式下的默认值onItemClick: (value: string) => void- 用于处理点击默认值项的回调函数这些类型定义与组件新功能完全匹配,确保了TypeScript类型安全性和API一致性。
Also applies to: 26-26
src/packages/searchbar/demo.tsx (2)
11-11: 引入了新的示例以展示受控和默认值的用法正确导入了Demo10组件,这将用于展示SearchBar的新功能。
52-53: 正确整合了新示例到演示页面新增的Demo10示例被正确地添加到了演示页面中,并使用对应的翻译标题。
src/packages/searchbar/demos/h5/demo1.tsx (2)
2-2: 合理引入相关组件正确导入了所需的图标和分割线组件,用于增强SearchBar的视觉表现。
Also applies to: 4-4
9-20: 基础用法示例优化新版基础用法示例更加丰富,展示了两种不同配置的SearchBar:
- 简单配置:带placeholder和右侧文本
- 复杂配置:带左侧图标、placeholder和自定义右侧内容(包含图标、分隔线和文本)
这种展示方式更全面地展示了组件的基础能力,有助于用户理解组件的灵活性。
src/packages/searchbar/demos/h5/demo10.tsx (3)
1-5: 组件引入和状态声明正确导入了React hooks和所需组件,设置了适当的初始状态用于展示受控和非受控用法。
7-8: 状态初始化设置合理设置了两种状态变量:
dvalue:用于非受控模式,初始化为逗号分隔的多值value:用于受控模式,初始化为单个值这样的设置有效地展示了组件的两种使用模式。
26-42: 受控模式示例这个示例很好地展示了:
- 使用
value和onChange实现受控模式- 使用
autoFocus属性自动聚焦- 自定义复杂的右侧内容,包含图标和按钮
实现正确,展示了受控组件的典型用法。
src/packages/searchbar/doc.taro.md (3)
89-90: 添加并完善属性文档适当更新了
value属性的描述,明确标注其为"受控"属性,并新增了defaultValue属性的说明,清晰解释了它支持通过逗号分隔成多个值。这有助于开发者理解两种使用模式的区别。
101-101: 简化默认图标配置更新了
leftIn属性的默认值说明,移除了之前显式设置的尺寸属性,使文档更加简洁。
109-109: 添加新事件回调文档新增了
onItemClick事件的说明,清晰解释了其触发条件和参数。
src/packages/searchbar/searchbar.tsx
Outdated
| useEffect(() => { | ||
| setValue(defaultValue) | ||
| }, [defaultValue]) | ||
|
|
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
defaultValue 变更副作用可能破坏受控模式
useEffect 每当 defaultValue 变化即调用 setValue,
若组件已经处于“受控”(由 value 驱动) 状态,会被意外覆盖。
-useEffect(() => {
- setValue(defaultValue)
-}, [defaultValue])
+useEffect(() => {
+ // 仅在组件非受控且 defaultValue 有效时同步内部状态
+ if (outerValue === undefined && defaultValue !== undefined) {
+ setValue(defaultValue)
+ }
+}, [defaultValue, outerValue])这样可以避免父组件通过 value 控制时被打断。
让我们先查看 src/packages/searchbar/searchbar.tsx 中的组件实现,以确认 defaultValue、outerValue 及其状态管理逻辑:
🏁 Script executed:
#!/bin/bash
sed -n '1,200p' src/packages/searchbar/searchbar.tsxLength of output: 4819
我们先查看 usePropsValue 的实现,以确认它如何处理 value 与 defaultValue:
🏁 Script executed:
#!/bin/bash
rg "usePropsValue" -n srcLength of output: 12844
继续查看 usePropsValue 的完整实现,以确认它如何处理 defaultValue:
🏁 Script executed:
#!/bin/bash
sed -n '1,200p' src/hooks/use-props-value.tsLength of output: 977
🏁 Script executed:
#!/bin/bash
rg "ComponentDefaults" -n srcLength of output: 26793
优化 defaultValue 同步逻辑,避免受控模式被覆盖
当前的 useEffect 在 defaultValue 变化时无条件调用 setValue(defaultValue),会导致组件处于受控(传入 value)时触发多余更新甚至覆盖。建议改为:仅在非受控(outerValue === undefined)且 defaultValue 有效时再同步内部状态。
待修改位置:
- 文件:
src/packages/searchbar/searchbar.tsx - 行号:约 72–75
-useEffect(() => {
- setValue(defaultValue)
-}, [defaultValue])
+useEffect(() => {
+ // 仅在组件非受控且 defaultValue 有效时同步内部状态
+ if (outerValue === undefined && defaultValue !== undefined) {
+ setValue(defaultValue)
+ }
+}, [defaultValue, outerValue])📝 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.
| useEffect(() => { | |
| setValue(defaultValue) | |
| }, [defaultValue]) | |
| useEffect(() => { | |
| // 仅在组件非受控且 defaultValue 有效时同步内部状态 | |
| if (outerValue === undefined && defaultValue !== undefined) { | |
| setValue(defaultValue) | |
| } | |
| }, [defaultValue, outerValue]) |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
src/packages/searchbar/demo.tsx (1)
17-17: 建议完善英文翻译为中文和繁体中文添加了"默认值、受控"的翻译,但英文版本仍使用了中文。
- title10: '默认值、受控', + title10: 'Default Value & Controlled Mode',Also applies to: 27-27, 37-37
src/packages/searchbar/demos/h5/demo10.tsx (1)
15-18: 确保控制台日志在生产环境中被移除在onItemClick回调中包含console.log语句,虽然这在示例中有助于演示,但应确保这类调试代码不会进入生产环境。
onItemClick={(value: string) => { - console.log('click', value) setDvalue('黄瓜') }}src/packages/searchbar/searchbar.tsx (2)
81-97: 优化事件处理函数重命名事件处理函数采用
handle前缀,使命名更规范,同时简化了回调函数的调用方式,提高了代码可读性和维护性。注意:事件处理函数中的可选链判断可以进一步优化。
你可以考虑使用可选链操作符来简化代码:
- const handleChange = (event: ChangeEvent<HTMLInputElement>) => { - const { value } = event.target - onChange && onChange(value, event) - setValue(value) - } + const handleChange = (event: ChangeEvent<HTMLInputElement>) => { + const { value } = event.target + onChange?.(value, event) + setValue(value) + }🧰 Tools
🪛 Biome (1.9.4)
[error] 83-83: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 89-89: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 94-94: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 96-96: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
190-193: 优化清除值函数逻辑简化了条件判断语句,并确保在清除值时调用
onChange回调,保持了组件行为的一致性。注意:这里的
onChange调用也可以使用可选链优化。你可以使用可选链操作符进一步简化代码:
- onChange && onChange('') + onChange?.('')🧰 Tools
🪛 Biome (1.9.4)
[error] 192-192: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 193-193: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
src/packages/searchbar/demo.tsx(3 hunks)src/packages/searchbar/demos/h5/demo1.tsx(1 hunks)src/packages/searchbar/demos/h5/demo10.tsx(1 hunks)src/packages/searchbar/demos/h5/demo3.tsx(1 hunks)src/packages/searchbar/demos/h5/demo5.tsx(1 hunks)src/packages/searchbar/doc.md(3 hunks)src/packages/searchbar/doc.taro.md(3 hunks)src/packages/searchbar/doc.zh-TW.md(2 hunks)src/packages/searchbar/searchbar.scss(2 hunks)src/packages/searchbar/searchbar.tsx(8 hunks)src/sites/sites-react/doc/docs/react/migrate-from-v2.md(1 hunks)src/styles/variables.scss(1 hunks)src/types/spec/searchbar/base.ts(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/packages/searchbar/demos/h5/demo5.tsx (1)
src/packages/calendarcard/icon.taro.tsx (1)
ArrowLeft(44-44)
src/packages/searchbar/demos/h5/demo10.tsx (1)
src/packages/searchbar/searchbar.tsx (1)
SearchBar(25-233)
🪛 LanguageTool
src/packages/searchbar/doc.md
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 | 1px 8px | | --nutui-searchbar-background | 搜索框背景色 | $color-background-sunken |...
(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 | $color-background-sunken | | --nutui-searchbar-color | ...
(GL_BARBARISM_REPLACE)
[locale-violation] ~123-~123: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...| $color-title | | --nutui-searchbar-gap | 搜索框外部/大间距 | 12px | | --nutui-searc...
(GL_BARBARISM_REPLACE)
[locale-violation] ~124-~124: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 | 12px | | --nutui-searchbar-inner-gap | 搜索框内部元素间的间距 | 12px | | --nutui-sea...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ze-base| | \--nutui-searchbar-content-background | 搜索框中间内容区的背景色 |$color-background-ove...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...bar-content-background | 搜索框中间内容区的背景色 | $color-background-overlay | | --nutui-searchbar-content...
(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圆角 | 19px | | --nutui-searchbar-input-height | 搜索框输入区高度 | 38px | | --nutui...
(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框输入区高度 | 38px | | --nutui-searchbar-input-padding | 搜索框输入区padding | 0 0 0 8px |...
(GL_BARBARISM_REPLACE)
[duplication] ~130-~130: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框输入区padding | 0 0 0 8px | | --nutui-searchbar-input-tex...
(WORD_REPETITION)
src/packages/searchbar/doc.zh-TW.md
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 | 1px 8px | | --nutui-searchbar-background | 搜索框背景色 | $color-background-sunken |...
(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 | $color-background-sunken | | --nutui-searchbar-color | ...
(GL_BARBARISM_REPLACE)
[locale-violation] ~123-~123: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...| $color-title | | --nutui-searchbar-gap | 搜索框外部/大間距 | 12px | | --nutui-searc...
(GL_BARBARISM_REPLACE)
[locale-violation] ~124-~124: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 | 12px | | --nutui-searchbar-inner-gap | 搜索框內部元素間的間距 | 12px | | --nutui-sea...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ze-base| | \--nutui-searchbar-content-background | 搜索框中間內容區的背景色 |$color-background-ove...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...bar-content-background | 搜索框中間內容區的背景色 | $color-background-overlay | | --nutui-searchbar-content...
(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圓角 | 19px | | --nutui-searchbar-input-height | 搜索框輸入區高度 | 38px | | --nutui...
(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框輸入區高度 | 38px | | --nutui-searchbar-input-padding | 搜索框輸入區padding | 0 0 0 8px |...
(GL_BARBARISM_REPLACE)
[duplication] ~130-~130: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框輸入區padding | 0 0 0 8px | | --nutui-searchbar-input-tex...
(WORD_REPETITION)
src/packages/searchbar/doc.taro.md
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 | 1px 8px | | --nutui-searchbar-background | 搜索框背景色 | $color-background-sunken |...
(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 | $color-background-sunken | | --nutui-searchbar-color | ...
(GL_BARBARISM_REPLACE)
[locale-violation] ~123-~123: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...| $color-title | | --nutui-searchbar-gap | 搜索框外部/大间距 | 12px | | --nutui-searc...
(GL_BARBARISM_REPLACE)
[locale-violation] ~124-~124: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 | 12px | | --nutui-searchbar-inner-gap | 搜索框内部元素间的间距 | 12px | | --nutui-sea...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ze-base| | \--nutui-searchbar-content-background | 搜索框中间内容区的背景色 |$color-background-ove...
(GL_BARBARISM_REPLACE)
[locale-violation] ~126-~126: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...bar-content-background | 搜索框中间内容区的背景色 | $color-background-overlay | | --nutui-searchbar-content...
(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圆角 | 19px | | --nutui-searchbar-input-height | 搜索框输入区高度 | 38px | | --nutui...
(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框输入区高度 | 38px | | --nutui-searchbar-input-padding | 搜索框输入区padding | 0 0 0 8px |...
(GL_BARBARISM_REPLACE)
[duplication] ~130-~130: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框输入区padding | 0 0 0 8px | | --nutui-searchbar-input-tex...
(WORD_REPETITION)
🪛 Biome (1.9.4)
src/packages/searchbar/searchbar.tsx
[error] 78-78: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 83-83: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 89-89: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 94-94: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 96-96: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 192-192: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (55)
src/styles/variables.scss (4)
1929-1937: 样式间距和背景变量更新搜索栏样式变量更新使组件设计更加精细:
- 边距从
6px 16px调整为1px 8px,创造更紧凑的外观- 背景色从
$color-background更改为$color-background-sunken,提供更好的层次感- 元素间距从
16px减少到12px,使布局更加紧凑- 新增
$searchbar-inner-gap变量,提供内部元素8px的间距控制这些变化使搜索栏在各种界面布局中更加协调和精致。
1947-1952: 圆角半径优化圆角半径的调整使搜索栏外观更加现代化:
- 内容边框圆角从
4px增加到8px- 圆形边框圆角从
18px轻微调整到19px这些微小但重要的调整使组件符合当前设计趋势,提供更柔和的视觉效果。
1953-1958: 新增图标和输入框变量新增了重要的样式变量,提高了组件的一致性和可定制性:
$searchbar-icon-size:标准化图标尺寸为20px$searchbar-input-height:设置输入框高度为38px$searchbar-input-padding:指定输入框内边距为0 0 0 8px这些新变量使开发者能够更容易地保持风格一致,并支持新增的默认值显示功能。
1965-1966: 更新输入光标颜色光标颜色从
$color-title更改为$color-primary,使其与品牌色一致,提高了用户在输入时的视觉反馈。src/packages/searchbar/demos/h5/demo3.tsx (1)
12-12: 主题配置背景色优化将搜索栏内容背景色从
#eee更改为#fff,使其在主题定制示例中更具视觉吸引力,同时展示了组件的可配置性。这种白色背景更好地突出内容,并与整体视觉设计保持一致。src/types/spec/searchbar/base.ts (2)
7-7: 新增 defaultValue 属性添加了
defaultValue字符串属性,支持设置搜索栏的默认值。这提高了组件的灵活性,允许开发者为搜索栏设置初始状态,特别是在需要显示多个默认值的场景下。
26-26: 新增 onItemClick 回调函数添加了
onItemClick回调函数,用于处理点击默认值项的事件。这个回调接收被点击项的值作为参数,使开发者能够实现交互式的默认值管理,例如删除或选择特定项。src/packages/searchbar/demos/h5/demo5.tsx (1)
11-12: 移除图标显式尺寸属性移除了图标组件上的硬编码宽度和高度属性,遵循了更好的实践方式。这使图标可以:
- 通过 CSS 变量自动继承尺寸,支持主题和响应式设计
- 利用新增的
$searchbar-icon-size变量保持一致的尺寸- 减少重复代码并提高维护性
建议确保项目文档中明确说明这些图标现在的尺寸由 CSS 变量控制。
Also applies to: 22-22
src/sites/sites-react/doc/docs/react/migrate-from-v2.md (1)
183-188: 文档更新符合新功能实现这部分文档清晰地说明了SearchBar组件的新增功能,支持受控模式、默认值显示和默认值项的交互处理。文档内容与代码实现保持一致。
src/packages/searchbar/demo.tsx (2)
11-11: 正确导入新的示例组件成功导入了新的Demo10组件,用于展示SearchBar的默认值和受控功能。
52-54: 合理安排示例顺序将默认值和受控示例放在基础用法之后,符合从简单到复杂的示例组织原则,便于用户理解。
src/packages/searchbar/demos/h5/demo10.tsx (4)
1-5: 导入了必要的组件和钩子正确导入了React的useState钩子、图标组件、SearchBar和Button组件,为示例提供了必要的依赖。
6-9: 初始化状态逻辑清晰使用useState钩子分别初始化了defaultValue和value状态,用于演示非受控和受控模式。
11-25: 默认值功能展示完整第一个SearchBar组件展示了新增的defaultValue和onItemClick功能,设置了backable、清除了左侧内容、添加了右侧图标,演示全面。
26-42: 受控模式实现正确第二个SearchBar组件正确实现了受控模式,使用value和onChange配合,同时启用了autoFocus属性和自定义右侧内容,展示了组件的灵活性。
src/packages/searchbar/demos/h5/demo1.tsx (2)
2-4: 添加了必要的图标和分隔符组件导入了Photograph和Scan图标组件以及Divider分隔符组件,增强了基础示例的视觉效果和功能展示。
9-20: 丰富了基础示例的多样性将原先的简单示例扩展为两个不同配置的示例,分别展示了简单文本和复杂布局的右侧内容,以及左侧图标的使用,增强了基础示例的参考价值。
src/packages/searchbar/doc.zh-TW.md (6)
89-90: 文档增加 value 和 defaultValue 属性,清晰地区分受控与非受控用法属性扩展合理,并明确标注了
value为受控方式,同时新增defaultValue支持非受控使用和多个默认值展示,提升了组件的灵活性。
101-101: 简化了 leftIn 属性的默认图标展示将
leftIn属性的默认值从明确指定尺寸的图标简化为<Search />,使代码更简洁,同时保持功能一致性。
109-109: 新增 onItemClick 回调支持默认值点击交互添加
onItemClick事件处理函数,使开发者可以响应用户点击默认值 X 号的操作,增强了组件的交互性。
119-121: 优化搜索框样式变量配置调整了外观相关样式变量,减小了内边距并更新了背景色,使组件更美观紧凑。
🧰 Tools
🪛 LanguageTool
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 |1px 8px| | --nutui-searchbar-background | 搜索框背景色 |$color-background-sunken|...(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 |$color-background-sunken| | --nutui-searchbar-color | ...(GL_BARBARISM_REPLACE)
123-124: 完善间距变量设计增加了内部元素间距变量
inner-gap,同时调整外部间距值,使布局更加合理清晰。🧰 Tools
🪛 LanguageTool
[locale-violation] ~123-~123: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...|$color-title| | --nutui-searchbar-gap | 搜索框外部/大間距 |12px| | --nutui-searc...(GL_BARBARISM_REPLACE)
[locale-violation] ~124-~124: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 |12px| | --nutui-searchbar-inner-gap | 搜索框內部元素間的間距 |12px| | --nutui-sea...(GL_BARBARISM_REPLACE)
127-130: 优化圆角和输入区域尺寸增大了内容区圆角和输入区高度,并调整了输入区的内边距,使组件在视觉上更加现代化且提升了用户体验。
🧰 Tools
🪛 LanguageTool
[locale-violation] ~129-~129: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圓角 |19px| | --nutui-searchbar-input-height | 搜索框輸入區高度 |38px| | --nutui...(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框輸入區高度 |38px| | --nutui-searchbar-input-padding | 搜索框輸入區padding |0 0 0 8px|...(GL_BARBARISM_REPLACE)
[duplication] ~130-~130: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框輸入區padding |0 0 0 8px| | --nutui-searchbar-input-tex...(WORD_REPETITION)
src/packages/searchbar/doc.taro.md (5)
89-90: 完善属性说明,新增 defaultValue 支持文档更新清晰地标明了
value为受控模式,并添加了defaultValue属性支持通过逗号分隔的多个默认值,增强了组件的灵活性。
101-101: 简化 leftIn 属性的默认值将默认搜索图标从特定尺寸简化为
<Search />,使代码更简洁,同时保持了功能一致性。
109-109: 添加 onItemClick 回调提升交互体验新增了
onItemClick事件处理函数,支持用户点击默认值 X 号时的交互,使组件更加完善。
120-124: 调整样式变量提升外观调整了内边距、背景色和间距相关变量,新增了内部元素间距变量,使组件布局更加合理。
🧰 Tools
🪛 LanguageTool
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 |1px 8px| | --nutui-searchbar-background | 搜索框背景色 |$color-background-sunken|...(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 |$color-background-sunken| | --nutui-searchbar-color | ...(GL_BARBARISM_REPLACE)
[locale-violation] ~123-~123: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...|$color-title| | --nutui-searchbar-gap | 搜索框外部/大间距 |12px| | --nutui-searc...(GL_BARBARISM_REPLACE)
[locale-violation] ~124-~124: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 |12px| | --nutui-searchbar-inner-gap | 搜索框内部元素间的间距 |12px| | --nutui-sea...(GL_BARBARISM_REPLACE)
127-130: 优化组件圆角和输入区域增大了内容区圆角值和输入区高度,调整了输入区内边距,使组件视觉效果更加现代化。
🧰 Tools
🪛 LanguageTool
[locale-violation] ~129-~129: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圆角 |19px| | --nutui-searchbar-input-height | 搜索框输入区高度 |38px| | --nutui...(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框输入区高度 |38px| | --nutui-searchbar-input-padding | 搜索框输入区padding |0 0 0 8px|...(GL_BARBARISM_REPLACE)
[duplication] ~130-~130: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框输入区padding |0 0 0 8px| | --nutui-searchbar-input-tex...(WORD_REPETITION)
src/packages/searchbar/doc.md (5)
89-90: 完善属性文档,优化受控和非受控模式说明明确了
value属性为受控模式,并新增defaultValue属性支持多个默认值展示,文档描述清晰准确。
101-101: 简化 leftIn 属性默认图标将默认搜索图标从特定尺寸简化为
<Search />,保持与组件实现一致,提高代码可读性。
109-109: 新增事件处理回调增强组件交互性添加
onItemClick回调函数,使开发者能够响应用户对默认值项的点击操作,增强了组件的功能完整性。
120-124: 优化样式变量定义与默认值调整了内边距、背景色和间距相关变量,新增了内部元素间的间距变量,使组件布局更加合理。
🧰 Tools
🪛 LanguageTool
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 |1px 8px| | --nutui-searchbar-background | 搜索框背景色 |$color-background-sunken|...(GL_BARBARISM_REPLACE)
[locale-violation] ~121-~121: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 |$color-background-sunken| | --nutui-searchbar-color | ...(GL_BARBARISM_REPLACE)
[locale-violation] ~123-~123: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...|$color-title| | --nutui-searchbar-gap | 搜索框外部/大间距 |12px| | --nutui-searc...(GL_BARBARISM_REPLACE)
[locale-violation] ~124-~124: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 |12px| | --nutui-searchbar-inner-gap | 搜索框内部元素间的间距 |12px| | --nutui-sea...(GL_BARBARISM_REPLACE)
127-130: 提升输入区域视觉体验增大了内容区圆角、round 模式下的圆角和输入区高度,调整了输入区内边距,使组件外观更加现代美观。
🧰 Tools
🪛 LanguageTool
[locale-violation] ~129-~129: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圆角 |19px| | --nutui-searchbar-input-height | 搜索框输入区高度 |38px| | --nutui...(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框输入区高度 |38px| | --nutui-searchbar-input-padding | 搜索框输入区padding |0 0 0 8px|...(GL_BARBARISM_REPLACE)
[duplication] ~130-~130: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框输入区padding |0 0 0 8px| | --nutui-searchbar-input-tex...(WORD_REPETITION)
src/packages/searchbar/searchbar.scss (8)
12-16: 统一设置图标尺寸样式为图标组件添加了统一的尺寸样式,确保所有图标在组件中保持一致的大小,提升了组件视觉的一致性。
19-28: 优化内容区域样式为内容区添加了相对定位,更新了内边距设置,并添加了主色边框,使搜索框在视觉上更加突出且美观。
31-36: 更新图标颜色为主题色调整图标颜色使用主题主色,增强了组件的视觉识别性和与整体设计的一致性。
38-50: 优化左右内部区域样式更新了左侧图标的右边距和右侧元素的字体样式,添加了对嵌套图标颜色的特殊处理,使布局更加平衡。
52-71: 重构输入框样式使用 flex 布局优化了输入框容器和输入元素,设置了透明背景、边框清除和统一文本颜色,提升了用户输入体验。
73-80: 优化清除按钮样式调整了清除按钮的尺寸和颜色,添加了右侧间距,使其更加协调地融入整体设计。
82-105: 新增默认值项展示容器样式添加了展示默认值的容器样式,支持多个默认值的水平排列显示,每个值项都有独立的背景色和圆角,同时设置了关闭图标的合适样式,增强了组件的功能性和视觉表现。
175-181: 增加焦点状态样式新增了搜索框焦点状态的样式,调整内边距并使用特殊边框色突出显示,提高了用户操作的视觉反馈。
src/packages/searchbar/searchbar.tsx (14)
2-8: 优化导入和依赖关系调整了组件的依赖导入,引入
classNames工具和usePropsValue钩子,为支持受控与非受控模式提供基础。同时简化了图标组件的导入。
23-23: 简化默认图标配置将默认搜索图标简化为
<Search />,移除了不必要的尺寸属性,使代码更加简洁。
35-35: 提升引用命名的语义化将
searchRef重命名为searchInputRef,更准确地反映了引用的用途,提高了代码可读性。
39-40: 扩展组件 Props 支持新特性添加了
defaultValue和onItemClick属性,为支持默认值展示和交互提供了接口,增强了组件的功能性。Also applies to: 60-60
66-70: 使用 usePropsValue 重构状态管理用
usePropsValue钩子替代原有的useState,更好地处理受控与非受控状态,提升了组件状态管理的稳定性和一致性。
72-74: 增加 defaultValue 变更同步添加对
defaultValue属性变更的监听,确保当默认值更新时组件状态能够正确同步,增强了组件的可靠性。
104-104: 使用 classNames 优化类名处理采用
classNames库处理条件类名,使类名逻辑更加清晰和统一,提高了代码可维护性。
115-118: 更新事件绑定命名将事件处理函数的绑定更新为新的命名方式,保持代码一致性。
123-139: 实现默认值渲染功能新增
renderDefaultValue方法,支持将逗号分隔的默认值转换为可点击的标签列表展示,并通过onItemClick回调处理点击删除操作,显著增强了组件的功能和用户体验。
153-153: 简化返回按钮图标移除了箭头图标的明确尺寸参数,使用默认尺寸设置,保持与整体风格一致。
161-169: 优化右侧内容渲染逻辑增强了
renderRightIn方法,根据内容类型条件性地应用图标样式类,使组件能够更灵活地处理不同类型的右侧内容。
178-178: 函数命名更符合功能语义将
handleClear重命名为renderClear,更准确地反映了该函数的渲染功能,提高了代码可读性。
207-214: 使用 classNames 统一根元素类名处理应用
classNames库处理根元素的条件类名,包括禁用和焦点状态,使类名管理更加清晰和一致。
217-228: 优化渲染逻辑更新了组件根元素类名应用方式,并改进了内容区域的条件类名处理。添加了对默认值渲染的条件判断,使清除按钮和默认值不会同时显示,提升了用户界面的清晰度。
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (4)
src/packages/searchbar/searchbar.tsx (2)
71-74: 💥defaultValue的副作用仍会覆盖受控模式
useEffect在defaultValue变化时无条件执行setValue(defaultValue),若外部通过value受控驱动组件,将被意外篡改。此前已反馈过同样问题,仍未修复。建议仅在组件处于非受控状态时同步defaultValue。-useEffect(() => { - setValue(defaultValue) -}, [defaultValue]) +useEffect(() => { + // 仅在非受控(outerValue 未定义)且 defaultValue 有效时同步 + if (outerValue === undefined && defaultValue !== undefined) { + setValue(defaultValue) + } +}, [defaultValue, outerValue])
124-131: 🔗onItemClick仍缺少可选链保护
点击默认值标签时直接调用onItemClick(item),当父组件未传该回调会抛异常。此前已留下同样评论,建议改为可选链调用。- onClick={() => onItemClick(item)} + onClick={() => onItemClick?.(item)}src/packages/searchbar/searchbar.taro.tsx (2)
78-81: 💥defaultValue同步逻辑仍会覆盖受控值
与 web 版相同的问题:受控场景下会被defaultValue强行覆盖。-useEffect(() => { - setValue(defaultValue) -}, [defaultValue]) +useEffect(() => { + if (outerValue === undefined && defaultValue !== undefined) { + setValue(defaultValue) + } +}, [defaultValue, outerValue])
133-141: 🔗onItemClick缺少可选链保护
Taro 版本亦存在同样风险,需改为onItemClick?.(item)。- onClick={() => onItemClick(item)} + onClick={() => onItemClick?.(item)}
🧹 Nitpick comments (5)
src/packages/searchbar/demos/h5/demo10.tsx (1)
11-42: 第一个搜索栏实现了默认值与受控值的协同工作这个搜索栏展示了:
- 如何使用
defaultValue属性展示多个默认值- 如何通过
onItemClick处理默认值的删除- 如何在聚焦时将默认值转移到输入框
- 如何自定义右侧内容
实现了完整的默认值与受控值的交互流程。
但有两处可以优化:
- 移除调试用的 console.log 语句
- 考虑优化默认值处理逻辑,可以提取为单独的函数提高代码可读性
- onItemClick={(value: string) => { - console.log('click', value) - if (dvalue) { - const arr = dvalue.split(',') - const newArr = arr.filter((item: string) => item !== value) - const newVal = newArr.length > 1 ? newArr.join(',') : newArr[0] - setValue1(newVal) - setDvalue(newVal) - } - }} - onFocus={() => { - console.log('focus dvalue', dvalue) - if (dvalue) { - setValue1(dvalue) - setDvalue('') - } - }} + onItemClick={handleItemClick} + onFocus={handleFocus}并在组件上方添加处理函数:
const handleItemClick = (value: string) => { if (dvalue) { const arr = dvalue.split(',') const newArr = arr.filter((item: string) => item !== value) const newVal = newArr.length > 1 ? newArr.join(',') : newArr[0] setValue1(newVal) setDvalue(newVal) } } const handleFocus = () => { if (dvalue) { setValue1(dvalue) setDvalue('') } }src/packages/searchbar/demos/taro/demo10.tsx (2)
37-42: 右侧图标布局有待优化在第一个SearchBar的
rightIn和right属性中,同时使用了图标,但布局上可能存在重叠或紧凑的问题。建议考虑添加适当的间距或只保留一个位置的图标。- rightIn={ - <div style={{ display: 'flex', alignItems: 'center' }}> - <Photograph color="#505259" /> - </div> - } - right={<Category />} + rightIn={ + <div style={{ display: 'flex', alignItems: 'center' }}> + <Photograph color="#505259" style={{ marginRight: '8px' }} /> + </div> + } + right={<Category style={{ marginLeft: '8px' }} />}
16-25: 默认值删除逻辑可优化在
onItemClick处理函数中,当数组长度为1时的处理逻辑可以更简洁。当只有一个元素时,直接使用该元素而不是创建只有一个元素的数组会更高效。- const newVal = newArr.length > 1 ? newArr.join(',') : newArr[0] + const newVal = newArr.length > 0 ? (newArr.length > 1 ? newArr.join(',') : newArr[0]) : ''这样修改后,也处理了数组为空的情况,使逻辑更加健壮。
src/packages/searchbar/searchbar.tsx (1)
75-78: ✨ 使用可选链简化空引用判断
searchSelf && searchSelf.focus()/blur()可改为searchInputRef.current?.focus()等写法,减少布尔运算并符合 Biome 建议。- const searchSelf: HTMLInputElement | null = searchInputRef.current - searchSelf && searchSelf.focus() + searchInputRef.current?.focus()同理可应用于
blur()处。Also applies to: 91-93
🧰 Tools
🪛 Biome (1.9.4)
[error] 77-77: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/packages/searchbar/searchbar.taro.tsx (1)
82-85: ✨ 使用可选链优化 Ref 调用
可按照 Biome 建议改为searchInputRef.current?.focus()/blur()。- const searchSelf: HTMLInputElement | null = searchInputRef.current - searchSelf && searchSelf.focus() + searchInputRef.current?.focus()Also applies to: 101-103
🧰 Tools
🪛 Biome (1.9.4)
[error] 84-84: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (20)
src/packages/searchbar/demo.taro.tsx(4 hunks)src/packages/searchbar/demo.tsx(3 hunks)src/packages/searchbar/demos/h5/demo1.tsx(1 hunks)src/packages/searchbar/demos/h5/demo10.tsx(1 hunks)src/packages/searchbar/demos/h5/demo2.tsx(1 hunks)src/packages/searchbar/demos/h5/demo3.tsx(1 hunks)src/packages/searchbar/demos/h5/demo4.tsx(1 hunks)src/packages/searchbar/demos/h5/demo5.tsx(1 hunks)src/packages/searchbar/demos/h5/demo6.tsx(3 hunks)src/packages/searchbar/demos/h5/demo7.tsx(1 hunks)src/packages/searchbar/demos/taro/demo1.tsx(1 hunks)src/packages/searchbar/demos/taro/demo10.tsx(1 hunks)src/packages/searchbar/doc.en-US.md(1 hunks)src/packages/searchbar/doc.md(4 hunks)src/packages/searchbar/doc.taro.md(4 hunks)src/packages/searchbar/doc.zh-TW.md(3 hunks)src/packages/searchbar/searchbar.scss(2 hunks)src/packages/searchbar/searchbar.taro.tsx(5 hunks)src/packages/searchbar/searchbar.tsx(8 hunks)src/sites/sites-react/doc/docs/taro/migrate-from-v2.md(1 hunks)
✅ Files skipped from review due to trivial changes (5)
- src/packages/searchbar/demos/h5/demo7.tsx
- src/packages/searchbar/demos/h5/demo2.tsx
- src/packages/searchbar/demos/h5/demo6.tsx
- src/packages/searchbar/demos/h5/demo4.tsx
- src/packages/searchbar/doc.en-US.md
🚧 Files skipped from review as they are similar to previous changes (5)
- src/packages/searchbar/demos/h5/demo3.tsx
- src/packages/searchbar/demo.tsx
- src/packages/searchbar/demos/h5/demo5.tsx
- src/packages/searchbar/demos/h5/demo1.tsx
- src/packages/searchbar/searchbar.scss
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/packages/searchbar/demos/taro/demo1.tsx (2)
src/packages/searchbar/searchbar.taro.tsx (1)
SearchBar(32-231)src/packages/searchbar/searchbar.tsx (1)
SearchBar(25-230)
src/packages/searchbar/demos/h5/demo10.tsx (1)
src/packages/searchbar/searchbar.tsx (1)
SearchBar(25-230)
src/packages/searchbar/demos/taro/demo10.tsx (1)
src/packages/searchbar/searchbar.taro.tsx (1)
SearchBar(32-231)
src/packages/searchbar/searchbar.tsx (2)
src/hooks/use-props-value.ts (1)
usePropsValue(11-35)src/packages/calendarcard/icon.taro.tsx (1)
ArrowLeft(44-44)
🪛 Biome (1.9.4)
src/packages/searchbar/searchbar.taro.tsx
[error] 84-84: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 89-89: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 96-96: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 102-102: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 103-103: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 197-197: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 198-198: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 201-201: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/packages/searchbar/searchbar.tsx
[error] 77-77: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 82-82: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 87-87: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 92-92: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 93-93: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 189-189: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🪛 LanguageTool
src/packages/searchbar/doc.md
[locale-violation] ~127-~127: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 | 1px 8px | | --nutui-searchbar-background | 搜索框背景色 | $color-background-sunken |...
(GL_BARBARISM_REPLACE)
[locale-violation] ~127-~127: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 | $color-background-sunken | | --nutui-searchbar-color | ...
(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...| $color-title | | --nutui-searchbar-gap | 搜索框外部/大间距 | 12px | | --nutui-searc...
(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 | 12px | | --nutui-searchbar-inner-gap | 搜索框内部元素间的间距 | 12px | | --nutui-sea...
(GL_BARBARISM_REPLACE)
[locale-violation] ~132-~132: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ze-base| | \--nutui-searchbar-content-background | 搜索框中间内容区的背景色 |$color-background-ove...
(GL_BARBARISM_REPLACE)
[locale-violation] ~132-~132: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...bar-content-background | 搜索框中间内容区的背景色 | $color-background-overlay | | --nutui-searchbar-content...
(GL_BARBARISM_REPLACE)
[locale-violation] ~135-~135: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圆角 | 19px | | --nutui-searchbar-input-height | 搜索框输入区高度 | 38px | | --nutui...
(GL_BARBARISM_REPLACE)
[locale-violation] ~136-~136: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框输入区高度 | 38px | | --nutui-searchbar-input-padding | 搜索框输入区padding | 0 0 0 8px |...
(GL_BARBARISM_REPLACE)
[duplication] ~136-~136: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框输入区padding | 0 0 0 8px | | --nutui-searchbar-input-tex...
(WORD_REPETITION)
src/packages/searchbar/doc.taro.md
[locale-violation] ~129-~129: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 | 1px 8px | | --nutui-searchbar-background | 搜索框背景色 | $color-background-sunken |...
(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 | $color-background-sunken | | --nutui-searchbar-color | ...
(GL_BARBARISM_REPLACE)
[locale-violation] ~131-~131: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...| $color-title | | --nutui-searchbar-gap | 搜索框外部/大间距 | 12px | | --nutui-searc...
(GL_BARBARISM_REPLACE)
[locale-violation] ~132-~132: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 | 12px | | --nutui-searchbar-inner-gap | 搜索框内部元素间的间距 | 12px | | --nutui-sea...
(GL_BARBARISM_REPLACE)
[locale-violation] ~134-~134: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ze-base| | \--nutui-searchbar-content-background | 搜索框中间内容区的背景色 |$color-background-ove...
(GL_BARBARISM_REPLACE)
[locale-violation] ~134-~134: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...bar-content-background | 搜索框中间内容区的背景色 | $color-background-overlay | | --nutui-searchbar-content...
(GL_BARBARISM_REPLACE)
[locale-violation] ~137-~137: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圆角 | 19px | | --nutui-searchbar-input-height | 搜索框输入区高度 | 38px | | --nutui...
(GL_BARBARISM_REPLACE)
[locale-violation] ~138-~138: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框输入区高度 | 38px | | --nutui-searchbar-input-padding | 搜索框输入区padding | 0 0 0 8px |...
(GL_BARBARISM_REPLACE)
[duplication] ~138-~138: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框输入区padding | 0 0 0 8px | | --nutui-searchbar-input-tex...
(WORD_REPETITION)
src/packages/searchbar/doc.zh-TW.md
[locale-violation] ~129-~129: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 | 1px 8px | | --nutui-searchbar-background | 搜索框背景色 | $color-background-sunken |...
(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 | $color-background-sunken | | --nutui-searchbar-color | ...
(GL_BARBARISM_REPLACE)
[locale-violation] ~131-~131: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...| $color-title | | --nutui-searchbar-gap | 搜索框外部/大間距 | 12px | | --nutui-searc...
(GL_BARBARISM_REPLACE)
[locale-violation] ~132-~132: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 | 12px | | --nutui-searchbar-inner-gap | 搜索框內部元素間的間距 | 12px | | --nutui-sea...
(GL_BARBARISM_REPLACE)
[locale-violation] ~134-~134: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ze-base| | \--nutui-searchbar-content-background | 搜索框中間內容區的背景色 |$color-background-ove...
(GL_BARBARISM_REPLACE)
[locale-violation] ~134-~134: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...bar-content-background | 搜索框中間內容區的背景色 | $color-background-overlay | | --nutui-searchbar-content...
(GL_BARBARISM_REPLACE)
[locale-violation] ~137-~137: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圓角 | 19px | | --nutui-searchbar-input-height | 搜索框輸入區高度 | 38px | | --nutui...
(GL_BARBARISM_REPLACE)
[locale-violation] ~138-~138: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框輸入區高度 | 38px | | --nutui-searchbar-input-padding | 搜索框輸入區padding | 0 0 0 8px |...
(GL_BARBARISM_REPLACE)
[duplication] ~138-~138: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框輸入區padding | 0 0 0 8px | | --nutui-searchbar-input-tex...
(WORD_REPETITION)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (27)
src/packages/searchbar/demos/taro/demo1.tsx (3)
2-3: 导入了新组件以支持增强的搜索栏功能代码正确导入了
Divider组件和图标组件Photograph和Scan,这些是展示增强型搜索栏所必需的。
8-19: 搜索栏示例增强,展示了多种配置方式代码展示了两种搜索栏的实现方式:
- 简单搜索栏:带有文本右侧内容
- 高级搜索栏:带有左侧扫描图标和复杂的右侧内容(包含拍照图标、分隔线和彩色文本)
这很好地展示了组件的灵活性和自定义能力,与PR的目标一致。
14-17: 右侧内容区域布局良好右侧区域使用了 flex 布局并正确对齐了元素,添加了点击事件处理器,并使用分隔线和样式化文本增强了视觉效果。
src/packages/searchbar/demo.taro.tsx (3)
15-15: 新增了展示默认值和受控功能的演示组件这里正确导入了新的演示组件,用于展示 SearchBar 组件的新功能。
21-21: 为新功能添加了多语言支持代码为新增的"默认值、受控"功能添加了中文简体、中文繁体和英文的翻译,保持了国际化的一致性。
Also applies to: 31-31, 41-41
57-58: 在演示页面中恰当位置添加了新组件代码在适当位置添加了 Demo10 组件及其标题,使其成为搜索栏演示的一部分,维持了良好的用户体验和功能展示流程。
src/sites/sites-react/doc/docs/taro/migrate-from-v2.md (1)
182-187: 完善了 SearchBar 组件的文档说明文档清晰地介绍了 SearchBar 组件的新功能:
- 明确声明了
value属性支持受控模式- 新增了
defaultValue属性,支持以逗号分隔的字符串设置多个默认值- 新增了
onItemClick属性,用于处理点击默认值项的删除操作这些文档更新与PR目标一致,为开发者提供了清晰的组件使用指南。
src/packages/searchbar/demos/h5/demo10.tsx (3)
1-4: 导入必要组件和图标代码正确导入了所需的组件和图标,为演示做好了准备。
6-8: 状态管理设置为演示受控模式和默认值功能设置了三个状态变量:
dvalue:用于管理默认值value:用于第二个搜索栏的受控值value1:用于第一个搜索栏的受控值状态设计合理,可以演示完整的功能流程。
43-59: 第二个搜索栏展示了基础受控模式第二个搜索栏展示了:
- 基本受控输入
- 自动聚焦功能
- 更复杂的右侧内容(图标+按钮组合)
实现恰当,提供了不同于第一个搜索栏的使用场景和UI样式。
src/packages/searchbar/doc.zh-TW.md (6)
23-29: 已添加默认值和受控模式的新示例 - 这很好!新添加的示例展示了SearchBar组件的两个新功能:默认值和受控模式。这能帮助开发者更好地理解如何使用这些新特性。
97-98: 属性描述清晰明确对
value属性明确标记为"受控",并添加了新的defaultValue属性,支持通过逗号分割显示多个默认值,这样的文档描述非常清晰。
117-117: 新增事件处理器描述准确
onItemClick事件处理器的描述准确表明了其用途:当用户点击默认值的关闭图标时触发,这与新增的默认值功能相匹配。
128-129: 样式变量更新合理更新的padding值和背景色变量使搜索框样式更加现代化和一致,符合整体设计风格。
🧰 Tools
🪛 LanguageTool
[locale-violation] ~129-~129: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 |1px 8px| | --nutui-searchbar-background | 搜索框背景色 |$color-background-sunken|...(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 |$color-background-sunken| | --nutui-searchbar-color | ...(GL_BARBARISM_REPLACE)
131-132: 新增内部间距变量,优化布局新增的
inner-gap变量有助于统一组件内部元素间的间距,提高了组件布局的一致性。🧰 Tools
🪛 LanguageTool
[locale-violation] ~131-~131: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...|$color-title| | --nutui-searchbar-gap | 搜索框外部/大間距 |12px| | --nutui-searc...(GL_BARBARISM_REPLACE)
[locale-violation] ~132-~132: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 |12px| | --nutui-searchbar-inner-gap | 搜索框內部元素間的間距 |12px| | --nutui-sea...(GL_BARBARISM_REPLACE)
135-138: 输入区样式优化合理圆角、高度和内边距的调整使组件更加美观,同时保持了良好的用户体验。不同模式下(方形/圆形)的圆角差异设置也很合理。
🧰 Tools
🪛 LanguageTool
[locale-violation] ~137-~137: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...d模式下的圓角 |19px| | --nutui-searchbar-input-height | 搜索框輸入區高度 |38px| | --nutui...(GL_BARBARISM_REPLACE)
[locale-violation] ~138-~138: 'input' é un xenismo. É preferíbel dicir "entrada"
Context: ...索框輸入區高度 |38px| | --nutui-searchbar-input-padding | 搜索框輸入區padding |0 0 0 8px|...(GL_BARBARISM_REPLACE)
[duplication] ~138-~138: Posíbel erro tipográfico: hai unha palabra repetida.
Context: ...archbar-input-padding | 搜索框輸入區padding |0 0 0 8px| | --nutui-searchbar-input-tex...(WORD_REPETITION)
src/packages/searchbar/doc.taro.md (4)
23-29: 新增默认值和受控模式示例,增强文档完整性新增的示例部分清晰展示了SearchBar组件的新特性,帮助Taro用户快速理解如何使用这些功能。
97-98: 属性描述准确清晰明确标注了
value为受控属性,并添加了defaultValue属性说明,支持通过逗号分割成多个默认值,文档描述非常准确。
117-117: 事件回调函数描述准确
onItemClick回调函数的描述清晰表达了其功能:当用户点击默认值的关闭按钮时触发,与新增的默认值功能完美配合。
128-129: 样式变量更新合理一致调整后的样式变量(padding、背景色、间距、圆角、高度等)使组件在Taro环境中呈现出更现代、更一致的外观,提升了用户体验。
Also applies to: 131-132, 135-138
🧰 Tools
🪛 LanguageTool
[locale-violation] ~129-~129: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 |1px 8px| | --nutui-searchbar-background | 搜索框背景色 |$color-background-sunken|...(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 |$color-background-sunken| | --nutui-searchbar-color | ...(GL_BARBARISM_REPLACE)
src/packages/searchbar/doc.md (4)
21-27: 新增默认值和受控模式示例,文档更加完善新增的示例部分有效展示了SearchBar组件的新特性,使开发者能够直观了解如何使用默认值和受控模式功能。
95-96: 属性描述清晰明确对
value明确标注为受控属性,并新增defaultValue属性描述,支持通过逗号分割成多个默认值,文档表述准确清晰。
115-115: 事件处理器描述准确
onItemClick事件处理器的描述清晰表明了其用途:当用户点击默认值项的关闭图标时触发,与新增的默认值功能逻辑一致。
126-130: 样式变量更新合理对各种样式变量(padding、背景色、间距、圆角、高度等)的调整使组件呈现出更现代、更一致的外观,同时保持了良好的用户体验。
Also applies to: 133-136
🧰 Tools
🪛 LanguageTool
[locale-violation] ~127-~127: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...ing值 |1px 8px| | --nutui-searchbar-background | 搜索框背景色 |$color-background-sunken|...(GL_BARBARISM_REPLACE)
[locale-violation] ~127-~127: 'background' é un xenismo. É preferíbel dicir "formación de base"
Context: ...--nutui-searchbar-background | 搜索框背景色 |$color-background-sunken| | --nutui-searchbar-color | ...(GL_BARBARISM_REPLACE)
[locale-violation] ~129-~129: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...|$color-title| | --nutui-searchbar-gap | 搜索框外部/大间距 |12px| | --nutui-searc...(GL_BARBARISM_REPLACE)
[locale-violation] ~130-~130: 'gap' é un xenismo. É preferíbel dicir "hiato"
Context: ...距 |12px| | --nutui-searchbar-inner-gap | 搜索框内部元素间的间距 |12px| | --nutui-sea...(GL_BARBARISM_REPLACE)
src/packages/searchbar/demos/taro/demo10.tsx (3)
1-9: 状态管理设计合理组件使用了三个状态变量来管理不同场景:
dvalue用于默认值,value和value1用于受控输入,这种设计清晰展示了组件的两种使用模式。
11-32: 默认值处理逻辑完善第一个SearchBar组件展示了
defaultValue和onItemClick的使用方式。当焦点进入搜索框时,将默认值转移到受控值中并清空默认值,这是一种合理的交互设计。
onItemClick的实现也很完善,能够正确从默认值列表中移除被点击的项,并更新状态。
43-59: 受控组件示例实现良好第二个SearchBar组件展示了受控模式的使用,
autoFocus属性和右侧搜索按钮的组合提供了良好的用户体验。右侧内容的样式设置也很合理,使用flex布局使元素垂直居中对齐。
src/packages/searchbar/searchbar.tsx
Outdated
| const clearaVal = (event: MouseEvent<HTMLDivElement>) => { | ||
| if (disabled || readOnly) { | ||
| return | ||
| } | ||
| if (disabled || readOnly) return | ||
| setValue('') | ||
| onChange && onChange?.('') | ||
| onChange && onChange('') | ||
| onClear && onClear(event) |
There was a problem hiding this comment.
🚨 clearaVal 调用 onChange 参数缺失
onChange 在其他位置期望 (value, event) 两个参数,这里仅传递了 '',会造成类型不一致或信息丢失。
- onChange && onChange('')
+ onChange?.('', event)📝 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.
| const clearaVal = (event: MouseEvent<HTMLDivElement>) => { | |
| if (disabled || readOnly) { | |
| return | |
| } | |
| if (disabled || readOnly) return | |
| setValue('') | |
| onChange && onChange?.('') | |
| onChange && onChange('') | |
| onClear && onClear(event) | |
| const clearaVal = (event: MouseEvent<HTMLDivElement>) => { | |
| if (disabled || readOnly) return | |
| setValue('') | |
| onChange?.('', event) | |
| onClear && onClear(event) | |
| } |
🧰 Tools
🪛 Biome (1.9.4)
[error] 189-189: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 190-190: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
| if (disabled || readOnly) return | ||
| setValue('') | ||
| forceFocus() | ||
| onChange && onChange?.('') | ||
| onChange && onChange('') | ||
| onClear && onClear(event) |
There was a problem hiding this comment.
🚨 清空回调参数不完整
仅向 onChange 传入空字符串,遗漏事件对象。
- onChange && onChange('')
+ onChange?.('', event)🧰 Tools
🪛 Biome (1.9.4)
[error] 197-197: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 198-198: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feat_v3.x #3209 +/- ##
=============================================
+ Coverage 86.54% 86.62% +0.08%
=============================================
Files 289 289
Lines 18739 18807 +68
Branches 2822 2830 +8
=============================================
+ Hits 16217 16292 +75
+ Misses 2517 2510 -7
Partials 5 5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (3)
src/packages/searchbar/searchbar.tsx (3)
71-73:⚠️ Potential issuedefaultValue 同步逻辑需要优化以避免破坏受控模式
当前的 useEffect 在 defaultValue 变化时无条件调用
setValue(defaultValue),会导致组件处于受控(传入value)时被意外覆盖。-useEffect(() => { - setValue(defaultValue) -}, [defaultValue]) +useEffect(() => { + // 仅在组件非受控且 defaultValue 有效时同步内部状态 + if (outerValue === undefined && defaultValue !== undefined) { + setValue(defaultValue) + } +}, [defaultValue, outerValue])
120-136:⚠️ Potential issueonItemClick 调用需做可选链保护
当前直接调用
onItemClick(item),当父组件未传该回调时会抛出运行时异常。-onClick={() => onItemClick(item)} +onClick={() => onItemClick?.(item)}
187-191:⚠️ Potential issueclearaVal 调用 onChange 参数缺失
onChange在其他位置期望接收(value, event)两个参数,这里仅传递了空字符串,会导致类型不一致或信息丢失。-onChange && onChange('') +onChange?.('', event)🧰 Tools
🪛 Biome (1.9.4)
[error] 190-191: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🧹 Nitpick comments (3)
src/packages/searchbar/searchbar.tsx (3)
80-84: handleChange 函数可以使用可选链使用可选链可以使代码更简洁并避免潜在的错误。
-onChange && onChange(value, event) +onChange?.(value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 82-82: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
87-87: handleFocus 函数使用冗余的可选链
event?.target?.value中使用了多个可选链,但上下文中 event 一定存在,可以简化。-onFocus && onFocus(event?.target?.value, event) +onFocus?.(event.target.value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 87-87: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
92-94: handleBlur 函数也有类似问题同上,可以简化可选链的使用。
-searchSelf && searchSelf.blur() -onBlur && onBlur(event?.target?.value, event) +searchSelf?.blur() +onBlur?.(event.target.value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 92-92: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 93-93: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/packages/searchbar/__tests__/searchbar.spec.tsx(1 hunks)src/packages/searchbar/searchbar.tsx(7 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/packages/searchbar/searchbar.tsx
[error] 77-77: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 82-82: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 87-87: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 92-92: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 93-93: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (6)
src/packages/searchbar/__tests__/searchbar.spec.tsx (3)
29-33: 测试用例覆盖了新增的默认值功能测试用例正确验证了新增的
defaultValue属性,确保组件能够正确渲染默认值标签。
35-42: rightIn 属性测试完善测试用例很好地覆盖了 rightIn 属性的两种使用场景:字符串和 React 元素。这与组件实现中对 rightIn 渲染逻辑的增强相匹配。
44-89: 事件处理测试完善且全面该测试用例全面覆盖了组件的各种交互场景,包括受控输入、焦点变化、按钮点击等。使用
waitFor确保异步状态更新后的断言有效。使用 Demo 组件模拟受控场景的测试方法非常合适,能够真实反映用户使用场景。
src/packages/searchbar/searchbar.tsx (3)
65-69: 使用 usePropsValue 增强受控与非受控逻辑使用
usePropsValue代替原有的useState是个很好的改进,这样能够更好地处理受控与非受控组件场景。
155-167: renderRightIn 函数优化合理使用
React.isValidElement检查是合理的,这样可以根据不同类型的 rightIn 提供适当的渲染方式。
224-226: 条件渲染逻辑清晰优化根据是否存在 defaultValue 决定是否显示清除按钮的逻辑非常合理。只在没有默认值且有输入内容时才显示清除按钮,可以避免界面元素过多造成混乱。
| }) | ||
|
|
||
| useEffect(() => { | ||
| setValue(defaultValue) |
There was a problem hiding this comment.
defaultValue一般作为非受控的属性名,这里似乎不应该监听defaultValue的变化来更新状态
There was a problem hiding this comment.
原定于通过默认值控制,后增加 tag 标识处理。已fixed
|
|
||
| useEffect(() => { | ||
| setValue(defaultValue) | ||
| }, [defaultValue]) |
There was a problem hiding this comment.
原定于通过默认值控制,后增加 tag 标识处理。已fixed
|
带 tag 的搜索框,获得焦点的时候,把分割符号去掉? |
|
更多选项无法展开 |
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
src/packages/searchbar/searchbar.tsx (1)
183-189:⚠️ Potential issue问题:
clearaVal中onChange调用参数缺失在清空输入框时,
onChange回调只传递了空字符串,但缺少了事件对象,这与其他地方的调用模式不一致。- onChange && onChange('') + onChange?.('', event)🧰 Tools
🪛 Biome (1.9.4)
[error] 186-187: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 187-188: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/packages/searchbar/searchbar.taro.tsx (1)
193-193:⚠️ Potential issue问题:
clearaVal中onChange调用参数缺失
onChange回调在其他地方传递了两个参数(值和事件),但这里只传递了空字符串,导致参数不一致。- onChange && onChange('') + onChange?.('', event)🧰 Tools
🪛 Biome (1.9.4)
[error] 193-193: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🧹 Nitpick comments (7)
src/packages/searchbar/searchbar.tsx (4)
76-80: 建议:使用可选链操作符当前的回调调用方式存在潜在风险,当
onChange未定义时可能导致错误。- onChange && onChange(value, event) + onChange?.(value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 78-78: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
83-83: 建议:使用可选链操作符简化访问使用可选链操作符可以简化条件检查逻辑。
- onFocus && onFocus(event?.target?.value, event) + onFocus?.(event?.target?.value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 83-83: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
89-89: 建议:使用可选链操作符与前面类似,使用可选链操作符提高代码健壮性。
- onBlur && onBlur(event?.target?.value, event) + onBlur?.(event?.target?.value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 89-89: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
175-175: 问题:clearaVal事件处理函数需要类型
onClick={clearaVal}直接传递函数而不指定事件参数,可能会导致类型不匹配的问题。- onClick={clearaVal} + onClick={(event) => clearaVal(event)}src/packages/searchbar/searchbar.taro.tsx (3)
85-85: 建议:使用可选链操作符处理回调时应使用可选链以提高代码健壮性。
- onChange && onChange(eventValue, event) + onChange?.(eventValue, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 85-85: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
92-92: 建议:使用可选链操作符同样,处理
onFocus回调时也应使用可选链。- onFocus && onFocus(event?.detail?.value, event) + onFocus?.(event?.detail?.value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 92-92: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
99-99: 建议:使用可选链操作符处理
onBlur回调时也应使用可选链。- onBlur && onBlur(event?.detail?.value, event) + onBlur?.(event?.detail?.value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 99-99: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/packages/searchbar/searchbar.taro.tsx(5 hunks)src/packages/searchbar/searchbar.tsx(7 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/packages/searchbar/searchbar.tsx (2)
src/hooks/use-props-value.ts (1)
usePropsValue(11-35)src/packages/calendarcard/icon.taro.tsx (1)
ArrowLeft(44-44)
src/packages/searchbar/searchbar.taro.tsx (2)
src/hooks/use-props-value.ts (1)
usePropsValue(11-35)src/packages/calendarcard/icon.taro.tsx (1)
ArrowLeft(44-44)
🪛 Biome (1.9.4)
src/packages/searchbar/searchbar.tsx
[error] 73-73: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 78-78: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 83-83: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 88-88: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 89-89: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/packages/searchbar/searchbar.taro.tsx
[error] 80-80: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 85-85: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 92-92: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 98-98: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 99-99: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 193-193: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 194-194: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 197-197: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (9)
src/packages/searchbar/searchbar.tsx (5)
65-69: 改进:使用 usePropsValue 提升组件状态管理通过引入
usePropsValue钩子替代原有的useState,大幅提升了组件的受控和非受控模式兼容性。这种方式能够自动处理value和defaultValue之间的关系,使组件更加符合 React 最佳实践。
116-132: 很好的实现:默认值标签展示功能新增的默认值展示功能实现得很好,提供了清晰的用户界面元素来显示和管理默认值。特别是:
- 使用逗号分隔多个默认值
- 为每个标签添加关闭图标
- 实现了点击删除功能
在实际应用中,这个功能可以提供更好的搜索体验。
124-124: 问题:onItemClick回调需要可选链保护当
onItemClick未定义时,当前的直接调用方式会导致运行时错误。- onClick={() => onItemClick?.(item)} + onClick={() => onItemClick?.(item)}这里已经使用了可选链,很好。这样既保持类型提示,又确保在非受控场景下组件稳定运行。
154-162: 改进:优化右侧元素渲染逻辑根据元素类型渲染不同的结构是一个很好的改进,这使得组件更加灵活,能够处理更多类型的右侧内容。使用
React.isValidElement检查是正确且安全的方法。
220-222: 改进:条件渲染清除按钮根据
defaultValue和value状态条件渲染清除按钮的逻辑很好,这确保了用户界面的一致性。当有默认值标签显示时,不显示清除按钮是合理的设计决策。src/packages/searchbar/searchbar.taro.tsx (4)
72-76: 改进:使用 usePropsValue 提升组件受控性使用
usePropsValue取代原有的状态管理方式,统一了组件的受控和非受控行为,使其更符合 React 组件设计规范,同时提高了代码一致性。
128-144: 很好的实现:默认值标签展示功能新增的默认值展示功能实现得很好,包括:
- 正确使用了 Taro 的
View组件- 为每个标签提供了独特的 key
- 实现点击回调使用了可选链,确保安全
这个功能对于提升用户体验非常有价值,允许用户看到并管理默认搜索值。
164-173: 改进:优化右侧元素渲染逻辑对右侧元素的条件渲染处理得很好,使用
React.isValidElement判断是否需要添加图标类名是正确的实现方式。这提高了组件的灵活性和可扩展性。
217-222: 改进:优化输入框和默认值的布局结构将输入框和默认值标签包装在专门的容器中是个很好的设计决定,这将使布局更加灵活,也便于应用样式。条件渲染清除按钮的逻辑与 React 版本保持一致,确保了组件行为的一致性。
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (5)
src/packages/searchbar/searchbar.taro.tsx (1)
126-135:⚠️ Potential issue修正
clearaVal中onChange回调参数不完整当清空输入框时,只向
onChange传递了空字符串,而没有传递事件对象,这与组件其他地方调用onChange(value, event)的模式不一致。-onChange && onChange('') +onChange?.('', event)保持参数一致性有助于使用方更可预测地处理事件。
🧰 Tools
🪛 Biome (1.9.4)
[error] 131-131: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 132-132: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/packages/searchbar/searchbar.tsx (4)
181-204: 优化标签渲染逻辑
渲染标签列表时使用了索引作为 key,这在列表项重新排序时可能导致不必要的重渲染或状态错误。建议使用更稳定的唯一标识。
使用了 setTimeout 但没有清理逻辑,可能导致内存泄漏。
const renderValueByTags = useCallback(() => { if (!value) { - setTimeout(() => { + // 避免使用 setTimeout,可以直接调用 + requestAnimationFrame(() => { forceFocus() - }, 0) }) return null } const list = value.split(',') if (!list) return null return ( <div className="nut-searchbar-values"> {list.map((item, index) => ( <div - key={`def-${index}`} + key={`${item}-${index}`} className="nut-searchbar-value" onClick={(e) => onItemClick?.(item, e)} > {item} <Close /> </div> ))} </div> ) }, [value, onItemClick])🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 183-187: src/packages/searchbar/searchbar.tsx#L183-L187
Added lines #L183 - L187 were not covered by tests
250-250: 使用 locale 系统进行国际化"清除"文本被硬编码为中文,建议使用 locale 系统以支持国际化。
-aria-label="清除" +aria-label={locale.clear || "清除"}同时建议在 locale 配置中添加对应的翻译项。
119-128:⚠️ Potential issue修正
clearaVal中onChange回调参数不完整当清空输入框时,只向
onChange传递了空字符串,而没有传递事件对象,这与组件其他地方调用onChange(value, event)的模式不一致。-onChange && onChange('') +onChange?.('', event)保持参数一致性有助于使用方更可预测地处理事件。
🧰 Tools
🪛 Biome (1.9.4)
[error] 124-124: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 125-125: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
109-118: 🛠️ Refactor suggestion处理 setTimeout 可能导致的内存泄漏
handleBlur中使用了 setTimeout 但未在组件卸载时清除,这可能导致内存泄漏。建议使用 useEffect 清理定时器。+const [blurTimer, setBlurTimer] = useState<NodeJS.Timeout | null>(null) const handleBlur = useCallback( (event: FocusEvent<HTMLInputElement>) => { searchInputRef.current?.blur() onBlur && onBlur(event.target?.value, event) - setTimeout(() => { + const timer = setTimeout(() => { setInnerTag(event.target?.value ? tag : false) }, 150) + setBlurTimer(timer) }, [onBlur, tag, value] ) +useEffect(() => { + return () => { + if (blurTimer) clearTimeout(blurTimer) + } +}, [blurTimer])🧰 Tools
🪛 Biome (1.9.4)
[error] 112-112: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🪛 GitHub Check: codecov/patch
[warning] 114-114: src/packages/searchbar/searchbar.tsx#L114
Added line #L114 was not covered by tests
🧹 Nitpick comments (9)
src/packages/searchbar/demos/taro/demo10.tsx (1)
37-53: 移除注释代码这段被注释的代码似乎是未完成或废弃的功能。如果不需要,建议完全移除;如果是计划中的功能,应该添加TODO注释说明用途。
-{/* <SearchBar - backable - leftIn={null} - value={value} - onChange={(val) => { - setValue(val) - }} - // autoFocus - rightIn={ - <div style={{ display: 'flex', alignItems: 'center' }}> - <Photograph color="#505259" style={{ marginRight: '12px' }} /> - <Button type="primary" size="mini"> - 搜索 - </Button> - </div> - } -/> */}src/packages/searchbar/__tests__/searchbar.spec.tsx (1)
44-89: 全面的事件处理测试这个测试用例很全面,通过创建一个完整的Demo组件来模拟真实使用场景,测试了所有主要事件和状态更新。使用
waitFor处理异步状态更新很合理。建议添加对
onItemClick回调的测试,因为这是新增的重要功能。test('should handle all events correctly', async () => { const handleChange = vi.fn() const handleFocus = vi.fn() const handleBlur = vi.fn() const handleClick = vi.fn() const handleClear = vi.fn() + const handleItemClick = vi.fn() const Demo = () => { const [value, setValue] = useState('奶茶') const onChange = (newValue: string) => { setValue(newValue) // 更新状态 handleChange(newValue) // 调用传入的 onChange 处理函数 } return ( <SearchBar value={value} autoFocus + tag onChange={onChange} onFocus={handleFocus} onBlur={handleBlur} onInputClick={handleClick} onClear={handleClear} + onItemClick={handleItemClick} /> ) } const { container } = render(<Demo />) // 现有测试代码... + // 测试标签点击 + if (container.querySelector('.nut-searchbar-value')) { + const tag = container.querySelector('.nut-searchbar-value') as Element + fireEvent.click(tag) + expect(handleItemClick).toHaveBeenCalledTimes(1) + }src/packages/searchbar/searchbar.taro.tsx (5)
96-96: 使用可选链操作符增强代码健壮性建议在调用回调函数时使用可选链操作符,这样即使回调未定义也不会抛出错误。
-onChange && onChange(eventValue, event) +onChange?.(eventValue, event)其他几处相同模式的回调也应同时修改 (105, 114, 131, 132, 286行)。
🧰 Tools
🪛 Biome (1.9.4)
[error] 96-96: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
206-230: 优化标签渲染逻辑
渲染标签列表时使用了索引作为 key,这在列表项重新排序时可能导致不必要的重渲染或状态错误。建议使用更稳定的唯一标识。
使用了 setTimeout 但没有清理逻辑,可能导致内存泄漏。
在用户点击标签时,建议提供更明确的视觉或焦点反馈。
const renderValueByTags = useCallback(() => { if (!innerTag) return null if (!value) { - setTimeout(() => { + // 避免使用 setTimeout,可以直接调用 + requestAnimationFrame(() => { forceFocus() - }, 0) }) return null } const list = value.split(',') if (!list) return null return ( <View className="nut-searchbar-values"> {list.map((item, index) => ( <View - key={`def-${index}`} + key={`${item}-${index}`} className="nut-searchbar-value" onClick={(e) => onItemClick?.(item, e)} > {item} <Close /> </View> ))} </View> ) }, [value, onItemClick, innerTag])
163-201: 考虑简化环境判断逻辑当前代码中WEB环境和非WEB环境有大量重复代码,只有
focus/autoFocus属性不同。建议提取共同部分减少冗余。const renderField = () => { const inputCls = classNames(`${classPrefix}-input`) + const commonProps = { + className: inputCls, + ref: searchInputRef, + style: { + ...style, + ...{ color: `${innerTag ? 'transparent' : '#333'}` }, + }, + value, + placeholder: placeholder || locale.placeholder, + disabled: disabled || readOnly, + maxlength: maxLength, + onInput: handleInput, + onFocus: handleFocus, + onBlur: handleBlur, + onClick: onInputClick, + onConfirm: onConfirm, + } + return ( <> {Taro.getEnv() === 'WEB' ? ( - <TaroInput - className={inputCls} - ref={searchInputRef} - style={{ - ...style, - ...{ color: `${innerTag ? 'transparent' : '#333'}` }, - }} - value={value} - placeholder={placeholder || locale.placeholder} - disabled={disabled || readOnly} - maxlength={maxLength} - autoFocus={autoFocus} - onInput={handleInput} - onFocus={handleFocus} - onBlur={handleBlur} - onClick={onInputClick} - onConfirm={onConfirm} - /> + <TaroInput {...commonProps} autoFocus={autoFocus} /> ) : ( - <TaroInput - className={inputCls} - ref={searchInputRef} - style={{ - ...style, - ...{ color: `${innerTag ? 'transparent' : '#333'}` }, - }} - value={value} - placeholder={placeholder || locale.placeholder} - disabled={disabled || readOnly} - maxlength={maxLength} - focus={autoFocus} - onInput={handleInput} - onFocus={handleFocus} - onBlur={handleBlur} - onClick={onInputClick} - onConfirm={onConfirm} - /> + <TaroInput {...commonProps} focus={autoFocus} /> )} </> ) }
270-283: 优化清除按钮逻辑当前清除按钮通过 CSS 的 visibility 属性来控制显示/隐藏,但这仍会在 DOM 中保留元素。考虑使用条件渲染来提高性能,尤其是在低端设备上。
const renderClear = useCallback(() => { + if (!value || !clearable || innerTag) return null return ( <View className={`${classPrefix}-clear ${classPrefix}-icon`} - style={{ - visibility: `${!innerTag && value && clearable ? 'visible' : 'hidden'}`, - }} onClick={clearaVal} aria-label="清除" > <MaskClose /> </View> ) }, [value, clearable, clearaVal, innerTag])
278-278: 使用 locale 系统进行国际化"清除"文本被硬编码为中文,建议使用 locale 系统以支持国际化。
-aria-label="清除" +aria-label={locale.clear || "清除"}同时建议在 locale 配置中添加对应的翻译项。
src/packages/searchbar/searchbar.tsx (2)
88-91: 使用可选链操作符增强代码健壮性建议在调用回调函数时使用可选链操作符,这样即使回调未定义也不会抛出错误。
-onChange && onChange(value, event) +onChange?.(value, event)其他几处相同模式的回调也应同时修改 (103, 112, 124, 125, 137行)。
🧰 Tools
🪛 Biome (1.9.4)
[error] 88-88: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
244-255: renderClear 方法与 Taro 版本实现不一致Web 版本中
renderClear实现与 Taro 版本不同:Web 版本在条件不满足时返回 null,而 Taro 版本则使用 CSS visibility 控制显示隐藏。这种不一致可能导致行为差异。建议统一两个版本的行为模式,都采用条件渲染的方式:
const renderClear = useCallback(() => { - if (!value || !clearable) return null + if (!value || !clearable || innerTag) return null return ( <div className={`${classPrefix}-clear ${classPrefix}-icon`} onClick={clearaVal} aria-label="清除" > <MaskClose /> </div> ) }, [value, clearable, clearaVal])
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
scripts/harmony/update-taro-entry.js(2 hunks)src/packages/searchbar/__tests__/searchbar.spec.tsx(1 hunks)src/packages/searchbar/demos/h5/demo10.tsx(1 hunks)src/packages/searchbar/demos/taro/demo1.tsx(1 hunks)src/packages/searchbar/demos/taro/demo10.tsx(1 hunks)src/packages/searchbar/demos/taro/demo5.tsx(1 hunks)src/packages/searchbar/searchbar.scss(2 hunks)src/packages/searchbar/searchbar.taro.tsx(4 hunks)src/packages/searchbar/searchbar.tsx(4 hunks)src/types/spec/searchbar/base.ts(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/packages/searchbar/demos/taro/demo5.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
- src/packages/searchbar/demos/h5/demo10.tsx
- src/packages/searchbar/demos/taro/demo1.tsx
- src/packages/searchbar/searchbar.scss
🧰 Additional context used
🧬 Code Graph Analysis (3)
scripts/harmony/update-taro-entry.js (3)
scripts/taro/generate-taro-route.js (2)
configRef(9-9)config(2-2)scripts/taro/generate-taro-pages.js (1)
config(4-4)scripts/create-component-mode.js (1)
config(5-5)
src/packages/searchbar/__tests__/searchbar.spec.tsx (1)
src/packages/searchbar/searchbar.tsx (1)
SearchBar(33-273)
src/packages/searchbar/demos/taro/demo10.tsx (1)
src/packages/searchbar/searchbar.taro.tsx (1)
SearchBar(40-306)
🪛 Biome (1.9.4)
src/packages/searchbar/searchbar.tsx
[error] 88-88: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 103-103: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 112-112: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 124-124: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 125-125: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 137-137: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/packages/searchbar/searchbar.taro.tsx
[error] 96-96: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 105-105: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 114-114: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 131-131: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 132-132: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 286-287: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🪛 GitHub Check: codecov/patch
src/packages/searchbar/searchbar.tsx
[warning] 114-114: src/packages/searchbar/searchbar.tsx#L114
Added line #L114 was not covered by tests
[warning] 132-139: src/packages/searchbar/searchbar.tsx#L132-L139
Added lines #L132 - L139 were not covered by tests
[warning] 183-187: src/packages/searchbar/searchbar.tsx#L183-L187
Added lines #L183 - L187 were not covered by tests
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (8)
scripts/harmony/update-taro-entry.js (2)
24-24: 变量定义类型的调整将
configRef从const改为let是为了支持后续的过滤操作,这个变更是必要的,逻辑清晰。
52-54: 优化了导航配置的处理逻辑添加过滤空页面数组的逻辑很合理,这样可以避免在生成的配置中包含没有实际页面的导航项,提高了代码的健壮性。
src/types/spec/searchbar/base.ts (3)
7-7: 增加默认值属性,支持非受控模式添加
defaultValue属性很好地支持了非受控组件模式,使组件更加灵活。这与 React 的设计理念一致。
20-20: 新增标签展示模式
tag属性的添加使搜索框支持标签显示模式,增强了组件的展示能力,对于多值输入场景非常有用。
27-27: 添加标签点击事件回调
onItemClick回调函数的添加完善了标签交互功能,允许开发者自定义处理标签点击事件,增强了组件的可控性。src/packages/searchbar/demos/taro/demo10.tsx (1)
5-8: 示例组件状态管理组件状态设置合理,使用了 useState 创建了两个状态变量:一个用于普通值,一个用于逗号分隔的多值。
src/packages/searchbar/__tests__/searchbar.spec.tsx (2)
29-33: 添加标签渲染测试很好地测试了标签渲染功能,验证了传入逗号分隔的值时能正确显示为多个标签。
35-42: 增加了右侧内容测试测试了
rightIn属性的两种用法:字符串和React节点,覆盖了主要使用场景。
| <SearchBar | ||
| backable | ||
| leftIn={null} | ||
| value={value1} | ||
| tag | ||
| onItemClick={(val: string) => { | ||
| console.log('click', val) | ||
| const arr = value1.split(',') | ||
| const newArr = arr.filter((item: string) => item !== val) | ||
| const newVal = newArr.length > 1 ? newArr.join(',') : newArr.join('') | ||
| setValue1(newVal) | ||
| }} | ||
| onFocus={(val: string) => { | ||
| console.log('focus value', val) | ||
| setValue1(val.split(',').join('')) | ||
| }} | ||
| onChange={(val) => { | ||
| console.log('onChange', val) | ||
| setValue1(val) | ||
| }} | ||
| rightIn={ | ||
| <div style={{ display: 'flex', alignItems: 'center' }}> | ||
| <Photograph color="#505259" /> | ||
| </div> | ||
| } | ||
| right={<Category />} | ||
| /> |
There was a problem hiding this comment.
🛠️ Refactor suggestion
完善标签删除逻辑
标签点击处理逻辑符合预期,但可以进一步优化数组处理和状态更新:
- 当用户点击标签时,在失去焦点后应该重新展示为标签格式
- 根据PR评论,当搜索框获取焦点时,标签之间的分隔符应被移除
onFocus={(val: string) => {
console.log('focus value', val)
setValue1(val.split(',').join(''))
}}
onBlur={(val: string) => {
+ // 在失去焦点时,如果输入内容包含多个项目,重新格式化为逗号分隔
+ if (val && !val.includes(',') && val.trim() !== '') {
+ const items = val.split(/\s+/).filter(item => item.trim() !== '');
+ if (items.length > 1) {
+ setValue1(items.join(','));
+ return;
+ }
+ }
+ setValue1(val);
}}📝 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.
| <SearchBar | |
| backable | |
| leftIn={null} | |
| value={value1} | |
| tag | |
| onItemClick={(val: string) => { | |
| console.log('click', val) | |
| const arr = value1.split(',') | |
| const newArr = arr.filter((item: string) => item !== val) | |
| const newVal = newArr.length > 1 ? newArr.join(',') : newArr.join('') | |
| setValue1(newVal) | |
| }} | |
| onFocus={(val: string) => { | |
| console.log('focus value', val) | |
| setValue1(val.split(',').join('')) | |
| }} | |
| onChange={(val) => { | |
| console.log('onChange', val) | |
| setValue1(val) | |
| }} | |
| rightIn={ | |
| <div style={{ display: 'flex', alignItems: 'center' }}> | |
| <Photograph color="#505259" /> | |
| </div> | |
| } | |
| right={<Category />} | |
| /> | |
| <SearchBar | |
| backable | |
| leftIn={null} | |
| value={value1} | |
| tag | |
| onItemClick={(val: string) => { | |
| console.log('click', val) | |
| const arr = value1.split(',') | |
| const newArr = arr.filter((item: string) => item !== val) | |
| const newVal = newArr.length > 1 ? newArr.join(',') : newArr.join('') | |
| setValue1(newVal) | |
| }} | |
| onFocus={(val: string) => { | |
| console.log('focus value', val) | |
| setValue1(val.split(',').join('')) | |
| }} | |
| onBlur={(val: string) => { | |
| // 在失去焦点时,如果输入内容包含多个项目,重新格式化为逗号分隔 | |
| if (val && !val.includes(',') && val.trim() !== '') { | |
| const items = val.split(/\s+/).filter(item => item.trim() !== ''); | |
| if (items.length > 1) { | |
| setValue1(items.join(',')); | |
| return; | |
| } | |
| } | |
| setValue1(val); | |
| }} | |
| onChange={(val) => { | |
| console.log('onChange', val) | |
| setValue1(val) | |
| }} | |
| rightIn={ | |
| <div style={{ display: 'flex', alignItems: 'center' }}> | |
| <Photograph color="#505259" /> | |
| </div> | |
| } | |
| right={<Category />} | |
| /> |
| {renderField()} | ||
| {clearable && !value && renderRightIn()} | ||
| {clearable && value && handleClear()} | ||
| {innerTag ? renderValueByTags() : renderClear()} |
There was a problem hiding this comment.
🛠️ Refactor suggestion
处理标签渲染和清除按钮的条件逻辑不一致
Web 版本使用 {innerTag ? renderValueByTags() : renderClear()} 表示只会渲染标签或清除按钮中的一个,而 Taro 版本中这两个元素是分开渲染的,可能同时显示。这种不一致可能导致用户体验差异。
-{innerTag ? renderValueByTags() : renderClear()}
+{innerTag && renderValueByTags()}
+{!innerTag && renderClear()}或者使用与 Taro 版本一致的实现:
-{innerTag ? renderValueByTags() : renderClear()}
+{renderValueByTags()}
+{renderClear()}📝 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.
| {innerTag ? renderValueByTags() : renderClear()} | |
| - {innerTag ? renderValueByTags() : renderClear()} | |
| + {innerTag && renderValueByTags()} | |
| + {!innerTag && renderClear()} |
| (e: React.KeyboardEvent) => { | ||
| if (e.key === 'Enter') { | ||
| const event = e.nativeEvent | ||
| if (typeof event.cancelable !== 'boolean' || event.cancelable) { | ||
| event.preventDefault() | ||
| } | ||
| onSearch && onSearch(value as string) | ||
| } | ||
| }, | ||
| [onSearch, value] | ||
| ) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
增加键盘事件处理的测试覆盖
静态分析工具报告这段代码未被测试覆盖。建议添加相应的单元测试,确保键盘事件的处理逻辑按预期工作。
可测试以下情况:
- 按下 Enter 键时触发搜索回调
- 事件preventDefault 被正确调用
- 不同键的不同行为
🏁 Script executed:
#!/bin/bash
# 检查是否有对应的键盘事件测试
grep -r "onKeyDown\|press.*Enter\|key.*event" src/packages/searchbar/__tests__Length of output: 80
我们可以进一步确认是否已为 SearchBar 的键盘事件添加测试,运行以下脚本:
请求确认运行结果,以决定是否需要新增键盘事件处理的单元测试覆盖。
🏁 Script executed:
#!/bin/bash
# 列出 src/packages/searchbar 目录下所有测试文件
test_files=$(find src/packages/searchbar -type f | grep -E "(__tests__|\\.test\\.(js|ts|tsx))")
if [ -z "$test_files" ]; then
echo "未找到 searchbar 的测试文件"
exit 0
fi
echo "找到以下测试文件:"
echo "$test_files"
echo "—— 在这些文件中搜索 'Enter' 相关测试 ——"
grep -R "Enter" $test_files || echo "在测试文件中未找到与 'Enter' 相关的测试"Length of output: 657
请为 SearchBar 组件的键盘事件处理补充单元测试
在当前的 src/packages/searchbar/__tests__/searchbar.spec.tsx 中,未发现对 Enter 键处理逻辑的测试覆盖。建议新增以下测试用例,确保键盘事件行为符合预期:
- 按下 Enter 键时,应调用
onSearch回调 - 按下 Enter 键时,应正确调用
event.preventDefault() - 按下其他键(如 Esc、空格等)时,不应触发
onSearch
请在上述测试文件中添加相应覆盖。
🧰 Tools
🪛 Biome (1.9.4)
[error] 137-137: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🪛 GitHub Check: codecov/patch
[warning] 132-139: src/packages/searchbar/searchbar.tsx#L132-L139
Added lines #L132 - L139 were not covered by tests
|
1、清除按钮扩大点击区,移除占位 2、文字居又展示右侧空白太大 |
done |
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (4)
src/packages/searchbar/demos/taro/demo10.tsx (1)
22-25: 🛠️ Refactor suggestion考虑添加onBlur事件处理
组件在获取焦点时将逗号分隔的字符串转换为无分隔符的形式,但缺少相应的onBlur处理逻辑来恢复其显示。根据PR评论,当搜索框获取焦点时标签之间的分隔符应被移除,失去焦点后应恢复。
onFocus={(val: string) => { console.log('focus value', val) setValue1(val.split(',').join('')) }} +onBlur={(val: string) => { + // 在失去焦点时,如果输入内容不包含逗号且不为空,将其格式化为逗号分隔形式 + if (val && !val.includes(',') && val.trim() !== '') { + const items = val.split(/\s+/).filter(item => item.trim() !== ''); + if (items.length > 1) { + setValue1(items.join(',')); + return; + } + } + setValue1(val); +}}src/packages/searchbar/searchbar.taro.tsx (1)
142-143:⚠️ Potential issue清空回调参数不完整
清空输入时,仅向
onChange传入空字符串,遗漏了事件对象参数。这与其他onChange调用不一致,可能导致使用者在处理事件时遇到问题。- onChange && onChange('') + onChange?.('', event)🧰 Tools
🪛 Biome (1.9.4)
[error] 142-142: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 143-143: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/packages/searchbar/searchbar.tsx (2)
131-139:⚠️ Potential issue清空回调参数不完整
清空输入时,仅向
onChange传入空字符串,遗漏了事件对象参数。这与其他onChange调用不一致,可能导致使用者在处理事件时遇到问题。- onChange && onChange('') + onChange?.('', event)🧰 Tools
🪛 Biome (1.9.4)
[error] 136-136: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 137-137: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
279-280: 🛠️ Refactor suggestion标签渲染和清除按钮的条件逻辑需统一
Web版本使用
{innerTag ? renderValueByTags() : renderClear()}表示只会渲染标签或清除按钮中的一个,而Taro版本中这两个元素是分开渲染的,可能同时显示。这种不一致可能导致用户体验差异。-{innerTag ? renderValueByTags() : renderClear()} +{innerTag && renderValueByTags()} +{!innerTag && renderClear()}
🧹 Nitpick comments (5)
src/packages/searchbar/demos/taro/demo10.tsx (1)
15-25: 优化标签点击处理逻辑当前实现在删除标签时,如果只剩下一个标签,会将其显示为没有逗号的单一值。建议考虑保持一致的数据格式处理,即使只有一个项目也使用同样的格式。此外,应当考虑空数组情况的处理。
onItemClick={(val: string) => { console.log('click', val) const arr = value1.split(',') const newArr = arr.filter((item: string) => item !== val) - const newVal = newArr.length > 1 ? newArr.join(',') : newArr.join('') + const newVal = newArr.join(',') setValue1(newVal) }}src/packages/searchbar/searchbar.taro.tsx (4)
96-97: 代码规范:使用可选链操作符根据静态分析工具建议,应使用可选链操作符替代逻辑与操作符,以提高代码一致性和可读性。
- onChange && onChange(eventValue, event) + onChange?.(eventValue, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 96-96: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
105-106: 代码规范:使用可选链操作符根据静态分析工具建议,应使用可选链操作符替代逻辑与操作符,以提高代码一致性和可读性。
- onFocus && onFocus(event.detail?.value, event) + onFocus?.(event.detail?.value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 105-105: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
116-117: 代码规范:使用可选链操作符根据静态分析工具建议,应使用可选链操作符替代逻辑与操作符,以提高代码一致性和可读性。
- onBlur && onBlur(event.detail?.value, event) + onBlur?.(event.detail?.value, event)🧰 Tools
🪛 Biome (1.9.4)
[error] 116-116: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
217-241: renderValueByTags函数良好实现,考虑优化边缘情况新增的标签渲染功能实现完善,但在value为空时使用setTimeout强制聚焦可能导致用户体验问题。当前实现在空值情况下立即执行forceFocus,可能会干扰用户的正常操作流程。
const renderValueByTags = useCallback(() => { if (!innerTag) return null if (!value) { - setTimeout(() => { - forceFocus() - }, 0) + // 只在组件挂载或value变为空时聚焦,避免不必要的频繁聚焦 + useEffect(() => { + if (!value) { + forceFocus() + } + }, [value, forceFocus]) return null } const list = value.split(',') if (!list) return null return ( // 其余代码保持不变
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/packages/searchbar/demos/taro/demo10.tsx(1 hunks)src/packages/searchbar/searchbar.scss(2 hunks)src/packages/searchbar/searchbar.taro.tsx(4 hunks)src/packages/searchbar/searchbar.tsx(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/packages/searchbar/searchbar.scss
🧰 Additional context used
🧠 Learnings (1)
src/packages/searchbar/searchbar.taro.tsx (1)
Learnt from: irisSong
PR: jdf2e/nutui-react#3209
File: src/packages/searchbar/searchbar.taro.tsx:111-124
Timestamp: 2025-05-02T01:45:09.567Z
Learning: 在 React/Taro 组件中使用 setTimeout 或 setInterval 时,应当在组件卸载时通过 useEffect 的清理函数清除定时器,以防止内存泄漏。可以使用 useState 存储定时器 ID,并在 useEffect 的返回函数中清除。
🧬 Code Graph Analysis (1)
src/packages/searchbar/searchbar.tsx (2)
src/hooks/use-props-value.ts (1)
usePropsValue(11-35)src/packages/calendarcard/icon.taro.tsx (1)
ArrowLeft(44-44)
🪛 Biome (1.9.4)
src/packages/searchbar/searchbar.taro.tsx
[error] 96-96: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 105-105: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 116-116: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 142-142: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 143-143: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 297-298: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/packages/searchbar/searchbar.tsx
[error] 88-88: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 103-103: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 114-114: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 136-136: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 137-137: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 149-149: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: test
🔇 Additional comments (2)
src/packages/searchbar/searchbar.taro.tsx (1)
111-128: 定时器处理优化已应用很好!根据之前的学习反馈,您已正确实现了定时器的清理,通过useState存储定时器ID并在组件卸载时清除,防止内存泄漏。这是React组件中处理setTimeout的最佳实践。
🧰 Tools
🪛 Biome (1.9.4)
[error] 116-116: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/packages/searchbar/searchbar.tsx (1)
73-79: 使用usePropsValue进行状态管理的良好实践使用
usePropsValue来处理受控与非受控组件的状态管理是一个很好的改进。这样可以更好地支持默认值和控制值的切换,提高组件的灵活性。
| }, [right]) | ||
|
|
||
| const renderClear = useCallback(() => { | ||
| return ( | ||
| <View | ||
| className={`${classPrefix}-clear ${classPrefix}-icon`} | ||
| onClick={(e: any) => clearaVal(e)} | ||
| className={`${classPrefix}-clear ${classPrefix}-icon`} | ||
| style={{ | ||
| visibility: `${!innerTag && value && clearable ? 'visible' : 'hidden'}`, | ||
| }} |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
考虑统一Web和Taro版本的渲染逻辑
Taro版本中renderValueByTags和renderClear可以同时显示,而Web版本使用三元表达式(innerTag ? renderValueByTags() : renderClear())使它们互斥。这种不一致可能导致用户在不同平台上体验差异。建议统一两个版本的实现方式。
🏁 Script executed:
#!/bin/bash
# 查找Web版本中相关渲染逻辑
echo "Web版本的渲染逻辑:"
rg -n "renderValueByTags|renderClear" src/packages/searchbar/searchbar.tsx
echo "======================"
echo "Taro版本的渲染逻辑:"
rg -n "renderValueByTags|renderClear" src/packages/searchbar/searchbar.taro.tsxLength of output: 754
统一 Web 与 Taro 版本的渲染逻辑
目前两端实现不一致,导致用户体验差异:
- Web 版本(src/packages/searchbar/searchbar.tsx:279)使用
{innerTag ? renderValueByTags() : renderClear()}
——互斥渲染,仅展示标签或清除按钮之一。 - Taro 版本(src/packages/searchbar/searchbar.taro.tsx:310–311)使用
{renderValueByTags()}
{renderClear()}
——同时渲染,两个组件都会存在但通过样式控制可见性。
建议统一为同一种模式:
- 若意图互斥渲染:Taro 端改为
{innerTag ? renderValueByTags() : renderClear()}; - 若意图同时渲染仅调整可见性:Web 端改为同时调用并通过
visibility/display控制。
请根据产品设计调整并同步更新两端实现。
| const onKeydown = useCallback( | ||
| (e: React.KeyboardEvent) => { | ||
| if (e.key === 'Enter') { | ||
| const event = e.nativeEvent | ||
| if (typeof event.cancelable !== 'boolean' || event.cancelable) { | ||
| event.preventDefault() | ||
| } | ||
| onSearch && onSearch(value as string) | ||
| } | ||
| }, | ||
| [onSearch, value] | ||
| ) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
键盘事件处理逻辑缺少测试覆盖
新增的键盘事件处理逻辑看起来实现良好,但静态分析工具报告该代码段未被测试覆盖。应当添加针对Enter键触发搜索功能的单元测试,确保其按预期工作。
🏁 Script executed:
#!/bin/bash
# 检查是否有对应的键盘事件测试
echo "搜索在测试文件中是否有键盘事件相关测试:"
grep -r "onKeyDown\|press.*Enter\|key.*event" src/packages/searchbar/__tests__Length of output: 352
🏁 Script executed:
#!/bin/bash
# 在所有测试文件中搜索 Enter 关键字
echo "搜索 Enter 关键字:"
rg "Enter" -n -g "*.test.tsx" -g "*.test.ts" -g "*.spec.tsx" -g "*.spec.ts"
# 在所有测试文件中搜索 onKeydown 调用
echo "搜索 onKeydown:"
rg "onKeydown" -n -g "*.test.tsx" -g "*.test.ts" -g "*.spec.tsx" -g "*.spec.ts"Length of output: 229
添加 Enter 键触发搜索的单元测试
当前位于 src/packages/searchbar/searchbar.tsx 的 onKeydown 回调在现有测试中未被覆盖,需要补充针对 Enter 键触发搜索的测试:
- 测试文件:在
src/packages/searchbar/__tests__/searchbar.test.tsx(或同级测试目录)中新增 - 场景一:当输入框有值时,模拟用户按下 Enter,断言
onSearch被调用且参数等于输入值 - 场景二:当输入框为空时,模拟按下 Enter,断言
onSearch不被调用 - 建议使用 React Testing Library 的
fireEvent.keyDown或userEvent.keyboard('{Enter}')
请补充以上测试以确保键盘事件逻辑得到充分验证。
🧰 Tools
🪛 Biome (1.9.4)
[error] 149-149: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
| if (!value) { | ||
| setTimeout(() => { | ||
| forceFocus() | ||
| }, 0) | ||
| return null | ||
| } | ||
| const list = value.split(',') | ||
| if (!list) return null | ||
| return ( | ||
| <div className="nut-searchbar-values"> | ||
| {list.map((item, index) => ( | ||
| <div | ||
| key={`def-${index}`} | ||
| className="nut-searchbar-value" | ||
| onClick={(e) => onItemClick?.(item, e)} | ||
| > | ||
| {item} | ||
| <Close /> | ||
| </div> | ||
| ))} | ||
| </div> | ||
| ) | ||
| }, [value, onItemClick]) |
There was a problem hiding this comment.
renderValueByTags中setTimeout使用可能导致内存泄漏
在renderValueByTags函数中使用了setTimeout但未在组件卸载时清除,这可能导致内存泄漏。应该和blur timer一样使用state存储timer ID并在组件卸载时清除。
+const [focusTimer, setFocusTimer] = useState<NodeJS.Timeout | null>(null)
const renderValueByTags = useCallback(() => {
if (!value) {
- setTimeout(() => {
+ const timer = setTimeout(() => {
forceFocus()
}, 0)
+ setFocusTimer(timer)
return null
}
// 其余代码不变
}, [value, onItemClick])
useEffect(() => {
return () => {
if (blurTimer) clearTimeout(blurTimer)
+ if (focusTimer) clearTimeout(focusTimer)
}
-}, [blurTimer])
+}, [blurTimer, focusTimer])| style={{ | ||
| visibility: `${!innerTag && value && clearable ? 'visible' : 'hidden'}`, | ||
| }} | ||
| onClick={clearaVal} |
There was a problem hiding this comment.
onTouchStart 和 onMousedown 早于 onBlur 事件,可以阻止默认行为防止失去焦点。实际体验下效果和定时器的差不多。
建议考虑去掉失去焦点保持键盘的逻辑。


🤔 这个变动的性质是?
🔗 相关 Issue
💡 需求背景和解决方案
☑️ 请求合并前的自查清单
Summary by CodeRabbit
新功能
defaultValue属性,可设置多个默认值(以逗号分隔),并支持onItemClick回调处理默认值的点击事件。defaultValue与受控模式的使用。样式
文档
defaultValue、onItemClick新增属性及样式变量变更,完善 API 说明及迁移指引。演示/示例
测试