fix: the ribbon's bare icon buttons carry their labels
Layout's hyphenation, page numbers, line numbers and page decoration, and Review's accept/reject and comment pane, all passed a label that the icon variant drops. They are small buttons now, stacked two to a column so the band keeps its height, with the caret after the label as a row reads.
This commit is contained in:
1 parent
3e5a546bb9
commit
d0d2ea2338
3 files changed
+127
-108
No files matched your search
@@ -34,21 +34,19 @@
|
||||
} = $props();
|
||||
|
||||
const ICON_SIZE = { big: 28, small: 14, icon: 20 } as const;
|
||||
|
||||
// One button when the whole of it opens the menu, and the caret joins the column
|
||||
// under the label.
|
||||
let stackCaret = $derived(caret && !onCaret && variant === 'big');
|
||||
</script>
|
||||
|
||||
{#snippet face(withLabel = true)}
|
||||
<span class="rb-face">
|
||||
{#if content}{@render content()}
|
||||
{:else if icon}<Icon name={icon} size={ICON_SIZE[variant]} />{/if}
|
||||
{#if caret && !onCaret && !stackCaret}
|
||||
{#if caret && !onCaret && variant === 'icon'}
|
||||
<Icon name="chevronDown" size={10} />
|
||||
{/if}
|
||||
</span>
|
||||
{#if withLabel && label && variant !== 'icon'}<span class="rb-label">{label}</span>{/if}
|
||||
<!-- A row reads left to right, so its caret follows the label rather than the icon. -->
|
||||
{#if caret && !onCaret && variant === 'small'}<Icon name="chevronDown" size={10} />{/if}
|
||||
<!-- Held open on every big button, carrying a caret or nothing: the group centres
|
||||
its controls, so one taller button lifts its own icon and label off the row. -->
|
||||
{#if variant === 'big' && !onCaret}
|
||||
|
||||
@@ -242,88 +242,94 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<RibbonButton
|
||||
icon="hyphenation"
|
||||
label={t().ribbon.hyphenation}
|
||||
title={t().ribbon.hyphenationHint}
|
||||
active={hyphenate}
|
||||
onclick={() => (hyphenate = !hyphenate)}
|
||||
/>
|
||||
|
||||
<div class="rb-menu-wrap" use:clickOutside={'pageNum'}>
|
||||
<div class="rb-col">
|
||||
<RibbonButton
|
||||
icon="pageNumber"
|
||||
label={t().ribbon.pageNumberFormat}
|
||||
title={t().ribbon.pageNumberFormat}
|
||||
caret
|
||||
active={isMenuOpen('pageNum')}
|
||||
onclick={() => toggleMenu('pageNum')}
|
||||
variant="small"
|
||||
icon="hyphenation"
|
||||
label={t().ribbon.hyphenation}
|
||||
title={t().ribbon.hyphenationHint}
|
||||
active={hyphenate}
|
||||
onclick={() => (hyphenate = !hyphenate)}
|
||||
/>
|
||||
{#if isMenuOpen('pageNum')}
|
||||
<div class="ribbon-menu" use:anchored role="menu">
|
||||
<div class="rb-menu-label">{t().ribbon.pageNumberFormat}</div>
|
||||
{#each PAGE_NUM_FORMATS as f}
|
||||
<button class:selected={pageNumbering.format === f} onclick={() => (pageNumbering = { ...pageNumbering, format: f })}>
|
||||
{[1, 2, 3].map((n) => formatOrdinal(n, f)).join(', ')}
|
||||
<div class="rb-menu-wrap" use:clickOutside={'pageNum'}>
|
||||
<RibbonButton
|
||||
variant="small"
|
||||
icon="pageNumber"
|
||||
label={t().ribbon.pageNumberFormat}
|
||||
title={t().ribbon.pageNumberFormat}
|
||||
caret
|
||||
active={isMenuOpen('pageNum')}
|
||||
onclick={() => toggleMenu('pageNum')}
|
||||
/>
|
||||
{#if isMenuOpen('pageNum')}
|
||||
<div class="ribbon-menu" use:anchored role="menu">
|
||||
<div class="rb-menu-label">{t().ribbon.pageNumberFormat}</div>
|
||||
{#each PAGE_NUM_FORMATS as f}
|
||||
<button class:selected={pageNumbering.format === f} onclick={() => (pageNumbering = { ...pageNumbering, format: f })}>
|
||||
{[1, 2, 3].map((n) => formatOrdinal(n, f)).join(', ')}
|
||||
</button>
|
||||
{/each}
|
||||
<div class="rb-menu-label">{t().ribbon.pageNumberStart}</div>
|
||||
<label class="num-row">
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
max="9999"
|
||||
value={pageNumbering.start}
|
||||
onchange={(e) => (pageNumbering = { ...pageNumbering, start: clampPageStart(Number(e.currentTarget.value)) })}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rb-col">
|
||||
<div class="rb-menu-wrap" use:clickOutside={'lineNum'}>
|
||||
<RibbonButton
|
||||
variant="small"
|
||||
icon="lineNumbers"
|
||||
label={t().ribbon.lineNumbers}
|
||||
title={t().lineNumbers.title}
|
||||
caret
|
||||
active={isMenuOpen('lineNum') || lineNumbering.on}
|
||||
onclick={() => toggleMenu('lineNum')}
|
||||
/>
|
||||
{#if isMenuOpen('lineNum')}
|
||||
<div class="ribbon-menu" use:anchored role="menu">
|
||||
<button class:selected={!lineNumbering.on} onclick={() => (lineNumbering = { ...lineNumbering, on: false })}>
|
||||
{t().lineNumbers.off}
|
||||
</button>
|
||||
{/each}
|
||||
<div class="rb-menu-label">{t().ribbon.pageNumberStart}</div>
|
||||
<label class="num-row">
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
max="9999"
|
||||
value={pageNumbering.start}
|
||||
onchange={(e) => (pageNumbering = { ...pageNumbering, start: clampPageStart(Number(e.currentTarget.value)) })}
|
||||
/>
|
||||
</label>
|
||||
<button class:selected={lineNumbering.on && lineNumbering.restart === 'continuous'}
|
||||
onclick={() => (lineNumbering = { ...lineNumbering, on: true, restart: 'continuous' })}>
|
||||
{t().lineNumbers.continuous}
|
||||
</button>
|
||||
<button class:selected={lineNumbering.on && lineNumbering.restart === 'page'}
|
||||
onclick={() => (lineNumbering = { ...lineNumbering, on: true, restart: 'page' })}>
|
||||
{t().lineNumbers.perPage}
|
||||
</button>
|
||||
<div class="rb-menu-label">{t().lineNumbers.interval}</div>
|
||||
<label class="num-row">
|
||||
<input type="number" min="1" max="100" value={lineNumbering.interval}
|
||||
onchange={(e) => (lineNumbering = { ...lineNumbering, interval: Math.max(1, Math.min(100, Number(e.currentTarget.value) || 1)) })} />
|
||||
</label>
|
||||
<label class="check-row">
|
||||
<input type="checkbox" checked={lineNumbering.countEmpty}
|
||||
onchange={(e) => (lineNumbering = { ...lineNumbering, countEmpty: e.currentTarget.checked })} />
|
||||
{t().lineNumbers.countEmpty}
|
||||
</label>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="rb-menu-wrap" use:clickOutside={'lineNum'}>
|
||||
<RibbonButton
|
||||
icon="lineNumbers"
|
||||
label={t().ribbon.lineNumbers}
|
||||
title={t().lineNumbers.title}
|
||||
caret
|
||||
active={isMenuOpen('lineNum') || lineNumbering.on}
|
||||
onclick={() => toggleMenu('lineNum')}
|
||||
variant="small"
|
||||
icon="watermark"
|
||||
label={t().ribbon.pageDecor}
|
||||
title={t().pageDecor.title}
|
||||
active={!!(pageDecor.background || pageDecor.border || pageDecor.watermark)}
|
||||
onclick={() => (decorOpen = true)}
|
||||
/>
|
||||
{#if isMenuOpen('lineNum')}
|
||||
<div class="ribbon-menu" use:anchored role="menu">
|
||||
<button class:selected={!lineNumbering.on} onclick={() => (lineNumbering = { ...lineNumbering, on: false })}>
|
||||
{t().lineNumbers.off}
|
||||
</button>
|
||||
<button class:selected={lineNumbering.on && lineNumbering.restart === 'continuous'}
|
||||
onclick={() => (lineNumbering = { ...lineNumbering, on: true, restart: 'continuous' })}>
|
||||
{t().lineNumbers.continuous}
|
||||
</button>
|
||||
<button class:selected={lineNumbering.on && lineNumbering.restart === 'page'}
|
||||
onclick={() => (lineNumbering = { ...lineNumbering, on: true, restart: 'page' })}>
|
||||
{t().lineNumbers.perPage}
|
||||
</button>
|
||||
<div class="rb-menu-label">{t().lineNumbers.interval}</div>
|
||||
<label class="num-row">
|
||||
<input type="number" min="1" max="100" value={lineNumbering.interval}
|
||||
onchange={(e) => (lineNumbering = { ...lineNumbering, interval: Math.max(1, Math.min(100, Number(e.currentTarget.value) || 1)) })} />
|
||||
</label>
|
||||
<label class="check-row">
|
||||
<input type="checkbox" checked={lineNumbering.countEmpty}
|
||||
onchange={(e) => (lineNumbering = { ...lineNumbering, countEmpty: e.currentTarget.checked })} />
|
||||
{t().lineNumbers.countEmpty}
|
||||
</label>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<RibbonButton
|
||||
icon="watermark"
|
||||
label={t().ribbon.pageDecor}
|
||||
title={t().pageDecor.title}
|
||||
active={!!(pageDecor.background || pageDecor.border || pageDecor.watermark)}
|
||||
onclick={() => (decorOpen = true)}
|
||||
/>
|
||||
</RibbonGroup>
|
||||
|
||||
<PageDecorDialog bind:open={decorOpen} bind:decor={pageDecor} />
|
||||
@@ -379,6 +385,10 @@
|
||||
|
||||
.rb-menu-wrap { position: relative; }
|
||||
|
||||
/* Two rows of named commands beside the big ones, as the band is one big button tall. */
|
||||
.rb-col { display: flex; flex-direction: column; gap: 2px; }
|
||||
.rb-col :global(.rb-small) { width: 100%; }
|
||||
|
||||
.col-preview { flex-shrink: 0; }
|
||||
|
||||
.margin-menu, .format-menu, .breaks-menu { min-width: 230px; }
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
onclick={() => onNewComment?.()}
|
||||
/>
|
||||
<RibbonButton
|
||||
variant="small"
|
||||
icon="comment"
|
||||
label={t().comments.title}
|
||||
title={t().comments.showPane}
|
||||
@@ -110,34 +111,41 @@
|
||||
active={recordChanges()}
|
||||
onclick={() => setRecordChanges(!recordChanges())}
|
||||
/>
|
||||
<RibbonButton
|
||||
icon="check"
|
||||
label={t().revisions.accept}
|
||||
title={t().revisions.acceptHint}
|
||||
disabled={!hasRevisions}
|
||||
onclick={() => editor?.chain().focus().acceptRevisions().run()}
|
||||
/>
|
||||
<RibbonButton
|
||||
icon="close"
|
||||
label={t().revisions.reject}
|
||||
title={t().revisions.rejectHint}
|
||||
disabled={!hasRevisions}
|
||||
onclick={() => editor?.chain().focus().rejectRevisions().run()}
|
||||
/>
|
||||
<RibbonButton
|
||||
variant="small"
|
||||
icon="check"
|
||||
label={t().revisions.acceptAll}
|
||||
disabled={!hasRevisions}
|
||||
onclick={() => editor?.chain().focus().acceptRevisions(true).run()}
|
||||
/>
|
||||
<RibbonButton
|
||||
variant="small"
|
||||
icon="close"
|
||||
label={t().revisions.rejectAll}
|
||||
disabled={!hasRevisions}
|
||||
onclick={() => editor?.chain().focus().rejectRevisions(true).run()}
|
||||
/>
|
||||
<!-- The one at the cursor over the whole document, so the pair reads as one column. -->
|
||||
<div class="rb-col">
|
||||
<RibbonButton
|
||||
variant="small"
|
||||
icon="check"
|
||||
label={t().revisions.accept}
|
||||
title={t().revisions.acceptHint}
|
||||
disabled={!hasRevisions}
|
||||
onclick={() => editor?.chain().focus().acceptRevisions().run()}
|
||||
/>
|
||||
<RibbonButton
|
||||
variant="small"
|
||||
icon="check"
|
||||
label={t().revisions.acceptAll}
|
||||
disabled={!hasRevisions}
|
||||
onclick={() => editor?.chain().focus().acceptRevisions(true).run()}
|
||||
/>
|
||||
</div>
|
||||
<div class="rb-col">
|
||||
<RibbonButton
|
||||
variant="small"
|
||||
icon="close"
|
||||
label={t().revisions.reject}
|
||||
title={t().revisions.rejectHint}
|
||||
disabled={!hasRevisions}
|
||||
onclick={() => editor?.chain().focus().rejectRevisions().run()}
|
||||
/>
|
||||
<RibbonButton
|
||||
variant="small"
|
||||
icon="close"
|
||||
label={t().revisions.rejectAll}
|
||||
disabled={!hasRevisions}
|
||||
onclick={() => editor?.chain().focus().rejectRevisions(true).run()}
|
||||
/>
|
||||
</div>
|
||||
</RibbonGroup>
|
||||
|
||||
<div class="ribbon-sep"></div>
|
||||
@@ -153,6 +161,9 @@
|
||||
.rb-menu-wrap { position: relative; }
|
||||
.stats-menu { min-width: 240px; }
|
||||
|
||||
.rb-col { display: flex; flex-direction: column; gap: 2px; }
|
||||
.rb-col :global(.rb-small) { width: 100%; }
|
||||
|
||||
.stat {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
Reference in new issue
Block a user