all should work now
This commit is contained in:
219
README.md
219
README.md
@@ -1,10 +1,20 @@
|
||||
# Menu Plugin for Obsidian
|
||||
# Obsidian Menus
|
||||
|
||||
Create custom navigation menus in Obsidian using simple code blocks. Supports internal links, external URLs, and local file links with built-in themes and full customization.
|
||||
Create simple, stylable menus from code blocks. You write links inside a `menu` code block, and the plugin renders:
|
||||
- a single div with class `menu-container`
|
||||
- a set of anchor tags inside it
|
||||
|
||||
You can:
|
||||
- Pick a built-in template (default, minimal, slate, horizon, aether)
|
||||
- Use your own CSS class (no plugin CSS applied)
|
||||
- Override styles using a small, safe set of YAML-like variables
|
||||
- Mix template + extra classes (e.g., `layout: horizon wide`)
|
||||
|
||||
CSS stays clean and predictable.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
Create a menu using a `menu` code block with one of the built-in layouts:
|
||||
Create a menu using a `menu` code block with one of the built-in templates:
|
||||
|
||||
````markdown
|
||||
```menu
|
||||
@@ -16,32 +26,21 @@ layout: default
|
||||
```
|
||||
````
|
||||
|
||||
## Built-in Layouts
|
||||
- `[[Note]]` or `[[Note|Alias]]` creates internal links.
|
||||
- `[Text](https://example.com)` creates web links.
|
||||
- `[Text](file:///C:/path/to/file)` opens local files/folders.
|
||||
|
||||
### `default`
|
||||
Standard buttons with borders and backgrounds
|
||||
````markdown
|
||||
```menu
|
||||
layout: default
|
||||
[[Dashboard]]
|
||||
[GitHub](https://github.com)
|
||||
[Files](file:///C:/Users/Documents)
|
||||
```
|
||||
````
|
||||
## Built-in Templates
|
||||
|
||||
### `minimal`
|
||||
Clean text links with subtle colors
|
||||
````markdown
|
||||
```menu
|
||||
layout: minimal
|
||||
[[Notes]]
|
||||
[Web](https://example.com)
|
||||
[Folder](file:///C:/Projects)
|
||||
```
|
||||
````
|
||||
Available out of the box:
|
||||
- default
|
||||
- minimal
|
||||
- slate
|
||||
- horizon
|
||||
- aether
|
||||
|
||||
Example:
|
||||
|
||||
### `slate`
|
||||
Solid background buttons
|
||||
````markdown
|
||||
```menu
|
||||
layout: slate
|
||||
@@ -50,37 +49,95 @@ layout: slate
|
||||
```
|
||||
````
|
||||
|
||||
### `horizon`
|
||||
Modern outlined style
|
||||
You can also add extra classes like `wide` next to the layout:
|
||||
|
||||
````markdown
|
||||
```menu
|
||||
layout: horizon
|
||||
layout: horizon wide
|
||||
[[Dashboard]]
|
||||
[Resources](https://example.com)
|
||||
```
|
||||
````
|
||||
|
||||
### `aether`
|
||||
Grid layout with equal-width items
|
||||
Note: Built-in template CSS only applies when a built-in layout is selected. Internally, the container gets a `data-layout="..."` attribute which gates the plugin CSS. If you don’t select a built-in layout, none of the plugin CSS will affect your menu.
|
||||
|
||||
## Custom CSS Class Mode (No Plugin CSS)
|
||||
|
||||
Use your own CSS by providing a custom class via `class:` or `layout:` with a non-built-in value. In this mode, the plugin does not apply any of its CSS. It only renders the HTML and exposes inline CSS variables from the YAML-like overrides.
|
||||
|
||||
````markdown
|
||||
```menu
|
||||
layout: aether
|
||||
[[Projects]]
|
||||
[GitHub](https://github.com)
|
||||
[Documents](file:///C:/Users/Documents)
|
||||
class: my-menu wide
|
||||
bg: #111
|
||||
text: #eee
|
||||
hover-text: #0af
|
||||
internal-hover-text: orange
|
||||
|
||||
[[Home]]
|
||||
[Web](https://example.com)
|
||||
[Folder](file:///C:/Projects)
|
||||
```
|
||||
````
|
||||
|
||||
## Link Types
|
||||
Then, in a CSS snippet:
|
||||
|
||||
- **Internal**: `[[Note Name]]` or `[[Note Name|Display Text]]`
|
||||
- **External**: `[Display Text](https://example.com)`
|
||||
- **Files**: `[Display Text](file:///C:/path/to/file)`
|
||||
```css
|
||||
/* Example custom styling */
|
||||
.menu-container.my-menu {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
## Color Customization
|
||||
.menu-container.my-menu a {
|
||||
text-decoration: none;
|
||||
padding: 0.5rem 0.8rem;
|
||||
border-radius: 6px;
|
||||
color: var(--text, var(--text-normal));
|
||||
background: var(--bg, transparent);
|
||||
border: 1px solid var(--border, var(--background-modifier-border));
|
||||
}
|
||||
|
||||
Add color properties using YAML syntax:
|
||||
.menu-container.my-menu a:hover {
|
||||
color: var(--hover-text, var(--text-accent));
|
||||
background: var(--hover-bg, transparent);
|
||||
border-color: var(--hover-border, var(--text-accent));
|
||||
}
|
||||
```
|
||||
|
||||
## YAML-like Overrides (Safe Whitelist)
|
||||
|
||||
The code block supports a small set of variables. No raw CSS properties are accepted in the code block. If you need full CSS power, use a CSS snippet in your IDE.
|
||||
|
||||
Global variables:
|
||||
- bg
|
||||
- text
|
||||
- border
|
||||
- font
|
||||
- hover-text
|
||||
- hover-bg
|
||||
- hover-border
|
||||
- hover-font
|
||||
|
||||
Per link type variants (prefix with internal-, external-, file-):
|
||||
- internal-bg, internal-text, internal-border, internal-font
|
||||
- internal-hover-text, internal-hover-bg, internal-hover-border, internal-hover-font
|
||||
- external-... (same set)
|
||||
- file-... (same set)
|
||||
|
||||
Naming aliases supported:
|
||||
- text-hover -> hover-text
|
||||
- bg-hover -> hover-bg
|
||||
- border-hover -> hover-border
|
||||
- font-hover -> hover-font
|
||||
- accent -> hover-text (and internal-accent/external-accent/file-accent -> corresponding -hover-text)
|
||||
|
||||
Behavior of keys:
|
||||
- bg applies to the buttons (anchors), not the container
|
||||
- hover-* applies to the hover state of the buttons
|
||||
- type-specific keys (e.g., internal-text) override the global ones for that link type
|
||||
|
||||
Examples (template mode):
|
||||
````markdown
|
||||
```menu
|
||||
layout: default
|
||||
@@ -88,49 +145,51 @@ bg: #1a1a1a
|
||||
text: #ffffff
|
||||
hover-text: #ff6b6b
|
||||
border: #333333
|
||||
|
||||
[[Home]]
|
||||
[GitHub](https://github.com)
|
||||
```
|
||||
````
|
||||
|
||||
### Global Color Variables
|
||||
- `bg`: Background color
|
||||
- `text`: Text color
|
||||
- `border`: Border color
|
||||
- `hover-text`: Hover text color
|
||||
- `hover-bg`: Hover background
|
||||
- `hover-border`: Hover border color
|
||||
- `font`: Font family
|
||||
|
||||
### Link-Type Specific Colors
|
||||
Customize each link type individually:
|
||||
|
||||
Per-link-type overrides:
|
||||
````markdown
|
||||
```menu
|
||||
layout: minimal
|
||||
internal-text: #00ff00
|
||||
external-text: #ff6600
|
||||
file-text: #0066ff
|
||||
internal-font: "Arial"
|
||||
internal-font: "Fira Code"
|
||||
external-font: "Georgia"
|
||||
file-font: "Arial"
|
||||
|
||||
[[Internal Link]]
|
||||
[External Link](https://example.com)
|
||||
[File Link](file:///C:/Documents)
|
||||
```
|
||||
````
|
||||
|
||||
**Available for each type** (`internal`, `external`, `file`):
|
||||
- `{type}-text`: Text color
|
||||
- `{type}-bg`: Background color
|
||||
- `{type}-border`: Border color
|
||||
- `{type}-font`: Font family
|
||||
- `{type}-hover-text`: Hover text color
|
||||
- `{type}-hover-bg`: Hover background
|
||||
- `{type}-hover-border`: Hover border color
|
||||
## Link Types
|
||||
|
||||
## Advanced Examples
|
||||
- Internal: `[[Note Name]]` or `[[Note Name|Display Text]]`
|
||||
- External: `[Display Text](https://example.com)`
|
||||
- Files: `[Display Text](file:///C:/path/to/file)`
|
||||
|
||||
### Gradient Background
|
||||
Behavior:
|
||||
- Internal links open within Obsidian.
|
||||
- External links open in your browser.
|
||||
- File links open via the OS.
|
||||
|
||||
## Notes
|
||||
|
||||
- Use either `layout:` or `class:`. If the value contains a built-in template, the template is applied. Otherwise, it’s treated as a pure CSS class (no plugin CSS).
|
||||
- If no `layout:` or `class:` is provided, `layout: default` is assumed.
|
||||
- Colors support hex, rgb, hsl, CSS variables, and gradients.
|
||||
- Font names with spaces need quotes: `font: "Work Sans"`.
|
||||
- You can append additional classes after the layout or class: `layout: horizon wide my-extra`.
|
||||
|
||||
## Examples
|
||||
|
||||
Built-in template with overrides:
|
||||
````markdown
|
||||
```menu
|
||||
layout: horizon
|
||||
@@ -142,23 +201,25 @@ hover-text: #ffd700
|
||||
```
|
||||
````
|
||||
|
||||
### Different Fonts Per Link Type
|
||||
Custom class with overrides:
|
||||
````markdown
|
||||
```menu
|
||||
layout: default
|
||||
font: "Inter"
|
||||
internal-font: "Fira Code"
|
||||
external-font: "Georgia"
|
||||
file-font: "Arial"
|
||||
[[Code Notes]]
|
||||
[Articles](https://medium.com)
|
||||
[Local Files](file:///C:/Documents)
|
||||
class: my-toolbar
|
||||
text: var(--text-normal)
|
||||
hover-text: var(--text-accent)
|
||||
[[Inbox]]
|
||||
[Wiki](https://example.com)
|
||||
```
|
||||
````
|
||||
|
||||
## Notes
|
||||
|
||||
- Use either `layout:` or `class:` (both work the same)
|
||||
- File paths use `file://` protocol
|
||||
- Colors support hex, rgb, hsl, CSS variables, and gradients
|
||||
- Font names with spaces need quotes: `font: "Work Sans"`
|
||||
Minimal template focusing on text colors:
|
||||
````markdown
|
||||
```menu
|
||||
layout: minimal
|
||||
internal-text: var(--text-accent)
|
||||
external-text: var(--text-faint)
|
||||
file-text: var(--text-muted)
|
||||
[[Notes]]
|
||||
[Web](https://example.com)
|
||||
[Folder](file:///C:/Projects)
|
||||
```
|
||||
|
||||
131
main.ts
131
main.ts
@@ -1,30 +1,13 @@
|
||||
import { Plugin } from 'obsidian';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const { shell } = require('electron');
|
||||
|
||||
// Simple YAML parser for color properties
|
||||
function parseYAML(text: string) {
|
||||
const result: Record<string, string> = {};
|
||||
const lines = text.split('\n');
|
||||
for (const line of lines) {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed && trimmed.includes(':')) {
|
||||
const [key, ...valueParts] = trimmed.split(':');
|
||||
const value = valueParts.join(':').trim();
|
||||
if (key && value) {
|
||||
result[key.trim()] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export default class MenuPlugin extends Plugin {
|
||||
async onload() {
|
||||
this.registerMarkdownCodeBlockProcessor('menu', (source, el, ctx) => {
|
||||
const lines = source.trim().split('\n');
|
||||
let layout = '';
|
||||
let layoutOrClass = '';
|
||||
let colors: Record<string, string> = {};
|
||||
const links: string[] = [];
|
||||
|
||||
@@ -33,7 +16,7 @@ export default class MenuPlugin extends Plugin {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed.startsWith('layout:') || trimmed.startsWith('class:')) {
|
||||
const colonIndex = trimmed.indexOf(':');
|
||||
layout = trimmed.substring(colonIndex + 1).trim();
|
||||
layoutOrClass = trimmed.substring(colonIndex + 1).trim();
|
||||
} else if (trimmed.includes(':') && !trimmed.startsWith('[') && !trimmed.startsWith('[[')) {
|
||||
// Parse color properties
|
||||
const [key, ...valueParts] = trimmed.split(':');
|
||||
@@ -48,23 +31,102 @@ export default class MenuPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
const finalLayout = layout || 'default';
|
||||
const container = el.createEl('div', { cls: `menu-container ${finalLayout}` });
|
||||
|
||||
// Apply custom colors as CSS variables
|
||||
if (Object.keys(colors).length > 0) {
|
||||
for (const [key, value] of Object.entries(colors)) {
|
||||
// Replace 'accent' with 'hover-text' for consistency
|
||||
let cssKey = key.replace(/accent/g, 'hover-text');
|
||||
container.style.setProperty(`--${cssKey}`, value);
|
||||
// Determine layout and classes
|
||||
const builtInLayouts = new Set(['default', 'minimal', 'slate', 'horizon', 'aether']);
|
||||
const container = el.createEl('div', { cls: 'menu-container' });
|
||||
|
||||
let selectedLayout = '';
|
||||
let extraClasses: string[] = [];
|
||||
|
||||
if (layoutOrClass) {
|
||||
const tokens = layoutOrClass.split(/\s+/).filter(Boolean);
|
||||
if (tokens.length) {
|
||||
// Allow built-in layout to appear anywhere in the list (e.g., "class: my-class horizon wide")
|
||||
const builtInIndex = tokens.findIndex(t => builtInLayouts.has(t));
|
||||
if (builtInIndex !== -1) {
|
||||
selectedLayout = tokens[builtInIndex];
|
||||
extraClasses = tokens.filter((_, i) => i !== builtInIndex);
|
||||
} else {
|
||||
// Custom class mode: do not apply plugin CSS (no data-layout)
|
||||
extraClasses = tokens;
|
||||
}
|
||||
}
|
||||
// Example: ensure hover-text is set and add a comment for usage
|
||||
if (colors['hover-text']) {
|
||||
container.style.setProperty('--hover-text', colors['hover-text']);
|
||||
// To use in CSS: a:hover { color: var(--hover-text); }
|
||||
} else {
|
||||
// No layout/class provided: use default built-in template
|
||||
selectedLayout = 'default';
|
||||
}
|
||||
|
||||
// Apply selected built-in template via data attribute (gates plugin CSS)
|
||||
if (selectedLayout) {
|
||||
container.setAttr('data-layout', selectedLayout);
|
||||
}
|
||||
|
||||
// Apply any extra classes (e.g., "wide" or user-provided classes)
|
||||
for (const cls of extraClasses) {
|
||||
container.addClass(cls);
|
||||
}
|
||||
|
||||
// Apply custom properties (whitelist only: bg, text, border, font and their -hover variants,
|
||||
// plus internal-, external-, file- prefixed versions). No raw CSS props allowed.
|
||||
if (Object.keys(colors).length > 0) {
|
||||
const baseKeys = new Set([
|
||||
'bg','text','border','font',
|
||||
'hover-text','hover-bg','hover-border','hover-font',
|
||||
]);
|
||||
const normalizeKey = (raw: string) => {
|
||||
let s = raw.trim().toLowerCase();
|
||||
// Normalize synonyms/order for hover variants
|
||||
s = s
|
||||
// Prefer "hover-*" (matches CSS)
|
||||
.replace(/\btext-hover\b/g, 'hover-text')
|
||||
.replace(/\bbg-hover\b/g, 'hover-bg')
|
||||
.replace(/\bborder-hover\b/g, 'hover-border')
|
||||
// Old naming from earlier versions -> new "hover-*" order
|
||||
.replace(/\binternal-text-hover\b/g, 'internal-hover-text')
|
||||
.replace(/\binternal-bg-hover\b/g, 'internal-hover-bg')
|
||||
.replace(/\binternal-border-hover\b/g, 'internal-hover-border')
|
||||
.replace(/\bexternal-text-hover\b/g, 'external-hover-text')
|
||||
.replace(/\bexternal-bg-hover\b/g, 'external-hover-bg')
|
||||
.replace(/\bexternal-border-hover\b/g, 'external-hover-border')
|
||||
.replace(/\bfile-text-hover\b/g, 'file-hover-text')
|
||||
.replace(/\bfile-bg-hover\b/g, 'file-hover-bg')
|
||||
.replace(/\bfile-border-hover\b/g, 'file-hover-border')
|
||||
// Back-compat for "accent" -> "hover-text"
|
||||
.replace(/\baccent\b/g, 'hover-text')
|
||||
.replace(/\binternal-accent\b/g, 'internal-hover-text')
|
||||
.replace(/\bexternal-accent\b/g, 'external-hover-text')
|
||||
.replace(/\bfile-accent\b/g, 'file-hover-text')
|
||||
.replace(/\bbackground\b/g, 'bg');
|
||||
return s;
|
||||
};
|
||||
const isAllowed = (key: string) => {
|
||||
if (baseKeys.has(key)) return true;
|
||||
const m = key.match(/^(internal|external|file)-(.*)$/);
|
||||
return !!(m && baseKeys.has(m[2]));
|
||||
};
|
||||
for (const [rawKey, value] of Object.entries(colors)) {
|
||||
const key = normalizeKey(rawKey);
|
||||
if (!isAllowed(key)) continue;
|
||||
container.style.setProperty(`--${key}`, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// In custom class mode (no built-in layout), apply base inline styles to anchors so whitelist vars work without CSS.
|
||||
const applyInlineBaseStyles = (a: HTMLElement, variant: 'internal' | 'external' | 'file' | 'generic') => {
|
||||
const prefix = variant === 'generic' ? '' : `${variant}-`;
|
||||
const get = (k: string) => (colors[`${prefix}${k}`] ?? colors[k]);
|
||||
const bgVal = get('bg'); if (bgVal) a.style.background = bgVal as string;
|
||||
const textVal = get('text'); if (textVal) a.style.color = textVal as string;
|
||||
const borderVal = get('border'); if (borderVal) a.style.borderColor = borderVal as string;
|
||||
const fontVal = get('font'); if (fontVal) a.style.fontFamily = fontVal as string;
|
||||
// Expose hover values as CSS variables on the anchor for user CSS to consume if desired
|
||||
const hoverKeys = ['hover-bg','hover-text','hover-border','hover-font'];
|
||||
for (const hk of hoverKeys) {
|
||||
const v = get(hk);
|
||||
if (v) a.style.setProperty(`--${hk}`, v as string);
|
||||
}
|
||||
};
|
||||
|
||||
// Process each link
|
||||
for (const link of links) {
|
||||
if (link.startsWith('[[') && link.endsWith(']]')) {
|
||||
@@ -80,6 +142,7 @@ export default class MenuPlugin extends Plugin {
|
||||
attr: { 'data-href': href }
|
||||
});
|
||||
a.addClass('menu-internal-link');
|
||||
if (!selectedLayout) applyInlineBaseStyles(a, 'internal');
|
||||
a.style.cursor = 'pointer';
|
||||
a.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
@@ -103,8 +166,10 @@ export default class MenuPlugin extends Plugin {
|
||||
// Add appropriate class based on link type
|
||||
if (url.startsWith('file://')) {
|
||||
a.addClass('menu-file-link');
|
||||
if (!selectedLayout) applyInlineBaseStyles(a, 'file');
|
||||
} else {
|
||||
a.addClass('menu-external-link');
|
||||
if (!selectedLayout) applyInlineBaseStyles(a, 'external');
|
||||
}
|
||||
a.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
91
styles.css
91
styles.css
@@ -1,6 +1,6 @@
|
||||
/* Special styles to hide the border and </> icon on hover */
|
||||
|
||||
.markdown-source-view.mod-cm6 .cm-embed-block:not(.cm-table-widget, .cm-lang-base):has(.menu-container):hover {
|
||||
.markdown-source-view.mod-cm6 .cm-embed-block:not(.cm-table-widget, .cm-lang-base):has(.menu-container[data-layout]):hover {
|
||||
border-width: 0;
|
||||
outline: 0;
|
||||
box-shadow: var(--background-primary) 0 0 0 1px inset !important;
|
||||
@@ -22,8 +22,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.menu-container,
|
||||
.menu-container a {
|
||||
.menu-container[data-layout],
|
||||
.menu-container[data-layout] a {
|
||||
transition: 125ms;
|
||||
}
|
||||
|
||||
@@ -35,12 +35,11 @@
|
||||
|
||||
/* Default style variant */
|
||||
|
||||
.menu-container.default {
|
||||
.menu-container[data-layout='default'] {
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
gap: 0.7em;
|
||||
flex-wrap: wrap;
|
||||
border-radius: 6px;
|
||||
background-color: var(--bg, var(--background-primary));
|
||||
font-family: var(--font, inherit);
|
||||
|
||||
a {
|
||||
@@ -51,49 +50,51 @@
|
||||
font-weight: 500;
|
||||
border: 1px solid var(--border, var(--background-modifier-border));
|
||||
color: var(--text, var(--text-normal));
|
||||
background: var(--bg, var(--background-primary));
|
||||
font-family: var(--font, inherit);
|
||||
|
||||
&:hover {
|
||||
color: var(--hover-text, var(--accent, var(--text-accent)));
|
||||
border-color: var(--hover-border, var(--accent, var(--text-accent)));
|
||||
background: var(--hover-bg, transparent);
|
||||
}
|
||||
|
||||
&.menu-internal-link {
|
||||
color: var(--internal-text, var(--text, var(--text-normal)));
|
||||
border-color: var(--internal-border, var(--border, var(--background-modifier-border)));
|
||||
background-color: var(--internal-bg, transparent);
|
||||
background: var(--internal-bg, var(--bg, var(--background-primary)));
|
||||
font-family: var(--internal-font, var(--font, inherit));
|
||||
|
||||
&:hover {
|
||||
color: var(--internal-hover-text, var(--internal-accent, var(--hover-text, var(--accent, var(--text-accent)))));
|
||||
border-color: var(--internal-hover-border, var(--hover-border, var(--accent, var(--text-accent))));
|
||||
background-color: var(--internal-hover-bg, var(--hover-bg, transparent));
|
||||
background: var(--internal-hover-bg, var(--hover-bg, transparent));
|
||||
}
|
||||
}
|
||||
|
||||
&.menu-external-link {
|
||||
color: var(--external-text, var(--text, var(--text-normal)));
|
||||
border-color: var(--external-border, var(--border, var(--background-modifier-border)));
|
||||
background-color: var(--external-bg, transparent);
|
||||
background: var(--external-bg, var(--bg, var(--background-primary)));
|
||||
font-family: var(--external-font, var(--font, inherit));
|
||||
|
||||
&:hover {
|
||||
color: var(--external-hover-text, var(--external-accent, var(--hover-text, var(--accent, var(--text-accent)))));
|
||||
border-color: var(--external-hover-border, var(--hover-border, var(--accent, var(--text-accent))));
|
||||
background-color: var(--external-hover-bg, var(--hover-bg, transparent));
|
||||
background: var(--external-hover-bg, var(--hover-bg, transparent));
|
||||
}
|
||||
}
|
||||
|
||||
&.menu-file-link {
|
||||
color: var(--file-text, var(--text, var(--text-normal)));
|
||||
border-color: var(--file-border, var(--border, var(--background-modifier-border)));
|
||||
background-color: var(--file-bg, transparent);
|
||||
background: var(--file-bg, var(--bg, var(--background-primary)));
|
||||
font-family: var(--file-font, var(--font, inherit));
|
||||
|
||||
&:hover {
|
||||
color: var(--file-hover-text, var(--file-accent, var(--hover-text, var(--accent, var(--text-accent)))));
|
||||
border-color: var(--file-hover-border, var(--hover-border, var(--accent, var(--text-accent))));
|
||||
background-color: var(--file-hover-bg, var(--hover-bg, transparent));
|
||||
background: var(--file-hover-bg, var(--hover-bg, transparent));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,12 +113,11 @@
|
||||
|
||||
|
||||
/* Minimal style variant */
|
||||
.menu-container.minimal {
|
||||
.menu-container[data-layout='minimal'] {
|
||||
display: flex;
|
||||
gap: 0.2em;
|
||||
flex-wrap: wrap;
|
||||
transition: 125ms;
|
||||
background-color: var(--bg, transparent);
|
||||
font-family: var(--font, inherit);
|
||||
|
||||
a {
|
||||
@@ -128,10 +128,11 @@
|
||||
font-size: 0.9em;
|
||||
font-weight: normal;
|
||||
color: var(--text, var(--text-normal));
|
||||
background: var(--bg, transparent);
|
||||
font-family: var(--font, inherit);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--hover-bg, var(--background-secondary));
|
||||
background: var(--hover-bg, var(--background-secondary));
|
||||
color: var(--hover-text, var(--accent, var(--text-accent)));
|
||||
}
|
||||
|
||||
@@ -141,7 +142,7 @@
|
||||
|
||||
&:hover {
|
||||
color: var(--internal-hover-text, var(--internal-accent, var(--hover-text, var(--internal-hover, var(--text-accent-hover)))));
|
||||
background-color: var(--internal-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
background: var(--internal-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +152,7 @@
|
||||
|
||||
&:hover {
|
||||
color: var(--external-hover-text, var(--external-accent, var(--hover-text, var(--external-hover, var(--text-normal)))));
|
||||
background-color: var(--external-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
background: var(--external-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,18 +162,17 @@
|
||||
|
||||
&:hover {
|
||||
color: var(--file-hover-text, var(--file-accent, var(--hover-text, var(--file-hover, var(--text-normal)))));
|
||||
background-color: var(--file-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
background: var(--file-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Minimal style variant */
|
||||
.menu-container.slate {
|
||||
.menu-container[data-layout='slate'] {
|
||||
display: flex;
|
||||
gap: 0.2em;
|
||||
flex-wrap: wrap;
|
||||
background-color: var(--bg, transparent);
|
||||
font-family: var(--font, inherit);
|
||||
|
||||
a {
|
||||
@@ -182,13 +182,13 @@
|
||||
transition: color 0.15s ease;
|
||||
font-size: 0.9em;
|
||||
font-weight: normal;
|
||||
background-color: var(--item-bg, var(--background-secondary));
|
||||
background: var(--bg, var(--background-secondary));
|
||||
border: 1px solid var(--border, var(--background-secondary));
|
||||
color: var(--text, var(--text-faint));
|
||||
font-family: var(--font, inherit);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--hover-bg, var(--background-secondary));
|
||||
background: var(--hover-bg, var(--background-secondary));
|
||||
color: var(--hover-text, var(--accent, var(--text-accent)));
|
||||
border: 1px solid var(--hover-border, var(--accent, var(--text-accent)));
|
||||
}
|
||||
@@ -196,51 +196,50 @@
|
||||
&.menu-internal-link {
|
||||
color: var(--internal-text, var(--text, var(--text-faint)));
|
||||
border-color: var(--internal-border, var(--border, var(--background-secondary)));
|
||||
background-color: var(--internal-bg, var(--item-bg, var(--background-secondary)));
|
||||
background: var(--internal-bg, var(--bg, var(--background-secondary)));
|
||||
font-family: var(--internal-font, var(--font, inherit));
|
||||
|
||||
&:hover {
|
||||
color: var(--internal-hover-text, var(--internal-accent, var(--hover-text, var(--accent, var(--text-accent)))));
|
||||
border-color: var(--internal-hover-border, var(--hover-border, var(--accent, var(--text-accent))));
|
||||
background-color: var(--internal-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
background: var(--internal-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
}
|
||||
}
|
||||
|
||||
&.menu-external-link {
|
||||
color: var(--external-text, var(--text, var(--text-faint)));
|
||||
border-color: var(--external-border, var(--border, var(--background-secondary)));
|
||||
background-color: var(--external-bg, var(--item-bg, var(--background-secondary)));
|
||||
background: var(--external-bg, var(--bg, var(--background-secondary)));
|
||||
font-family: var(--external-font, var(--font, inherit));
|
||||
|
||||
&:hover {
|
||||
color: var(--external-hover-text, var(--external-accent, var(--hover-text, var(--accent, var(--text-accent)))));
|
||||
border-color: var(--external-hover-border, var(--hover-border, var(--accent, var(--text-accent))));
|
||||
background-color: var(--external-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
background: var(--external-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
}
|
||||
}
|
||||
|
||||
&.menu-file-link {
|
||||
color: var(--file-text, var(--text, var(--text-faint)));
|
||||
border-color: var(--file-border, var(--border, var(--background-secondary)));
|
||||
background-color: var(--file-bg, var(--item-bg, var(--background-secondary)));
|
||||
background: var(--file-bg, var(--bg, var(--background-secondary)));
|
||||
font-family: var(--file-font, var(--font, inherit));
|
||||
|
||||
&:hover {
|
||||
color: var(--file-hover-text, var(--file-accent, var(--hover-text, var(--accent, var(--text-accent)))));
|
||||
border-color: var(--file-hover-border, var(--hover-border, var(--accent, var(--text-accent))));
|
||||
background-color: var(--file-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
background: var(--file-hover-bg, var(--hover-bg, var(--background-secondary)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.menu-container.horizon {
|
||||
.menu-container[data-layout='horizon'] {
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
flex-wrap: wrap;
|
||||
border-radius: 8px;
|
||||
background-color: var(--bg, var(--background-primary));
|
||||
font-family: var(--font, 'Space Grotesk', Inter, sans-serif);
|
||||
|
||||
a {
|
||||
@@ -254,49 +253,51 @@
|
||||
border-radius: 3px;
|
||||
padding-block: var(--size-2, 0.5em);
|
||||
padding-inline: var(--size-3, 2em);
|
||||
background: var(--bg, transparent);
|
||||
transition: 250ms;
|
||||
|
||||
&:hover {
|
||||
color: var(--hover-text, var(--accent, var(--orange-500, darkorange)));
|
||||
border: 1px solid var(--hover-border, var(--accent, var(--orange-500, darkorange)));
|
||||
background: var(--hover-bg, transparent);
|
||||
}
|
||||
|
||||
&.menu-internal-link {
|
||||
color: var(--internal-text, var(--text, var(--cyan-500, darkcyan)));
|
||||
border-color: var(--internal-border, var(--border, var(--cyan-500, darkcyan)));
|
||||
background-color: var(--internal-bg, transparent);
|
||||
background: var(--internal-bg, var(--bg, transparent));
|
||||
font-family: var(--internal-font, var(--font, 'Space Grotesk', Inter, sans-serif));
|
||||
|
||||
&:hover {
|
||||
color: var(--internal-hover-text, var(--internal-accent, var(--hover-text, var(--accent, var(--orange-500, darkorange)))));
|
||||
border-color: var(--internal-hover-border, var(--hover-border, var(--accent, var(--orange-500, darkorange))));
|
||||
background-color: var(--internal-hover-bg, var(--hover-bg, transparent));
|
||||
background: var(--internal-hover-bg, var(--hover-bg, transparent));
|
||||
}
|
||||
}
|
||||
|
||||
&.menu-external-link {
|
||||
color: var(--external-text, var(--text, var(--cyan-500, darkcyan)));
|
||||
border-color: var(--external-border, var(--border, var(--cyan-500, darkcyan)));
|
||||
background-color: var(--external-bg, transparent);
|
||||
background: var(--external-bg, var(--bg, transparent));
|
||||
font-family: var(--external-font, var(--font, 'Space Grotesk', Inter, sans-serif));
|
||||
|
||||
&:hover {
|
||||
color: var(--external-hover-text, var(--external-accent, var(--hover-text, var(--accent, var(--orange-500, darkorange)))));
|
||||
border-color: var(--external-hover-border, var(--hover-border, var(--accent, var(--orange-500, darkorange))));
|
||||
background-color: var(--external-hover-bg, var(--hover-bg, transparent));
|
||||
background: var(--external-hover-bg, var(--hover-bg, transparent));
|
||||
}
|
||||
}
|
||||
|
||||
&.menu-file-link {
|
||||
color: var(--file-text, var(--text, var(--cyan-500, darkcyan)));
|
||||
border-color: var(--file-border, var(--border, var(--cyan-500, darkcyan)));
|
||||
background-color: var(--file-bg, transparent);
|
||||
background: var(--file-bg, var(--bg, transparent));
|
||||
font-family: var(--file-font, var(--font, 'Space Grotesk', Inter, sans-serif));
|
||||
|
||||
&:hover {
|
||||
color: var(--file-hover-text, var(--file-accent, var(--hover-text, var(--accent, var(--orange-500, darkorange)))));
|
||||
border-color: var(--file-hover-border, var(--hover-border, var(--accent, var(--orange-500, darkorange))));
|
||||
background-color: var(--file-hover-bg, var(--hover-bg, transparent));
|
||||
background: var(--file-hover-bg, var(--hover-bg, transparent));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,11 +309,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.menu-container.aether {
|
||||
.menu-container[data-layout='aether'] {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 0.5em;
|
||||
background-color: var(--bg, transparent);
|
||||
font-family: var(--font, inherit);
|
||||
|
||||
a {
|
||||
@@ -323,50 +323,51 @@
|
||||
border-radius: 8px;
|
||||
color: var(--text, var(--text-normal));
|
||||
border: 1px solid var(--border, var(--background-modifier-border));
|
||||
background: var(--bg, transparent);
|
||||
font-family: var(--font, inherit);
|
||||
|
||||
&:hover {
|
||||
color: var(--hover-text, var(--accent, var(--text-accent)));
|
||||
border-color: var(--hover-border, var(--accent, var(--text-accent)));
|
||||
background-color: var(--hover-bg, var(--background-modifier-hover));
|
||||
background: var(--hover-bg, var(--background-modifier-hover));
|
||||
}
|
||||
|
||||
&.menu-internal-link {
|
||||
color: var(--internal-text, var(--text, var(--text-normal)));
|
||||
border-color: var(--internal-border, var(--border, var(--background-modifier-border)));
|
||||
background-color: var(--internal-bg, transparent);
|
||||
background: var(--internal-bg, var(--bg, transparent));
|
||||
font-family: var(--internal-font, var(--font, inherit));
|
||||
|
||||
&:hover {
|
||||
color: var(--internal-hover-text, var(--internal-accent, var(--hover-text, var(--accent, var(--text-accent)))));
|
||||
border-color: var(--internal-hover-border, var(--hover-border, var(--accent, var(--text-accent))));
|
||||
background-color: var(--internal-hover-bg, var(--hover-bg, var(--background-modifier-hover)));
|
||||
background: var(--internal-hover-bg, var(--hover-bg, var(--background-modifier-hover)));
|
||||
}
|
||||
}
|
||||
|
||||
&.menu-external-link {
|
||||
color: var(--external-text, var(--text, var(--text-normal)));
|
||||
border-color: var(--external-border, var(--border, var(--background-modifier-border)));
|
||||
background-color: var(--external-bg, transparent);
|
||||
background: var(--external-bg, var(--bg, transparent));
|
||||
font-family: var(--external-font, var(--font, inherit));
|
||||
|
||||
&:hover {
|
||||
color: var(--external-hover-text, var(--external-accent, var(--hover-text, var(--accent, var(--text-accent)))));
|
||||
border-color: var(--external-hover-border, var(--hover-border, var(--accent, var(--text-accent))));
|
||||
background-color: var(--external-hover-bg, var(--hover-bg, var(--background-modifier-hover)));
|
||||
background: var(--external-hover-bg, var(--hover-bg, var(--background-modifier-hover)));
|
||||
}
|
||||
}
|
||||
|
||||
&.menu-file-link {
|
||||
color: var(--file-text, var(--text, var(--text-normal)));
|
||||
border-color: var(--file-border, var(--border, var(--background-modifier-border)));
|
||||
background-color: var(--file-bg, transparent);
|
||||
background: var(--file-bg, var(--bg, transparent));
|
||||
font-family: var(--file-font, var(--font, inherit));
|
||||
|
||||
&:hover {
|
||||
color: var(--file-hover-text, var(--file-accent, var(--hover-text, var(--accent, var(--text-accent)))));
|
||||
border-color: var(--file-hover-border, var(--hover-border, var(--accent, var(--text-accent))));
|
||||
background-color: var(--file-hover-bg, var(--hover-bg, var(--background-modifier-hover)));
|
||||
background: var(--file-hover-bg, var(--hover-bg, var(--background-modifier-hover)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user