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

@potmot/list

v0.0.7

Published

Editable, Selectable. Simple ViewList and EditList components.

Downloads

748

Readme

@potmot/list

基于 Vue3 + TypeScript 的通用列表组件库,提供编辑和视图两种列表,支持键盘操作、多选、剪贴板等功能。

特性

  • 🔧 TypeScript - 完整的类型推导支持
  • 🌐 泛型支持 - 适用于任何数据类型
  • 🎨 完全可定制 - 支持自定义插槽(head、line、tail)
  • 📦 轻量级 - 依赖少,体积小
  • 可访问性 - 支持键盘导航和焦点管理

ViewList 组件

  • ⌨️ 键盘快捷键
    • Ctrl/Cmd + A - 全选
    • Ctrl/Cmd + C - 复制选中项
    • Arrow Up / Arrow Down - 切换选中项
  • 🖱️ 鼠标交互 - 支持单选、多选、范围选择
  • 📋 剪贴板支持 - 复制 JSON 格式数据
  • 🎯 智能交互 - 自动识别交互式元素

EditList 组件

  • ⌨️ 键盘快捷键
    • Delete / Backspace - 删除选中项
    • Ctrl/Cmd + A - 全选
    • Ctrl/Cmd + C - 复制选中项
    • Ctrl/Cmd + X - 剪切选中项
    • Ctrl/Cmd + V - 粘贴 JSON 数据
    • Arrow Up / Arrow Down - 上下移动选中项
    • Enter - 在选中项后插入新行
  • 🖱️ 鼠标交互
    • 点击选择单项
    • Ctrl/Cmd + 点击 多选
    • Shift + 点击 范围选择
  • 📋 剪贴板支持 - 复制/粘贴 JSON 格式数据
  • 数据验证 - 支持自定义 JSON 验证器

快速开始

使用对应包管理器进行安装

npm install @potmot/list
yarn add @potmot/list
pnpm add @potmot/list

导入样式

import '@potmot/list/es/index.css'

可根据需要覆盖样式变量

:root {
    --potmot-list--text-color: #444;

    --potmot-list--bg-color: #fff;
    --potmot-list--bg-color--hover: #eee;
    --potmot-list--bg-color--selected: #89bdf4;

    --potmot-list--icon-color: #666;
    --potmot-list--icon-size: 1rem;
}

EditList 简单使用示例


<script setup lang="ts">
    import {EditList} from '@potmot/list';
    import {ref} from 'vue';

    type EditListItem = {
        id: string;
        name: string;
        age: number;
    };

    const editListData = ref<EditListItem[]>([]);

    const nextId = ref(1);
    const defaultEditListData = (): EditListItem => ({
        id: `${nextId.value}`,
        name: `New Name`,
        age: 18,
    });

    const handleCopied = (data: EditListItem[]) => {
        alert(`复制了 ${data.map((it) => it.name).join(',')}`);
    };

    const validateItem = (item: any) => {
        if (typeof item !== 'object') {
            return false;
        }
        if (!item.id || !item.name || !item.age) {
            return false;
        }
        return !(
            typeof item.id !== 'string' ||
            typeof item.name !== 'string' ||
            typeof item.age !== 'number'
        );
    };

    const beforePaste = (items: EditListItem[]) => {
        for (const item of items) {
            item.id = `${nextId.value++}`;
        }
    };
</script>

<template>
    <EditList
        :lines="editListData"
        :to-key="(item) => item.id"
        :default-line="defaultEditListData"
        @copied="handleCopied"
        :pasteValidator="validateItem"
        :before-paste="beforePaste"
    >
        <template #line="{item}">
            <div class="line-item">
                <span>ID: {{ item.id }}</span>
                <span>姓名: {{ item.name }}</span>
                <span>年龄: {{ item.age }}</span>
            </div>
        </template>
    </EditList>
</template>

ViewList 简单使用示例


<script setup lang="ts">
    import {ViewList} from '@potmot/list';
    import {ref} from 'vue';

    type ViewListItem = {
        id: string;
        name: string;
        age: number;
    };

    const viewListData = ref<ViewListItem[]>([
        {
            id: '1',
            name: 'Jack',
            age: 18,
        },
        {
            id: '2',
            name: 'Rose',
            age: 19,
        },
        {
            id: '3',
            name: 'Mary',
            age: 20,
        },
    ]);

    const handleCopied = (data: ViewListItem[]) => {
        alert(`复制了 ${data.map((it) => it.name).join(',')}`);
    };
</script>

<template>
    <ViewList
        :lines="viewListData"
        :to-key="(item) => item.id"
        @copied="handleCopied"
    >
        <template #line="{item}">
            <div class="line-item">
                <span>id: {{ item.id }}</span>
                <span>名字: {{ item.name }}</span>
                <span>年龄: {{ item.age }}</span>
            </div>
        </template>
    </ViewList>
</template>

API 文档

EditList Props

| 属性 | 类型 | 必填 | 说明 | |------------------|----------------------------------------------------------|----|---------------------| | lines | T[] | ✅ | 列表数据(支持 v-model) | | defaultLine | T \| (() => T \| Promise<T>) | ✅ | 默认新行数据或生成函数 | | toKey | (line: T, index: number) => string | ✅ | 生成唯一键的函数 | | pasteValidator | (json: any, onError?: (error: any) => void) => boolean | ❌ | 粘贴验证函数 | | ignoreClassNames | string[] | ❌ | 交互式元素的类名列表 | | beforeCopy | (data: T[]) => void | ❌ | 复制前回调,可以在复制前对数据进行处理 | | beforePaste | (data: T[]) => void | ❌ | 粘贴前回调,可以在粘贴前对数据进行处理 |

ViewList Props

| 属性 | 类型 | 必填 | 说明 | |------------------|--------------------------------------|----|---------------------| | lines | T[] | ✅ | 列表数据 | | toKey | (line: T, index: number) => string | ✅ | 生成唯一键的函数 | | ignoreClassNames | string[] | ❌ | 交互式元素的类名列表 | | beforeCopy | (data: T[]) => void | ❌ | 复制前回调,可以在复制前对数据进行处理 |

EditList Events

| 事件名 | 参数 | 说明 | |--------------|-------------------------------------------|----------| | click-item | (e: MouseEvent, item: T, index: number) | 点击列表项时触发 | | selected | (item: T, index: number) | 选中项时触发 | | unselected | (item: T, index: number) | 取消选中时触发 | | added | (added: T[]) | 添加项时触发 | | deleted | (deleted: T[]) | 删除项时触发 | | copied | (copied: T[]) | 复制成功时触发 | | copy-failed | (error: any) | 复制失败时触发 | | pasted | (pasted: T[]) | 粘贴成功时触发 | | paste-failed | (error: any) | 粘贴失败时触发 |

ViewList Events

| 事件名 | 参数 | 说明 | |------------|-------------------------------------------|----------| | click-item | (e: MouseEvent, item: T, index: number) | 点击列表项时触发 | | selected | (item: T, index: number) | 选中项时触发 | | unselected | (item: T, index: number) | 取消选中时触发 | | copied | (copied: T[]) | 复制成功时触发 | | copy-failed | (error: any) | 复制失败时触发 |

Slots

EditList / ViewList

| 插槽名 | 作用域参数 | 说明 | |------|------------------------------|---------------------------| | head | { lines: T[] } | 列表头部内容 | | line | { item: T, index: number } | 列表项渲染 | | tail | { lines: T[] } | 列表尾部内容(EditList 默认包含添加按钮) |

Expose

ViewListExpose

| 属性 | 类型 | 说明 | |-------------------------|----------------------------|----------| | listRef | Ref<HTMLElement \| null> | 列表容器引用 | | bodyRef | Ref<HTMLElement \| null> | 列表主体引用 | | focusList | () => void | 聚焦列表 | | indexSelection | IndexSelection | 选择状态管理对象 | | expandSelectionUpward | () => void | 向上扩充选中区间 | | expandSelectionDownward | () => void | 向下扩充选中区间 |

EditListExpose

| 属性 | 类型 | 说明 | |-------------------------|----------------------------------------------|-----------| | listRef | Ref<HTMLElement \| null> | 列表容器引用 | | bodyRef | Ref<HTMLElement \| null> | 列表主体引用 | | focusList | () => void | 聚焦列表 | | indexSelection | IndexSelection | 选择状态管理对象 | | expandSelectionUpward | () => void | 向上扩充选中区间 | | expandSelectionDownward | () => void | 向下扩充选中区间 | | insert | (index: number) => Promise<T> | 在指定位置插入新行 | | remove | (index: number) => Promise<T \| undefined> | 删除指定位置的行 | | moveUpSelection | () => Promise<void> | 上移选中项 | | moveDownSelection | () => Promise<void> | 下移选中项 |

IndexSelection API

| 方法/属性 | 类型 | 说明 | |---------------------|------------------------------------------|----------| | current | DeepReadonly<Ref<number \| undefined>> | 当前选中项索引 | | setCurrent | (index: number \| undefined) => void | 设置当前选中项 | | selectedSet | DeepReadonly<Ref<Set<number>>> | 已选中的项集合 | | isSelected | (index: number) => boolean | 判断是否选中 | | select | (index: number \| number[]) => void | 选中指定索引 | | selectRange | (start: number, end: number) => void | 选中范围 | | unselect | (index: number \| number[]) => void | 取消选中指定索引 | | unselectRange | (start: number, end: number) => void | 取消选中范围 | | unselectAll | () => void | 取消全部选中 | | resetSelection | (indexes: number[]) => void | 重置选中状态 | | resetSelectionRange | (start: number, end: number) => void | 重置为范围选中 |

ListGlobalConfig

列表组件库的全局配置对象,用于设置默认的行为和处理程序。可以在应用级别进行配置以影响所有列表组件的默认行为。

配置项

| 属性 | 类型 | 默认值 | 说明 | |---------------------|------------------------------------------------|-------------------------------------------------------------------|-----------------------------| | ignoreClassNames | string[] | [] | 交互式元素的类名列表,这些元素不会触发列表项的选择操作 | | copySuccessHandler | ((data: any[]) => void) \| null \| undefined | null | 复制成功时的全局回调函数,接收复制的数据数组作为参数 | | copyFailedHandler | ((error: any) => void) \| null \| undefined | (error: any) => { console.error('List copy failed.', error); } | 复制失败时的全局回调函数,接收错误信息作为参数 | | pasteSuccessHandler | ((data: any[]) => void) \| null \| undefined | null | 粘贴成功时的全局回调函数,接收粘贴的数据数组作为参数 | | pasteFailedHandler | ((error: any) => void) \| null \| undefined | (error: any) => { console.error('List paste failed.', error); } | 粘贴失败时的全局回调函数,接收错误信息作为参数 |

使用示例

License

MIT