From 2e9c3b20ed6273c334faf77fb1b02fed3e5e2f5b Mon Sep 17 00:00:00 2001 From: Steffen Becker Date: Fri, 14 Aug 2026 23:35:14 +0200 Subject: [PATCH] fix: one colour picker everywhere, and its panel lands under its button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The note-separator, page-decoration and table-line colours were native or a 20-swatch grid; they now open the app's own picker, which grew a swatch-only variant (no icon) for a dialog field plus a disabled state. Its panels move to the top layer: a transformed ancestor is the containing block for position:fixed, and the floating table toolbar has one — cell shading opened its palette in the bottom-right corner. --- src/lib/components/ColorPicker.svelte | 43 ++++++++++-- src/lib/components/NoteOptionsDialog.svelte | 16 +++-- src/lib/components/PageDecorDialog.svelte | 78 ++++++++++++++------- src/lib/components/TableBorderPicker.svelte | 63 +++-------------- 4 files changed, 113 insertions(+), 87 deletions(-) diff --git a/src/lib/components/ColorPicker.svelte b/src/lib/components/ColorPicker.svelte index 54000f4..436bf53 100644 --- a/src/lib/components/ColorPicker.svelte +++ b/src/lib/components/ColorPicker.svelte @@ -12,6 +12,7 @@ chevronTitle, clearLabel, open = $bindable(false), + disabled = false, onApply, onClear, onOpen, @@ -25,10 +26,12 @@ chevronTitle: string; clearLabel?: string; open?: boolean; + disabled?: boolean; onApply: (color: string, range: { from: number; to: number }) => void; onClear: (range: { from: number; to: number }) => void; onOpen?: () => void; - icon: Snippet; + // A toolbar button's glyph. A dialog field passes none and is the swatch alone. + icon?: Snippet; } = $props(); // Row 1 = greyscale, row 2 = standard hues. Rows 3–7 are generated per column @@ -80,6 +83,10 @@ // The panels are `fixed` and placed from the button's rect, so a scrolling // ancestor (the style manager's field column) can't clip them. let split = $state(); + // …and they live in the top layer, whose containing block is the viewport whatever + // sits above the button: a transform makes an ancestor the containing block for + // `fixed`, and the floating table toolbar has one (it hangs itself above the table). + const topLayer = (node: HTMLElement) => node.showPopover(); let panel = $state(); let pos = $state({ top: 0, left: 0 }); @@ -416,18 +423,20 @@
- -
{#if open && view === 'palette'} -
+
{title}
- {/each} -
- {/each} -
+ (color = c)} + onClear={() => (color = '#000000')} + />
{/if} @@ -279,34 +268,4 @@ background: currentColor; } - .bp-colors { - display: flex; - flex-direction: column; - gap: 2px; - } - - .bp-color-row { - display: flex; - gap: 2px; - } - - .bp-color { - width: 18px; - height: 18px; - min-width: unset; - padding: 0; - border: 1px solid var(--color-border); - border-radius: 2px; - cursor: pointer; - transition: transform 0.05s; - } - - .bp-color:hover { - transform: scale(1.15); - } - - .bp-color.active { - outline: 2px solid var(--color-primary); - outline-offset: 1px; - }