iter(g230): demo 挂页级命令面板跳转

This commit is contained in:
HIsheR
2026-10-26 20:43:13 +08:00
parent 4a571af7ba
commit 0d3c166674
+17 -1
View File
@@ -1570,6 +1570,7 @@ const content = h(
const open = signal(false); // 显隐信号:按钮与快捷键共用同一份状态 const open = signal(false); // 显隐信号:按钮与快捷键共用同一份状态
const cmdk = commandPalette({ const cmdk = commandPalette({
open, open,
hotkey: false, // 全局 Ctrl+K 已让给页级跳转面板(多实例约定:只有一个实例注册快捷键),此卡用按钮唤起
items: [ items: [
{ id: 'save', label: '保存当前页面', group: '文件', hint: '⌘S' }, { id: 'save', label: '保存当前页面', group: '文件', hint: '⌘S' },
{ id: 'export', label: '导出为 Markdown', group: '文件', hint: '⌘E' }, { id: 'export', label: '导出为 Markdown', group: '文件', hint: '⌘E' },
@@ -1582,7 +1583,7 @@ const content = h(
}); });
return h('div', null, button({ label: '打开命令面板(⌘/Ctrl + K)', onClick: () => open(true) }), cmdk.el); return h('div', null, button({ label: '打开命令面板(⌘/Ctrl + K)', onClick: () => open(true) }), cmdk.el);
})(), })(),
typography({ variant: 'paragraph', type: 'secondary', content: '试试输入「协」或拼音 yaoqing / dark:keywords 让中文别名与拼音也能命中,不用改组件。' }), typography({ variant: 'paragraph', type: 'secondary', content: '试试输入「协」或拼音 yaoqing / dark:keywords 让中文别名与拼音也能命中,不用改组件。多实例时只有一处注册 ⌘K——本页的 Ctrl+K 属于页级跳转面板,这里用按钮唤起。' }),
), ),
card({ title: '为什么不用原生 input + datalist' }, card({ title: '为什么不用原生 input + datalist' },
typography({ variant: 'paragraph', type: 'secondary', content: 'datalist 无法分组、不搜说明文字、也控制不了高亮与焦点归还;命令面板要的是「输入即缩小 + 键盘走完整个流程」,所以自绘列表并用 aria-activedescendant 把高亮交给读屏。' }), typography({ variant: 'paragraph', type: 'secondary', content: 'datalist 无法分组、不搜说明文字、也控制不了高亮与焦点归还;命令面板要的是「输入即缩小 + 键盘走完整个流程」,所以自绘列表并用 aria-activedescendant 把高亮交给读屏。' }),
@@ -1609,6 +1610,21 @@ const demoTour = tour({
}); });
document.body.append(demoTour.el); document.body.append(demoTour.el);
// 页级命令面板:Ctrl+K 跳转任意演示区块;items 与侧边目录同源(从 .sec 反推,清单改动自动跟随)
const demoPalette = commandPalette({
open: signal(false),
placeholder: '跳转到组件…',
emptyText: '没有匹配的组件',
items: Array.from(content.querySelectorAll<HTMLElement>('section.sec')).map((sec) => ({
id: sec.id,
label: sec.querySelector('h2')?.textContent ?? sec.id,
group: '跳转',
keywords: [sec.id.replace(/^sec-/, '')], // 锚点 id 去 sec- 前缀当拼音外的第二检索路
})),
onSelect: (it) => document.getElementById(it.id)?.scrollIntoView({ behavior: 'smooth' }),
});
document.body.append(demoPalette.el);
const toc = h('aside', { class: 'toc' }, h('div', { class: 'toc-title' }, '目录')); // 目录项由 buildToc 填充 const toc = h('aside', { class: 'toc' }, h('div', { class: 'toc-title' }, '目录')); // 目录项由 buildToc 填充
const app = h('div', { class: 'shell' }, toc, content); const app = h('div', { class: 'shell' }, toc, content);