diff --git a/src/lib/components/ribbon/RibbonButton.svelte b/src/lib/components/ribbon/RibbonButton.svelte index e93b525..6f35bca 100644 --- a/src/lib/components/ribbon/RibbonButton.svelte +++ b/src/lib/components/ribbon/RibbonButton.svelte @@ -34,17 +34,26 @@ } = $props(); const ICON_SIZE = { big: 28, small: 14, icon: 20 } as const; + + // Nothing to split when the whole button opens the menu, so the caret joins the + // column under the label instead of sitting beside the icon. + let stackCaret = $derived(caret && !onCaret && variant === 'big'); {#snippet face(withLabel = true)} {#if content}{@render content()} {:else if icon}{/if} - {#if caret && !onCaret} + {#if caret && !onCaret && !stackCaret} {/if} {#if withLabel && label && variant !== 'icon'}{label}{/if} + + {#if variant === 'big' && !onCaret} + {#if caret}{/if} + {/if} {/snippet} {#if caret && onCaret} @@ -67,7 +76,15 @@ {:else} - {/if} @@ -98,8 +115,8 @@ gap: 2px; } - /* Icon over label. The hover tint paints the icon box, not the whole button — - Word's signature, and what keeps a labelled column from looking like a slab. */ + /* Icon over label, and the tint takes both. Word paints only the icon box, but + then the words beside an identical-looking neighbour light up and these do not. */ .rb-big { flex-direction: column; gap: 4px; @@ -115,9 +132,9 @@ margin: 0 -4px; } - .rb-big:hover:not(:disabled) .rb-face { background: var(--w-hover); } - .rb-big:active:not(:disabled) .rb-face { background: var(--w-pressed); } - .rb-big.active .rb-face { background: var(--w-active); } + .rb-big:hover:not(:disabled) { background: var(--w-hover); } + .rb-big:active:not(:disabled) { background: var(--w-pressed); } + .rb-big.active { background: var(--w-active); } /* A row in a stacked mini-column (Cut / Copy under a big Paste). */ .rb-small { @@ -145,6 +162,14 @@ color: inherit; } + /* Rides closer to the label than the 4px column gap: the two read as one line. */ + .rb-stack-caret { + display: flex; + height: 10px; + margin-top: -3px; + color: var(--w-text-dim); + } + /* Split button: the two halves read as one control, so the hover outline sits on the wrapper and each half only tints its own surface. */ .rb-split { @@ -169,15 +194,15 @@ } /* A big split button stacks, as in Word: the icon runs the command, the label - and its caret open the menu. Welded to the right the caret would float at - icon height, beside the label rather than with it. */ + and the caret under it open the menu. Icon, label and caret each get their + own line — abreast, the caret widens the button by its own width. */ .rb-split-col { flex-direction: column; } - .rb-split-col .rb-big { padding: 4px 7px 0; } + .rb-split-col .rb-big { padding: 3px 7px 0; } .rb-split-col .rb-caret { + flex-direction: column; width: auto; - gap: 3px; - padding: 4px 7px 6px; + padding: 0 7px 2px; border-radius: 0 0 3px 3px; color: var(--w-text); } diff --git a/src/lib/components/ribbon/menu.svelte.ts b/src/lib/components/ribbon/menu.svelte.ts index d3526a1..4dfbbb0 100644 --- a/src/lib/components/ribbon/menu.svelte.ts +++ b/src/lib/components/ribbon/menu.svelte.ts @@ -111,3 +111,16 @@ export function clickOutside(node: HTMLElement, id?: string) { window.addEventListener('mousedown', handler); return { destroy() { window.removeEventListener('mousedown', handler); } }; } + +// A reused picker keeps its trigger inside its own component, so the caption the +// ribbon puts beside it is not part of that button: hovering the words lit nothing +// and clicking them did nothing. Forwards a click that missed every button to the +// first one, so glyph and caption behave as the single control they look like. +export function captionClicks(node: HTMLElement) { + function handler(e: MouseEvent) { + if ((e.target as HTMLElement).closest('button, select, input')) return; + node.querySelector('button')?.click(); + } + node.addEventListener('click', handler); + return { destroy() { node.removeEventListener('click', handler); } }; +} diff --git a/src/lib/components/ribbon/tabs/FrameTabs.svelte b/src/lib/components/ribbon/tabs/FrameTabs.svelte index 31c35cf..2b6f2f9 100644 --- a/src/lib/components/ribbon/tabs/FrameTabs.svelte +++ b/src/lib/components/ribbon/tabs/FrameTabs.svelte @@ -1,4 +1,5 @@