Skip to content

Commit 5c31c77

Browse files
authored
feat: override Naive UI with base font size (#20)
* Watching changes in .slidev-layout * Add debug msg to useInjectStyle.ts * Only read font size when layout loaded * Inject base font sizes through config provider * Add a comment * Remove useBaseFontSizes from naive.ts * Directly import base font size * Use isDark as a singleton * Rename base font hook * Add a comment in useBaseFontSize * Bump version * Update latest changes
1 parent ecc0983 commit 5c31c77

File tree

8 files changed

+94
-33
lines changed

8 files changed

+94
-33
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,13 @@ supported, along with full compatibility for props and slots.
109109

110110
## Latest Changes
111111

112+
- **`v0.8.0`:** Override Naive UI font size with base font size.
112113
- **`v0.7.0`:** Added support for using addon as a Vue plugin.
113114
- **`v0.6.0`:** Added full support for UnoCSS utility classes. No more `!`
114115
prefixes needed!
115116
- **`v0.5.1`:** Improved logic in `main.ts`.
116117
- **`v0.5.0`:** Added support for dynamic dark theme.
117-
- **`v0.4.0:`** Fixed a bug that caused Naive UI styles not loaded.
118-
- **`v0,3.0:`** Adopted a new way of loading components.
119-
- **`v0.2.0:`** Added all components.
120-
- **`v0.1.0:`** First working version with a few components.
118+
- **`v0.4.0`:** Fixed a bug that caused Naive UI styles not loaded.
119+
- **`v0,3.0`:** Adopted a new way of loading components.
120+
- **`v0.2.0`:** Added all components.
121+
- **`v0.1.0`:** First working version with a few components.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "slidev-addon-naive",
3-
"version": "0.7.0",
3+
"version": "0.8.0",
44
"description": "An addon that brings Naive UI components to Slidev.",
55
"keywords": [
66
"naive-ui",

src/naive.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { type App } from "vue";
2+
13
import naive from "naive-ui";
24

35
import useConfigProvider from "./useConfigProvider.ts";
46
import useInjectStyle from "./useInjectStyle.ts";
57

68
export default {
7-
install(app) {
9+
install(app: App) {
810
app.use(naive); // setup Naive UI
911
useInjectStyle(); // inject styles to <head>
1012
useConfigProvider(app); // provide theme and overrides

src/useBaseFontSize.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { ref } from "vue";
2+
3+
// must be a ref for Naive components to be rendered with overrides
4+
const fontSize = ref("16px"); // default font size
5+
6+
const setBaseFontSize = () => {
7+
const element = document.querySelector(".slidev-layout");
8+
if (element) {
9+
const computedStyle = window.getComputedStyle(element);
10+
fontSize.value = computedStyle.fontSize;
11+
console.debug("[Naive] Base font size:", fontSize.value);
12+
} else {
13+
console.error(
14+
"[Naive] .slidev-layout not found, using default font size (16px)",
15+
);
16+
}
17+
};
18+
19+
if (typeof window === "undefined") {
20+
console.error(
21+
`[Naive] Window is undefined, can't observe DOM to set base font size`,
22+
);
23+
} else {
24+
// Setup observer for DOM changes
25+
const observer = new MutationObserver(() => {
26+
const slidevLayout = document.querySelector(".slidev-layout");
27+
28+
if (slidevLayout) {
29+
console.debug("[Naive] Found .slidev-layout");
30+
observer.disconnect(); // stop observing the document body
31+
setBaseFontSize();
32+
}
33+
});
34+
35+
// Start observing the document body for layout appearance
36+
observer.observe(document.body, {
37+
childList: true,
38+
subtree: true,
39+
});
40+
41+
console.debug("[Naive] Watching for .slidev-layout element to show up");
42+
}
43+
44+
export default fontSize;

src/useConfigProvider.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,31 @@
1-
import { ref, computed } from "vue";
1+
import { ref, computed, type App } from "vue";
22
import { darkTheme, lightTheme } from "naive-ui";
3+
import { ConfigProviderInjection } from "naive-ui/es/config-provider/src/internal-interface.js";
34

4-
import useDarkTheme from "./useDarkTheme.ts";
5+
import isDark from "./useDarkTheme.ts";
6+
import baseFontSize from "./useBaseFontSize.ts";
57

6-
const useConfigProvider = (app) => {
8+
/**
9+
* I'm trying to mimic the design of original Naive UI, which can be found by
10+
* checking default theme variables or inspecting Naive UI website.
11+
*
12+
* https://www.naiveui.com/en-US/docs/theme
13+
*/
14+
15+
const themeOverrides = computed(() => ({
16+
common: {
17+
fontSize: baseFontSize.value, // regular text - 16px
18+
fontSizeMedium: baseFontSize.value, // default buttons - 16px
19+
},
20+
}));
21+
22+
const useConfigProvider = (app: App) => {
723
// Manually inject n-config-provider context
8-
const isDark = useDarkTheme();
924
app.provide("n-config-provider", {
1025
mergedThemeRef: computed(() => (isDark.value ? darkTheme : lightTheme)), // required
11-
mergedThemeOverridesRef: ref({}), // required
26+
mergedThemeOverridesRef: themeOverrides, // required
1227
mergedClsPrefixRef: ref("n"), // required for styles
13-
});
28+
} as Partial<ConfigProviderInjection>);
1429
};
1530

1631
export default useConfigProvider;

src/useDarkTheme.ts

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
1-
import { ref, type Ref } from "vue";
1+
import { ref } from "vue";
22

3-
const useDarkTheme = (): Ref<boolean> => {
4-
const isDark = ref(false);
3+
const isDark = ref(false);
54

6-
if (typeof window !== "undefined") {
7-
// Initialize with current state
8-
isDark.value = document.documentElement.classList.contains("dark");
9-
10-
// Watch for changes in the 'dark' class
11-
const observer = new MutationObserver(() => {
12-
isDark.value = document.documentElement.classList.contains("dark");
13-
});
5+
if (typeof window !== "undefined") {
6+
// Initialize with current state
7+
isDark.value = document.documentElement.classList.contains("dark");
148

15-
// Start observing the html element for class changes
16-
observer.observe(document.documentElement, {
17-
attributes: true,
18-
attributeFilter: ["class"],
19-
});
20-
}
9+
// Watch for changes in the 'dark' class
10+
const observer = new MutationObserver(() => {
11+
isDark.value = document.documentElement.classList.contains("dark");
12+
});
2113

22-
return isDark;
23-
};
14+
// Start observing the html element for class changes
15+
observer.observe(document.documentElement, {
16+
attributes: true,
17+
attributeFilter: ["class"],
18+
});
19+
}
2420

25-
export default useDarkTheme;
21+
export default isDark;

src/useInjectStyle.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const useInjectStyle = () => {
77
meta.name = name;
88
head.appendChild(meta);
99
});
10+
console.debug("[Naive] Styles injected to <head>");
1011
}
1112
};
1213

uno.config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import { defineConfig, presetWind } from "unocss";
1313
export default defineConfig({
1414
presets: [
1515
presetWind({
16-
important: ":root", // makes UnoCSS override Naive UI styles
16+
// Makes UnoCSS override Naive UI styles. This is needed for some UnoCSS
17+
// utility classes to take effect without adding ! prefix
18+
important: ":root",
1719
}),
1820
],
1921
});

0 commit comments

Comments
 (0)