Redesign canvas toolbar with grouped dropdowns and collapse
28 flat tool buttons replaced with 6 category dropdowns (Create, Media, Embed, AI, Travel, Decide) plus direct-access Connect/Memory/Zoom buttons. Toolbar is now collapsible via a minimize toggle. Mobile responsive with accordion-style groups. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7937066486
commit
5c3db2caea
|
|
@ -26,33 +26,131 @@
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
align-items: center;
|
||||||
padding: 8px 16px;
|
gap: 4px;
|
||||||
|
padding: 6px 10px;
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toolbar button {
|
/* Dropdown group container */
|
||||||
padding: 8px 16px;
|
.toolbar-group {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-group-toggle {
|
||||||
|
padding: 7px 12px;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #f1f5f9;
|
background: #f1f5f9;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 14px;
|
font-size: 13px;
|
||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toolbar button:hover {
|
.toolbar-group-toggle:hover {
|
||||||
background: #e2e8f0;
|
background: #e2e8f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toolbar button.active {
|
.toolbar-group.open > .toolbar-group-toggle {
|
||||||
background: #14b8a6;
|
background: #14b8a6;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toolbar-dropdown {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 6px);
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
min-width: 160px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.18);
|
||||||
|
padding: 6px;
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-group.open > .toolbar-dropdown {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-dropdown button {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
text-align: left;
|
||||||
|
white-space: nowrap;
|
||||||
|
transition: background 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-dropdown button:hover {
|
||||||
|
background: #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Separator between sections */
|
||||||
|
.toolbar-sep {
|
||||||
|
width: 1px;
|
||||||
|
height: 24px;
|
||||||
|
background: #e2e8f0;
|
||||||
|
margin: 0 2px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Direct toolbar buttons (Connect, Memory, Zoom) */
|
||||||
|
#toolbar > button {
|
||||||
|
padding: 7px 12px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f1f5f9;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px;
|
||||||
|
transition: background 0.2s;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar > button:hover {
|
||||||
|
background: #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar > button.active {
|
||||||
|
background: #14b8a6;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Collapse/expand toggle */
|
||||||
|
#toolbar-collapse {
|
||||||
|
padding: 7px 8px !important;
|
||||||
|
background: transparent !important;
|
||||||
|
font-size: 16px !important;
|
||||||
|
line-height: 1;
|
||||||
|
opacity: 0.6;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar-collapse:hover {
|
||||||
|
opacity: 1;
|
||||||
|
background: #f1f5f9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar.collapsed .toolbar-group,
|
||||||
|
#toolbar.collapsed .toolbar-sep,
|
||||||
|
#toolbar.collapsed > button:not(#toolbar-collapse) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar.collapsed {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
#community-info {
|
#community-info {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 72px;
|
top: 72px;
|
||||||
|
|
@ -389,7 +487,7 @@
|
||||||
touch-action: manipulation;
|
touch-action: manipulation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide desktop toolbar, show as grid overlay when toggled */
|
/* Hide desktop toolbar, show as column overlay when toggled */
|
||||||
#toolbar {
|
#toolbar {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|
@ -410,20 +508,48 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toolbar button {
|
/* On mobile, flatten groups into a grid */
|
||||||
flex: 0 0 calc(33.33% - 4px);
|
#toolbar .toolbar-group {
|
||||||
padding: 10px 4px;
|
width: 100%;
|
||||||
font-size: 12px;
|
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide zoom/reset from toolbar grid (they're in #mobile-zoom) */
|
#toolbar .toolbar-group-toggle {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
padding: 10px 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar .toolbar-dropdown {
|
||||||
|
position: static;
|
||||||
|
transform: none;
|
||||||
|
box-shadow: none;
|
||||||
|
padding: 4px 0 4px 12px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar .toolbar-dropdown button {
|
||||||
|
padding: 10px 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar > button {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
padding: 10px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbar .toolbar-sep {
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide zoom/reset from toolbar (they're in #mobile-zoom) */
|
||||||
#toolbar #zoom-in,
|
#toolbar #zoom-in,
|
||||||
#toolbar #zoom-out,
|
#toolbar #zoom-out,
|
||||||
#toolbar #reset-view {
|
#toolbar #reset-view,
|
||||||
|
#toolbar #toolbar-collapse {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,36 +587,79 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="toolbar">
|
<div id="toolbar">
|
||||||
<button id="new-markdown" title="New Note">📝 Note</button>
|
<button id="toolbar-collapse" title="Minimize toolbar">◀</button>
|
||||||
<button id="new-wrapper" title="New Card">🗂️ Card</button>
|
|
||||||
<button id="new-slide" title="New Slide">🎞️ Slide</button>
|
<div class="toolbar-group">
|
||||||
<button id="new-chat" title="New Chat">💬 Chat</button>
|
<button class="toolbar-group-toggle">📝 Create</button>
|
||||||
<button id="new-piano" title="New Piano">🎹 Piano</button>
|
<div class="toolbar-dropdown">
|
||||||
<button id="new-embed" title="New Embed">🔗 Embed</button>
|
<button id="new-markdown" title="New Note">📝 Note</button>
|
||||||
<button id="new-google-item" title="New Google Item">📎 Google</button>
|
<button id="new-wrapper" title="New Card">🗂️ Card</button>
|
||||||
<button id="new-calendar" title="New Calendar">📅 Calendar</button>
|
<button id="new-slide" title="New Slide">🎞️ Slide</button>
|
||||||
<button id="new-map" title="New Map">🗺️ Map</button>
|
<button id="new-obs-note" title="New Rich Note">📓 Rich Note</button>
|
||||||
<button id="new-image-gen" title="New AI Image">🎨 Image</button>
|
<button id="new-chat" title="New Chat">💬 Chat</button>
|
||||||
<button id="new-video-gen" title="New AI Video">🎬 Video</button>
|
</div>
|
||||||
<button id="new-prompt" title="New AI Chat">🤖 AI</button>
|
</div>
|
||||||
<button id="new-transcription" title="New Transcription">🎤 Transcribe</button>
|
|
||||||
<button id="new-video-chat" title="New Video Call">📹 Call</button>
|
<div class="toolbar-group">
|
||||||
<button id="new-obs-note" title="New Rich Note">📓 Rich Note</button>
|
<button class="toolbar-group-toggle">🎨 Media</button>
|
||||||
<button id="new-workflow" title="New Workflow">⚙️ Workflow</button>
|
<div class="toolbar-dropdown">
|
||||||
<button id="new-itinerary" title="New Itinerary">🗓️ Itinerary</button>
|
<button id="new-image-gen" title="New AI Image">🎨 AI Image</button>
|
||||||
<button id="new-destination" title="New Destination">📍 Destination</button>
|
<button id="new-video-gen" title="New AI Video">🎬 AI Video</button>
|
||||||
<button id="new-budget" title="New Budget">💰 Budget</button>
|
<button id="new-transcription" title="New Transcription">🎤 Transcribe</button>
|
||||||
<button id="new-packing-list" title="New Packing List">🎒 Packing</button>
|
<button id="new-video-chat" title="New Video Call">📹 Video Call</button>
|
||||||
<button id="new-booking" title="New Booking">✈️ Booking</button>
|
<button id="new-piano" title="New Piano">🎹 Piano</button>
|
||||||
<button id="new-token" title="New Token">🪙 Token</button>
|
</div>
|
||||||
<button id="new-choice-vote" title="New Poll">☑ Poll</button>
|
</div>
|
||||||
<button id="new-choice-rank" title="New Ranking">📊 Rank</button>
|
|
||||||
<button id="new-choice-spider" title="New Scoring">🕸 Spider</button>
|
<div class="toolbar-group">
|
||||||
<button id="new-social-post" title="New Post">📱 Post</button>
|
<button class="toolbar-group-toggle">🔗 Embed</button>
|
||||||
|
<div class="toolbar-dropdown">
|
||||||
|
<button id="new-embed" title="New Embed">🔗 Web Embed</button>
|
||||||
|
<button id="new-google-item" title="New Google Item">📎 Google</button>
|
||||||
|
<button id="new-calendar" title="New Calendar">📅 Calendar</button>
|
||||||
|
<button id="new-map" title="New Map">🗺️ Map</button>
|
||||||
|
<button id="new-social-post" title="New Post">📱 Social Post</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-group">
|
||||||
|
<button class="toolbar-group-toggle">🤖 AI</button>
|
||||||
|
<div class="toolbar-dropdown">
|
||||||
|
<button id="new-prompt" title="New AI Chat">🤖 AI Chat</button>
|
||||||
|
<button id="new-workflow" title="New Workflow">⚙️ Workflow</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-group">
|
||||||
|
<button class="toolbar-group-toggle">✈️ Travel</button>
|
||||||
|
<div class="toolbar-dropdown">
|
||||||
|
<button id="new-itinerary" title="New Itinerary">🗓️ Itinerary</button>
|
||||||
|
<button id="new-destination" title="New Destination">📍 Destination</button>
|
||||||
|
<button id="new-budget" title="New Budget">💰 Budget</button>
|
||||||
|
<button id="new-packing-list" title="New Packing List">🎒 Packing List</button>
|
||||||
|
<button id="new-booking" title="New Booking">✈️ Booking</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="toolbar-group">
|
||||||
|
<button class="toolbar-group-toggle">📊 Decide</button>
|
||||||
|
<div class="toolbar-dropdown">
|
||||||
|
<button id="new-choice-vote" title="New Poll">☑ Poll</button>
|
||||||
|
<button id="new-choice-rank" title="New Ranking">📊 Ranking</button>
|
||||||
|
<button id="new-choice-spider" title="New Scoring">🕸 Scoring</button>
|
||||||
|
<button id="new-token" title="New Token">🪙 Token</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="toolbar-sep"></span>
|
||||||
|
|
||||||
<button id="new-arrow" title="Connect rSpaces">↗️ Connect</button>
|
<button id="new-arrow" title="Connect rSpaces">↗️ Connect</button>
|
||||||
<button id="toggle-memory" title="Forgotten rSpaces">💭 Memory</button>
|
<button id="toggle-memory" title="Forgotten rSpaces">💭 Memory</button>
|
||||||
|
|
||||||
|
<span class="toolbar-sep"></span>
|
||||||
|
|
||||||
<button id="zoom-in" title="Zoom In">+</button>
|
<button id="zoom-in" title="Zoom In">+</button>
|
||||||
<button id="zoom-out" title="Zoom Out">-</button>
|
<button id="zoom-out" title="Zoom Out">−</button>
|
||||||
<button id="reset-view" title="Reset View">Reset</button>
|
<button id="reset-view" title="Reset View">Reset</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -1458,14 +1627,50 @@
|
||||||
if (window.innerWidth > 768) return;
|
if (window.innerWidth > 768) return;
|
||||||
const btn = e.target.closest("button");
|
const btn = e.target.closest("button");
|
||||||
if (!btn) return;
|
if (!btn) return;
|
||||||
// Keep open for connect, memory, zoom controls
|
// Keep open for connect, memory, zoom, group toggles, collapse
|
||||||
const keepOpen = ["new-arrow", "toggle-memory", "zoom-in", "zoom-out", "reset-view"];
|
const keepOpen = ["new-arrow", "toggle-memory", "zoom-in", "zoom-out", "reset-view", "toolbar-collapse"];
|
||||||
|
if (btn.classList.contains("toolbar-group-toggle")) return;
|
||||||
if (!keepOpen.includes(btn.id)) {
|
if (!keepOpen.includes(btn.id)) {
|
||||||
toolbarEl.classList.remove("mobile-open");
|
toolbarEl.classList.remove("mobile-open");
|
||||||
mobileMenuBtn.textContent = "✚";
|
mobileMenuBtn.textContent = "✚";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Dropdown group toggles
|
||||||
|
toolbarEl.querySelectorAll(".toolbar-group-toggle").forEach(toggle => {
|
||||||
|
toggle.addEventListener("click", (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
const group = toggle.closest(".toolbar-group");
|
||||||
|
const wasOpen = group.classList.contains("open");
|
||||||
|
// Close all other groups
|
||||||
|
toolbarEl.querySelectorAll(".toolbar-group.open").forEach(g => g.classList.remove("open"));
|
||||||
|
// Toggle this one
|
||||||
|
if (!wasOpen) group.classList.add("open");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close dropdowns when clicking a tool inside one
|
||||||
|
toolbarEl.querySelectorAll(".toolbar-dropdown button").forEach(btn => {
|
||||||
|
btn.addEventListener("click", () => {
|
||||||
|
toolbarEl.querySelectorAll(".toolbar-group.open").forEach(g => g.classList.remove("open"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close dropdowns when clicking outside
|
||||||
|
document.addEventListener("click", (e) => {
|
||||||
|
if (!e.target.closest("#toolbar")) {
|
||||||
|
toolbarEl.querySelectorAll(".toolbar-group.open").forEach(g => g.classList.remove("open"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Collapse/expand toolbar
|
||||||
|
const collapseBtn = document.getElementById("toolbar-collapse");
|
||||||
|
collapseBtn.addEventListener("click", () => {
|
||||||
|
const isCollapsed = toolbarEl.classList.toggle("collapsed");
|
||||||
|
collapseBtn.textContent = isCollapsed ? "▶" : "◀";
|
||||||
|
collapseBtn.title = isCollapsed ? "Expand toolbar" : "Minimize toolbar";
|
||||||
|
});
|
||||||
|
|
||||||
// Mobile zoom controls (separate from toolbar)
|
// Mobile zoom controls (separate from toolbar)
|
||||||
document.getElementById("mz-in").addEventListener("click", () => {
|
document.getElementById("mz-in").addEventListener("click", () => {
|
||||||
scale = Math.min(scale * 1.25, maxScale);
|
scale = Math.min(scale * 1.25, maxScale);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue