Skip to content

Tappable 可点击容器

为移动端优化的可点击容器组件,提供平台特定的交互反馈效果。

导入

ts
import { Tappable } from '@xcloud/ui-mobile';

示例

基础用法

tsx
import { Tappable } from '@xcloud/ui-mobile';

function Example() {
  return (
    <Tappable onClick={() => console.log('Clicked!')}>
      <div className="p-4">点击我</div>
    </Tappable>
  );
}

平台特定效果

Android (Base) - 水波纹效果

tsx
<Tappable platform="base" interactiveAnimation="background">
  <div>Android 水波纹效果</div>
</Tappable>

iOS - 透明度变化

tsx
<Tappable platform="ios">
  <div>iOS 透明度反馈</div>
</Tappable>

交互动画类型

tsx
{/* 背景水波纹 (仅 Android) */}
<Tappable interactiveAnimation="background">
  <div>背景动画</div>
</Tappable>

{/* 透明度变化 */}
<Tappable interactiveAnimation="opacity">
  <div>透明度动画</div>
</Tappable>

禁用和只读状态

tsx
{/* 禁用状态 - 降低透明度,禁用点击 */}
<Tappable disabled>
  <div>禁用状态</div>
</Tappable>

{/* 只读状态 - 保持可见性,禁用交互 */}
<Tappable readOnly>
  <div>只读状态</div>
</Tappable>

自定义 HTML 标签

tsx
{/* 使用 button 元素 */}
<Tappable Component="button" onClick={handleClick}>
  <span>按钮</span>
</Tappable>

{/* 使用 a 元素 */}
<Tappable Component="a" href="/path">
  <span>链接</span>
</Tappable>

API

属性类型默认值说明
ComponentElementType'div'HTML 标签类型
platform'ios' | 'base''base'平台类型,影响交互效果
interactiveAnimation'opacity' | 'background''background'交互动画类型
readOnlyboolean-只读状态
disabledboolean-禁用状态
...restPropsAllHTMLAttributes<HTMLElement>-其他 HTML 属性

平台差异

Android (platform="base")

  • interactiveAnimation="background": 显示水波纹效果
  • interactiveAnimation="opacity": 透明度变化
  • 支持 Material Design 触摸反馈

iOS (platform="ios")

  • 始终使用透明度变化,忽略 interactiveAnimation 设置
  • 符合 iOS Human Interface Guidelines
  • active:opacity-65hover:opacity-85

使用场景

1. 列表项

tsx
<div className="divide-y">
  {items.map(item => (
    <Tappable
      key={item.id}
      onClick={() => navigate(item.path)}
      className="p-4"
    >
      <div className="flex justify-between">
        <span>{item.title}</span>
        <span className="text-gray-400">›</span>
      </div>
    </Tappable>
  ))}
</div>

2. 卡片

tsx
<Tappable onClick={handleCardClick} className="rounded-lg border p-4">
  <CardContent />
</Tappable>

3. 自定义按钮

tsx
<Tappable
  Component="button"
  platform="ios"
  className="rounded-full bg-blue-500 px-6 py-3 text-white"
>
  提交
</Tappable>

水波纹效果实现

水波纹效果使用 useRipple hook 和 Ripple 组件实现:

  • 监听 pointerDownpointerCancel 事件
  • 动态生成涟漪圆形动画
  • 仅在 platform="base"interactiveAnimation="background" 时显示
  • 不影响只读状态元素

最佳实践

  1. 选择合适的平台: 根据目标用户设备选择 platform
  2. 语义化标签: 使用合适的 Component 属性(button/a/div)
  3. 无障碍性:
    tsx
    <Tappable Component="button" aria-label="关闭对话框">
      <CloseIcon />
    </Tappable>
  4. 避免嵌套: 不要嵌套多个 Tappable 组件
  5. 性能优化: 对于长列表,考虑使用虚拟滚动减少 DOM 节点

样式注意事项

组件自带以下样式:

  • position: relative 用于水波纹定位
  • cursor: pointer 表示可点击
  • transition-opacity 用于透明度动画
  • disabled:opacity-35 禁用状态样式
  • read-only:pointer-events-auto 只读状态样式

可通过 className 覆盖或扩展这些样式。

与 Touch 组件的区别

  • Tappable: 简单的点击反馈,适用于按钮、列表项等
  • Touch: 复杂的手势处理(滑动、拖拽等),适用于轮播图、滑动操作等

如需手势支持,请使用 Touch 组件。

基于 MIT 许可发布