Skip to content

Commit f819320

Browse files
fix(noticebar): children cannot update responsively in vertical mode (#3251)
* fix(noticebar): first item is not visible when scrolling vertically * fix(noticebar): children cannot update responsively in vertical mode --------- Co-authored-by: songsong <[email protected]>
1 parent 949ad30 commit f819320

File tree

11 files changed

+301
-97
lines changed

11 files changed

+301
-97
lines changed

src/packages/noticebar/__test__/noticebar.spec.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as React from 'react'
2+
import { useState } from 'react'
23
import { render, fireEvent, waitFor, act } from '@testing-library/react'
34
import '@testing-library/jest-dom'
45
import { Fabulous } from '@nutui/icons-react'
@@ -260,3 +261,94 @@ test('vertical container height calculation with children', async () => {
260261
{ timeout: 3000 }
261262
)
262263
})
264+
265+
test('dynamic children update test', async () => {
266+
let setList: any
267+
const height = 40
268+
269+
const TestComponent = () => {
270+
const [list, updateList] = useState(['原始项目1', '原始项目2', '原始项目3'])
271+
setList = updateList
272+
273+
return (
274+
<NoticeBar direction="vertical" height={height} speed={10} duration={500}>
275+
{list.map((item, index) => (
276+
<div
277+
className="custom-item"
278+
style={{ height: `${height}px`, lineHeight: `${height}px` }}
279+
key={index}
280+
>
281+
{item}
282+
</div>
283+
))}
284+
</NoticeBar>
285+
)
286+
}
287+
288+
const { container } = render(<TestComponent />)
289+
290+
// 等待初始渲染完成
291+
await waitFor(() => {
292+
const wrapElement = container.querySelector('.nut-noticebar-box-wrap')
293+
expect(wrapElement).toHaveStyle('height: 160px') // (3 + 1) * 40
294+
295+
// 1. 初始时容器的垂直位移为0(显示第一项)
296+
expect(wrapElement).toHaveStyle('transform: translate3D(0,0px,0)')
297+
298+
const items = container.querySelectorAll('.custom-item')
299+
expect(items).toHaveLength(3)
300+
expect(items[0]).toHaveTextContent('原始项目1')
301+
})
302+
303+
// 等待轮播进行一段时间,确保当前不是第一项
304+
await waitFor(
305+
() => {
306+
const wrapElement = container.querySelector('.nut-noticebar-box-wrap')
307+
const transform = wrapElement
308+
?.getAttribute('style')
309+
?.match(/transform:\s*translate3D\(([^,]+),([^,]+),([^)]+)\)/)
310+
const yOffset = transform ? transform[2].trim() : '0px'
311+
312+
// 验证已经轮播到非第一项(垂直偏移不为0)
313+
expect(yOffset).not.toBe('0px')
314+
},
315+
{ timeout: 2000 }
316+
) // 给足够时间让轮播发生
317+
318+
// 变更列表数据
319+
act(() => {
320+
setList(['新项目A', '新项目B', '新项目C', '新项目D'])
321+
})
322+
323+
await waitFor(() => {
324+
// 验证容器高度更新为新的计算值
325+
const wrapElement = container.querySelector('.nut-noticebar-box-wrap')
326+
expect(wrapElement).toHaveStyle('height: 200px') // (4 + 1) * 40
327+
328+
// 验证变更后重置回第一项:
329+
// 1. 容器的垂直位移重置为0
330+
expect(wrapElement).toHaveStyle('transform: translate3D(0,0px,0)')
331+
332+
// 2. 第一个子项没有额外的transform
333+
const firstItem = container.querySelector(
334+
'.custom-item:first-child'
335+
) as HTMLElement
336+
expect(firstItem.style.transform).toBe('')
337+
338+
// 验证元素结构更新:应该有4个项目
339+
const items = container.querySelectorAll('.custom-item')
340+
expect(items).toHaveLength(4)
341+
342+
// 验证当前显示的是新列表的第一项内容
343+
expect(items[0]).toHaveTextContent('新项目A')
344+
expect(items[1]).toHaveTextContent('新项目B')
345+
expect(items[2]).toHaveTextContent('新项目C')
346+
expect(items[3]).toHaveTextContent('新项目D')
347+
348+
// 验证样式更新:每个item的高度样式
349+
items.forEach((item) => {
350+
expect(item).toHaveStyle(`height: ${height}px`)
351+
expect(item).toHaveStyle(`line-height: ${height}px`)
352+
})
353+
})
354+
})

src/packages/noticebar/demo.taro.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const NoticeBarDemo = () => {
2929
customeRight: '自定义右侧内容',
3030
vertical: '垂直滚动',
3131
complexAm: '纵向模式:自定义左侧图标',
32-
customAm: '纵向模式:自定义滚动内容',
32+
customAm: '纵向模式:自定义滚动内容,动态变更滚动内容',
3333
customRightIcon: '纵向模式:自定义右侧图标',
3434
},
3535
'en-US': {
@@ -42,7 +42,7 @@ const NoticeBarDemo = () => {
4242
customeRight: 'custom right content',
4343
vertical: 'Vertical Scroll',
4444
complexAm: 'Vertical Scroll Complex Animation',
45-
customAm: 'Vertical Scroll Custom Style',
45+
customAm: 'Vertical Scroll Custom Style,Dynamic Change Scroll Content',
4646
customRightIcon: 'Vertical Scroll Custom Right Icon',
4747
},
4848
})

src/packages/noticebar/demo.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const NoticeBarDemo = () => {
2525
customeRight: '自定义右侧内容',
2626
vertical: '垂直滚动',
2727
complexAm: '纵向模式:自定义左侧图标',
28-
customAm: '纵向模式:自定义滚动内容',
28+
customAm: '纵向模式:自定义滚动内容,动态变更滚动内容',
2929
customRightIcon: '纵向模式:自定义右侧图标',
3030
},
3131
'en-US': {
@@ -38,7 +38,7 @@ const NoticeBarDemo = () => {
3838
customeRight: 'custom right content',
3939
vertical: 'Vertical Scroll',
4040
complexAm: 'Vertical Scroll Complex Animation',
41-
customAm: 'Vertical Scroll Custom Style',
41+
customAm: 'Vertical Scroll Custom Style,Dynamic Change Scroll Content',
4242
customRightIcon: 'Vertical Scroll Custom Right Icon',
4343
},
4444
})

src/packages/noticebar/demos/h5/demo10.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import React from 'react'
2-
import { NoticeBar } from '@nutui/nutui-react'
1+
import React, { useState } from 'react'
2+
import { Button, NoticeBar, Space } from '@nutui/nutui-react'
33

44
const Demo9 = () => {
55
const horseLamp3 = [
@@ -9,6 +9,8 @@ const Demo9 = () => {
99
'CheckBox 复选按钮',
1010
]
1111

12+
const [list, setList] = useState(horseLamp3)
13+
1214
return (
1315
<>
1416
<NoticeBar
@@ -21,7 +23,7 @@ const Demo9 = () => {
2123
console.log('close')
2224
}}
2325
>
24-
{horseLamp3.map((item, index) => {
26+
{list.map((item, index) => {
2527
return (
2628
<div
2729
className="custom-item"
@@ -36,6 +38,26 @@ const Demo9 = () => {
3638
)
3739
})}
3840
</NoticeBar>
41+
42+
<Space style={{ marginTop: '10px' }}>
43+
<Button
44+
size="small"
45+
onClick={() => {
46+
setList((prev) => [...prev, `${prev.length + 1}`])
47+
}}
48+
>
49+
添加最后一项
50+
</Button>
51+
52+
<Button
53+
size="small"
54+
onClick={() => {
55+
setList((prev) => prev.slice(0, -1))
56+
}}
57+
>
58+
删除最后一项
59+
</Button>
60+
</Space>
3961
</>
4062
)
4163
}

src/packages/noticebar/demos/taro/demo10.tsx

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import React from 'react'
2-
import { NoticeBar } from '@nutui/nutui-react-taro'
1+
import React, { useState } from 'react'
2+
import { Button, NoticeBar, Space } from '@nutui/nutui-react-taro'
33

44
const Demo10 = () => {
55
const horseLamp3 = [
@@ -9,6 +9,8 @@ const Demo10 = () => {
99
'CheckBox 复选按钮',
1010
]
1111

12+
const [list, setList] = useState(horseLamp3)
13+
1214
return (
1315
<>
1416
<NoticeBar
@@ -21,7 +23,7 @@ const Demo10 = () => {
2123
console.log('close')
2224
}}
2325
>
24-
{horseLamp3.map((item, index) => {
26+
{list.map((item, index) => {
2527
return (
2628
<div
2729
className="custom-item"
@@ -36,6 +38,26 @@ const Demo10 = () => {
3638
)
3739
})}
3840
</NoticeBar>
41+
42+
<Space style={{ marginTop: '10px' }}>
43+
<Button
44+
size="small"
45+
onClick={() => {
46+
setList((prev) => [...prev, `${prev.length + 1}`])
47+
}}
48+
>
49+
添加最后一项
50+
</Button>
51+
52+
<Button
53+
size="small"
54+
onClick={() => {
55+
setList((prev) => prev.slice(0, -1))
56+
}}
57+
>
58+
删除最后一项
59+
</Button>
60+
</Space>
3961
</>
4062
)
4163
}

src/packages/noticebar/doc.en-US.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Add Right mode to set more custom content.
8888

8989
:::
9090

91-
### Vertical Scroll Custom Style
91+
### Vertical Scroll Custom Style, Dynamic Content Updates
9292

9393
:::demo
9494

src/packages/noticebar/doc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ import { NoticeBar } from '@nutui/nutui-react'
9696

9797
:::
9898

99-
### 纵向模式:自定义右侧图标
99+
### 纵向模式:自定义右侧图标,动态变更滚动内容
100100

101101
:::demo
102102

src/packages/noticebar/doc.taro.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ import { NoticeBar } from '@nutui/nutui-react-taro'
9696

9797
:::
9898

99-
### 纵向模式:自定义右侧图标
99+
### 纵向模式:自定义右侧图标,动态变更滚动内容
100100

101101
:::demo
102102

src/packages/noticebar/doc.zh-TW.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ import { NoticeBar } from '@nutui/nutui-react'
9696

9797
:::
9898

99-
### 縱嚮模式:自定義右側圖標
99+
### 縱嚮模式:自定義右側圖標,動態變更滾動內容
100100

101101
:::demo
102102

0 commit comments

Comments
 (0)