mirror of
https://github.com/IliesAllali/parenthese.git
synced 2026-11-06 23:32:08 +00:00
Merge pull request #184 from IliesAllali/feat/ctrl-k
Ctrl+K ouvre la recherche, raccourcis affichés
This commit is contained in:
5 files changed
+56
-2
No files matched your search
@@ -0,0 +1,10 @@
|
||||
import { shortcutKeys } from '../utils/shortcuts.js'
|
||||
|
||||
// Raccourci clavier affiché à droite d'une entrée de menu ; caché sur écran tactile (styles/pz.css, .pz-kbd)
|
||||
export default function Kbd({ mod, k }) {
|
||||
return (
|
||||
<span className="pz-kbd" aria-hidden="true">
|
||||
{shortcutKeys(mod, k).map((key) => <kbd key={key}>{key}</kbd>)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import { t } from '../../i18n/index.js'
|
||||
import { PHONE_QUERY } from '../../utils/sheetDrag'
|
||||
import './ContextualNavbar.css'
|
||||
import { initialOf } from '../../utils/initial.js'
|
||||
import Kbd from '../Kbd.jsx'
|
||||
|
||||
const ANNOT_TOOLS = [
|
||||
{ id: 'pointer', label: t('Sélection'), Icon: MousePointer2 },
|
||||
@@ -211,9 +212,9 @@ function ContextualNavbar({
|
||||
}
|
||||
const fixItems = []
|
||||
if (isFamily) {
|
||||
fixItems.push({ key: 'edit', icon: <Pencil {...ICON} />, label: editLabel, sub: editModeActive ? null : t('dates, noms, liens, le propriétaire relit'), onSelect: onEditClick })
|
||||
fixItems.push({ key: 'edit', icon: <Pencil {...ICON} />, label: editLabel, sub: editModeActive ? null : t('dates, noms, liens, le propriétaire relit'), onSelect: onEditClick, shortcut: 'e' })
|
||||
} else if (isOwner || isDemo) {
|
||||
fixItems.push({ key: 'edit', icon: <Pencil {...ICON} />, label: editLabel, onSelect: onEditClick })
|
||||
fixItems.push({ key: 'edit', icon: <Pencil {...ICON} />, label: editLabel, onSelect: onEditClick, shortcut: 'e' })
|
||||
}
|
||||
if (addItems.length) addGroups.push({ label: t('Ajouter'), items: addItems })
|
||||
if (fixItems.length) addGroups.push({ label: t('Corriger'), items: fixItems })
|
||||
@@ -235,6 +236,7 @@ function ContextualNavbar({
|
||||
label={item.label}
|
||||
sub={item.sub}
|
||||
onSelect={run(item.onSelect)}
|
||||
right={item.shortcut ? <Kbd mod="ctrl" k={item.shortcut} /> : null}
|
||||
/>
|
||||
))}
|
||||
</NavMenuGroup>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Search, X } from 'lucide-react'
|
||||
import SearchResultsDropdown from './SearchResultsDropdown'
|
||||
import './ExpandableSearch.css'
|
||||
import { t } from '../../i18n/index.js'
|
||||
import { isCommandK, withShortcut } from '../../utils/shortcuts.js'
|
||||
|
||||
/**
|
||||
* Recherche expandable haut-droite
|
||||
@@ -80,6 +81,22 @@ function ExpandableSearch({
|
||||
setExpanded(true)
|
||||
}
|
||||
|
||||
// Ctrl+K (⌘K sur Mac), de n'importe où : ouvre la recherche, ou y remet le curseur si elle est déjà ouverte
|
||||
useEffect(() => {
|
||||
function handleCommandK(event) {
|
||||
if (!isCommandK(event)) return
|
||||
event.preventDefault()
|
||||
if (!expanded) setExpanded(true)
|
||||
else {
|
||||
inputRef.current?.focus()
|
||||
inputRef.current?.select()
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', handleCommandK)
|
||||
return () => document.removeEventListener('keydown', handleCommandK)
|
||||
}, [expanded])
|
||||
|
||||
const handleInputChange = (e) => {
|
||||
const value = e.target.value
|
||||
setQuery(value)
|
||||
@@ -106,6 +123,7 @@ function ExpandableSearch({
|
||||
className="search-icon-button"
|
||||
onClick={handleExpand}
|
||||
aria-label={t('Rechercher une personne')}
|
||||
title={withShortcut(t('Rechercher une personne'), 'cmd', 'k')}
|
||||
>
|
||||
<span className="search-icon"><Search size={22} strokeWidth={2} /></span>
|
||||
</button>
|
||||
|
||||
@@ -277,3 +277,8 @@ button:disabled:has(.pz-busy.is-busy) { opacity: 1; cursor: progress; }
|
||||
inset: min(0px, calc((100% - 44px) / 2)) min(0px, calc((100% - 44px) / 2));
|
||||
}
|
||||
}
|
||||
|
||||
/* Raccourci clavier à droite d'une entrée de menu (components/Kbd.jsx) ; rien sur écran tactile */
|
||||
.pz-kbd { display: inline-flex; gap: 3px; margin-left: auto; padding-left: 12px; }
|
||||
.pz-kbd kbd { min-width: 20px; padding: 1px 5px; border: 1px solid var(--pz-line); border-radius: 5px; background: var(--pz-bg); font: 500 11px/16px var(--pz-sans); color: var(--pz-muted); text-align: center; }
|
||||
@media (pointer: coarse) { .pz-kbd { display: none; } }
|
||||
@@ -0,0 +1,19 @@
|
||||
// Raccourcis clavier affichés dans l'interface (infobulles, menus). Sur Mac, Ctrl s'écrit ⌃ et Cmd ⌘.
|
||||
const isMac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || '')
|
||||
|
||||
// mod : 'ctrl' (Ctrl partout) ou 'cmd' (⌘ sur Mac, Ctrl ailleurs)
|
||||
export function shortcutKeys(mod, key) {
|
||||
const modifier = mod === 'cmd' ? (isMac ? '⌘' : 'Ctrl') : (isMac ? '⌃' : 'Ctrl')
|
||||
return [modifier, key.toUpperCase()]
|
||||
}
|
||||
|
||||
// Texte d'une infobulle : « Rechercher une personne (Ctrl K) », « … (⌘K) » sur Mac
|
||||
export function withShortcut(label, mod, key) {
|
||||
const keys = shortcutKeys(mod, key)
|
||||
return `${label} (${isMac ? keys.join('') : keys.join(' ')})`
|
||||
}
|
||||
|
||||
// Ctrl+K, ou ⌘K sur Mac
|
||||
export function isCommandK(event) {
|
||||
return (event.ctrlKey || event.metaKey) && !event.shiftKey && !event.altKey && event.key.toLowerCase() === 'k'
|
||||
}
|
||||
Reference in new issue
Block a user