mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-26 06:05:56 +00:00
* feat: init * fix * fix * fix * feat * feat * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * feat: implement icons * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * feat: update init command * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * feat: dialog * feat * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * feat: add registry:base item type * feat: rename frame to canva * fix * feat * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fi * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * feat: add all colors * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * fix * feat: add outfit font * fix * fix * fix * fix * fix * chore: changeset * fix * fix * fix * fix * fix * fix * fix * fix
124 lines
3.6 KiB
TypeScript
124 lines
3.6 KiB
TypeScript
"use client"
|
|
|
|
import * as React from "react"
|
|
import Script from "next/script"
|
|
import { useTheme } from "next-themes"
|
|
|
|
import { useMetaColor } from "@/hooks/use-meta-color"
|
|
import { Button } from "@/registry/new-york-v4/ui/button"
|
|
import { Kbd } from "@/registry/new-york-v4/ui/kbd"
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipTrigger,
|
|
} from "@/registry/new-york-v4/ui/tooltip"
|
|
|
|
export const DARK_MODE_FORWARD_TYPE = "dark-mode-forward"
|
|
|
|
export function ModeSwitcher() {
|
|
const { setTheme, resolvedTheme } = useTheme()
|
|
const { setMetaColor, metaColor } = useMetaColor()
|
|
|
|
React.useEffect(() => {
|
|
setMetaColor(metaColor)
|
|
}, [metaColor, setMetaColor])
|
|
|
|
const toggleTheme = React.useCallback(() => {
|
|
setTheme(resolvedTheme === "dark" ? "light" : "dark")
|
|
}, [resolvedTheme, setTheme])
|
|
|
|
React.useEffect(() => {
|
|
const down = (e: KeyboardEvent) => {
|
|
if ((e.key === "d" || e.key === "D") && !e.metaKey && !e.ctrlKey) {
|
|
if (
|
|
(e.target instanceof HTMLElement && e.target.isContentEditable) ||
|
|
e.target instanceof HTMLInputElement ||
|
|
e.target instanceof HTMLTextAreaElement ||
|
|
e.target instanceof HTMLSelectElement
|
|
) {
|
|
return
|
|
}
|
|
|
|
e.preventDefault()
|
|
toggleTheme()
|
|
}
|
|
}
|
|
|
|
document.addEventListener("keydown", down)
|
|
return () => document.removeEventListener("keydown", down)
|
|
}, [toggleTheme])
|
|
|
|
return (
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="group/toggle extend-touch-target size-8"
|
|
onClick={toggleTheme}
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
className="size-4.5"
|
|
>
|
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" />
|
|
<path d="M12 3l0 18" />
|
|
<path d="M12 9l4.65 -4.65" />
|
|
<path d="M12 14.3l7.37 -7.37" />
|
|
<path d="M12 19.6l8.85 -8.85" />
|
|
</svg>
|
|
<span className="sr-only">Toggle theme</span>
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent className="flex items-center gap-2 pr-1">
|
|
Toggle Mode <Kbd>D</Kbd>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
)
|
|
}
|
|
|
|
export function DarkModeScript() {
|
|
return (
|
|
<Script
|
|
id="dark-mode-listener"
|
|
strategy="beforeInteractive"
|
|
dangerouslySetInnerHTML={{
|
|
__html: `
|
|
(function() {
|
|
// Forward D key
|
|
document.addEventListener('keydown', function(e) {
|
|
if ((e.key === 'd' || e.key === 'D') && !e.metaKey && !e.ctrlKey) {
|
|
if (
|
|
(e.target instanceof HTMLElement && e.target.isContentEditable) ||
|
|
e.target instanceof HTMLInputElement ||
|
|
e.target instanceof HTMLTextAreaElement ||
|
|
e.target instanceof HTMLSelectElement
|
|
) {
|
|
return;
|
|
}
|
|
e.preventDefault();
|
|
if (window.parent && window.parent !== window) {
|
|
window.parent.postMessage({
|
|
type: '${DARK_MODE_FORWARD_TYPE}',
|
|
key: e.key
|
|
}, '*');
|
|
}
|
|
}
|
|
});
|
|
|
|
})();
|
|
`,
|
|
}}
|
|
/>
|
|
)
|
|
}
|