npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@zh40s05/zepp-adaptive-button

v1.2.2

Published

ZeppOS 自适应按键融合库 — 物理按键与触摸屏按钮融合 / Fuse physical keys with touchscreen buttons

Readme

zabt — ZeppOS 自适应按键融合库 / ZeppOS Adaptive Button Library

中文 | English


中文

是什么

zabt 将 ZeppOS 手表物理按键与触摸屏按钮融合,提供五大功能:

  1. 焦点高亮 — 按键导航时按钮显示高亮色,清楚指示当前选中
  2. 按下动画 — SELECT/HOME 按下时按钮显示按下色,抬起恢复(物理按键 + 触屏同款视觉)
  3. 超时撤销 — 按住 SELECT 超过 1 秒自动取消,日志输出按钮文字
  4. 触屏焦点同步 — 触屏点击按钮后按键焦点自动移动到该按钮
  5. 焦点跟随滚动 — 自由滚动/Swiper 翻页时自动滚动至聚焦按钮(含自定义平滑动画)

首个 zabtBtn() 自动注册按键,无需手动 onKey

安装

# pnpm(推荐)
pnpm add @zh40s05/zepp-adaptive-button
# npm
npm install @zh40s05/zepp-adaptive-button
# 手动
cp zabt.js your-app/utils/zabt.js

快速开始

相比普通按钮仅两处改动:换函数名、加可选 order

import { zabtBtn } from '../utils/zabt'

// 普通按钮 / normal button
const btn = zabtBtn({
  x: 100,
  y: 310,
  w: 280,
  h: 56,
  radius: 28,
  text_size: 28,
  normal_color: 0x374151,
  press_color: 0x232C36,
  text: '确认',
  click_func: () => showToast({ content: 'ok' }),
  order: 0,
})

// 弹窗按钮 — antiBounce: true / modal button
const infoBtn = zabtBtn({
  x: 220,
  y: 420,
  w: 40,
  h: 40,
  radius: 20,
  text_size: 22,
  normal_color: 0x374151,
  press_color: 0x232C36,
  text: 'i',
  click_func: () => {
    let m = createModal({
      autoHide: true,
      onClick: () => { m.show(false); zabtUnblock() }
    })
  },
  order: 1,
  antiBounce: true,
})

API

| 导出 | 说明 | |---|---| | zabtBtn(opts) | 创建融合按钮。所有 createWidget(widget.BUTTON, ...) 字段 + order/focusColor/focusSrc/antiBounce | | zabtSetScrollConfig(cfg) | 焦点跟随滚动 + 自动系统滚动模式配置 | | zabtSetLabel(w, text) | 修改按钮文字 | | zabtSetNormalColor(w, c) | 修改 normal 态颜色(自动重算 focusColor) | | zabtBlock() | 手动阻断按键 | | zabtUnblock() | 释放阻断 + 丢弃一次残留确认事件 |

按钮可选参数

| 参数 | 说明 | |---|---| | order | 导航顺序。不传按创建顺序自动补入,冲突后延 | | focusColor | 高亮色。不传基于 normal_color 自动调亮(每通道 +0x28) | | focusSrc | 高亮图片(图片按钮)。不传显示"未定义高亮" | | antiBounce | true 用于弹窗/模态框按钮。默认 false |

antiBounce — 何时用

问题:按键打开弹窗,同一次按键的尾随 CLICK 在弹窗关闭后重新触发按钮。

方案antiBounce: true 动作后自动阻断。弹窗关闭时调 zabtUnblock() 释放 + 丢弃一次残留事件。

| ✅ 用 | ❌ 不用 | |---|---| | createModal | showToast | | 消耗按键的 UI 层 | launchApp | | | setProperty / 状态切换 |

焦点跟随滚动 — zabtSetScrollConfig

替代手动 setScrollMode,一次调用同时配置系统滚动模式 + 按钮焦点追踪。

需 app.json 权限:"data:os.device.info"

| 模式 | 调用 | 官方对应 | |---|---|---| | 锁定(默认) | 不调用 | — | | 自由滚动 | { mode: 'free' } | SCROLL_MODE_FREE | | 纵向翻页 | { mode: 'swiper', pageCount: 3 } | SCROLL_MODE_SWIPER + options.height/count | | 横向翻页 | { mode: 'swiper-h', pageCount: 3 } | SCROLL_MODE_SWIPER_HORIZONTAL + options.width/count |

自动获取(可传入覆盖):screenHeight(设备屏幕高度), pageSize(默认等于屏幕高度)

// 自由滚动
zabtSetScrollConfig({ mode: 'free' })

// 横向翻页
zabtSetScrollConfig({ mode: 'swiper-h', pageCount: 3 })

行为规则

  • 无焦点 + SELECT → 触发 order 最小按钮
  • 无焦点 + UP → 选中 order 最小 / DOWN → 选中 order 次小
  • 导航边界环绕
  • SELECT 按住 > 1s → 超时撤销(日志输出按钮文字)
  • 触屏点击 → 执行动作 + 移动内部焦点(不显示高亮),之后按键恢复

Example / 示例

example/ 自包含测试程序,直接复制运行 zeus build

演示:order 分配、focusColor 自动/手动、动态修改文字颜色、antiBounce 弹窗、自由滚动、横向/纵向翻页。


English

What

zabt fuses physical keys with touchscreen buttons. Five features:

  1. Focus Highlight — focused button shows highlight color during key navigation
  2. Press Animation — SELECT/HOME shows press color on hold, restores on release (same visual as touch)
  3. Hold-to-Cancel — holding SELECT > 1s cancels the action, logs button text
  4. Touch-Focus Sync — touching a button moves key focus to it
  5. Scroll-Aware Focus — auto-scrolls (free) or auto-flips (swiper) to keep focused button visible, with custom smooth animation

Keys are auto-registered on the first zabtBtn() call — no manual onKey needed.

Install

pnpm add @zh40s05/zepp-adaptive-button
npm install @zh40s05/zepp-adaptive-button
cp zabt.js your-app/utils/zabt.js

Quick Start

Only 2 changes from a normal button: swap the function, add optional order.

import { zabtBtn } from '../utils/zabt'

// Normal button / 普通按钮
const btn = zabtBtn({
  x: 100,
  y: 310,
  w: 280,
  h: 56,
  radius: 28,
  text_size: 28,
  normal_color: 0x374151,
  press_color: 0x232C36,
  text: 'Confirm',
  click_func: () => showToast({ content: 'ok' }),
  order: 0,
})

// Modal button — antiBounce: true / 弹窗按钮
const infoBtn = zabtBtn({
  x: 220,
  y: 420,
  w: 40,
  h: 40,
  radius: 20,
  text_size: 22,
  normal_color: 0x374151,
  press_color: 0x232C36,
  text: 'i',
  click_func: () => {
    let m = createModal({
      autoHide: true,
      onClick: () => { m.show(false); zabtUnblock() }
    })
  },
  order: 1,
  antiBounce: true,
})

API

| Export | Description | |---|---| | zabtBtn(opts) | Create fused button. All createWidget(widget.BUTTON, ...) fields + order/focusColor/focusSrc/antiBounce | | zabtSetScrollConfig(cfg) | Scroll-aware focus + auto system scroll mode setup | | zabtSetLabel(w, text) | Change button text | | zabtSetNormalColor(w, c) | Change normal color (auto-recalc focusColor) | | zabtBlock() | Manually block key input | | zabtUnblock() | Unblock + discard one residual confirm event |

Button Options

| Field | Description | |---|---| | order | Navigation order. Auto-assigned if omitted, conflicts shift later | | focusColor | Highlight color. Auto-calc from normal_color (+0x28/channel) | | focusSrc | Highlight image (image buttons). Falls back to "未定义高亮" | | antiBounce | true for modal/popup buttons. Default false |

antiBounce — When & Why

Problem: key-triggered modal → trailing CLICK re-triggers after close.

Solution: antiBounce: true auto-blocks after action. Call zabtUnblock() on modal close.

| ✅ Use | ❌ Don't | |---|---| | createModal | showToast | | Any key-consuming UI | launchApp | | | setProperty / state toggle |

Scroll-Aware Focus — zabtSetScrollConfig

Replaces manual setScrollMode. One call = system scroll mode + focus tracking.

Requires "data:os.device.info" in app.json.

| Mode | Config | Official API | |---|---|---| | Locked (default) | (no call) | — | | Free scroll | { mode: 'free' } | SCROLL_MODE_FREE | | Swiper V | { mode: 'swiper', pageCount: 3 } | SCROLL_MODE_SWIPER + height/count | | Swiper H | { mode: 'swiper-h', pageCount: 3 } | SCROLL_MODE_SWIPER_HORIZONTAL + width/count |

Auto-detected (override by passing): screenHeight, pageSize (defaults to screenHeight)

zabtSetScrollConfig({ mode: 'free' })
zabtSetScrollConfig({ mode: 'swiper-h', pageCount: 3 })

Behavior

  • No focus + SELECT → smallest-order button
  • No focus + UP → smallest / DOWN → second-smallest
  • Navigation wraps
  • SELECT held > 1s → cancelled (logs button text)
  • Touch-click → execute + move focus (no highlight), keys restore highlight

Example

example/ — self-contained test app with 4 page modes.

Demos: order, focusColor, dynamic updates, antiBounce modal, free scroll, swiper-h, swiper-v.

License

MIT © 2026 ZHAO