-
Notifications
You must be signed in to change notification settings - Fork 348
feat(carousel): add draggable carousel #4006
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
The head ref may contain hidden characters: "Feature\u2014Carousel"
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,7 @@ export default { | |
| type: 'String', | ||
| defaultValue: '', | ||
| desc: { | ||
| 'zh-CN': '宽高比,默认为16:2。', | ||
| 'zh-CN': '宽高比,默认为 16:2。', | ||
| 'en-US': 'Aspect ratio. The default value is 16:2.' | ||
| }, | ||
| mode: ['mobile-first'], | ||
|
|
@@ -199,6 +199,22 @@ export default { | |
| mode: ['pc', 'mobile-first'], | ||
| pcDemo: 'swipeable', | ||
| mfDemo: '' | ||
| }, | ||
| //draggable | ||
| { | ||
| name: 'draggable', | ||
| type: 'boolean', | ||
| defaultValue: 'false', | ||
| desc: { | ||
| 'zh-CN': '是否允许拖拽切换幻灯片', | ||
| 'en-US': 'Whether to allow dragging to switch slides' | ||
| }, | ||
| mode: ['pc', 'mobile-first'], | ||
| pcDemo: 'draggable', | ||
| mfDemo: 'draggable', | ||
| meta: { | ||
| stable: '3.29.0' | ||
| } | ||
| } | ||
|
Comment on lines
+203
to
218
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Verify the default value in the component definition
rg -n "draggable" packages/vue/src/carousel/src/index.ts -A 3 -B 1Repository: opentiny/tiny-vue Length of output: 167 🏁 Script executed: #!/bin/bash
# Check the actual code in the API docs file at the specified lines
sed -n '203,218p' examples/sites/demos/apis/carousel.jsRepository: opentiny/tiny-vue Length of output: 483 Fix default value mismatch and remove redundant comment. The API documentation specifies Also remove the redundant comment 🤖 Prompt for AI Agents |
||
| ], | ||
| events: [ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| <template> | ||
| <tiny-collapse v-model="activeName" draggable @change="change"> | ||
| <tiny-collapse-item title="一致性 Consistency" name="1"> | ||
| <div>与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;</div> | ||
| <div>在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。</div> | ||
| </tiny-collapse-item> | ||
| <tiny-collapse-item title="反馈 Feedback" name="2"> | ||
| <div>控制反馈:通过界面样式和交互动效让用户可以清晰的感知自己的操作;</div> | ||
| <div>页面反馈:操作后,通过页面元素的变化清晰地展现当前状态。</div> | ||
| </tiny-collapse-item> | ||
| <tiny-collapse-item title="效率 Efficiency" name="3"> | ||
| <div>简化流程:设计简洁直观的操作流程;</div> | ||
| <div>清晰明确:语言表达清晰且表意明确,让用户快速理解进而作出决策;</div> | ||
| <div>帮助用户识别:界面简单直白,让用户快速识别而非回忆,减少用户记忆负担。</div> | ||
| </tiny-collapse-item> | ||
| <tiny-collapse-item title="可控 Controllability" name="4"> | ||
| <div>用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;</div> | ||
| <div>结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。</div> | ||
| </tiny-collapse-item> | ||
| </tiny-collapse> | ||
| </template> | ||
|
|
||
| <script> | ||
| import { TinyCollapse, TinyCollapseItem, TinyModal } from '@opentiny/vue' | ||
|
|
||
| export default { | ||
| components: { | ||
| TinyCollapse, | ||
| TinyCollapseItem | ||
| }, | ||
| data() { | ||
| return { | ||
| activeName: '1' | ||
| } | ||
| }, | ||
| methods: { | ||
| change(val) { | ||
| TinyModal.message({ | ||
| message: 'change 事件,当前选中的值为:' + val, | ||
| status: 'info' | ||
| }) | ||
| } | ||
| } | ||
| } | ||
| </script> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -22,7 +22,7 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| desc: { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'zh-CN': | ||||||||||||||||||||||||||||||||||||||||||||||||||
| '<p>配置 `accordion` 属性为 true 后,折叠面板将展示手风琴效果。配置 `v-model` 设置当前激活的面板(如果是手风琴模式,绑定值类型需要为 string ,否则为 array );`change` 事件,在当前激活面板改变时触发,参数为当前的 value 值;配置 `name` 属性作为每个 collapse-item 的唯一标志符<p>', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| '<p>配置 `accordion` 属性为 true 后,折叠面板将展示手风琴效果。配置 `v-model` 设置当前激活的面板 (如果是手风琴模式,绑定值类型需要为 string,否则为 array );`change` 事件,在当前激活面板改变时触发,参数为当前的 value 值;配置 `name` 属性作为每个 collapse-item 的唯一标志符<p>', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'en-US': | ||||||||||||||||||||||||||||||||||||||||||||||||||
| '<p>If the `accordion` attribute is set to true, the collapse panel displays the accordion effect. Configure `v-model` Sets the currently active panel. (In accordion mode, the binding value type must be string. Otherwise, the binding value type is array.) `change` event, which is triggered when the current active panel changes. The parameter is the current value. Configure the `name` attribute as the unique identifier for each collapse-item</p>' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -88,7 +88,7 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||
| 'en-US': 'Prevent Collapse Panel Close Event' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| desc: { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'zh-CN': '<p>:before-close 折叠面板关闭前事件,方法里面 return true/false,表示是否可以关闭<p>', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'zh-CN': '<p>:before-close 折叠面板关闭前事件,方法里面 return true/false,表示是否可以关闭<p>', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'en-US': | ||||||||||||||||||||||||||||||||||||||||||||||||||
| '<p>:before-close: indicates the event before the folding panel is closed. In the method, return true or false indicates whether the folding panel can be closed.</p>' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -154,6 +154,19 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||
| 'en-US': '<p>Icons are implemented by configuring the built-in icon slot of Collapse.</p>' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| codeFiles: ['slot-icon.vue'] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| //draggable | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| demoId: 'draggable', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| name: { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'zh-CN': '可拖拽', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'en-US': 'Draggable' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| desc: { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'zh-CN': '<p>通过配置 Collapse 内置的 draggable 属性实现拖拽<p>', | ||||||||||||||||||||||||||||||||||||||||||||||||||
| 'en-US': '<p>Drag and drop is implemented by configuring the built-in draggable slot of Collapse.</p>' | ||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| codeFiles: ['draggable.vue'] | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+158
to
+169
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doc text should reference the The demo uses a prop ( ✏️ Suggested wording- desc: {
- 'zh-CN': '<p>通过配置 Collapse 内置的 draggable 插槽实现拖拽<p>',
- 'en-US': '<p>Drag and drop is implemented by configuring the built-in draggable slot of Collapse.</p>'
- },
+ desc: {
+ 'zh-CN': '<p>通过配置 Collapse 的 <code>draggable</code> 属性实现拖拽<p>',
+ 'en-US': '<p>Enable drag by setting the <code>draggable</code> prop on Collapse.</p>'
+ },📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import { test, expect } from '@playwright/test' | ||
|
|
||
| test('draggable - 基本功能测试', async ({ page }) => { | ||
| page.on('pageerror', (exception) => expect(exception).toBeNull()) | ||
|
|
||
| // 1. 打开页面 | ||
| await page.goto('carousel#draggable') | ||
|
|
||
| // 2. 验证组件加载 | ||
| await expect(page.locator('.tiny-carousel')).toBeVisible() | ||
|
|
||
| // 3. 验证有轮播项 | ||
| const items = page.locator('.tiny-carousel__item') | ||
| const count = await items.count() | ||
| expect(count).toBeGreaterThan(0) | ||
|
|
||
| // 4. 验证初始状态 | ||
| await expect(items.nth(0)).toHaveClass(/active/) | ||
|
|
||
| // 5. 测试鼠标事件可以触发(不验证具体切换) | ||
| const carousel = page.locator('.tiny-carousel').first() | ||
| await carousel.hover() | ||
| await carousel.dispatchEvent('mousedown') | ||
| await page.waitForTimeout(50) | ||
| await carousel.dispatchEvent('mousemove', { clientX: 100, clientY: 100 }) | ||
| await page.waitForTimeout(50) | ||
| await carousel.dispatchEvent('mouseup') | ||
|
|
||
| // 6. 测试触摸事件可以触发 | ||
| await carousel.dispatchEvent('touchstart') | ||
| await page.waitForTimeout(50) | ||
| await carousel.dispatchEvent('touchend') | ||
|
Comment on lines
+29
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Touch events lack required touch point data. The Consider using proper touch event initialization- await carousel.dispatchEvent('touchstart')
- await page.waitForTimeout(50)
- await carousel.dispatchEvent('touchend')
+ await carousel.evaluate((el) => {
+ const rect = el.getBoundingClientRect()
+ const touch = new Touch({
+ identifier: 1,
+ target: el,
+ clientX: rect.left + rect.width / 2,
+ clientY: rect.top + rect.height / 2
+ })
+ el.dispatchEvent(new TouchEvent('touchstart', { touches: [touch] }))
+ el.dispatchEvent(new TouchEvent('touchend', { changedTouches: [touch] }))
+ })🤖 Prompt for AI Agents |
||
|
|
||
| // 7. 验证没有报错即可 | ||
| console.log('draggable 测试通过') | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| <template> | ||
| <tiny-carousel height="150px" draggable> | ||
| <tiny-carousel-item class="carousel-item-demo" v-for="item in 4" :key="item"> | ||
| <h3>{{ item }}</h3> | ||
| </tiny-carousel-item> | ||
| </tiny-carousel> | ||
| </template> | ||
|
|
||
| <script> | ||
| import { TinyCarousel, TinyCarouselItem } from '@opentiny/vue' | ||
|
|
||
| export default { | ||
| components: { | ||
| TinyCarousel, | ||
| TinyCarouselItem | ||
| } | ||
| } | ||
| </script> | ||
|
|
||
| <style scoped> | ||
| .tiny-carousel__item h3 { | ||
| color: #808080; | ||
| opacity: 0.75; | ||
| line-height: 150px; | ||
| margin: 0; | ||
| text-align: center; | ||
| font-size: 25px; | ||
| } | ||
|
|
||
| .carousel-item-demo:nth-child(2n) { | ||
| background-color: rgba(221, 221, 221, 0.2); | ||
| } | ||
|
|
||
| .carousel-item-demo:nth-child(2n + 1) { | ||
| background-color: rgba(221, 221, 221, 0.1); | ||
| } | ||
| </style> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
新的特性需要添加版本信息哈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ourcx 可参考以下文档添加版本信息:
给组件的新 API 添加 meta 信息