Skip to content

Commit

Permalink
feat(nextra-theme-docs): support custom primary color saturation (#2281)
Browse files Browse the repository at this point in the history
Co-authored-by: Dimitri POSTOLOV <en3m@ya.ru>
Co-authored-by: Dimitri POSTOLOV <dmytropostolov@gmail.com>
  • Loading branch information
3 people authored Sep 24, 2023
1 parent a2d09c9 commit 7aec7bb
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 28 deletions.
5 changes: 5 additions & 0 deletions .changeset/dirty-papayas-relax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'nextra-theme-docs': minor
---

add `primarySaturation` theme option
2 changes: 2 additions & 0 deletions docs/pages/docs/docs-theme/api/use-config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ context.
- `notFound`: data to display when the page is not found
- `primaryHue`: data about
[Theme Color](/docs/docs-theme/theme-configuration#theme-color)
- `primarySaturation`: data about
[Theme Color](/docs/docs-theme/theme-configuration#theme-color)
- `project`: data about
[Project Link](/docs/docs-theme/theme-configuration#project-link)
- `search`: data about [Search](/docs/docs-theme/theme-configuration#search)
Expand Down
69 changes: 50 additions & 19 deletions docs/pages/docs/docs-theme/theme-configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -193,38 +193,69 @@ Customize the theme behavior of the website.

### Theme Color

You can adjust the theme color of the website by setting a primary hue value to
dark or light themes.
You can adjust the theme color of the website by setting primary hue and
saturation values for light and dark themes.

<OptionTable
options={[
[
'primaryHue',
'number | { dark: number; light: number }',
'The hue of the primary theme color.'
],
[
'primarySaturation',
'number | { dark: number; light: number }',
'The saturation of the primary theme color.'
]
]}
/>

Try it out for this website:

<div className="mt-4 flex h-6 items-center gap-2">
<input
type="range"
min="0"
max="360"
step="1"
onChange={e => {
const hue = e.target.value
document.documentElement.style.setProperty(
'--nextra-primary-hue',
hue + 'deg'
)
document.getElementById('test-theme-hue').innerText = hue
}}
/>
<code id="test-theme-hue" className="text-sm text-gray-500"></code>
</div>
| Hue | Saturation |
| ----- | ------------ |
| {hue} | {saturation} |

export const hue = (
<div className="flex h-6 items-center gap-2">
<input
type="range"
min="0"
max="360"
step="1"
onChange={e => {
const value = `${e.target.value}deg`
e.target.nextSibling.textContent = value
document.documentElement.style.setProperty(
'--nextra-primary-hue',
value
)
}}
/>
<code className="w-14 text-sm text-gray-500" />
</div>
)

export const saturation = (
<div className="flex h-6 items-center gap-2">
<input
type="range"
min="0"
max="100"
step="1"
onChange={e => {
const value = `${e.target.value}%`
e.target.nextSibling.textContent = value
document.documentElement.style.setProperty(
'--nextra-primary-saturation',
value
)
}}
/>
<code className="text-sm text-gray-500 w-14" />
</div>
)

## Navbar

Expand Down
3 changes: 2 additions & 1 deletion docs/pages/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ a.cta:active span {
transform: translateX(5px);
}
a.cta:focus-visible {
outline: 2px solid hsl(var(--nextra-primary-hue) 100% 77%);
outline: 2px solid
hsl(var(--nextra-primary-hue) var(--nextra-primary-saturation) 77%);
outline-offset: 2px;
}
a.cta:focus-visible span {
Expand Down
9 changes: 7 additions & 2 deletions docs/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ body {
}

.home-content a {
--tw-ring-color: hsl(var(--nextra-primary-hue) 100% 50%/0.3);
--tw-ring-color: hsl(
var(--nextra-primary-hue) var(--nextra-primary-saturation) 50%/0.3
);
--tw-text-opacity: 1;
text-underline-position: under;
text-decoration-line: underline;
text-decoration-thickness: from-font;
color: hsl(var(--nextra-primary-hue) 100% 50% / var(--tw-text-opacity));
color: hsl(
var(--nextra-primary-hue) var(--nextra-primary-saturation) 50% /
var(--tw-text-opacity)
);
}

figcaption {
Expand Down
2 changes: 1 addition & 1 deletion examples/swr-site/pages/blog.en-US.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function Page() {
{page.frontMatter?.description}
<Link
href={page.route}
className="block text-[color:hsl(var(--nextra-primary-hue),100%,50%)] underline underline-offset-2 decoration-from-font"
className="block nx-text-primary-600 underline underline-offset-2 decoration-from-font"
>
Read more →
</Link>
Expand Down
8 changes: 7 additions & 1 deletion packages/nextra-theme-docs/src/components/head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ export function Head(): ReactElement {
// `head` can be either FC or ReactNode. We have to directly call it if it's an
// FC because hooks like Next.js' `useRouter` aren't allowed inside NextHead.
const head = typeof config.head === 'function' ? config.head({}) : config.head
const hue = config.primaryHue
const { primaryHue: hue, primarySaturation: saturation } = config
const { dark: darkHue, light: lightHue } =
typeof hue === 'number' ? { dark: hue, light: hue } : hue
const { dark: darkSaturation, light: lightSaturation } =
typeof saturation === 'number'
? { dark: saturation, light: saturation }
: saturation
const frontMatter = config.frontMatter as NextSeoProps

return (
Expand Down Expand Up @@ -61,13 +65,15 @@ export function Head(): ReactElement {
<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>
{head}
Expand Down
10 changes: 10 additions & 0 deletions packages/nextra-theme-docs/src/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ export const themeSchema = z.strictObject({
light: z.number()
})
),
primarySaturation: z.number().or(
z.strictObject({
dark: z.number(),
light: z.number()
})
),
project: z.strictObject({
icon: z.custom<ReactNode | FC>(...reactNode),
link: z.string().startsWith('https://').optional()
Expand Down Expand Up @@ -276,6 +282,10 @@ export const DEFAULT_THEME: DocsThemeConfig = {
dark: 204,
light: 212
},
primarySaturation: {
dark: 100,
light: 100
},
project: {
icon: (
<>
Expand Down
8 changes: 4 additions & 4 deletions packages/nextra-theme-docs/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ const colors = require('tailwindcss/colors')
const makePrimaryColor =
l =>
({ opacityValue }) => {
if (opacityValue === undefined) {
return `hsl(var(--nextra-primary-hue) 100% ${l}%)`
}
return `hsl(var(--nextra-primary-hue) 100% ${l}% / ${opacityValue})`
return (
`hsl(var(--nextra-primary-hue) var(--nextra-primary-saturation) ${l}%` +
(opacityValue ? ` / ${opacityValue})` : ')')
)
}

/** @type {import('tailwindcss').Config} */
Expand Down

1 comment on commit 7aec7bb

@vercel
Copy link

@vercel vercel bot commented on 7aec7bb Sep 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.