refactor(app): derive menu shortcut formats
This commit is contained in:
parent
1a03c0e8e8
commit
38d30e25e0
|
|
@ -83,6 +83,11 @@
|
|||
"label": "Copy",
|
||||
"accelerator": "CmdOrCtrl+C"
|
||||
},
|
||||
{
|
||||
"id": "cut",
|
||||
"label": "Cut",
|
||||
"accelerator": "CmdOrCtrl+X"
|
||||
},
|
||||
{
|
||||
"id": "paste",
|
||||
"label": "Paste",
|
||||
|
|
@ -170,8 +175,7 @@
|
|||
},
|
||||
{
|
||||
"id": "dev-tools",
|
||||
"label": "Developer Tools",
|
||||
"accelerator": "CmdOrCtrl+Alt+I"
|
||||
"label": "Developer Tools"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { dirname } from 'node:path'
|
|||
|
||||
import { APP_MENU_SCHEMA } from '../src/app/shell/menu/schema'
|
||||
import type { AppMenuEntry, AppMenuGroupSchema } from '../src/app/shell/menu/schema'
|
||||
import { shortcutTokenToAccelerator } from '../src/app/shell/menu/shortcut'
|
||||
|
||||
function isNativeVisible(entry: { target?: string }): boolean {
|
||||
return entry.target !== 'browser'
|
||||
|
|
@ -14,7 +15,7 @@ function cleanEntry(entry: AppMenuEntry): unknown | null {
|
|||
return {
|
||||
id: entry.id,
|
||||
label: entry.label,
|
||||
accelerator: entry.accelerator,
|
||||
accelerator: entry.accelerator ?? shortcutTokenToAccelerator(entry.shortcut),
|
||||
checkbox: entry.checkbox,
|
||||
sub: entry.sub?.map(cleanEntry).filter(Boolean)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import { computed } from 'vue'
|
||||
|
||||
import { useEditorCommands, useI18n, formatShortcut } from '@open-pencil/vue'
|
||||
import { useEditorCommands, useI18n } from '@open-pencil/vue'
|
||||
import type { MenuEntry } from '@open-pencil/vue'
|
||||
|
||||
import { useEditorStore } from '@/app/editor/active-store'
|
||||
import { createSharedEditorMenuActions } from '@/app/shell/menu/editor-actions'
|
||||
import { APP_MENU_SCHEMA } from '@/app/shell/menu/schema'
|
||||
import type { AppMenuActionItem, AppMenuEntry, AppMenuGroupSchema } from '@/app/shell/menu/schema'
|
||||
import { appMenuShortcutLabel } from '@/app/shell/menu/shortcut'
|
||||
import { openFileDialog } from '@/app/shell/menu/use'
|
||||
import { useAppTheme } from '@/app/shell/theme'
|
||||
|
||||
|
|
@ -107,12 +108,12 @@ export function useAppMenu() {
|
|||
}
|
||||
|
||||
if (entry.command) {
|
||||
return commandMenuItem(entry.command, formatShortcut(entry.shortcut))
|
||||
return commandMenuItem(entry.command, appMenuShortcutLabel(entry.id))
|
||||
}
|
||||
|
||||
return {
|
||||
label: entry.label,
|
||||
shortcut: formatShortcut(entry.shortcut),
|
||||
shortcut: appMenuShortcutLabel(entry.id),
|
||||
action: itemAction(entry),
|
||||
checked: checked(entry),
|
||||
onCheckedChange: onCheckedChange(entry),
|
||||
|
|
|
|||
|
|
@ -31,17 +31,16 @@ export const APP_MENU_SCHEMA = [
|
|||
{
|
||||
label: 'File',
|
||||
items: [
|
||||
{ id: 'new', label: 'New', shortcut: 'MOD+N', accelerator: 'CmdOrCtrl+N' },
|
||||
{ id: 'open', label: 'Open…', shortcut: 'MOD+O', accelerator: 'CmdOrCtrl+O' },
|
||||
{ id: 'new', label: 'New', shortcut: 'MOD+N' },
|
||||
{ id: 'open', label: 'Open…', shortcut: 'MOD+O' },
|
||||
{ type: 'separator' },
|
||||
{ id: 'save', label: 'Save', shortcut: 'MOD+S', accelerator: 'CmdOrCtrl+S' },
|
||||
{ id: 'save-as', label: 'Save As…', shortcut: 'MOD+SHIFT+S', accelerator: 'CmdOrCtrl+Shift+S' },
|
||||
{ id: 'save', label: 'Save', shortcut: 'MOD+S' },
|
||||
{ id: 'save-as', label: 'Save As…', shortcut: 'MOD+SHIFT+S' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
id: 'export-selection',
|
||||
label: 'Export Selection',
|
||||
shortcut: 'MOD+SHIFT+E',
|
||||
accelerator: 'CmdOrCtrl+Shift+E',
|
||||
sub: [
|
||||
{ id: 'export-png', label: 'PNG' },
|
||||
{ id: 'export-svg', label: 'SVG' },
|
||||
|
|
@ -50,7 +49,7 @@ export const APP_MENU_SCHEMA = [
|
|||
},
|
||||
{ type: 'separator' },
|
||||
{ id: 'autosave', label: 'Autosave', checkbox: true },
|
||||
{ id: 'close', label: 'Close Tab', shortcut: 'MOD+W', accelerator: 'CmdOrCtrl+W' }
|
||||
{ id: 'close', label: 'Close Tab', shortcut: 'MOD+W' }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -60,32 +59,28 @@ export const APP_MENU_SCHEMA = [
|
|||
id: 'edit.undo',
|
||||
label: 'Undo',
|
||||
shortcut: 'MOD+Z',
|
||||
accelerator: 'CmdOrCtrl+Z',
|
||||
command: 'edit.undo'
|
||||
},
|
||||
{
|
||||
id: 'edit.redo',
|
||||
label: 'Redo',
|
||||
shortcut: 'MOD+SHIFT+Z',
|
||||
accelerator: 'CmdOrCtrl+Shift+Z',
|
||||
command: 'edit.redo'
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ id: 'copy', label: 'Copy', shortcut: 'MOD+C', accelerator: 'CmdOrCtrl+C' },
|
||||
{ id: 'cut', label: 'Cut', shortcut: 'MOD+X', accelerator: 'CmdOrCtrl+X' },
|
||||
{ id: 'paste', label: 'Paste', shortcut: 'MOD+V', accelerator: 'CmdOrCtrl+V' },
|
||||
{ id: 'copy', label: 'Copy', shortcut: 'MOD+C' },
|
||||
{ id: 'cut', label: 'Cut', shortcut: 'MOD+X' },
|
||||
{ id: 'paste', label: 'Paste', shortcut: 'MOD+V' },
|
||||
{
|
||||
id: 'selection.duplicate',
|
||||
label: 'Duplicate',
|
||||
shortcut: 'MOD+D',
|
||||
accelerator: 'CmdOrCtrl+D',
|
||||
command: 'selection.duplicate'
|
||||
},
|
||||
{
|
||||
id: 'selection.delete',
|
||||
label: 'Delete',
|
||||
shortcut: '⌫',
|
||||
accelerator: 'Backspace',
|
||||
command: 'selection.delete'
|
||||
},
|
||||
{ type: 'separator' },
|
||||
|
|
@ -93,7 +88,6 @@ export const APP_MENU_SCHEMA = [
|
|||
id: 'selection.selectAll',
|
||||
label: 'Select All',
|
||||
shortcut: 'MOD+A',
|
||||
accelerator: 'CmdOrCtrl+A',
|
||||
command: 'selection.selectAll'
|
||||
}
|
||||
]
|
||||
|
|
@ -105,25 +99,22 @@ export const APP_MENU_SCHEMA = [
|
|||
id: 'view.zoom100',
|
||||
label: 'Zoom to 100%',
|
||||
shortcut: 'MOD+0',
|
||||
accelerator: 'CmdOrCtrl+0',
|
||||
command: 'view.zoom100'
|
||||
},
|
||||
{
|
||||
id: 'view.zoomFit',
|
||||
label: 'Zoom to Fit',
|
||||
shortcut: 'MOD+1',
|
||||
accelerator: 'CmdOrCtrl+1',
|
||||
command: 'view.zoomFit'
|
||||
},
|
||||
{
|
||||
id: 'view.zoomSelection',
|
||||
label: 'Zoom to Selection',
|
||||
shortcut: 'MOD+2',
|
||||
accelerator: 'CmdOrCtrl+2',
|
||||
command: 'view.zoomSelection'
|
||||
},
|
||||
{ id: 'zoom-in', label: 'Zoom In', shortcut: 'MOD+=', accelerator: 'CmdOrCtrl+=' },
|
||||
{ id: 'zoom-out', label: 'Zoom Out', shortcut: 'MOD+-', accelerator: 'CmdOrCtrl+-' },
|
||||
{ id: 'zoom-in', label: 'Zoom In', shortcut: 'MOD+=' },
|
||||
{ id: 'zoom-out', label: 'Zoom Out', shortcut: 'MOD+-' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
id: 'theme',
|
||||
|
|
@ -136,12 +127,11 @@ export const APP_MENU_SCHEMA = [
|
|||
},
|
||||
{ id: 'language', label: 'Language', target: 'browser' },
|
||||
{ type: 'separator' },
|
||||
{ id: 'toggle-ui', label: 'Toggle UI', shortcut: 'MOD+\\', accelerator: 'CmdOrCtrl+\\' },
|
||||
{ id: 'toggle-ui', label: 'Toggle UI', shortcut: 'MOD+\\' },
|
||||
{ id: 'profiler', label: 'Profiler', checkbox: true, target: 'browser' },
|
||||
{
|
||||
id: 'dev-tools',
|
||||
label: 'Developer Tools',
|
||||
accelerator: 'CmdOrCtrl+Alt+I',
|
||||
target: 'native'
|
||||
}
|
||||
]
|
||||
|
|
@ -153,14 +143,12 @@ export const APP_MENU_SCHEMA = [
|
|||
id: 'selection.group',
|
||||
label: 'Group Selection',
|
||||
shortcut: 'MOD+G',
|
||||
accelerator: 'CmdOrCtrl+G',
|
||||
command: 'selection.group'
|
||||
},
|
||||
{
|
||||
id: 'selection.ungroup',
|
||||
label: 'Ungroup Selection',
|
||||
shortcut: 'MOD+SHIFT+G',
|
||||
accelerator: 'CmdOrCtrl+Shift+G',
|
||||
command: 'selection.ungroup'
|
||||
},
|
||||
{ type: 'separator' },
|
||||
|
|
@ -168,7 +156,6 @@ export const APP_MENU_SCHEMA = [
|
|||
id: 'selection.createComponent',
|
||||
label: 'Create Component',
|
||||
shortcut: 'MOD+ALT+K',
|
||||
accelerator: 'CmdOrCtrl+Alt+K',
|
||||
command: 'selection.createComponent'
|
||||
},
|
||||
{
|
||||
|
|
@ -186,14 +173,12 @@ export const APP_MENU_SCHEMA = [
|
|||
id: 'selection.bringToFront',
|
||||
label: 'Bring to Front',
|
||||
shortcut: ']',
|
||||
accelerator: ']',
|
||||
command: 'selection.bringToFront'
|
||||
},
|
||||
{
|
||||
id: 'selection.sendToBack',
|
||||
label: 'Send to Back',
|
||||
shortcut: '[',
|
||||
accelerator: '[',
|
||||
command: 'selection.sendToBack'
|
||||
}
|
||||
]
|
||||
|
|
@ -201,9 +186,9 @@ export const APP_MENU_SCHEMA = [
|
|||
{
|
||||
label: 'Text',
|
||||
items: [
|
||||
{ id: 'text.bold', label: 'Bold', shortcut: 'MOD+B', accelerator: 'CmdOrCtrl+B' },
|
||||
{ id: 'text.italic', label: 'Italic', shortcut: 'MOD+I', accelerator: 'CmdOrCtrl+I' },
|
||||
{ id: 'text.underline', label: 'Underline', shortcut: 'MOD+U', accelerator: 'CmdOrCtrl+U' }
|
||||
{ id: 'text.bold', label: 'Bold', shortcut: 'MOD+B' },
|
||||
{ id: 'text.italic', label: 'Italic', shortcut: 'MOD+I' },
|
||||
{ id: 'text.underline', label: 'Underline', shortcut: 'MOD+U' }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -213,17 +198,16 @@ export const APP_MENU_SCHEMA = [
|
|||
id: 'selection.wrapInAutoLayout',
|
||||
label: 'Wrap in Auto Layout',
|
||||
shortcut: 'SHIFT+A',
|
||||
accelerator: 'Shift+A',
|
||||
command: 'selection.wrapInAutoLayout'
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ id: 'align-left', label: 'Align Left', shortcut: 'ALT+A', accelerator: 'Alt+A' },
|
||||
{ id: 'align-center', label: 'Align Center', shortcut: 'ALT+H', accelerator: 'Alt+H' },
|
||||
{ id: 'align-right', label: 'Align Right', shortcut: 'ALT+D', accelerator: 'Alt+D' },
|
||||
{ id: 'align-left', label: 'Align Left', shortcut: 'ALT+A' },
|
||||
{ id: 'align-center', label: 'Align Center', shortcut: 'ALT+H' },
|
||||
{ id: 'align-right', label: 'Align Right', shortcut: 'ALT+D' },
|
||||
{ type: 'separator' },
|
||||
{ id: 'align-top', label: 'Align Top', shortcut: 'ALT+W', accelerator: 'Alt+W' },
|
||||
{ id: 'align-middle', label: 'Align Middle', shortcut: 'ALT+V', accelerator: 'Alt+V' },
|
||||
{ id: 'align-bottom', label: 'Align Bottom', shortcut: 'ALT+S', accelerator: 'Alt+S' }
|
||||
{ id: 'align-top', label: 'Align Top', shortcut: 'ALT+W' },
|
||||
{ id: 'align-middle', label: 'Align Middle', shortcut: 'ALT+V' },
|
||||
{ id: 'align-bottom', label: 'Align Bottom', shortcut: 'ALT+S' }
|
||||
]
|
||||
}
|
||||
] satisfies AppMenuGroupSchema[]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { formatShortcut } from '@open-pencil/vue'
|
||||
|
||||
import type { AppMenuActionItem, AppMenuEntry } from '@/app/shell/menu/schema'
|
||||
import { APP_MENU_SCHEMA } from '@/app/shell/menu/schema'
|
||||
|
||||
|
|
@ -23,10 +25,36 @@ export function appMenuShortcut(id: string): string | undefined {
|
|||
return undefined
|
||||
}
|
||||
|
||||
export function appMenuTinykeysShortcut(id: string): string | string[] | undefined {
|
||||
const shortcut = appMenuShortcut(id)
|
||||
function normalizeShortcutToken(shortcut: string): string {
|
||||
return shortcut === '⌫' ? 'Backspace' : shortcut
|
||||
}
|
||||
|
||||
export function shortcutTokenToTinykeys(shortcut: string | undefined): string | undefined {
|
||||
return shortcut
|
||||
?.replaceAll('MOD', '$mod')
|
||||
? normalizeShortcutToken(shortcut)
|
||||
.replaceAll('MOD', '$mod')
|
||||
.replaceAll('SHIFT', 'Shift')
|
||||
.replaceAll('ALT', 'Alt')
|
||||
: undefined
|
||||
}
|
||||
|
||||
export function shortcutTokenToAccelerator(shortcut: string | undefined): string | undefined {
|
||||
return shortcut
|
||||
? normalizeShortcutToken(shortcut)
|
||||
.replaceAll('MOD', 'CmdOrCtrl')
|
||||
.replaceAll('SHIFT', 'Shift')
|
||||
.replaceAll('ALT', 'Alt')
|
||||
: undefined
|
||||
}
|
||||
|
||||
export function appMenuShortcutLabel(id: string): string | undefined {
|
||||
return formatShortcut(appMenuShortcut(id))
|
||||
}
|
||||
|
||||
export function appMenuTinykeysShortcut(id: string): string | undefined {
|
||||
return shortcutTokenToTinykeys(appMenuShortcut(id))
|
||||
}
|
||||
|
||||
export function appMenuAccelerator(id: string): string | undefined {
|
||||
return shortcutTokenToAccelerator(appMenuShortcut(id))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ import {
|
|||
|
||||
import IconChevronRight from '~icons/lucide/chevron-right'
|
||||
|
||||
import { vTestId, useI18n, formatShortcut } from '@open-pencil/vue'
|
||||
import { vTestId, useI18n } from '@open-pencil/vue'
|
||||
import { useMenuUI } from '@/components/ui/menu'
|
||||
import { IS_TAURI } from '@/constants'
|
||||
import { useAppMenu } from '@/app/shell/menu/app-menu'
|
||||
import { useDocumentNameRename } from '@/app/shell/menu/document-name'
|
||||
import { appMenuShortcut } from '@/app/shell/menu/shortcut'
|
||||
import { appMenuShortcutLabel } from '@/app/shell/menu/shortcut'
|
||||
import {
|
||||
hasMenuSubItems,
|
||||
isMenuCheckbox,
|
||||
|
|
@ -76,7 +76,7 @@ const subMenuCls = useMenuUI({ content: 'min-w-44' })
|
|||
@dblclick="startRename"
|
||||
>{{ store.state.documentName }}</span
|
||||
>
|
||||
<Tip :label="`${t.toggleUI} (${formatShortcut(appMenuShortcut('toggle-ui'))})`">
|
||||
<Tip :label="`${t.toggleUI} (${appMenuShortcutLabel('toggle-ui')})`">
|
||||
<button
|
||||
data-test-id="app-toggle-ui"
|
||||
class="flex size-6 shrink-0 cursor-pointer items-center justify-center rounded text-muted transition-colors hover:bg-hover hover:text-surface"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import {
|
|||
import type { EditorCommandId } from '@open-pencil/vue'
|
||||
|
||||
import { useEditorStore } from '@/app/editor/active-store'
|
||||
import { appMenuShortcut } from '@/app/shell/menu/shortcut'
|
||||
import { appMenuShortcutLabel } from '@/app/shell/menu/shortcut'
|
||||
import { COPY_AS_PNG_SHORTCUT, createCanvasMenuActions } from '@/app/editor/canvas/menu-actions'
|
||||
import { canvasMenuItemClass, canvasMenuShortcutClass } from '@/app/editor/canvas/menu-model'
|
||||
import { menu, useMenuUI } from '@/components/ui/menu'
|
||||
|
|
@ -64,7 +64,7 @@ function contextCommandTestId(id: EditorCommandId | undefined): string | undefin
|
|||
@select="execCommand('copy')"
|
||||
>
|
||||
<span>{{ t.copy }}</span
|
||||
><span class="text-[11px] text-muted">{{ formatShortcut(appMenuShortcut('copy')) }}</span>
|
||||
><span class="text-[11px] text-muted">{{ appMenuShortcutLabel('copy') }}</span>
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem
|
||||
data-test-id="context-cut"
|
||||
|
|
@ -73,11 +73,11 @@ function contextCommandTestId(id: EditorCommandId | undefined): string | undefin
|
|||
@select="execCommand('cut')"
|
||||
>
|
||||
<span>{{ t.cut }}</span
|
||||
><span class="text-[11px] text-muted">{{ formatShortcut(appMenuShortcut('cut')) }}</span>
|
||||
><span class="text-[11px] text-muted">{{ appMenuShortcutLabel('cut') }}</span>
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem data-test-id="context-paste" :class="cls.item" @select="execCommand('paste')">
|
||||
<span>{{ t.pasteHere }}</span
|
||||
><span class="text-[11px] text-muted">{{ formatShortcut(appMenuShortcut('paste')) }}</span>
|
||||
><span class="text-[11px] text-muted">{{ appMenuShortcutLabel('paste') }}</span>
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem
|
||||
data-test-id="context-duplicate"
|
||||
|
|
@ -86,7 +86,9 @@ function contextCommandTestId(id: EditorCommandId | undefined): string | undefin
|
|||
@select="getCommand('selection.duplicate').run()"
|
||||
>
|
||||
<span>{{ getCommand('selection.duplicate').label }}</span
|
||||
><span class="text-[11px] text-muted">{{ formatShortcut(editorCommandMetadata('selection.duplicate').shortcut) }}</span>
|
||||
><span class="text-[11px] text-muted">{{
|
||||
formatShortcut(editorCommandMetadata('selection.duplicate').shortcut)
|
||||
}}</span>
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem
|
||||
data-test-id="context-delete"
|
||||
|
|
@ -95,7 +97,9 @@ function contextCommandTestId(id: EditorCommandId | undefined): string | undefin
|
|||
@select="getCommand('selection.delete').run()"
|
||||
>
|
||||
<span>{{ getCommand('selection.delete').label }}</span
|
||||
><span class="text-[11px] text-muted">{{ editorCommandMetadata('selection.delete').shortcut }}</span>
|
||||
><span class="text-[11px] text-muted">{{
|
||||
editorCommandMetadata('selection.delete').shortcut
|
||||
}}</span>
|
||||
</ContextMenuItem>
|
||||
|
||||
<template v-for="(item, i) in canvasMenu" :key="`menu-${i}`">
|
||||
|
|
@ -163,7 +167,9 @@ function contextCommandTestId(id: EditorCommandId | undefined): string | undefin
|
|||
>
|
||||
<ContextMenuItem :class="cls.item" @select="copyAsPNG">
|
||||
<span>{{ t.copyAsPNG }}</span
|
||||
><span class="text-[11px] text-muted">{{ formatShortcut(COPY_AS_PNG_SHORTCUT) }}</span>
|
||||
><span class="text-[11px] text-muted">{{
|
||||
formatShortcut(COPY_AS_PNG_SHORTCUT)
|
||||
}}</span>
|
||||
</ContextMenuItem>
|
||||
<ContextMenuItem
|
||||
data-test-id="context-copy-as-jsx"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { nextTick, ref, watch } from 'vue'
|
|||
import { useEditorCommands, useI18n, formatShortcut } from '@open-pencil/vue'
|
||||
import { menuItem, useMenuUI } from '@/components/ui/menu'
|
||||
import { useEditorStore } from '@/app/editor/active-store'
|
||||
import { appMenuShortcut } from '@/app/shell/menu/shortcut'
|
||||
import { appMenuShortcut, appMenuShortcutLabel } from '@/app/shell/menu/shortcut'
|
||||
|
||||
const store = useEditorStore()
|
||||
const { getCommand } = useEditorCommands()
|
||||
|
|
@ -127,15 +127,15 @@ watch(open, (v) => {
|
|||
|
||||
<DropdownMenuItem :class="itemCls" @select="zoomIn">
|
||||
<span class="flex-1">{{ menuText.zoomIn }}</span>
|
||||
<span class="text-[11px] text-muted">{{ formatShortcut(appMenuShortcut('zoom-in')) }}</span>
|
||||
<span class="text-[11px] text-muted">{{ appMenuShortcutLabel('zoom-in') }}</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem :class="itemCls" @select="zoomOut">
|
||||
<span class="flex-1">{{ menuText.zoomOut }}</span>
|
||||
<span class="text-[11px] text-muted">{{ formatShortcut(appMenuShortcut('zoom-out')) }}</span>
|
||||
<span class="text-[11px] text-muted">{{ appMenuShortcutLabel('zoom-out') }}</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem :class="itemCls" @select="getCommand('view.zoomFit').run()">
|
||||
<span class="flex-1">{{ commands.zoomToFit }}</span>
|
||||
<span class="text-[11px] text-muted">{{ formatShortcut(appMenuShortcut('view.zoomFit')) }}</span>
|
||||
<span class="text-[11px] text-muted">{{ appMenuShortcutLabel('view.zoomFit') }}</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
v-for="preset in ZOOM_PRESETS"
|
||||
|
|
@ -145,7 +145,9 @@ watch(open, (v) => {
|
|||
>
|
||||
<icon-lucide-check v-if="isActivePreset(preset.level)" class="absolute left-2 size-3.5" />
|
||||
<span class="flex-1">{{ preset.label }}</span>
|
||||
<span v-if="preset.shortcut" class="text-[11px] text-muted">{{ formatShortcut(preset.shortcut) }}</span>
|
||||
<span v-if="preset.shortcut" class="text-[11px] text-muted">{{
|
||||
formatShortcut(preset.shortcut)
|
||||
}}</span>
|
||||
</DropdownMenuItem>
|
||||
|
||||
<DropdownMenuSeparator :class="menuCls.separator" />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ToggleGroupItem, ToggleGroupRoot } from 'reka-ui'
|
||||
|
||||
import { TypographyControlsRoot, useI18n, formatShortcut } from '@open-pencil/vue'
|
||||
import { TypographyControlsRoot, useI18n } from '@open-pencil/vue'
|
||||
|
||||
import FontPicker from '@/components/FontPicker.vue'
|
||||
import FontSettingsPopover from '@/components/FontSettings/FontSettingsPopover.vue'
|
||||
|
|
@ -10,7 +10,7 @@ import AppSelect from '@/components/ui/AppSelect.vue'
|
|||
import Tip from '@/components/ui/Tip.vue'
|
||||
import { useSectionUI } from '@/components/ui/section'
|
||||
import { loadFont } from '@/app/editor/fonts'
|
||||
import { appMenuShortcut } from '@/app/shell/menu/shortcut'
|
||||
import { appMenuShortcutLabel } from '@/app/shell/menu/shortcut'
|
||||
|
||||
const { panels, menu } = useI18n()
|
||||
const sectionCls = useSectionUI()
|
||||
|
|
@ -126,7 +126,7 @@ const fontLoader = { load: loadFont }
|
|||
</ToggleGroupItem>
|
||||
</ToggleGroupRoot>
|
||||
<div class="flex gap-0.5">
|
||||
<Tip :label="`${menu.bold} (${formatShortcut(appMenuShortcut('text.bold'))})`">
|
||||
<Tip :label="`${menu.bold} (${appMenuShortcutLabel('text.bold')})`">
|
||||
<button
|
||||
data-test-id="typography-bold-button"
|
||||
class="flex cursor-pointer items-center justify-center rounded border border-border bg-input px-2 py-1 font-bold text-muted hover:bg-hover hover:text-surface data-[state=on]:border-accent data-[state=on]:bg-accent data-[state=on]:text-white"
|
||||
|
|
@ -136,7 +136,7 @@ const fontLoader = { load: loadFont }
|
|||
<icon-lucide-bold class="size-3.5" />
|
||||
</button>
|
||||
</Tip>
|
||||
<Tip :label="`${menu.italic} (${formatShortcut(appMenuShortcut('text.italic'))})`">
|
||||
<Tip :label="`${menu.italic} (${appMenuShortcutLabel('text.italic')})`">
|
||||
<button
|
||||
class="flex cursor-pointer items-center justify-center rounded border border-border bg-input px-2 py-1 text-muted hover:bg-hover hover:text-surface data-[state=on]:border-accent data-[state=on]:bg-accent data-[state=on]:text-white"
|
||||
:data-state="ctx.activeFormatting.value.includes('italic') ? 'on' : 'off'"
|
||||
|
|
@ -145,7 +145,7 @@ const fontLoader = { load: loadFont }
|
|||
<icon-lucide-italic class="size-3.5" />
|
||||
</button>
|
||||
</Tip>
|
||||
<Tip :label="`${menu.underline} (${formatShortcut(appMenuShortcut('text.underline'))})`">
|
||||
<Tip :label="`${menu.underline} (${appMenuShortcutLabel('text.underline')})`">
|
||||
<button
|
||||
class="flex cursor-pointer items-center justify-center rounded border border-border bg-input px-2 py-1 text-muted hover:bg-hover hover:text-surface data-[state=on]:border-accent data-[state=on]:bg-accent data-[state=on]:text-white"
|
||||
:data-state="ctx.activeFormatting.value.includes('underline') ? 'on' : 'off'"
|
||||
|
|
|
|||
Loading…
Reference in a new issue