refactor(ui): improve slash menu layout and add shortcut hints
- increase menu width and max height constants - add SHORTCUT_HINT map displaying markdown shortcuts per block type - update empty state and list container to use rounded-lg and shadow-md - add section label header above block items - show monospace shortcut hint on each menu item - tighten item padding and icon size for denser layout
This commit is contained in:
@@ -2,9 +2,24 @@
|
|||||||
|
|
||||||
import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
const MENU_WIDTH = 256; // w-64
|
const MENU_WIDTH = 280;
|
||||||
const MENU_MAX_HEIGHT = 288; // max-h-72
|
const MENU_MAX_HEIGHT = 320;
|
||||||
const VIEWPORT_MARGIN = 8;
|
const VIEWPORT_MARGIN = 8;
|
||||||
|
|
||||||
|
const SHORTCUT_HINT = {
|
||||||
|
paragraph: '',
|
||||||
|
heading_1: '#',
|
||||||
|
heading_2: '##',
|
||||||
|
heading_3: '###',
|
||||||
|
heading_4: '####',
|
||||||
|
heading_5: '#####',
|
||||||
|
heading_6: '######',
|
||||||
|
bullet_item: '-',
|
||||||
|
numbered_item: '1.',
|
||||||
|
quote: '>',
|
||||||
|
code: '```',
|
||||||
|
divider: '---',
|
||||||
|
};
|
||||||
import { listBlocks } from './blockRegistry.js';
|
import { listBlocks } from './blockRegistry.js';
|
||||||
|
|
||||||
// Menu flottant des commandes. Affiché ancré à un élément (anchorRect).
|
// Menu flottant des commandes. Affiché ancré à un élément (anchorRect).
|
||||||
@@ -92,8 +107,8 @@ export default function SlashMenu({
|
|||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="fixed z-50 w-64 rounded-xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-lg p-3 text-sm text-neutral-500"
|
className="fixed z-50 rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-md px-3 py-2 text-xs text-neutral-500"
|
||||||
style={{ top, left, maxHeight }}
|
style={{ top, left, width: MENU_WIDTH, maxHeight }}
|
||||||
>
|
>
|
||||||
Aucune commande pour « {query} »
|
Aucune commande pour « {query} »
|
||||||
</div>
|
</div>
|
||||||
@@ -103,12 +118,16 @@ export default function SlashMenu({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={listRef}
|
ref={listRef}
|
||||||
className="fixed z-50 w-64 overflow-y-auto rounded-xl border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-lg py-1"
|
className="fixed z-50 overflow-y-auto rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-md py-1"
|
||||||
style={{ top, left, maxHeight }}
|
style={{ top, left, width: MENU_WIDTH, maxHeight }}
|
||||||
onMouseDown={(e) => e.preventDefault()} // ne pas voler le focus
|
onMouseDown={(e) => e.preventDefault()} // ne pas voler le focus
|
||||||
>
|
>
|
||||||
|
<div className="px-3 pt-1.5 pb-1 text-[10px] font-medium uppercase tracking-wider text-neutral-400 dark:text-neutral-500">
|
||||||
|
Blocs de base
|
||||||
|
</div>
|
||||||
{items.map((def, i) => {
|
{items.map((def, i) => {
|
||||||
const active = i === selectedIndex;
|
const active = i === selectedIndex;
|
||||||
|
const hint = SHORTCUT_HINT[def.type];
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
key={def.type}
|
key={def.type}
|
||||||
@@ -116,14 +135,19 @@ export default function SlashMenu({
|
|||||||
data-slash-index={i}
|
data-slash-index={i}
|
||||||
onMouseEnter={() => onHoverIndex?.(i)}
|
onMouseEnter={() => onHoverIndex?.(i)}
|
||||||
onClick={() => onSelect?.(def.type)}
|
onClick={() => onSelect?.(def.type)}
|
||||||
className={`w-full flex items-center gap-3 px-3 py-2 text-left text-sm transition-colors ${active ? 'bg-neutral-100 dark:bg-neutral-800' : 'hover:bg-neutral-50 dark:hover:bg-neutral-800/60'}`}
|
className={`w-full flex items-center gap-2.5 px-2 py-1 text-left transition-colors ${active ? 'bg-neutral-100 dark:bg-neutral-800' : ''}`}
|
||||||
>
|
>
|
||||||
<span className="w-7 h-7 flex items-center justify-center rounded-md border border-neutral-200 dark:border-neutral-700 text-xs font-medium text-neutral-700 dark:text-neutral-300">
|
<span className="w-6 h-6 flex items-center justify-center rounded-[5px] border border-neutral-200 dark:border-neutral-700 text-[11px] font-medium text-neutral-700 dark:text-neutral-300 flex-shrink-0">
|
||||||
{def.icon}
|
{def.icon}
|
||||||
</span>
|
</span>
|
||||||
<span className="flex-1 min-w-0 truncate text-neutral-900 dark:text-white">
|
<span className="flex-1 min-w-0 truncate text-[13px] text-neutral-900 dark:text-white">
|
||||||
{def.label}
|
{def.label}
|
||||||
</span>
|
</span>
|
||||||
|
{hint && (
|
||||||
|
<span className="text-[11px] font-mono text-neutral-400 dark:text-neutral-500 flex-shrink-0">
|
||||||
|
{hint}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
Reference in New Issue
Block a user