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

@zhencai/vue-focus-scope

v1.0.12

Published

一个基于 Vue 3 的焦点循环管理组件。它通过"哨兵节点"(Sentinel Nodes)技术,在指定的 DOM 作用域内实现键盘 Tab 键的无缝循环导航。

Readme

焦点管理组件

一个基于 Vue 3 的焦点循环管理组件。它通过"哨兵节点"(Sentinel Nodes)技术,在指定的 DOM 作用域内实现键盘 Tab 键的无缝循环导航。

适用于模态框(Modal)、下拉菜单、自定义表单或任何需要限制用户焦点范围的场景,符合 WAI-ARIA 无障碍最佳实践。

功能特性

  • 自动循环导航

    • Tab 到达最后一个元素时,自动跳回第一个
    • Shift + Tab 到达第一个元素时,自动跳到最后一个
  • 智能作用域限制

    • 自动过滤不可聚焦元素(tabindex="-1", disabled
    • 自动忽略被 <fieldset disabled> 包裹的元素
    • 排除内部哨兵节点,防止干扰正常流程
  • 双模式支持

    • loop (默认):强循环模式。焦点被严格限制在组件内部,无法通过 Tab 键移出
    • soft-loop:软循环模式。在首尾之间提供缓冲,允许特定的交互逻辑(防止单元素死循环)
  • 自动聚焦

    • 通过 autofocus 属性控制组件挂载时是否自动聚焦第一个可聚焦元素
    • 支持动态切换,可在组件挂载后通过改变属性值触发聚焦
    • 适用于多作用域场景,避免后挂载的组件抢占焦点
  • 无障碍友好:原生支持键盘导航,无需额外配置

安装

npm install @zhencai/vue-focus-scope

基础用法

<template>
  <FocusScope>
    <h3>用户登录</h3>
    <input type="text" placeholder="用户名" />
    <input type="password" placeholder="密码" />
    <button @click="submit">登录</button>
    <a href="/forgot">忘记密码?</a>
  </FocusScope>
</template>

<script setup lang="ts">
import { FocusScope } from "@zhencai/vue-focus-scope";
</script>

模式切换

通过 tabMode 属性控制循环行为:

<script setup lang="ts">
import { FocusScope } from "@zhencai/vue-focus-scope";
</script>
<template>
  <!-- 强循环:焦点永远无法逃出此区域 -->
  <FocusScope tab-mode="loop">
    <!-- 内容 -->
  </FocusScope>

  <!-- 软循环:适合只有一个输入框或需要特殊逃逸逻辑的场景 -->
  <FocusScope tab-mode="soft-loop">
    <input type="text" placeholder="唯一输入框" />
  </FocusScope>
</template>

自动聚焦控制

通过 autofocus 属性控制焦点行为:

<script setup lang="ts">
import { FocusScope } from "@zhencai/vue-focus-scope";
import { ref } from "vue";

const showDialog = ref(false);
</script>
<template>
  <div>
    <!-- 场景1:默认不自动聚焦 -->
    <FocusScope :autofocus="false">
      <input type="text" placeholder="不会自动聚焦" />
    </FocusScope>

    <!-- 场景2:挂载时自动聚焦 -->
    <FocusScope :autofocus="true">
      <input type="text" placeholder="会自动聚焦到这里" />
    </FocusScope>

    <!-- 场景3:动态控制聚焦(多作用域场景) -->
    <button @click="showDialog = true">打开对话框</button>
    <FocusScope v-if="showDialog" :autofocus="true">
      <input type="text" placeholder="对话框打开时自动聚焦" />
      <button @click="showDialog = false">关闭</button>
    </FocusScope>
  </div>
</template>

多作用域场景说明

  • 当页面有多个 FocusScope 组件时,为了避免后挂载的组件抢占焦点
  • 可以先将所有组件的 autofocus 设为 false
  • 在需要聚焦时(如对话框显示、标签页切换),动态将对应组件的 autofocus 设为 true

API 文档

Props

| 属性名 | 类型 | 默认值 | 说明 | | :---------- | :---------------------- | :------- | :-------------------------------------------------------------------------------------------------------------------- | | tabMode | 'loop' \| 'soft-loop' | 'loop' | 循环模式:- loop: 严格限制焦点在插槽内- soft-loop: 允许一定程度的外部交互,主要用于防止单元素死循环 | | autofocus | boolean | false | 是否自动聚焦第一个可聚焦元素:- true: 组件挂载时或属性变为 true 时自动聚焦- false: 不自动聚焦,需手动控制 |

Slots

| 名称 | 说明 | | :-------- | :------------------------------------------------------- | | default | 放置需要被管理焦点的子元素(如 input, button, a 标签等) |

工作原理

该组件利用 Focus Sentinel(焦点哨兵) 技术:

起始哨兵 (sentinel-start)

  • 位于插槽内容之前
  • 当用户按 Shift + Tab 从第一个元素回退时,焦点会落在此处
  • 组件拦截该事件,立即将焦点重定向到最后一个可聚焦元素

结束哨兵 (sentinel-end)

  • 位于插槽内容之后
  • 当用户按 Tab 从最后一个元素前进时,焦点会落在此处
  • 组件拦截该事件,立即将焦点重定向到第一个可聚焦元素

可聚焦元素检测

  • 内部使用 querySelectorAll 动态计算当前作用域内的有效焦点元素
  • 自动排除 tabindex="-1"disabled 状态以及被禁用的 fieldset

注意事项

  • 子元素要求:确保插槽内的元素是原生的可聚焦元素(如 <input>, <button>, <a href>)或具有有效的 tabindex

许可证

MIT