mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-29 15:44:22 +00:00
feat: implement reset shortcut (#10145)
* feat: implement reset shortcut * fix * fix
This commit is contained in:
@@ -73,7 +73,7 @@ export function MainMenu({ className }: React.ComponentProps<typeof Button>) {
|
||||
</PickerItem>
|
||||
<PickerSeparator />
|
||||
<PickerItem onClick={() => setShowResetDialog(true)}>
|
||||
Reset
|
||||
Reset <PickerShortcut>⇧R</PickerShortcut>
|
||||
</PickerItem>
|
||||
</PickerGroup>
|
||||
</PickerContent>
|
||||
|
||||
@@ -104,7 +104,7 @@ export function MenuColorPicker({
|
||||
<PickerTrigger>
|
||||
<div className="flex flex-col justify-start text-left">
|
||||
<div className="text-xs text-muted-foreground">Menu</div>
|
||||
<div className="line-clamp-1 text-sm font-medium text-foreground">
|
||||
<div className="line-clamp-1 max-w-[80%] truncate text-sm font-medium text-foreground">
|
||||
{currentMenu?.label}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
import { DARK_MODE_FORWARD_TYPE } from "@/app/(create)/components/mode-switcher"
|
||||
import { RANDOMIZE_FORWARD_TYPE } from "@/app/(create)/components/random-button"
|
||||
import { sendToIframe } from "@/app/(create)/hooks/use-iframe-sync"
|
||||
import { RESET_FORWARD_TYPE } from "@/app/(create)/hooks/use-reset"
|
||||
import {
|
||||
serializeDesignSystemSearchParams,
|
||||
useDesignSystemSearchParams,
|
||||
@@ -70,6 +71,15 @@ function handleMessage(event: MessageEvent) {
|
||||
cancelable: true,
|
||||
})
|
||||
)
|
||||
} else if (type === RESET_FORWARD_TYPE) {
|
||||
document.dispatchEvent(
|
||||
new KeyboardEvent("keydown", {
|
||||
key: "R",
|
||||
shiftKey: true,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
})
|
||||
)
|
||||
} else if (type === DARK_MODE_FORWARD_TYPE) {
|
||||
document.dispatchEvent(
|
||||
new KeyboardEvent("keydown", {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { HugeiconsIcon } from "@hugeicons/react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useRandom } from "@/app/(create)/hooks/use-random"
|
||||
import { RESET_FORWARD_TYPE } from "@/app/(create)/hooks/use-reset"
|
||||
|
||||
export const RANDOMIZE_FORWARD_TYPE = "randomize-forward"
|
||||
|
||||
@@ -40,7 +41,7 @@ export function RandomizeScript() {
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
(function() {
|
||||
// Forward R key
|
||||
// Forward r key (shuffle) and Shift+R (reset).
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if ((e.key === 'r' || e.key === 'R') && !e.metaKey && !e.ctrlKey) {
|
||||
if (
|
||||
@@ -53,8 +54,11 @@ export function RandomizeScript() {
|
||||
}
|
||||
e.preventDefault();
|
||||
if (window.parent && window.parent !== window) {
|
||||
var type = e.shiftKey
|
||||
? '${RESET_FORWARD_TYPE}'
|
||||
: '${RANDOMIZE_FORWARD_TYPE}';
|
||||
window.parent.postMessage({
|
||||
type: '${RANDOMIZE_FORWARD_TYPE}',
|
||||
type: type,
|
||||
key: e.key
|
||||
}, '*');
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ export default async function CreatePage() {
|
||||
return (
|
||||
<div
|
||||
data-slot="layout"
|
||||
className="group/layout relative z-10 flex h-svh flex-col overflow-hidden section-soft [--customizer-width:--spacing(56)] [--gap:--spacing(4)] md:[--gap:--spacing(6)]"
|
||||
className="group/layout relative z-10 flex h-svh flex-col overflow-hidden section-soft [--customizer-width:--spacing(48)] [--gap:--spacing(4)] md:[--gap:--spacing(6)] 2xl:[--customizer-width:--spacing(56)]"
|
||||
>
|
||||
<SiteHeader />
|
||||
<main
|
||||
|
||||
@@ -156,7 +156,7 @@ export function useRandom() {
|
||||
|
||||
React.useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
if ((e.key === "r" || e.key === "R") && !e.metaKey && !e.ctrlKey) {
|
||||
if (e.key === "r" && !e.shiftKey && !e.metaKey && !e.ctrlKey) {
|
||||
if (
|
||||
(e.target instanceof HTMLElement && e.target.isContentEditable) ||
|
||||
e.target instanceof HTMLInputElement ||
|
||||
|
||||
@@ -7,6 +7,7 @@ import { DEFAULT_CONFIG } from "@/registry/config"
|
||||
import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params"
|
||||
|
||||
const RESET_DIALOG_KEY = "create:reset-dialog-open"
|
||||
export const RESET_FORWARD_TYPE = "reset-forward"
|
||||
|
||||
export function useReset() {
|
||||
const [params, setParams] = useDesignSystemSearchParams()
|
||||
@@ -32,9 +33,9 @@ export function useReset() {
|
||||
menuColor: DEFAULT_CONFIG.menuColor,
|
||||
radius: DEFAULT_CONFIG.radius,
|
||||
template: DEFAULT_CONFIG.template,
|
||||
item: "preview",
|
||||
item: params.item,
|
||||
})
|
||||
}, [setParams, params.base])
|
||||
}, [setParams, params.base, params.item])
|
||||
|
||||
const handleShowResetDialogChange = React.useCallback(
|
||||
(open: boolean) => {
|
||||
@@ -48,6 +49,46 @@ export function useReset() {
|
||||
void setShowResetDialogData(false, { revalidate: false })
|
||||
}, [reset, setShowResetDialogData])
|
||||
|
||||
const showResetDialogRef = React.useRef(showResetDialog)
|
||||
React.useEffect(() => {
|
||||
showResetDialogRef.current = showResetDialog
|
||||
}, [showResetDialog])
|
||||
|
||||
const confirmResetRef = React.useRef(confirmReset)
|
||||
React.useEffect(() => {
|
||||
confirmResetRef.current = confirmReset
|
||||
}, [confirmReset])
|
||||
|
||||
React.useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
if (e.key === "R" && e.shiftKey && !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 the dialog is already open, confirm the reset.
|
||||
if (showResetDialogRef.current) {
|
||||
confirmResetRef.current()
|
||||
return
|
||||
}
|
||||
|
||||
handleShowResetDialogChange(true)
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", down)
|
||||
return () => {
|
||||
document.removeEventListener("keydown", down)
|
||||
}
|
||||
}, [handleShowResetDialogChange])
|
||||
|
||||
return {
|
||||
reset,
|
||||
showResetDialog,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import path from "path"
|
||||
import { createMDX } from "fumadocs-mdx/next"
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
@@ -25,6 +26,9 @@ const nextConfig = {
|
||||
},
|
||||
],
|
||||
},
|
||||
turbopack: {
|
||||
root: path.resolve(import.meta.dirname, "../.."),
|
||||
},
|
||||
experimental: {
|
||||
turbopackFileSystemCacheForDev: true,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user