Skip to content

Commit b776b16

Browse files
author
Dimitri POSTOLOV
authoredFeb 21, 2024
[v3] add backgroundColor.light and backgroundColor.dark theme options (#2732)
* add `--nextra-bg` css variable * more * more * add `backgroundColor.light`, `backgroundColor.dark` theme options * aa * prettier * fix steps styles * f11x * fix typecheck * fix blog styles * prettier
1 parent 7b4104c commit b776b16

File tree

21 files changed

+108
-82
lines changed

21 files changed

+108
-82
lines changed
 

‎.changeset/odd-kangaroos-occur.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'nextra-theme-docs': minor
3+
---
4+
5+
add `backgroundColor.light` and `backgroundColor.dark` theme options

‎.eslintrc.cjs

+5-6
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ module.exports = {
139139
plugins: ['typescript-sort-keys'],
140140
settings: {
141141
tailwindcss: {
142-
config: 'packages/nextra-theme-docs/tailwind.config.js',
142+
config: 'packages/nextra-theme-docs/tailwind.config.ts',
143143
callees: ['cn'],
144144
whitelist: [
145145
'nextra-breadcrumb',
@@ -166,7 +166,7 @@ module.exports = {
166166
files: 'packages/nextra-theme-blog/**',
167167
settings: {
168168
tailwindcss: {
169-
config: 'packages/nextra-theme-blog/tailwind.config.js',
169+
config: 'packages/nextra-theme-blog/tailwind.config.ts',
170170
whitelist: ['subheading-', 'post-item', 'post-item-more']
171171
}
172172
}
@@ -177,7 +177,7 @@ module.exports = {
177177
files: 'packages/nextra/**',
178178
settings: {
179179
tailwindcss: {
180-
config: 'packages/nextra-theme-docs/tailwind.config.js',
180+
config: 'packages/nextra-theme-docs/tailwind.config.ts',
181181
callees: ['cn'],
182182
whitelist: ['nextra-code', 'nextra-filetree']
183183
}
@@ -193,7 +193,7 @@ module.exports = {
193193
files: 'docs/**',
194194
settings: {
195195
tailwindcss: {
196-
config: 'docs/tailwind.config.js',
196+
config: 'docs/tailwind.config.ts',
197197
callees: ['cn'],
198198
whitelist: [
199199
'dash-ring',
@@ -217,7 +217,7 @@ module.exports = {
217217
files: 'examples/swr-site/**',
218218
settings: {
219219
tailwindcss: {
220-
config: 'examples/swr-site/tailwind.config.js',
220+
config: 'examples/swr-site/tailwind.config.ts',
221221
cssFiles: [
222222
'examples/swr-site/styles.css',
223223
'packages/nextra-theme-docs/dist/style.css'
@@ -244,7 +244,6 @@ module.exports = {
244244
files: [
245245
'prettier.config.js',
246246
'postcss.config.{js,cjs}',
247-
'tailwind.config.{js,cjs}',
248247
'next.config.js',
249248
'.eslintrc.cjs'
250249
],
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
/** @type {import('tailwindcss').Config} */
2-
module.exports = {
1+
import type { Config } from 'tailwindcss'
2+
3+
export default {
34
content: [
45
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
56
'./components/**/*.{js,ts,jsx,tsx}',
@@ -10,4 +11,4 @@ module.exports = {
1011
},
1112
plugins: [],
1213
darkMode: 'class'
13-
}
14+
} satisfies Config

‎examples/swr-site/styles.css

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@ body {
99
linear-gradient(
1010
to bottom,
1111
rgba(255, 255, 255, 0) 0%,
12-
rgba(255, 255, 255, 1) 300px
12+
rgb(var(--nextra-bg)) 300px
1313
),
1414
fixed 0 0 / 20px 20px radial-gradient(#d1d1d1 1px, transparent 0),
1515
fixed 10px 10px / 20px 20px radial-gradient(#d1d1d1 1px, transparent 0);
1616
}
1717

1818
.dark body {
1919
background:
20-
linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, #111 300px),
20+
linear-gradient(
21+
to bottom,
22+
rgba(0, 0, 0, 0) 0%,
23+
rgb(var(--nextra-bg)) 300px
24+
),
2125
fixed 0 0 / 20px 20px radial-gradient(#313131 1px, transparent 0),
2226
fixed 10px 10px / 20px 20px radial-gradient(#313131 1px, transparent 0);
2327
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
/** @type {import('tailwindcss').Config} */
2-
module.exports = {
1+
import type { Config } from 'tailwindcss'
2+
3+
export default {
34
darkMode: 'class',
45
content: ['./{components,pages}/**/*.{mdx,tsx}', './theme.config.tsx']
5-
}
6+
} satisfies Config

‎examples/swr-site/theme.config.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ const FOOTER_LINK_TEXT = {
6262
}
6363

6464
const config: DocsThemeConfig = {
65+
backgroundColor: {
66+
dark: '15,23,42',
67+
light: '254,252,232'
68+
},
6569
banner: {
6670
content: 'SWR 2.0 is out! Read more →',
6771
key: 'swr-2'

‎packages/nextra-theme-blog/src/index.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ export default function NextraLayout({
5959
<Head>
6060
<title>{title}</title>
6161
{config.head?.({ title, meta: frontMatter })}
62+
<style>
63+
{':root{--nextra-bg:250,250,250;}.dark{--nextra-bg:17,17,17;}'}
64+
</style>
6265
</Head>
6366
<BlogProvider value={{ config, opts: pageOpts }}>
6467
<article

‎packages/nextra-theme-blog/src/styles.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ html {
1212
}
1313

1414
body {
15-
@apply _px-4;
15+
@apply _px-4 _bg-[rgb(var(--nextra-bg))];
1616
}
1717

1818
article {

‎packages/nextra-theme-blog/tailwind.config.js ‎packages/nextra-theme-blog/tailwind.config.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
const colors = require('tailwindcss/colors')
2-
const docsConfig = require('../nextra-theme-docs/tailwind.config')
1+
import typography from '@tailwindcss/typography'
2+
import type { Config } from 'tailwindcss'
3+
import colors from 'tailwindcss/colors'
4+
import docsConfig from '../nextra-theme-docs/tailwind.config'
35

4-
/** @type {import('tailwindcss').Config} */
5-
module.exports = {
6+
export default {
67
prefix: docsConfig.prefix,
78
content: docsConfig.content,
89
theme: {
@@ -11,8 +12,7 @@ module.exports = {
1112
primary: colors.blue
1213
},
1314
extend: {
14-
colors: docsConfig.theme.extend.colors,
15-
typography: theme => ({
15+
typography: (theme: (str: string) => string) => ({
1616
dark: {
1717
css: {
1818
color: theme('colors.gray[300]'),
@@ -50,6 +50,6 @@ module.exports = {
5050
typography: ['dark']
5151
}
5252
},
53-
plugins: [require('@tailwindcss/typography')],
53+
plugins: [typography],
5454
darkMode: docsConfig.darkMode
55-
}
55+
} satisfies Config

‎packages/nextra-theme-docs/css/styles.css

+38-13
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ html {
1919
}
2020

2121
body {
22-
@apply _w-full _bg-white dark:_bg-dark dark:_text-gray-100;
22+
@apply _w-full dark:_text-gray-100;
2323
}
2424

2525
a,
@@ -44,7 +44,7 @@ summary {
4444

4545
@media (max-width: 767px) {
4646
.nextra-sidebar-container {
47-
@apply _fixed _pt-[calc(var(--nextra-navbar-height))] _top-0 _w-full _bottom-0 _z-[15] _overscroll-contain _bg-white dark:_bg-dark;
47+
@apply _fixed _pt-[calc(var(--nextra-navbar-height))] _top-0 _w-full _bottom-0 _z-[15] _overscroll-contain;
4848
transition: transform 0.8s cubic-bezier(0.52, 0.16, 0.04, 1);
4949
will-change: transform, opacity;
5050
contain: layout style;
@@ -103,17 +103,6 @@ summary::-webkit-details-marker {
103103
}
104104
}
105105

106-
@supports (
107-
(-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))
108-
) {
109-
.nextra-search ul {
110-
@apply _backdrop-blur-lg _bg-white/70 dark:_bg-dark/80;
111-
}
112-
.nextra-nav-container-blur {
113-
@apply _backdrop-blur-md _bg-white/[.85] dark:!_bg-dark/80;
114-
}
115-
}
116-
117106
input[type='search'] {
118107
&::-webkit-search-decoration,
119108
&::-webkit-search-cancel-button,
@@ -166,3 +155,39 @@ input[type='search'] {
166155
opacity: 1;
167156
}
168157
}
158+
159+
body,
160+
.nextra-nav-container-blur,
161+
.nextra-toc-footer,
162+
.nextra-sidebar-footer {
163+
@apply _bg-[rgb(var(--nextra-bg))];
164+
}
165+
.nextra-sidebar-container {
166+
@apply max-md:_bg-[rgb(var(--nextra-bg))];
167+
}
168+
169+
.nextra-nav-container-blur {
170+
@apply _pointer-events-none _absolute _z-[-1] _size-full;
171+
@apply _shadow-[0_2px_4px_rgba(0,0,0,.02),0_1px_0_rgba(0,0,0,.06)];
172+
@apply dark:_shadow-[0_-1px_0_rgba(255,255,255,.1)_inset];
173+
@apply contrast-more:_shadow-[0_0_0_1px_#000];
174+
@apply contrast-more:dark:_shadow-[0_0_0_1px_#fff];
175+
@apply _backdrop-blur-md _bg-[rgba(var(--nextra-bg),.7)];
176+
}
177+
178+
.nextra-toc-footer,
179+
.nextra-sidebar-footer {
180+
@apply _border-t dark:_border-neutral-800;
181+
@apply contrast-more:_shadow-none contrast-more:_border-neutral-400 contrast-more:dark:_border-neutral-400;
182+
@apply _shadow-[0_-12px_16px_rgb(var(--nextra-bg))];
183+
}
184+
185+
.nextra-search-results {
186+
@apply _border _border-gray-200 _text-gray-100 dark:_border-neutral-800;
187+
@apply _absolute _top-full _z-20 _mt-2 _overflow-auto _overscroll-contain _rounded-xl _py-2.5 _shadow-xl;
188+
@apply _max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)];
189+
@apply md:_max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)];
190+
@apply _inset-x-0 ltr:md:_left-auto rtl:md:_right-auto;
191+
@apply contrast-more:_border contrast-more:_border-gray-900 contrast-more:dark:_border-gray-50;
192+
@apply _backdrop-blur-lg _bg-[rgb(var(--nextra-bg),.8)];
193+
}

‎packages/nextra-theme-docs/src/components/head.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export function Head(): ReactElement {
2323
? { dark: saturation, light: saturation }
2424
: saturation
2525

26+
const bgColor = themeConfig.backgroundColor
27+
2628
return (
2729
<NextHead>
2830
{themeConfig.faviconGlyph ? (
@@ -54,7 +56,7 @@ export function Head(): ReactElement {
5456
name="viewport"
5557
content="width=device-width, initial-scale=1.0, viewport-fit=cover"
5658
/>
57-
<style>{`:root{--nextra-primary-hue:${lightHue}deg;--nextra-primary-saturation:${lightSaturation}%;--nextra-navbar-height:4rem;--nextra-menu-height:3.75rem;--nextra-banner-height:2.5rem;}.dark{--nextra-primary-hue:${darkHue}deg;--nextra-primary-saturation:${darkSaturation}%;}`}</style>
59+
<style>{`:root{--nextra-primary-hue:${lightHue}deg;--nextra-primary-saturation:${lightSaturation}%;--nextra-navbar-height:4rem;--nextra-menu-height:3.75rem;--nextra-banner-height:2.5rem;--nextra-bg:${bgColor.light};}.dark{--nextra-primary-hue:${darkHue}deg;--nextra-primary-saturation:${darkSaturation}%;--nextra-bg:${bgColor.dark};}`}</style>
5860
{head}
5961
</NextHead>
6062
)

‎packages/nextra-theme-docs/src/components/input.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
1212
spellCheck={false}
1313
className={cn(
1414
className,
15-
'_block _w-full _appearance-none _rounded-lg _px-3 _py-2 _transition-colors',
15+
'_w-full _appearance-none _rounded-lg _px-3 _py-2 _transition-colors',
1616
'_text-base _leading-tight md:_text-sm',
1717
'_bg-black/[.05] dark:_bg-gray-50/10',
18-
'focus:_bg-white dark:focus:_bg-dark',
18+
'focus:!_bg-transparent',
1919
'placeholder:_text-gray-500 dark:placeholder:_text-gray-400',
2020
'contrast-more:_border contrast-more:_border-current'
2121
)}

‎packages/nextra-theme-docs/src/components/navbar.tsx

+1-8
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,7 @@ export function Navbar({ items }: NavBarProps): ReactElement {
8686

8787
return (
8888
<div className="nextra-nav-container _sticky _top-0 _z-20 _w-full _bg-transparent print:_hidden">
89-
<div
90-
className={cn(
91-
'nextra-nav-container-blur',
92-
'_pointer-events-none _absolute _z-[-1] _size-full _bg-white dark:_bg-dark',
93-
'_shadow-[0_2px_4px_rgba(0,0,0,.02),0_1px_0_rgba(0,0,0,.06)] dark:_shadow-[0_-1px_0_rgba(255,255,255,.1)_inset]',
94-
'contrast-more:_shadow-[0_0_0_1px_#000] contrast-more:dark:_shadow-[0_0_0_1px_#fff]'
95-
)}
96-
/>
89+
<div className="nextra-nav-container-blur" />
9790
<nav className="_mx-auto _flex _h-[var(--nextra-navbar-height)] _max-w-[90rem] _items-center _justify-end _gap-4 _pl-[max(env(safe-area-inset-left),1.5rem)] _pr-[max(env(safe-area-inset-right),1.5rem)]">
9891
{themeConfig.logoLink ? (
9992
<NextLink

‎packages/nextra-theme-docs/src/components/search.tsx

+2-9
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export function Search({
161161
className={cn(
162162
'_absolute _my-1.5 _select-none ltr:_right-1.5 rtl:_left-1.5',
163163
'_h-5 _rounded _bg-white _px-1.5 _font-mono _text-[10px] _font-medium _text-gray-500',
164-
'_border dark:_border-gray-100/20 dark:_bg-dark/50',
164+
'_border dark:_border-gray-100/20 dark:_bg-black/50',
165165
'contrast-more:_border-current contrast-more:_text-current contrast-more:dark:_border-current',
166166
'_items-center _gap-1 _transition-opacity _flex',
167167
value
@@ -232,14 +232,7 @@ export function Search({
232232
>
233233
<ul
234234
className={cn(
235-
'nextra-scrollbar',
236-
// Using bg-white as background-color when the browser didn't support backdrop-filter
237-
'_border _border-gray-200 _bg-white _text-gray-100 dark:_border-neutral-800 dark:_bg-neutral-900',
238-
'_absolute _top-full _z-20 _mt-2 _overflow-auto _overscroll-contain _rounded-xl _py-2.5 _shadow-xl',
239-
'_max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)]',
240-
'md:_max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)]',
241-
'_inset-x-0 ltr:md:_left-auto rtl:md:_right-auto',
242-
'contrast-more:_border contrast-more:_border-gray-900 contrast-more:dark:_border-gray-50',
235+
'nextra-search-results nextra-scrollbar',
243236
overlayClassName
244237
)}
245238
ref={ulRef}

‎packages/nextra-theme-docs/src/components/sidebar.tsx

+3-7
Original file line numberDiff line numberDiff line change
@@ -441,14 +441,10 @@ export function Sidebar({
441441
{hasMenu && (
442442
<div
443443
className={cn(
444-
'_sticky _bottom-0',
445-
'_bg-white dark:_bg-dark', // when banner is showed, sidebar links can be behind menu, set bg color as body bg color
446-
'_mx-4 _py-4 _shadow-[0_-12px_16px_#fff]',
447-
'_flex _items-center _gap-2',
448-
'dark:_border-neutral-800 dark:_shadow-[0_-12px_16px_#111]',
449-
'contrast-more:_border-neutral-400 contrast-more:_shadow-none contrast-more:dark:_shadow-none',
444+
'nextra-sidebar-footer _sticky _bottom-0',
445+
'_flex _items-center _gap-2 _mx-4 _py-4',
450446
showSidebar
451-
? cn(hasI18n && '_justify-end', '_border-t')
447+
? hasI18n && '_justify-end'
452448
: '_py-4 _flex-wrap _justify-center'
453449
)}
454450
data-toggle-animation={

‎packages/nextra-theme-docs/src/components/toc.tsx

+2-4
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,8 @@ export function TOC({ toc, filePath }: TOCProps): ReactElement {
9494
{hasMetaInfo && (
9595
<div
9696
className={cn(
97-
hasHeadings &&
98-
'_mt-8 _border-t _bg-white _pt-8 _shadow-[0_-12px_16px_white] dark:_bg-dark dark:_shadow-[0_-12px_16px_#111]',
99-
'_sticky _bottom-0 _flex _flex-col _items-start _gap-2 _pb-8 dark:_border-neutral-800',
100-
'contrast-more:_border-t contrast-more:_border-neutral-400 contrast-more:_shadow-none contrast-more:dark:_border-neutral-400'
97+
hasHeadings && 'nextra-toc-footer _mt-8 _pt-8',
98+
'_sticky _bottom-0 _flex _flex-col _items-start _gap-2 _pb-8'
10199
)}
102100
>
103101
{themeConfig.feedback.content ? (

‎packages/nextra-theme-docs/src/constants.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ const PLACEHOLDER_LOCALES: Record<string, string> = {
3737
}
3838

3939
export const DEFAULT_THEME: DocsThemeConfig = {
40+
backgroundColor: {
41+
dark: '17,17,17',
42+
light: '250,250,250'
43+
},
4044
banner: {
4145
dismissible: true,
4246
key: 'nextra-banner'

‎packages/nextra-theme-docs/src/schemas.ts

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ export const themeSchema = /* @__PURE__ */ (() =>
2727
dismissible: z.boolean(),
2828
key: z.string()
2929
}),
30+
backgroundColor: z.strictObject({
31+
dark: z.string(),
32+
light: z.string()
33+
}),
3034
chat: z.strictObject({
3135
icon: z.custom<ReactNode | FC>(...reactNode),
3236
link: z.string().startsWith('https://').optional()

0 commit comments

Comments
 (0)
Please sign in to comment.