Redesign header UI with dropdown menu for vault filter and theme toggle
This commit is contained in:
parent
ae46e62902
commit
25c7533409
@ -94,9 +94,15 @@
|
|||||||
document.documentElement.setAttribute("data-theme", theme);
|
document.documentElement.setAttribute("data-theme", theme);
|
||||||
localStorage.setItem("obsigate-theme", theme);
|
localStorage.setItem("obsigate-theme", theme);
|
||||||
|
|
||||||
const icon = document.getElementById("theme-icon");
|
// Update theme button icon and label
|
||||||
if (icon) {
|
const themeBtn = document.getElementById("theme-toggle");
|
||||||
icon.setAttribute("data-lucide", theme === "dark" ? "moon" : "sun");
|
const themeLabel = document.getElementById("theme-label");
|
||||||
|
if (themeBtn && themeLabel) {
|
||||||
|
const icon = themeBtn.querySelector("i");
|
||||||
|
if (icon) {
|
||||||
|
icon.setAttribute("data-lucide", theme === "dark" ? "moon" : "sun");
|
||||||
|
}
|
||||||
|
themeLabel.textContent = theme === "dark" ? "Sombre" : "Clair";
|
||||||
safeCreateIcons();
|
safeCreateIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +120,32 @@
|
|||||||
applyTheme(current === "dark" ? "light" : "dark");
|
applyTheme(current === "dark" ? "light" : "dark");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initHeaderMenu() {
|
||||||
|
const menuBtn = document.getElementById("header-menu-btn");
|
||||||
|
const menuDropdown = document.getElementById("header-menu-dropdown");
|
||||||
|
|
||||||
|
if (!menuBtn || !menuDropdown) return;
|
||||||
|
|
||||||
|
menuBtn.addEventListener("click", (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
menuBtn.classList.toggle("active");
|
||||||
|
menuDropdown.classList.toggle("active");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close menu when clicking outside
|
||||||
|
document.addEventListener("click", (e) => {
|
||||||
|
if (!menuDropdown.contains(e.target) && e.target !== menuBtn) {
|
||||||
|
menuBtn.classList.remove("active");
|
||||||
|
menuDropdown.classList.remove("active");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevent menu from closing when clicking inside
|
||||||
|
menuDropdown.addEventListener("click", (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// API helpers
|
// API helpers
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -948,6 +980,7 @@
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
async function init() {
|
async function init() {
|
||||||
initTheme();
|
initTheme();
|
||||||
|
initHeaderMenu();
|
||||||
document.getElementById("theme-toggle").addEventListener("click", toggleTheme);
|
document.getElementById("theme-toggle").addEventListener("click", toggleTheme);
|
||||||
document.getElementById("header-logo").addEventListener("click", goHome);
|
document.getElementById("header-logo").addEventListener("click", goHome);
|
||||||
initSearch();
|
initSearch();
|
||||||
|
|||||||
@ -12,11 +12,43 @@
|
|||||||
|
|
||||||
<!-- CodeMirror 6 -->
|
<!-- CodeMirror 6 -->
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { EditorView, basicSetup } from "https://esm.sh/@codemirror/basic-setup@0.20.0";
|
import { EditorView, keymap, lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightActiveLine } from "https://esm.sh/@codemirror/view@6.9.0";
|
||||||
import { EditorState } from "https://esm.sh/@codemirror/state@6.2.0";
|
import { EditorState } from "https://esm.sh/@codemirror/state@6.2.0";
|
||||||
|
import { defaultHighlightStyle, syntaxHighlighting, indentOnInput, bracketMatching, foldGutter, foldKeymap } from "https://esm.sh/@codemirror/language@6.6.0";
|
||||||
|
import { defaultKeymap, history, historyKeymap } from "https://esm.sh/@codemirror/commands@6.2.3";
|
||||||
|
import { searchKeymap, highlightSelectionMatches } from "https://esm.sh/@codemirror/search@6.3.0";
|
||||||
|
import { autocompletion, completionKeymap, closeBrackets, closeBracketsKeymap } from "https://esm.sh/@codemirror/autocomplete@6.5.0";
|
||||||
import { markdown } from "https://esm.sh/@codemirror/lang-markdown@6.1.0";
|
import { markdown } from "https://esm.sh/@codemirror/lang-markdown@6.1.0";
|
||||||
import { oneDark } from "https://esm.sh/@codemirror/theme-one-dark@6.1.0";
|
import { oneDark } from "https://esm.sh/@codemirror/theme-one-dark@6.1.0";
|
||||||
import { keymap } from "https://esm.sh/@codemirror/view@6.9.0";
|
|
||||||
|
const basicSetup = [
|
||||||
|
lineNumbers(),
|
||||||
|
highlightActiveLineGutter(),
|
||||||
|
highlightSpecialChars(),
|
||||||
|
history(),
|
||||||
|
foldGutter(),
|
||||||
|
drawSelection(),
|
||||||
|
dropCursor(),
|
||||||
|
EditorState.allowMultipleSelections.of(true),
|
||||||
|
indentOnInput(),
|
||||||
|
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
|
||||||
|
bracketMatching(),
|
||||||
|
closeBrackets(),
|
||||||
|
autocompletion(),
|
||||||
|
rectangularSelection(),
|
||||||
|
crosshairCursor(),
|
||||||
|
highlightActiveLine(),
|
||||||
|
highlightSelectionMatches(),
|
||||||
|
keymap.of([
|
||||||
|
...closeBracketsKeymap,
|
||||||
|
...defaultKeymap,
|
||||||
|
...searchKeymap,
|
||||||
|
...historyKeymap,
|
||||||
|
...foldKeymap,
|
||||||
|
...completionKeymap,
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
window.CodeMirror = { EditorView, EditorState, basicSetup, markdown, oneDark, keymap };
|
window.CodeMirror = { EditorView, EditorState, basicSetup, markdown, oneDark, keymap };
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
@ -39,13 +71,27 @@
|
|||||||
<input type="text" id="search-input" placeholder="Recherche..." autocomplete="off">
|
<input type="text" id="search-input" placeholder="Recherche..." autocomplete="off">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<select id="vault-filter" class="search-vault-filter">
|
<div class="header-menu">
|
||||||
<option value="all">Toutes les vaults</option>
|
<button class="header-menu-btn" id="header-menu-btn" title="Options">
|
||||||
</select>
|
<i data-lucide="settings" style="width:18px;height:18px"></i>
|
||||||
|
</button>
|
||||||
<button class="theme-toggle" id="theme-toggle" title="Changer le thème">
|
<div class="header-menu-dropdown" id="header-menu-dropdown">
|
||||||
<i data-lucide="moon" id="theme-icon" style="width:18px;height:18px"></i>
|
<div class="menu-section">
|
||||||
</button>
|
<div class="menu-label">Vault</div>
|
||||||
|
<select id="vault-filter" class="menu-select">
|
||||||
|
<option value="all">Tous les vaults</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="menu-divider"></div>
|
||||||
|
<div class="menu-section">
|
||||||
|
<div class="menu-label">Thème</div>
|
||||||
|
<button class="menu-theme-btn" id="theme-toggle">
|
||||||
|
<i data-lucide="sun" style="width:16px;height:16px"></i>
|
||||||
|
<span id="theme-label">Clair</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- Main -->
|
<!-- Main -->
|
||||||
|
|||||||
@ -157,19 +157,11 @@ a:hover {
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-vault-filter {
|
.header-menu {
|
||||||
padding: 6px 10px;
|
position: relative;
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 8px;
|
|
||||||
background: var(--search-bg);
|
|
||||||
color: var(--text-primary);
|
|
||||||
font-family: 'JetBrains Mono', monospace;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
outline: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-toggle {
|
.header-menu-btn {
|
||||||
background: none;
|
background: none;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@ -180,10 +172,90 @@ a:hover {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
transition: color 200ms ease, border-color 200ms ease;
|
transition: color 200ms ease, border-color 200ms ease;
|
||||||
}
|
}
|
||||||
.theme-toggle:hover {
|
.header-menu-btn:hover {
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
border-color: var(--accent);
|
border-color: var(--accent);
|
||||||
}
|
}
|
||||||
|
.header-menu-btn.active {
|
||||||
|
color: var(--accent);
|
||||||
|
border-color: var(--accent);
|
||||||
|
background: var(--tag-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-menu-dropdown {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 8px);
|
||||||
|
right: 0;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 16px rgba(0,0,0,0.3);
|
||||||
|
min-width: 220px;
|
||||||
|
z-index: 100;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
.header-menu-dropdown.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-section {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-label {
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
color: var(--text-muted);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--search-bg);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 200ms ease;
|
||||||
|
}
|
||||||
|
.menu-select:hover, .menu-select:focus {
|
||||||
|
border-color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-divider {
|
||||||
|
height: 1px;
|
||||||
|
background: var(--border);
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-theme-btn {
|
||||||
|
width: 100%;
|
||||||
|
background: none;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--text-primary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-family: 'JetBrains Mono', monospace;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
transition: all 200ms ease;
|
||||||
|
}
|
||||||
|
.menu-theme-btn:hover {
|
||||||
|
background: var(--bg-hover);
|
||||||
|
border-color: var(--accent);
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Main body --- */
|
/* --- Main body --- */
|
||||||
.main-body {
|
.main-body {
|
||||||
@ -938,9 +1010,13 @@ body.resizing-v {
|
|||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-vault-filter {
|
.header-menu-btn {
|
||||||
font-size: 0.7rem;
|
padding: 5px 8px;
|
||||||
padding: 4px 6px;
|
}
|
||||||
|
|
||||||
|
.header-menu-dropdown {
|
||||||
|
right: -8px;
|
||||||
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user