starlight-theme-bejamas 0.0.0-canary.0138fd3
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/CHANGELOG.md +132 -0
- package/package.json +50 -0
- package/src/config.test.ts +40 -0
- package/src/config.ts +51 -0
- package/src/env.d.ts +16 -0
- package/src/global.d.ts +20 -0
- package/src/index.ts +152 -0
- package/src/lib/theme-choice.test.ts +251 -0
- package/src/lib/theme-choice.ts +346 -0
- package/src/lib/theme-stylesheet-runtime.test.ts +246 -0
- package/src/lib/theme-stylesheet.test.ts +16 -0
- package/src/lib/theme-stylesheet.ts +123 -0
- package/src/lib/utils.ts +6 -0
- package/src/lib/vite.ts +62 -0
- package/src/overrides/Footer.astro +143 -0
- package/src/overrides/Header.astro +166 -0
- package/src/overrides/Hero.astro +175 -0
- package/src/overrides/MobileTableOfContents.astro +275 -0
- package/src/overrides/PageFrame.astro +287 -0
- package/src/overrides/PageTitle.astro +142 -0
- package/src/overrides/Pagination.astro +57 -0
- package/src/overrides/Sidebar.astro +54 -0
- package/src/overrides/SiteTitle.astro +59 -0
- package/src/overrides/TableOfContents/TableOfContentsList.astro +88 -0
- package/src/overrides/TableOfContents/starlight-toc.ts +125 -0
- package/src/overrides/ThemeProvider.astro +198 -0
- package/src/overrides/ThemeSelect.astro +110 -0
- package/src/styles/theme.css +776 -0
- package/src/virtual-internal.d.ts +40 -0
- package/src/virtual-modules.d.ts +28 -0
- package/src/virtual.d.ts +12 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
const PAGE_TITLE_ID = "_top";
|
|
2
|
+
|
|
3
|
+
export class StarlightTOC extends HTMLElement {
|
|
4
|
+
private _current = this.querySelector<HTMLAnchorElement>(
|
|
5
|
+
'a[aria-current="true"]',
|
|
6
|
+
);
|
|
7
|
+
private minH = parseInt(this.dataset.minH || "2", 10);
|
|
8
|
+
private maxH = parseInt(this.dataset.maxH || "3", 10);
|
|
9
|
+
|
|
10
|
+
protected set current(link: HTMLAnchorElement) {
|
|
11
|
+
if (link === this._current) return;
|
|
12
|
+
if (this._current) this._current.removeAttribute("aria-current");
|
|
13
|
+
link.setAttribute("aria-current", "true");
|
|
14
|
+
this._current = link;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private onIdle = (cb: IdleRequestCallback) =>
|
|
18
|
+
(window.requestIdleCallback || ((cb) => setTimeout(cb, 1)))(cb);
|
|
19
|
+
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
this.onIdle(() => this.init());
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private init = (): void => {
|
|
26
|
+
/** All the links in the table of contents. */
|
|
27
|
+
const links = [...this.querySelectorAll("a")];
|
|
28
|
+
|
|
29
|
+
/** Test if an element is a table-of-contents heading. */
|
|
30
|
+
const isHeading = (el: Element): el is HTMLHeadingElement => {
|
|
31
|
+
if (el instanceof HTMLHeadingElement) {
|
|
32
|
+
// Special case for page title h1
|
|
33
|
+
if (el.id === PAGE_TITLE_ID) return true;
|
|
34
|
+
// Check the heading level is within the user-configured limits for the ToC
|
|
35
|
+
const level = el.tagName[1];
|
|
36
|
+
if (level) {
|
|
37
|
+
const int = parseInt(level, 10);
|
|
38
|
+
if (int >= this.minH && int <= this.maxH) return true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/** Walk up the DOM to find the nearest heading. */
|
|
45
|
+
const getElementHeading = (
|
|
46
|
+
el: Element | null,
|
|
47
|
+
): HTMLHeadingElement | null => {
|
|
48
|
+
if (!el) return null;
|
|
49
|
+
const origin = el;
|
|
50
|
+
while (el) {
|
|
51
|
+
if (isHeading(el)) return el;
|
|
52
|
+
// Assign the previous sibling’s last, most deeply nested child to el.
|
|
53
|
+
el = el.previousElementSibling;
|
|
54
|
+
while (el?.lastElementChild) {
|
|
55
|
+
el = el.lastElementChild;
|
|
56
|
+
}
|
|
57
|
+
// Look for headings amongst siblings.
|
|
58
|
+
const h = getElementHeading(el);
|
|
59
|
+
if (h) return h;
|
|
60
|
+
}
|
|
61
|
+
// Walk back up the parent.
|
|
62
|
+
return getElementHeading(origin.parentElement);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** Handle intersections and set the current link to the heading for the current intersection. */
|
|
66
|
+
const setCurrent: IntersectionObserverCallback = (entries) => {
|
|
67
|
+
for (const { isIntersecting, target } of entries) {
|
|
68
|
+
if (!isIntersecting) continue;
|
|
69
|
+
const heading = getElementHeading(target);
|
|
70
|
+
if (!heading) continue;
|
|
71
|
+
const link = links.find(
|
|
72
|
+
(link) => link.hash === "#" + encodeURIComponent(heading.id),
|
|
73
|
+
);
|
|
74
|
+
if (link) {
|
|
75
|
+
this.current = link;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Observe elements with an `id` (most likely headings) and their siblings.
|
|
82
|
+
// Also observe direct children of `.content` to include elements before
|
|
83
|
+
// the first heading.
|
|
84
|
+
const toObserve = document.querySelectorAll(
|
|
85
|
+
"main [id], main [id] ~ *, main .content > *",
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
let observer: IntersectionObserver | undefined;
|
|
89
|
+
const observe = () => {
|
|
90
|
+
if (observer) return;
|
|
91
|
+
observer = new IntersectionObserver(setCurrent, {
|
|
92
|
+
rootMargin: this.getRootMargin(),
|
|
93
|
+
});
|
|
94
|
+
toObserve.forEach((h) => observer!.observe(h));
|
|
95
|
+
};
|
|
96
|
+
observe();
|
|
97
|
+
|
|
98
|
+
let timeout: NodeJS.Timeout;
|
|
99
|
+
window.addEventListener("resize", () => {
|
|
100
|
+
// Disable intersection observer while window is resizing.
|
|
101
|
+
if (observer) {
|
|
102
|
+
observer.disconnect();
|
|
103
|
+
observer = undefined;
|
|
104
|
+
}
|
|
105
|
+
clearTimeout(timeout);
|
|
106
|
+
timeout = setTimeout(() => this.onIdle(observe), 200);
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
private getRootMargin(): `-${number}px 0% ${number}px` {
|
|
111
|
+
const navBarHeight =
|
|
112
|
+
document.querySelector("header")?.getBoundingClientRect().height || 0;
|
|
113
|
+
// `<summary>` only exists in mobile ToC, so will fall back to 0 in large viewport component.
|
|
114
|
+
const mobileTocHeight =
|
|
115
|
+
this.querySelector("summary")?.getBoundingClientRect().height || 0;
|
|
116
|
+
/** Start intersections at nav height + 2rem padding. */
|
|
117
|
+
const top = navBarHeight + mobileTocHeight + 32;
|
|
118
|
+
/** End intersections `53px` later. This is slightly more than the maximum `margin-top` in Markdown content. */
|
|
119
|
+
const bottom = top + 53;
|
|
120
|
+
const height = document.documentElement.clientHeight;
|
|
121
|
+
return `-${top}px 0% ${bottom - height}px`;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
customElements.define("starlight-toc", StarlightTOC);
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { buildThemeChoiceBootstrapInlineScript } from "../lib/theme-choice";
|
|
3
|
+
|
|
4
|
+
const themeChoiceBootstrapScript = buildThemeChoiceBootstrapInlineScript();
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<script is:inline set:html={themeChoiceBootstrapScript} />
|
|
8
|
+
|
|
9
|
+
{/* This is intentionally inlined to avoid FOUC. */}
|
|
10
|
+
<script is:inline>
|
|
11
|
+
window.StarlightThemeProvider = (() => {
|
|
12
|
+
const themeMetaMedias = [
|
|
13
|
+
"(prefers-color-scheme: light)",
|
|
14
|
+
"(prefers-color-scheme: dark)",
|
|
15
|
+
];
|
|
16
|
+
const fallbackThemeColors = {
|
|
17
|
+
light: "#ffffff",
|
|
18
|
+
dark: "#0f171f",
|
|
19
|
+
};
|
|
20
|
+
const parseTheme = (theme) =>
|
|
21
|
+
theme === "auto" || theme === "dark" || theme === "light"
|
|
22
|
+
? theme
|
|
23
|
+
: "auto";
|
|
24
|
+
const getPreferredColorScheme = () =>
|
|
25
|
+
window.matchMedia("(prefers-color-scheme: light)").matches
|
|
26
|
+
? "light"
|
|
27
|
+
: "dark";
|
|
28
|
+
|
|
29
|
+
const readThemeColors = () => {
|
|
30
|
+
const html = document.documentElement;
|
|
31
|
+
const prevTheme = html.dataset.theme;
|
|
32
|
+
const prevDark = html.classList.contains("dark");
|
|
33
|
+
|
|
34
|
+
const readBackground = (theme) => {
|
|
35
|
+
html.dataset.theme = theme;
|
|
36
|
+
html.classList.toggle("dark", theme === "dark");
|
|
37
|
+
return (
|
|
38
|
+
getComputedStyle(html).getPropertyValue("--background").trim() ||
|
|
39
|
+
undefined
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const light = readBackground("light") || fallbackThemeColors.light;
|
|
44
|
+
const dark = readBackground("dark") || fallbackThemeColors.dark;
|
|
45
|
+
|
|
46
|
+
if (prevTheme !== undefined && prevTheme !== "") {
|
|
47
|
+
html.dataset.theme = prevTheme;
|
|
48
|
+
html.classList.toggle("dark", prevDark);
|
|
49
|
+
} else {
|
|
50
|
+
html.removeAttribute("data-theme");
|
|
51
|
+
html.classList.toggle("dark", prevDark);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { light, dark };
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
function ensureThemeMeta(head, media) {
|
|
58
|
+
const baseSelector = `meta[name="theme-color"][media="${media}"]`;
|
|
59
|
+
let meta = head.querySelector(`${baseSelector}[data-theme-managed]`);
|
|
60
|
+
if (meta instanceof HTMLMetaElement) return meta;
|
|
61
|
+
|
|
62
|
+
meta = head.querySelector(baseSelector);
|
|
63
|
+
if (meta instanceof HTMLMetaElement) {
|
|
64
|
+
meta.setAttribute("data-theme-managed", "");
|
|
65
|
+
return meta;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
meta = document.createElement("meta");
|
|
69
|
+
meta.setAttribute("name", "theme-color");
|
|
70
|
+
meta.setAttribute("media", media);
|
|
71
|
+
meta.setAttribute("data-theme-managed", "");
|
|
72
|
+
head.appendChild(meta);
|
|
73
|
+
return meta;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function syncThemeColor(theme) {
|
|
77
|
+
const themeColors = readThemeColors();
|
|
78
|
+
const color = themeColors[theme];
|
|
79
|
+
const head = document.head;
|
|
80
|
+
if (!color || !head) return;
|
|
81
|
+
|
|
82
|
+
themeMetaMedias.forEach((media) => {
|
|
83
|
+
const meta = ensureThemeMeta(head, media);
|
|
84
|
+
meta.setAttribute("content", color);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const effectiveTheme =
|
|
89
|
+
document.documentElement.dataset.theme === "light" ||
|
|
90
|
+
document.documentElement.dataset.theme === "dark"
|
|
91
|
+
? document.documentElement.dataset.theme
|
|
92
|
+
: getPreferredColorScheme();
|
|
93
|
+
syncThemeColor(effectiveTheme);
|
|
94
|
+
return {
|
|
95
|
+
refreshThemeColors(theme) {
|
|
96
|
+
const themeChoice = parseTheme(
|
|
97
|
+
theme ?? document.documentElement.dataset.themeChoice,
|
|
98
|
+
);
|
|
99
|
+
const effectiveTheme =
|
|
100
|
+
themeChoice === "auto" ? getPreferredColorScheme() : themeChoice;
|
|
101
|
+
syncThemeColor(effectiveTheme);
|
|
102
|
+
},
|
|
103
|
+
updatePickers(theme) {
|
|
104
|
+
const themeChoice = parseTheme(
|
|
105
|
+
theme ?? document.documentElement.dataset.themeChoice,
|
|
106
|
+
);
|
|
107
|
+
document
|
|
108
|
+
.querySelectorAll("starlight-theme-select")
|
|
109
|
+
.forEach((picker) => {
|
|
110
|
+
const nativeSelect = picker.querySelector("select");
|
|
111
|
+
if (nativeSelect instanceof HTMLSelectElement) {
|
|
112
|
+
nativeSelect.value = themeChoice;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const selectRoot = picker.querySelector("#starlight-theme-select");
|
|
116
|
+
if (selectRoot instanceof HTMLElement) {
|
|
117
|
+
selectRoot.dataset.defaultValue = themeChoice;
|
|
118
|
+
selectRoot.dataset.value = themeChoice;
|
|
119
|
+
selectRoot.dispatchEvent(
|
|
120
|
+
new CustomEvent("select:set", { detail: { value: themeChoice } }),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
})();
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<script>
|
|
130
|
+
import { syncSemanticIconsInRoot } from "@bejamas/semantic-icons/browser";
|
|
131
|
+
import { refreshCurrentThemeStylesheet } from "../lib/theme-stylesheet";
|
|
132
|
+
|
|
133
|
+
const PRESET_CHANGE_EVENT = "bejamas:preset-change";
|
|
134
|
+
const SETUP_KEY = "__bejamasCurrentThemeStylesheetSync";
|
|
135
|
+
let reloadFrame = 0;
|
|
136
|
+
let pendingIconLibrary = null;
|
|
137
|
+
|
|
138
|
+
function syncDocumentIconLibrary() {
|
|
139
|
+
const renderedIcon = document.querySelector("[data-icon-library]");
|
|
140
|
+
const iconLibrary =
|
|
141
|
+
renderedIcon instanceof SVGElement
|
|
142
|
+
? renderedIcon.dataset.iconLibrary
|
|
143
|
+
: document.documentElement.dataset.iconLibrary;
|
|
144
|
+
|
|
145
|
+
if (iconLibrary) {
|
|
146
|
+
document.documentElement.dataset.iconLibrary = iconLibrary;
|
|
147
|
+
syncSemanticIconsInRoot(document, iconLibrary);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const scheduleCurrentThemeStylesheetRefresh = () => {
|
|
152
|
+
if (reloadFrame) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
reloadFrame = requestAnimationFrame(() => {
|
|
157
|
+
reloadFrame = 0;
|
|
158
|
+
void refreshCurrentThemeStylesheet().then(() => {
|
|
159
|
+
if (pendingIconLibrary) {
|
|
160
|
+
document.documentElement.dataset.iconLibrary = pendingIconLibrary;
|
|
161
|
+
syncSemanticIconsInRoot(document, pendingIconLibrary);
|
|
162
|
+
pendingIconLibrary = null;
|
|
163
|
+
}
|
|
164
|
+
window.StarlightThemeProvider?.refreshThemeColors?.();
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
if (!(SETUP_KEY in window)) {
|
|
170
|
+
window[SETUP_KEY] = true;
|
|
171
|
+
syncDocumentIconLibrary();
|
|
172
|
+
|
|
173
|
+
window.addEventListener("theme-toggle-changed", (event) => {
|
|
174
|
+
const themeChoice =
|
|
175
|
+
event instanceof CustomEvent && typeof event.detail?.themeChoice === "string"
|
|
176
|
+
? event.detail.themeChoice
|
|
177
|
+
: undefined;
|
|
178
|
+
|
|
179
|
+
window.StarlightThemeProvider?.refreshThemeColors?.(themeChoice);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
window.addEventListener(PRESET_CHANGE_EVENT, (event) => {
|
|
183
|
+
const presetChange = event;
|
|
184
|
+
|
|
185
|
+
pendingIconLibrary =
|
|
186
|
+
presetChange instanceof CustomEvent &&
|
|
187
|
+
typeof presetChange.detail?.iconLibrary === "string"
|
|
188
|
+
? presetChange.detail.iconLibrary
|
|
189
|
+
: null;
|
|
190
|
+
|
|
191
|
+
scheduleCurrentThemeStylesheetRefresh();
|
|
192
|
+
});
|
|
193
|
+
document.addEventListener("astro:after-swap", () => {
|
|
194
|
+
window.StarlightThemeProvider?.refreshThemeColors?.();
|
|
195
|
+
syncDocumentIconLibrary();
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
</script>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
import {
|
|
3
|
+
Select,
|
|
4
|
+
SelectItem,
|
|
5
|
+
SelectTrigger,
|
|
6
|
+
SelectValue,
|
|
7
|
+
SelectContent,
|
|
8
|
+
} from "virtual:starlight-theme-bejamas/components/select";
|
|
9
|
+
|
|
10
|
+
import { SunIcon, MoonIcon, LaptopIcon } from "@lucide/astro";
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<starlight-theme-select>
|
|
14
|
+
<div class="relative text-sm">
|
|
15
|
+
<div class="sl-bejamas-theme-select-icons">
|
|
16
|
+
<SunIcon class="theme-icon theme-icon-light size-4" />
|
|
17
|
+
<MoonIcon class="theme-icon theme-icon-dark size-4" />
|
|
18
|
+
<LaptopIcon class="theme-icon theme-icon-auto size-4" />
|
|
19
|
+
</div>
|
|
20
|
+
<Select defaultValue="auto" id="starlight-theme-select">
|
|
21
|
+
<SelectTrigger class="sl-bejamas-theme-select-control">
|
|
22
|
+
<SelectValue placeholder="Theme" />
|
|
23
|
+
</SelectTrigger>
|
|
24
|
+
<SelectContent>
|
|
25
|
+
<SelectItem value="light" class="flex items-center gap-2"
|
|
26
|
+
><SunIcon class="size-4" /> Light</SelectItem
|
|
27
|
+
>
|
|
28
|
+
<SelectItem value="dark" class="flex items-center gap-2"
|
|
29
|
+
><MoonIcon class="size-4" /> Dark</SelectItem
|
|
30
|
+
>
|
|
31
|
+
<SelectItem value="auto" class="flex items-center gap-2"
|
|
32
|
+
><LaptopIcon class="size-4" /> Auto</SelectItem
|
|
33
|
+
>
|
|
34
|
+
</SelectContent>
|
|
35
|
+
</Select>
|
|
36
|
+
</div>
|
|
37
|
+
</starlight-theme-select>
|
|
38
|
+
|
|
39
|
+
<script>
|
|
40
|
+
import {
|
|
41
|
+
getThemeChoiceFromRoot,
|
|
42
|
+
parseStoredThemeChoice,
|
|
43
|
+
setThemeChoice,
|
|
44
|
+
syncThemeChoiceControls,
|
|
45
|
+
} from "../lib/theme-choice";
|
|
46
|
+
|
|
47
|
+
class StarlightThemeSelect extends HTMLElement {
|
|
48
|
+
private selectRoot: HTMLElement | null = null;
|
|
49
|
+
|
|
50
|
+
private onSelectChange = (event: Event) => {
|
|
51
|
+
const value = (event as CustomEvent<{ value?: unknown }>).detail?.value;
|
|
52
|
+
if (typeof value !== "string") return;
|
|
53
|
+
|
|
54
|
+
const nextTheme = parseStoredThemeChoice(value);
|
|
55
|
+
const currentTheme = getThemeChoiceFromRoot(document.documentElement);
|
|
56
|
+
if (nextTheme === currentTheme) return;
|
|
57
|
+
|
|
58
|
+
setThemeChoice(nextTheme);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
connectedCallback() {
|
|
62
|
+
this.selectRoot = this.querySelector<HTMLElement>("#starlight-theme-select");
|
|
63
|
+
syncThemeChoiceControls(
|
|
64
|
+
getThemeChoiceFromRoot(document.documentElement),
|
|
65
|
+
this,
|
|
66
|
+
);
|
|
67
|
+
this.selectRoot?.addEventListener("select:change", this.onSelectChange);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
disconnectedCallback() {
|
|
71
|
+
this.selectRoot?.removeEventListener("select:change", this.onSelectChange);
|
|
72
|
+
this.selectRoot = null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!customElements.get("starlight-theme-select")) {
|
|
77
|
+
customElements.define("starlight-theme-select", StarlightThemeSelect);
|
|
78
|
+
}
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<style>
|
|
82
|
+
.theme-icon {
|
|
83
|
+
display: none;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
:global(html[data-theme-choice="light"]) .theme-icon-light {
|
|
87
|
+
display: block;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
:global(html[data-theme-choice="dark"]) .theme-icon-dark {
|
|
91
|
+
display: block;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
:global(html[data-theme-choice="auto"]) .theme-icon-auto {
|
|
95
|
+
display: block;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.sl-bejamas-theme-select-icons {
|
|
99
|
+
position: absolute;
|
|
100
|
+
z-index: 10;
|
|
101
|
+
left: calc(var(--spacing) * 3);
|
|
102
|
+
top: calc(var(--spacing) * 2.5);
|
|
103
|
+
pointer-events: none;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.sl-bejamas-theme-select-control {
|
|
107
|
+
padding-left: calc(var(--spacing) * 9);
|
|
108
|
+
width: calc(var(--spacing) * 28);
|
|
109
|
+
}
|
|
110
|
+
</style>
|