From 7db591da172d89533937eb8ecd5ea2f53da92461 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Tue, 3 Mar 2026 15:47:26 -0800 Subject: [PATCH] feat: add settings menus to all 4 decide/choice canvas elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each choice component now has a gear (⚙) settings panel for configuring title, options, criteria, and tool-specific parameters inline on the canvas. - folk-choice-vote: title, options (color+label), QV budget, reset votes - folk-choice-conviction: title, options (color+label), reset stakes - folk-choice-rank: title, options (label), reset rankings - folk-choice-spider: title, options, criteria with weight sliders, reset scores Co-Authored-By: Claude Opus 4.6 --- lib/folk-choice-conviction.ts | 104 +++++++++++++++++++++++++ lib/folk-choice-rank.ts | 97 ++++++++++++++++++++++++ lib/folk-choice-spider.ts | 138 ++++++++++++++++++++++++++++++++++ lib/folk-choice-vote.ts | 115 ++++++++++++++++++++++++++++ 4 files changed, 454 insertions(+) diff --git a/lib/folk-choice-conviction.ts b/lib/folk-choice-conviction.ts index 36d2497..f1d2e24 100644 --- a/lib/folk-choice-conviction.ts +++ b/lib/folk-choice-conviction.ts @@ -277,6 +277,23 @@ const styles = css` .participant-row { display: flex; align-items: center; gap: 6px; padding: 2px 0; font-size: 11px; color: #475569; } .participant-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; } .drawer-toggle.active { background: rgba(255,255,255,0.3); } + .settings-toggle.active { background: rgba(255,255,255,0.3); } + .settings-panel { display: none; flex-direction: column; gap: 12px; padding: 12px; overflow-y: auto; height: calc(100% - 36px); } + .settings-open .settings-panel { display: flex; } + .settings-open .body { display: none !important; } + .settings-open .results-drawer { display: none !important; } + .settings-label { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: #94a3b8; margin-bottom: 6px; } + .settings-input { width: 100%; box-sizing: border-box; border: 1px solid #e2e8f0; border-radius: 6px; padding: 6px 10px; font-size: 12px; outline: none; } + .settings-input:focus { border-color: #d97706; } + .settings-item { display: flex; align-items: center; gap: 6px; padding: 4px 0; } + .settings-item input[type="text"] { flex: 1; border: 1px solid #e2e8f0; border-radius: 4px; padding: 4px 6px; font-size: 11px; outline: none; min-width: 0; } + .settings-item input[type="color"] { width: 24px; height: 24px; border: none; border-radius: 4px; padding: 0; cursor: pointer; background: none; } + .settings-item .remove-btn { background: none; border: none; color: #94a3b8; cursor: pointer; font-size: 14px; padding: 2px 4px; border-radius: 4px; flex-shrink: 0; } + .settings-item .remove-btn:hover { color: #ef4444; background: #fef2f2; } + .settings-danger { background: none; border: 1px solid #fca5a5; color: #ef4444; border-radius: 6px; padding: 6px 12px; cursor: pointer; font-size: 11px; width: 100%; margin-top: 4px; } + .settings-danger:hover { background: #fef2f2; } + .settings-done { background: #d97706; color: white; border: none; border-radius: 6px; padding: 8px 16px; cursor: pointer; font-size: 12px; font-weight: 500; width: 100%; margin-top: auto; } + .settings-done:hover { background: #b45309; } `; // -- Data types -- @@ -349,6 +366,7 @@ export class FolkChoiceConviction extends FolkShape { #userId = ""; #userName = ""; #drawerOpen = false; + #settingsOpen = false; #tickInterval: ReturnType | null = null; // DOM refs @@ -359,6 +377,7 @@ export class FolkChoiceConviction extends FolkShape { #votersEl: HTMLElement | null = null; #drawerEl: HTMLElement | null = null; #chartEl: HTMLElement | null = null; + #settingsEl: HTMLElement | null = null; get title() { return this.#title; } set title(v: string) { this.#title = v; this.requestUpdate("title"); } @@ -442,6 +461,7 @@ export class FolkChoiceConviction extends FolkShape { Conviction
+
@@ -457,6 +477,7 @@ export class FolkChoiceConviction extends FolkShape {
+
+
+
+