starlight-cannoli-plugins 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{chunk-XMGAWBJ5.js → chunk-OXJMUUGP.js} +4 -2
- package/dist/index.d.ts +13 -1
- package/dist/index.js +19 -13
- package/dist/plugins/starlight-dom-patches/page-script.d.ts +2 -1
- package/dist/plugins/starlight-dom-patches/page-script.js +152 -6
- package/dist/plugins/starlight-dom-patches.d.ts +6 -0
- package/dist/plugins/starlight-dom-patches.js +1 -1
- package/dist/styles/_starlight.scss +82 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -399,6 +399,7 @@ An Astro integration that injects a client-side script to apply opt-in DOM patch
|
|
|
399
399
|
- `hideSingleLineGutters` (optional, default: `false`): Hides the line number gutter on Expressive Code blocks that contain only a single line.
|
|
400
400
|
- `syncTocLabelsFromHeadings` (optional, default: `false`): Copies the rendered HTML of each heading into its matching Starlight TOC anchor label, so the TOC properly reflects any custom markup (e.g. math) present in the heading.
|
|
401
401
|
- `wrapDetailsContent` (optional, default: `false`): Wraps the content of every `<details>` element (excluding its `<summary>`) in a `<div class="details-wrapper">`, useful for applying consistent spacing or animation styles.
|
|
402
|
+
- `offerTabbedContent` (optional, default: `false`): Injects a "Tabbed view" toggle checkbox immediately after `#starlight__on-this-page` in the right sidebar. When enabled by the user, the page's markdown content is reorganised into tabs — one per `<h2>` heading, plus an optional "Main" tab for any content that appears before the first `<h2>`. The toggle state is persisted to `localStorage`; active tab selection is not persisted. Only activates when the page has at least two sections (i.e. two or more `<h2>` elements, or one `<h2>` with pre-heading content). Has no effect on pages that lack `#starlight__on-this-page` (e.g. pages with the TOC disabled). Clicking a TOC anchor while tabs are enabled automatically switches to the tab containing the target heading. The generated elements use the classes `tabbed-content`, `tabbed-content-nav`, `tabbed-content-tab`, and `tabbed-content-panel` for styling; toggle button uses the existing `.toggle-checkbox-btn` class.
|
|
402
403
|
|
|
403
404
|
**Usage:**
|
|
404
405
|
|
|
@@ -414,6 +415,7 @@ export default defineConfig({
|
|
|
414
415
|
hideSingleLineGutters: true,
|
|
415
416
|
syncTocLabelsFromHeadings: true,
|
|
416
417
|
wrapDetailsContent: true,
|
|
418
|
+
offerTabbedContent: true,
|
|
417
419
|
}),
|
|
418
420
|
starlight({ title: "My Docs" }),
|
|
419
421
|
],
|
|
@@ -4,7 +4,8 @@ function starlightDomPatches(options = {}) {
|
|
|
4
4
|
const {
|
|
5
5
|
hideSingleLineGutters = false,
|
|
6
6
|
syncTocLabelsFromHeadings = false,
|
|
7
|
-
wrapDetailsContent = false
|
|
7
|
+
wrapDetailsContent = false,
|
|
8
|
+
offerTabbedContent = false
|
|
8
9
|
} = options;
|
|
9
10
|
return {
|
|
10
11
|
name: "starlight-dom-patches",
|
|
@@ -29,7 +30,8 @@ function starlightDomPatches(options = {}) {
|
|
|
29
30
|
const imports = [
|
|
30
31
|
hideSingleLineGutters ? "hideSingleLineGutters" : null,
|
|
31
32
|
syncTocLabelsFromHeadings ? "syncTocLabelsFromHeadings" : null,
|
|
32
|
-
wrapDetailsContent ? "wrapDetailsContent" : null
|
|
33
|
+
wrapDetailsContent ? "wrapDetailsContent" : null,
|
|
34
|
+
offerTabbedContent ? "tabbedH2Content" : null
|
|
33
35
|
].filter(Boolean);
|
|
34
36
|
if (imports.length === 0) return;
|
|
35
37
|
const calls = imports.map((fn) => `${fn}();`).join("\n");
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,12 @@ import 'vfile';
|
|
|
13
13
|
import 'mdast';
|
|
14
14
|
import 'expressive-code';
|
|
15
15
|
|
|
16
|
+
type TBadgeVariant = "note" | "danger" | "success" | "caution" | "tip" | "default";
|
|
17
|
+
type TIndexMarker = {
|
|
18
|
+
text: string;
|
|
19
|
+
variant: TBadgeVariant;
|
|
20
|
+
};
|
|
21
|
+
|
|
16
22
|
type TOptions = {
|
|
17
23
|
/**
|
|
18
24
|
* Controls how deep the nested group structure can go, where the root directory is level 0.
|
|
@@ -32,7 +38,13 @@ type TOptions = {
|
|
|
32
38
|
* regular sidebar entries. When undefined, no marker is added.
|
|
33
39
|
* @example "★"
|
|
34
40
|
*/
|
|
35
|
-
indexMarker?:
|
|
41
|
+
indexMarker?: TIndexMarker;
|
|
42
|
+
/**
|
|
43
|
+
* Whether sidebar groups should be collapsed by default. Starlight automatically expands
|
|
44
|
+
* the group containing the current page regardless of this setting.
|
|
45
|
+
* @default true
|
|
46
|
+
*/
|
|
47
|
+
collapsed?: boolean;
|
|
36
48
|
};
|
|
37
49
|
/**
|
|
38
50
|
* Starlight plugin that generates a sidebar by parsing markdown links from index.md files.
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunk-NCXV367P.js";
|
|
25
25
|
import {
|
|
26
26
|
starlightDomPatches
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-OXJMUUGP.js";
|
|
28
28
|
import "./chunk-4VNS5WPM.js";
|
|
29
29
|
|
|
30
30
|
// src/plugins/starlight-index-sourced-sidebar/index.ts
|
|
@@ -110,7 +110,7 @@ function tryResolveMarkdownFile(href, currentDir) {
|
|
|
110
110
|
}
|
|
111
111
|
return findMarkdownFile(resolved);
|
|
112
112
|
}
|
|
113
|
-
function buildItems(dirPath, currentDepth, maxDepth, visited, indexMarker) {
|
|
113
|
+
function buildItems(dirPath, currentDepth, maxDepth, visited, indexMarker, collapsed) {
|
|
114
114
|
const absDir = path.resolve(dirPath);
|
|
115
115
|
if (visited.has(absDir)) return [];
|
|
116
116
|
visited.add(absDir);
|
|
@@ -125,8 +125,9 @@ function buildItems(dirPath, currentDepth, maxDepth, visited, indexMarker) {
|
|
|
125
125
|
const items = [];
|
|
126
126
|
const indexBaseLabel = fm.title ?? pathSegmentToLabel(path.basename(absDir));
|
|
127
127
|
items.push({
|
|
128
|
-
label:
|
|
129
|
-
slug: normalizeSlug(filePathToSlug(indexFile))
|
|
128
|
+
label: indexBaseLabel,
|
|
129
|
+
slug: normalizeSlug(filePathToSlug(indexFile)),
|
|
130
|
+
...indexMarker && { badge: indexMarker }
|
|
130
131
|
});
|
|
131
132
|
for (const href of extractMarkdownLinks(indexFile)) {
|
|
132
133
|
if (isExternal(href)) continue;
|
|
@@ -143,8 +144,9 @@ function buildItems(dirPath, currentDepth, maxDepth, visited, indexMarker) {
|
|
|
143
144
|
continue;
|
|
144
145
|
const subBaseLabel = subFm.title ?? pathSegmentToLabel(path.basename(subDirPath));
|
|
145
146
|
items.push({
|
|
146
|
-
label:
|
|
147
|
-
slug: normalizeSlug(filePathToSlug(resolvedFile))
|
|
147
|
+
label: subBaseLabel,
|
|
148
|
+
slug: normalizeSlug(filePathToSlug(resolvedFile)),
|
|
149
|
+
...indexMarker && { badge: indexMarker }
|
|
148
150
|
});
|
|
149
151
|
} else {
|
|
150
152
|
const subItems = buildItems(
|
|
@@ -152,7 +154,8 @@ function buildItems(dirPath, currentDepth, maxDepth, visited, indexMarker) {
|
|
|
152
154
|
currentDepth + 1,
|
|
153
155
|
maxDepth,
|
|
154
156
|
visited,
|
|
155
|
-
indexMarker
|
|
157
|
+
indexMarker,
|
|
158
|
+
collapsed
|
|
156
159
|
);
|
|
157
160
|
if (subItems.length === 0) continue;
|
|
158
161
|
if (currentDepth + 1 >= maxDepth) {
|
|
@@ -160,7 +163,8 @@ function buildItems(dirPath, currentDepth, maxDepth, visited, indexMarker) {
|
|
|
160
163
|
} else {
|
|
161
164
|
items.push({
|
|
162
165
|
label: pathSegmentToLabel(path.basename(subDirPath)),
|
|
163
|
-
items: subItems
|
|
166
|
+
items: subItems,
|
|
167
|
+
collapsed
|
|
164
168
|
});
|
|
165
169
|
}
|
|
166
170
|
}
|
|
@@ -178,7 +182,7 @@ function buildItems(dirPath, currentDepth, maxDepth, visited, indexMarker) {
|
|
|
178
182
|
}
|
|
179
183
|
return items;
|
|
180
184
|
}
|
|
181
|
-
function getIndexSourcedSidebarItems(directory, maxDepthNesting = 100, indexMarker) {
|
|
185
|
+
function getIndexSourcedSidebarItems(directory, maxDepthNesting = 100, indexMarker, collapsed = true) {
|
|
182
186
|
const absDir = path.resolve(directory);
|
|
183
187
|
const rootGroupLabel = pathSegmentToLabel(path.basename(absDir));
|
|
184
188
|
const items = buildItems(
|
|
@@ -186,10 +190,11 @@ function getIndexSourcedSidebarItems(directory, maxDepthNesting = 100, indexMark
|
|
|
186
190
|
0,
|
|
187
191
|
maxDepthNesting,
|
|
188
192
|
/* @__PURE__ */ new Set(),
|
|
189
|
-
indexMarker
|
|
193
|
+
indexMarker,
|
|
194
|
+
collapsed
|
|
190
195
|
);
|
|
191
196
|
if (items.length === 0) return [];
|
|
192
|
-
return [{ label: rootGroupLabel, items }];
|
|
197
|
+
return [{ label: rootGroupLabel, items, collapsed }];
|
|
193
198
|
}
|
|
194
199
|
|
|
195
200
|
// src/plugins/starlight-index-sourced-sidebar/index.ts
|
|
@@ -200,13 +205,14 @@ function starlightIndexSourcedSidebar(options) {
|
|
|
200
205
|
hooks: {
|
|
201
206
|
"config:setup": (hookOptions) => {
|
|
202
207
|
const { updateConfig } = hookOptions;
|
|
203
|
-
const { directories, maxDepthNesting = 100, indexMarker } = options;
|
|
208
|
+
const { directories, maxDepthNesting = 100, indexMarker, collapsed = true } = options;
|
|
204
209
|
const sidebarItems = directories.map((directory) => {
|
|
205
210
|
const dirPath = join2(SITE_DOCS_ROOT2, directory);
|
|
206
211
|
const rawItems = getIndexSourcedSidebarItems(
|
|
207
212
|
dirPath,
|
|
208
213
|
maxDepthNesting,
|
|
209
|
-
indexMarker
|
|
214
|
+
indexMarker,
|
|
215
|
+
collapsed
|
|
210
216
|
);
|
|
211
217
|
const rootGroup = rawItems[0];
|
|
212
218
|
if (!rootGroup || !("items" in rootGroup)) return void 0;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
declare function hideSingleLineGutters(): void;
|
|
2
2
|
declare function syncTocLabelsFromHeadings(): void;
|
|
3
|
+
declare function tabbedH2Content(): void;
|
|
3
4
|
declare function wrapDetailsContent(): void;
|
|
4
5
|
|
|
5
|
-
export { hideSingleLineGutters, syncTocLabelsFromHeadings, wrapDetailsContent };
|
|
6
|
+
export { hideSingleLineGutters, syncTocLabelsFromHeadings, tabbedH2Content, wrapDetailsContent };
|
|
@@ -16,6 +16,12 @@ function hideSingleLineGutters() {
|
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
+
function headingInnerHTML(heading) {
|
|
20
|
+
if (heading.childElementCount === 1 && heading.children[0].tagName === "STRONG") {
|
|
21
|
+
return heading.children[0].innerHTML;
|
|
22
|
+
}
|
|
23
|
+
return heading.innerHTML;
|
|
24
|
+
}
|
|
19
25
|
function syncTocLabelsFromHeadings() {
|
|
20
26
|
document.querySelectorAll("starlight-toc ul li > a, mobile-starlight-toc ul li > a").forEach((anchor) => {
|
|
21
27
|
const href = anchor.getAttribute("href") ?? "";
|
|
@@ -27,13 +33,152 @@ function syncTocLabelsFromHeadings() {
|
|
|
27
33
|
if (!heading) return;
|
|
28
34
|
const span = anchor.querySelector(":scope > span");
|
|
29
35
|
if (!span) return;
|
|
30
|
-
span.innerHTML = heading
|
|
36
|
+
span.innerHTML = headingInnerHTML(heading);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function tabbedH2Content() {
|
|
40
|
+
console.log("[tabbedH2Content] running");
|
|
41
|
+
const LS_KEY = "starlight-dom-patches:tabbed-content";
|
|
42
|
+
const container = document.querySelector(
|
|
43
|
+
".main-pane .sl-markdown-content"
|
|
44
|
+
);
|
|
45
|
+
if (!container) {
|
|
46
|
+
console.log(
|
|
47
|
+
"[tabbedH2Content] no .main-pane .sl-markdown-content found \u2014 aborting"
|
|
48
|
+
);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const tocSection = document.getElementById("starlight__on-this-page");
|
|
52
|
+
if (!tocSection) {
|
|
53
|
+
console.log(
|
|
54
|
+
"[tabbedH2Content] #starlight__on-this-page not found \u2014 aborting"
|
|
55
|
+
);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const children = Array.from(container.children);
|
|
59
|
+
if (children.length === 0) {
|
|
60
|
+
console.log("[tabbedH2Content] content container is empty \u2014 aborting");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
console.log(`[tabbedH2Content] container element:`, container);
|
|
64
|
+
console.log(
|
|
65
|
+
`[tabbedH2Content] found ${children.length} children:`,
|
|
66
|
+
children.map((c) => c.tagName).join(", ")
|
|
67
|
+
);
|
|
68
|
+
const preH2Nodes = [];
|
|
69
|
+
const h2Sections = [];
|
|
70
|
+
let currentSection = null;
|
|
71
|
+
const isH2Wrapper = (el) => el.tagName === "DIV" && el.classList.contains("sl-heading-wrapper") && el.classList.contains("level-h2");
|
|
72
|
+
for (const child of children) {
|
|
73
|
+
if (isH2Wrapper(child)) {
|
|
74
|
+
if (currentSection) h2Sections.push(currentSection);
|
|
75
|
+
const h2 = child.querySelector("h2");
|
|
76
|
+
currentSection = {
|
|
77
|
+
label: h2 ? headingInnerHTML(h2) : "",
|
|
78
|
+
nodes: [child]
|
|
79
|
+
};
|
|
80
|
+
} else if (currentSection === null) {
|
|
81
|
+
preH2Nodes.push(child);
|
|
82
|
+
} else {
|
|
83
|
+
currentSection.nodes.push(child);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (currentSection) h2Sections.push(currentSection);
|
|
87
|
+
const hasPreContent = preH2Nodes.length > 0;
|
|
88
|
+
const totalSections = (hasPreContent ? 1 : 0) + h2Sections.length;
|
|
89
|
+
console.log(
|
|
90
|
+
`[tabbedH2Content] preH2Nodes: ${preH2Nodes.length}, h2Sections: ${h2Sections.length}, totalSections: ${totalSections}`
|
|
91
|
+
);
|
|
92
|
+
if (totalSections <= 1) {
|
|
93
|
+
console.log(
|
|
94
|
+
"[tabbedH2Content] only one section \u2014 aborting (no tabs needed)"
|
|
95
|
+
);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const allSections = [];
|
|
99
|
+
if (hasPreContent) allSections.push({ label: "Main", nodes: preH2Nodes });
|
|
100
|
+
allSections.push(...h2Sections);
|
|
101
|
+
const wrapper = document.createElement("div");
|
|
102
|
+
wrapper.className = "tabbed-content";
|
|
103
|
+
const nav = document.createElement("div");
|
|
104
|
+
nav.className = "tabbed-content-nav not-content";
|
|
105
|
+
const tabButtons = [];
|
|
106
|
+
const panels = [];
|
|
107
|
+
allSections.forEach((section, i) => {
|
|
108
|
+
const btn = document.createElement("button");
|
|
109
|
+
btn.className = "tabbed-content-tab";
|
|
110
|
+
btn.innerHTML = section.label;
|
|
111
|
+
btn.dataset.tab = String(i);
|
|
112
|
+
tabButtons.push(btn);
|
|
113
|
+
nav.appendChild(btn);
|
|
114
|
+
const panel = document.createElement("div");
|
|
115
|
+
panel.className = "tabbed-content-panel";
|
|
116
|
+
panel.dataset.panel = String(i);
|
|
117
|
+
section.nodes.forEach((node) => panel.appendChild(node));
|
|
118
|
+
panels.push(panel);
|
|
31
119
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
120
|
+
wrapper.appendChild(nav);
|
|
121
|
+
panels.forEach((p) => wrapper.appendChild(p));
|
|
122
|
+
container.appendChild(wrapper);
|
|
123
|
+
let activeTab = 0;
|
|
124
|
+
function activateTab(index) {
|
|
125
|
+
activeTab = index;
|
|
126
|
+
tabButtons.forEach((btn, i) => {
|
|
127
|
+
btn.dataset.active = String(i === index);
|
|
128
|
+
});
|
|
129
|
+
panels.forEach((panel, i) => {
|
|
130
|
+
panel.hidden = i !== index;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function setEnabled(enabled) {
|
|
134
|
+
wrapper.dataset.enabled = String(enabled);
|
|
135
|
+
nav.hidden = !enabled;
|
|
136
|
+
if (enabled) {
|
|
137
|
+
activateTab(activeTab);
|
|
138
|
+
} else {
|
|
139
|
+
panels.forEach((panel) => {
|
|
140
|
+
panel.hidden = false;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
tabButtons.forEach((btn, i) => {
|
|
145
|
+
btn.addEventListener("click", () => {
|
|
146
|
+
if (wrapper.dataset.enabled === "true") activateTab(i);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
function navigateToHash(hash) {
|
|
150
|
+
if (!hash || wrapper.dataset.enabled !== "true") return;
|
|
151
|
+
const id = hash.startsWith("#") ? hash.slice(1) : hash;
|
|
152
|
+
panels.forEach((panel, i) => {
|
|
153
|
+
if (panel.querySelector(`#${CSS.escape(id)}`)) activateTab(i);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
window.addEventListener(
|
|
157
|
+
"hashchange",
|
|
158
|
+
() => navigateToHash(window.location.hash)
|
|
159
|
+
);
|
|
160
|
+
if (window.location.hash) navigateToHash(window.location.hash);
|
|
161
|
+
const toggleLabel = document.createElement("label");
|
|
162
|
+
toggleLabel.className = "toggle-checkbox-btn";
|
|
163
|
+
const checkbox = document.createElement("input");
|
|
164
|
+
checkbox.type = "checkbox";
|
|
165
|
+
const toggleText = document.createElement("span");
|
|
166
|
+
toggleText.textContent = "Tabbed view";
|
|
167
|
+
toggleLabel.appendChild(checkbox);
|
|
168
|
+
toggleLabel.appendChild(toggleText);
|
|
169
|
+
tocSection.parentNode.insertBefore(toggleLabel, tocSection.nextSibling);
|
|
170
|
+
console.log(
|
|
171
|
+
"[tabbedH2Content] toggle checkbox injected after #starlight__on-this-page"
|
|
172
|
+
);
|
|
173
|
+
const initialEnabled = localStorage.getItem(LS_KEY) === "enabled";
|
|
174
|
+
console.log(
|
|
175
|
+
`[tabbedH2Content] localStorage value: ${localStorage.getItem(LS_KEY)}, initialEnabled: ${initialEnabled}`
|
|
176
|
+
);
|
|
177
|
+
checkbox.checked = initialEnabled;
|
|
178
|
+
setEnabled(initialEnabled);
|
|
179
|
+
checkbox.addEventListener("change", () => {
|
|
180
|
+
setEnabled(checkbox.checked);
|
|
181
|
+
localStorage.setItem(LS_KEY, checkbox.checked ? "enabled" : "disabled");
|
|
37
182
|
});
|
|
38
183
|
}
|
|
39
184
|
function wrapDetailsContent() {
|
|
@@ -67,5 +212,6 @@ function wrapDetailsContent() {
|
|
|
67
212
|
export {
|
|
68
213
|
hideSingleLineGutters,
|
|
69
214
|
syncTocLabelsFromHeadings,
|
|
215
|
+
tabbedH2Content,
|
|
70
216
|
wrapDetailsContent
|
|
71
217
|
};
|
|
@@ -7,6 +7,12 @@ interface DomPatchesOptions {
|
|
|
7
7
|
syncTocLabelsFromHeadings?: boolean;
|
|
8
8
|
/** Wrap `<details>` content (excluding `<summary>`) in a `.details-wrapper` div. @default false */
|
|
9
9
|
wrapDetailsContent?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Inject a toggle checkbox (after `#starlight__on-this-page`) that reorganises page content
|
|
12
|
+
* into tabs driven by `<h2>` boundaries. Toggle state is persisted to localStorage.
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
15
|
+
offerTabbedContent?: boolean;
|
|
10
16
|
}
|
|
11
17
|
/**
|
|
12
18
|
* Astro integration that injects a client-side script to apply DOM patches
|
|
@@ -133,6 +133,55 @@ div > div[class="page"] > svg {
|
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
/********** Tabbed H2 Content **********/
|
|
137
|
+
.tabbed-content-nav {
|
|
138
|
+
display: flex;
|
|
139
|
+
flex-wrap: wrap;
|
|
140
|
+
gap: 0.375rem;
|
|
141
|
+
margin-bottom: 1.75rem;
|
|
142
|
+
max-height: 9rem;
|
|
143
|
+
overflow-y: auto;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.tabbed-content-tab {
|
|
147
|
+
padding: 0.3rem 0.85rem;
|
|
148
|
+
border: none;
|
|
149
|
+
border-radius: 9999px;
|
|
150
|
+
background-color: var(--sl-color-gray-6);
|
|
151
|
+
color: var(--sl-color-gray-3);
|
|
152
|
+
cursor: pointer;
|
|
153
|
+
font-size: 0.8125em;
|
|
154
|
+
font-weight: 500;
|
|
155
|
+
transition:
|
|
156
|
+
color 0.15s ease,
|
|
157
|
+
background-color 0.15s ease;
|
|
158
|
+
|
|
159
|
+
&:hover {
|
|
160
|
+
background-color: var(--sl-color-gray-5);
|
|
161
|
+
color: var(--sl-color-text);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
&[data-active="true"] {
|
|
165
|
+
background-color: var(--sl-color-accent-high);
|
|
166
|
+
color: var(--sl-color-black);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
html[data-theme="light"] & {
|
|
170
|
+
background-color: var(--sl-color-gray-7);
|
|
171
|
+
color: var(--sl-color-gray-4);
|
|
172
|
+
|
|
173
|
+
&:hover {
|
|
174
|
+
background-color: var(--sl-color-gray-6);
|
|
175
|
+
color: var(--sl-color-gray-2);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
&[data-active="true"] {
|
|
179
|
+
background-color: var(--sl-color-accent-low);
|
|
180
|
+
color: var(--sl-color-white);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
136
185
|
/********** Toggle Checkbox Styles **********/
|
|
137
186
|
#toggle-all-details-btn {
|
|
138
187
|
display: flex;
|
|
@@ -167,6 +216,39 @@ div > div[class="page"] > svg {
|
|
|
167
216
|
}
|
|
168
217
|
}
|
|
169
218
|
|
|
219
|
+
.toggle-checkbox-btn {
|
|
220
|
+
display: flex;
|
|
221
|
+
align-items: center;
|
|
222
|
+
gap: 0.5rem;
|
|
223
|
+
cursor: pointer;
|
|
224
|
+
|
|
225
|
+
input[type="checkbox"] {
|
|
226
|
+
position: relative;
|
|
227
|
+
appearance: none;
|
|
228
|
+
width: 1.2em;
|
|
229
|
+
height: 1.2em;
|
|
230
|
+
border: 2px solid currentColor;
|
|
231
|
+
border-radius: 2px;
|
|
232
|
+
cursor: pointer;
|
|
233
|
+
display: flex;
|
|
234
|
+
align-items: center;
|
|
235
|
+
justify-content: center;
|
|
236
|
+
transition: background-color 0.2s ease;
|
|
237
|
+
|
|
238
|
+
&:checked {
|
|
239
|
+
background-color: var(--sl-color-accent);
|
|
240
|
+
border-color: var(--sl-color-accent);
|
|
241
|
+
|
|
242
|
+
&::after {
|
|
243
|
+
content: "✓";
|
|
244
|
+
color: white;
|
|
245
|
+
font-size: 0.8em;
|
|
246
|
+
font-weight: bold;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
170
252
|
// invert img.note-svg when on dark mode
|
|
171
253
|
img.note-svg {
|
|
172
254
|
padding-top: 1em;
|
package/package.json
CHANGED