CKUI

A modern, dependency-free UI library for Tampermonkey scripts

このスクリプトは単体で利用できません。右のようなメタデータを含むスクリプトから、ライブラリとして読み込まれます: // @require https://update.greasyfork.org/scripts/564901/1749919/CKUI.js

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
作者
CKylinMC
バージョン
2.4.2
作成日
2026/02/02
更新日
2026/02/06
大きさ
141KB
ライセンス
GPL-3.0-only

CKUI 是一个专为 Tampermonkey/Greasemonkey 用户脚本设计的现代化 UI 库,提供开箱即用的 UI 组件,无需任何外部依赖。

核心特性:

  • 零依赖 - 纯原生 JavaScript 实现,无需引入任何框架
  • 🎨 现代设计 - 参考 shadcn/ui 设计风格,美观且专业
  • 🌓 深色模式 - 内置浅色/深色主题,一键切换
  • 🔒 样式隔离 - 支持 Shadow DOM,完全避免样式冲突
  • 响应式 - 内置响应式数据绑定系统
  • 🛡️ 表单验证 - 强大的表单验证和回调系统
  • 📦 体积小巧 - 完整功能仅 100KB 左右

🚀 使用方法

在 Tampermonkey 脚本中使用

在你的用户脚本头部添加 @require 语句(页面顶部提供语句模板)

注意: CKUI 会在页面加载时自动初始化,你可以直接通过 ckuiunsafeWindow.ckui 访问所有功能。


📑 功能目录


📢 通知系统

显示各种类型的通知消息,自动定时关闭。

基本用法

// 成功通知
ckui.success('操作成功!', '成功');

// 错误通知
ckui.error('发生错误!', '错误');

// 警告通知
ckui.warning('请注意!', '警告');

// 信息通知
ckui.info('提示信息', '提示');

自定义通知

ckui.notify({
    title: '自定义标题',
    message: '这是自定义消息内容',
    type: 'success',  // 'success' | 'error' | 'warning' | 'info'
    duration: 5000,   // 显示时长(毫秒)
    shadow: false     // 是否使用 Shadow DOM
});

🪟 模态框

创建各种类型的对话框,支持自定义内容和按钮。

Alert 对话框

// 简单提示
await ckui.alert('这是一个提示!');

// 带标题的提示
await ckui.alert('操作成功', '成功');

Confirm 确认框

// 基本确认
try {
    await ckui.confirm('确定要删除吗?', '确认');
    console.log('用户点击了确定');
} catch (e) {
    console.log('用户点击了取消');
}

// 自定义确认框
ckui.confirm({
    title: '确认操作',
    content: '你确定要执行此操作吗?此操作不可撤销。',
    okText: '确定',
    cancelText: '取消'
}).then(() => {
    ckui.success('操作完成');
}).catch(() => {
    ckui.info('操作已取消');
});

Prompt 输入框

// 获取用户输入
const name = await ckui.prompt('请输入你的名字', '默认值');
console.log('用户输入:', name);

自定义模态框

const modal = ckui.modal({
    title: '自定义对话框',
    content: '这里可以是任意内容,包括 HTML 元素',
    width: '600px',
    okText: '确定',
    cancelText: '取消',
    allowHtml: true,  // 允许 HTML 内容
    shadow: false,    // 是否使用 Shadow DOM
    onOk: () => {
        console.log('点击了确定');
        return true;  // 返回 true 关闭模态框
    },
    onCancel: () => {
        console.log('点击了取消');
    }
});

modal.show();  // 显示
modal.close(); // 关闭

带图标的模态框

// 使用 Emoji 图标
ckui.alert('操作成功!', '成功', null, {
    icon: '✅',
    iconShape: 'circle',  // 'circle' | 'square'
    iconWidth: '28px'
});

// 使用图片 URL
ckui.modal({
    title: '用户信息',
    content: '个人资料已更新',
    icon: 'https://example.com/avatar.png',
    iconShape: 'circle',
    iconWidth: '48px'
}).show();

🎈 浮动窗口

创建可拖动、可调整大小的浮动窗口。

基本用法

const win = ckui.floatWindow({
    title: '浮动窗口',
    content: '可拖动的窗口内容',
    x: 100,           // X 坐标
    y: 100,           // Y 坐标
    width: '400px',   // 宽度
    draggable: true,  // 可拖动
    shadow: false     // 是否使用 Shadow DOM
});

win.show();   // 显示窗口
win.close();  // 关闭窗口
win.toggle(); // 切换显示/隐藏

带复杂内容的窗口

// 创建自定义内容
const content = ckui.createElement('div', {}, [
    ckui.createElement('p', {}, ['这是一个复杂的窗口']),
    ckui.button({ 
        label: '点击我', 
        primary: true,
        onClick: () => alert('按钮被点击了!')
    })
]);

const win = ckui.floatWindow({
    title: '工具面板',
    content: content,
    x: 200,
    y: 200,
    width: '500px'
});

win.show();

关闭事件监听

const win = ckui.floatWindow({
    title: '我的窗口',
    content: '内容'
});

// 添加关闭事件监听
win.onClose(() => {
    console.log('窗口被关闭了');
    ckui.info('窗口已关闭');
}, true);  // true 表示一次性回调

win.show();

📝 表单组件

强大的表单系统,支持多种输入类型、验证和回调。

完整表单示例

const form = ckui.form()
    // 文本输入
    .input({ 
        label: '用户名', 
        name: 'username',
        placeholder: '请输入用户名',
        validator: (value, allValues) => {
            if (!value) return '用户名不能为空';
            if (value.length < 3) return '用户名至少3个字符';
            return true;  // 验证通过
        },
        onChange: (value, allValues) => {
            console.log('用户名改变:', value);
        }
    })
    // 密码输入
    .input({ 
        label: '密码', 
        name: 'password',
        inputType: 'password',
        placeholder: '请输入密码'
    })
    // 多行文本
    .textarea({ 
        label: '备注', 
        name: 'note',
        placeholder: '请输入备注',
        validator: (value, allValues) => {
            if (value && value.length > 200) {
                return `备注太长了(${value.length}/200)`;
            }
            return true;
        }
    })
    // 下拉选择
    .select({ 
        label: '城市', 
        name: 'city',
        options: [
            { label: '请选择', value: '' },
            { label: '北京', value: 'beijing' },
            { label: '上海', value: 'shanghai' }
        ],
        validator: (value) => {
            if (!value) return '请选择城市';
            return true;
        }
    })
    // 标签输入
    .tags({
        label: '技能标签',
        name: 'skills',
        placeholder: '输入后按空格添加',
        value: ['JavaScript', 'Python'],
        maxTags: 5,
        validator: (tag, allTags) => {
            if (tag.length > 20) return '标签太长了';
            return true;
        }
    })
    // 下拉选择标签
    .selectTags({
        label: '兴趣爱好',
        name: 'hobbies',
        placeholder: '输入或选择',
        value: ['编程'],
        options: ['编程', '阅读', '音乐', '运动'],
        allowCustom: true,  // 允许自定义标签
        maxTags: 8
    })
    // 复选框
    .checkbox({ 
        label: '同意用户协议', 
        name: 'agree',
        validator: (checked) => {
            if (!checked) return '必须同意用户协议';
            return true;
        }
    })
    // 单选框
    .radio({
        label: '性别',
        name: 'gender',
        options: [
            { label: '男', value: 'male' },
            { label: '女', value: 'female' }
        ]
    })
    // 提交按钮
    .button({ 
        label: '提交',
        primary: true,
        onClick: () => {
            const values = form.getValues();
            console.log('表单值:', values);
            ckui.success('提交成功!');
        }
    });

// 在模态框中显示表单
ckui.modal({
    title: '用户注册',
    content: form.render(),
    width: '500px',
    footer: null  // 不显示默认底部按钮
}).show();

表单验证器

验证器函数会在字段失去焦点时触发:

validator: (value, allValues) => {
    // value: 当前字段的值
    // allValues: 表单所有字段的值对象

    // 返回 true 表示验证通过
    if (isValid(value)) return true;

    // 返回字符串表示验证失败,字符串为错误消息
    return '验证失败的错误消息';
}

onChange 回调

每当字段值改变时触发:

onChange: (value, allValues) => {
    console.log('当前值:', value);
    console.log('所有表单值:', allValues);

    // 可以在这里实现联动逻辑
    if (value === 'special') {
        // 做一些特殊处理
    }
}

⚡ 响应式数据绑定

创建响应式数据,自动更新绑定的 UI 组件。

基本用法

// 创建响应式数据
const count = ckui.reactive(0);

// 创建绑定的输入框
const input = ckui.input({
    placeholder: '输入文本...',
    reactive: count
});

// 订阅数据变化
count.subscribe(value => {
    console.log('值变化:', value);
});

// 修改值
count.value = 10;  // 自动更新所有绑定的组件

在表单中使用

const username = ckui.reactive('');
const email = ckui.reactive('');

const form = ckui.form()
    .input({
        label: '用户名',
        name: 'username',
        reactive: username
    })
    .input({
        label: '邮箱',
        name: 'email',
        reactive: email
    });

// 实时获取值
username.subscribe(value => {
    console.log('用户名:', value);
});

email.subscribe(value => {
    console.log('邮箱:', value);
});

📐 布局组件

提供灵活的布局方案。

Row/Col 网格布局

const layout = ckui.row(
    ckui.col(
        ckui.card({ title: '卡片1', content: '内容1' })
    ),
    ckui.col(
        ckui.card({ title: '卡片2', content: '内容2' })
    ),
    ckui.col(
        ckui.card({ title: '卡片3', content: '内容3' })
    )
);

document.body.appendChild(layout);

Space 间距组件

// 垂直间距(默认)
const layout = ckui.createElement('div', {}, [
    ckui.card({ title: '卡片1', content: '内容1' }),
    ckui.space(20),  // 20px 间距
    ckui.card({ title: '卡片2', content: '内容2' }),
    ckui.space(30),  // 30px 间距
    ckui.card({ title: '卡片3', content: '内容3' })
]);

// 水平间距
const buttons = ckui.createElement('div', { 
    style: 'display: flex;' 
}, [
    ckui.button({ label: '按钮1' }),
    ckui.space(10, 'horizontal'),
    ckui.button({ label: '按钮2', primary: true }),
    ckui.space(20, 'horizontal'),
    ckui.button({ label: '按钮3', danger: true })
]);

Card 卡片

const card = ckui.card({
    title: '卡片标题',
    content: '卡片内容',
    footer: '卡片底部'
});

document.body.appendChild(card);

📦 容器组件

条件显示和折叠面板。

HiddenArea 隐藏区域

// 通过响应式变量控制显示/隐藏
const visible = ckui.reactive(true);

const hiddenArea = ckui.hiddenarea({
    visible: visible,
    content: '这里的内容可以通过 visible 控制显示/隐藏'
});

// 切换显示
visible.value = false;  // 隐藏
visible.value = true;   // 显示

Detail 折叠面板

const openState = ckui.reactive(true);

const detail = ckui.detail({
    title: '点击展开/折叠',
    openState: openState,
    content: '这是可折叠的内容区域'
});

// 程序控制展开/折叠
openState.value = false;  // 折叠
openState.value = true;   // 展开

🌓 主题切换

内置浅色和深色主题。

// 切换到暗色主题
ckui.setTheme('dark');

// 切换到亮色主题
ckui.setTheme('light');

// 获取当前主题
const currentTheme = ckui.getTheme();  // 'light' 或 'dark'

🎭 Shadow DOM 支持

使用 Shadow DOM 完全隔离样式,避免与页面样式冲突。

在模态框中使用

ckui.modal({
    title: 'Shadow Modal',
    content: '这个 Modal 的样式完全隔离',
    shadow: true  // 启用 Shadow DOM
}).show();

在浮动窗口中使用

ckui.floatWindow({
    title: 'Shadow Window',
    content: '样式隔离的窗口',
    shadow: true
}).show();

在通知中使用

ckui.success('成功消息', '成功', { 
    shadow: true 
});

何时使用 Shadow DOM:

  • 页面有复杂的自定义样式
  • 多个脚本可能产生样式冲突
  • 需要确保组件样式的一致性

🔑 实例管理

通过 ID 管理和复用组件实例。

创建带 ID 的实例

// 创建浮动窗口并指定 ID
ckui.floatWindow({
    id: 'my-window',
    title: '命名窗口',
    content: '这个窗口有 ID'
}).show();

获取已存在的实例

// 通过 ID 获取实例
const window = ckui.getFloatWindow('my-window');
if (window) {
    window.close();  // 关闭窗口
}

刷新实例

// 如果 ID 已存在,会更新现有实例而不是创建新的
ckui.floatWindow({
    id: 'my-window',
    title: '更新后的标题',
    content: '更新后的内容'
}).show();

🛠️ 工具函数

createElement

创建 DOM 元素的便捷方法。

const div = ckui.createElement('div', {
    class: 'my-class',
    style: 'color: red;',
    id: 'my-id'
}, [
    '这是文本内容',
    ckui.createElement('span', {}, ['这是子元素'])
]);

Button 按钮

// 基本按钮
ckui.button({ 
    label: '点击我',
    onClick: () => alert('被点击了!')
});

// 主要按钮
ckui.button({ 
    label: '主要按钮',
    primary: true,
    onClick: () => {}
});

// 成功按钮
ckui.button({ 
    label: '成功',
    success: true
});

// 危险按钮
ckui.button({ 
    label: '删除',
    danger: true
});

📋 完整示例

创建一个功能完整的工具面板

(function() {
    'use strict';

    // 创建面板内容
    const createPanel = () => {
        const count = ckui.reactive(0);

        return ckui.createElement('div', { 
            style: 'padding: 10px;' 
        }, [
            ckui.createElement('h3', {}, ['工具面板']),

            ckui.space(10),

            ckui.createElement('div', {}, [
                ckui.createElement('span', {}, ['计数器: ']),
                ckui.createElement('strong', {}, [count.value.toString()])
            ]),

            ckui.space(10),

            ckui.createElement('div', { 
                style: 'display: flex; gap: 10px;' 
            }, [
                ckui.button({
                    label: '增加',
                    primary: true,
                    onClick: () => {
                        count.value++;
                        ckui.success(`当前计数: ${count.value}`);
                    }
                }),
                ckui.button({
                    label: '减少',
                    danger: true,
                    onClick: () => {
                        count.value--;
                        ckui.warning(`当前计数: ${count.value}`);
                    }
                }),
                ckui.button({
                    label: '重置',
                    onClick: () => {
                        count.value = 0;
                        ckui.info('计数已重置');
                    }
                })
            ])
        ]);
    };

    // 创建浮动窗口
    const panel = ckui.floatWindow({
        id: 'tool-panel',
        title: '🛠️ 我的工具',
        content: createPanel(),
        x: 100,
        y: 100,
        width: '300px',
        shadow: true
    });

    panel.show();

    // 添加快捷键
    document.addEventListener('keydown', (e) => {
        // Ctrl + Shift + P 切换面板显示
        if (e.ctrlKey && e.shiftKey && e.key === 'P') {
            panel.toggle();
        }
    });

    console.log('工具面板已加载!按 Ctrl+Shift+P 切换显示');
})();

📄 许可协议

CKUI 基于 GPL-3.0-only 协议开源。

这意味着:

  • ✅ 可以自由使用、修改和分发
  • ✅ 可以用于商业项目
  • ⚠️ 修改后的版本也必须开源
  • ⚠️ 必须保留原作者版权信息

💡 提示

  1. 初始化: CKUI 会在页面加载时自动初始化,无需手动调用
  2. unsafeWindow: 所有功能都通过 unsafeWindow.ckui 访问
  3. 样式隔离: 推荐在复杂页面使用 shadow: true 参数
  4. 表单验证: validator 函数在失焦时触发,返回 true 或错误消息字符串
  5. 响应式数据: 使用 ckui.reactive() 创建响应式变量,通过 .value 访问和修改
  6. 实例管理: 使用 id 参数可以避免重复创建相同窗口

🆕 更新日志

v2.3.0

  • ✨ 完整的 Shadow DOM 支持
  • ✨ 表单字段验证器和 onChange 回调
  • ✨ Space 间距组件
  • 🎨 优化错误提示样式

v2.2.x

  • ✨ Tags 和 SelectTags 组件
  • ✨ HiddenArea 和 Detail 容器组件
  • ✨ HTML 渲染和图标支持

v2.1.x

  • ✨ 实例管理系统
  • ✨ 深色主题支持
  • 🐛 修复多个已知问题