Skip to content

Commit

Permalink
feat: Allow Multiple Attributes (pacocoursey#275)
Browse files Browse the repository at this point in the history
* allow multiple attributes pacocoursey#274

* allow multiple attributes pacocoursey#274

Co-authored-by: Justin Trenary <trenaryja@gmail.com>
Co-authored-by: Nathan Kamenar <nkamenar.it@gmail.com>

* Update next-themes/src/types.ts

Co-authored-by: paco <34928425+pacocoursey@users.noreply.github.com>

* Update next-themes/src/index.tsx

Co-authored-by: paco <34928425+pacocoursey@users.noreply.github.com>

---------

Co-authored-by: Nathan Kamenar <nkamenar.it@gmail.com>
Co-authored-by: paco <34928425+pacocoursey@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 20, 2024
1 parent 060a000 commit ea66771
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
24 changes: 14 additions & 10 deletions next-themes/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use client'

import * as React from 'react'
import type { UseThemeProps, ThemeProviderProps } from './types'
import { script } from './script'
import type { Attribute, ThemeProviderProps, UseThemeProps } from './types'

const colorSchemes = ['light', 'dark']
const MEDIA = '(prefers-color-scheme: dark)'
Expand Down Expand Up @@ -52,18 +52,22 @@ const Theme = ({
const enable = disableTransitionOnChange ? disableAnimation() : null
const d = document.documentElement

if (attribute === 'class') {
d.classList.remove(...attrs)

if (name) d.classList.add(name)
} else {
if (name) {
d.setAttribute(attribute, name)
} else {
d.removeAttribute(attribute)
const handleAttribute = (attr: Attribute) => {
if (attr === 'class') {
d.classList.remove(...attrs)
if (name) d.classList.add(name)
} else if (attr.startsWith('data-')) {
if (name) {
d.setAttribute(attr, name)
} else {
d.removeAttribute(attr)
}
}
}

if (Array.isArray(attribute)) attribute.forEach(handleAttribute)
else handleAttribute(attribute)

if (enableColorScheme) {
const fallback = colorSchemes.includes(defaultTheme) ? defaultTheme : null
const colorScheme = colorSchemes.includes(resolved) ? resolved : fallback
Expand Down
6 changes: 4 additions & 2 deletions next-themes/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export interface UseThemeProps {
systemTheme?: 'dark' | 'light' | undefined
}

export type Attribute = `data-${string}` | 'class'

export interface ThemeProviderProps extends React.PropsWithChildren {
/** List of all available theme names */
themes?: string[] | undefined
Expand All @@ -34,8 +36,8 @@ export interface ThemeProviderProps extends React.PropsWithChildren {
storageKey?: string | undefined
/** Default theme name (for v0.0.12 and lower the default was light). If `enableSystem` is false, the default theme is light */
defaultTheme?: string | undefined
/** HTML attribute modified based on the active theme. Accepts `class` and `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.) */
attribute?: `data-${string}` | 'class' | undefined
/** HTML attribute modified based on the active theme. Accepts `class`, `data-*` (meaning any data attribute, `data-mode`, `data-color`, etc.), or an array which could include both */
attribute?: Attribute | Attribute[] | undefined
/** Mapping of theme name to HTML attribute value. Object where key is the theme name and value is the attribute value */
value?: ValueObject | undefined
/** Nonce string to pass to the inline script for CSP headers */
Expand Down

0 comments on commit ea66771

Please sign in to comment.