-
-
Notifications
You must be signed in to change notification settings - Fork 486
URL as source of truth for preview and "Open in tweakcn" button #237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llanesluis is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThis PR refactors website preview state management by migrating input URL state from persisted store to local component state, introduces a new OpenInTweakcnButton component for linking to an external editor, updates the useWebsitePreview hook's public API, and removes inputUrl-related methods from the WebsitePreviewStore. Changes
Sequence DiagramsequenceDiagram
participant User
participant Controls
participant Hook as useWebsitePreview
participant URLParam as useQueryState
participant IFrame
User->>Controls: Enter custom URL + press Enter
Controls->>Hook: setInputValue(url)
Hook->>Hook: setInputValueHandler updates local state
Hook->>Hook: Validation & normalization
activate Hook
Note over Hook: isCustomTab = true
Hook->>URLParam: Update url param (custom tab)
Hook->>Hook: currentUrl = normalized URL
deactivate Hook
Hook->>IFrame: loadUrlIntoIframe (cache buster)
IFrame->>User: Preview updates
User->>Controls: Click Reset
Controls->>Hook: reset()
Hook->>Hook: Clear inputValue
Hook->>URLParam: Clear url param
Hook->>Hook: currentUrl = ""
IFrame->>User: Preview cleared
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
components/dynamic-website-preview.tsx(4 hunks)components/open-in-tweakcn-button.tsx(1 hunks)hooks/use-website-preview.ts(4 hunks)store/website-preview-store.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
components/open-in-tweakcn-button.tsx (1)
lib/utils.ts (1)
cn(6-8)
hooks/use-website-preview.ts (1)
store/website-preview-store.ts (1)
useWebsitePreviewStore(10-21)
| <a | ||
| href={openInTweakcnUrl} | ||
| target="_blank" | ||
| rel="noreferrer" | ||
| className={cn("gap-1", disabled && "pointer-events-none opacity-50")} | ||
| > | ||
| Open in{" "} | ||
| <svg | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| viewBox="0 0 256 256" | ||
| className="size-5 text-current" | ||
| aria-hidden="true" | ||
| > | ||
| <rect width="256" height="256" fill="none" /> | ||
|
|
||
| <line | ||
| x1="208" | ||
| y1="128" | ||
| x2="207.8" | ||
| y2="128.2" | ||
| stroke="currentColor" | ||
| stroke-linecap="round" | ||
| stroke-width="24" | ||
| /> | ||
| <line | ||
| x1="168.2" | ||
| y1="167.8" | ||
| x2="128" | ||
| y2="208" | ||
| stroke="currentColor" | ||
| stroke-linecap="round" | ||
| stroke-width="24" | ||
| /> | ||
|
|
||
| <line | ||
| x1="192" | ||
| y1="40" | ||
| x2="115.8" | ||
| y2="116.2" | ||
| stroke="currentColor" | ||
| stroke-linecap="round" | ||
| stroke-width="24" | ||
| /> | ||
| <line | ||
| x1="76.2" | ||
| y1="155.8" | ||
| x2="40" | ||
| y2="192" | ||
| stroke="currentColor" | ||
| stroke-linecap="round" | ||
| stroke-width="24" | ||
| /> | ||
|
|
||
| <circle cx="188" cy="148" r="24" fill="none" stroke="currentColor" stroke-width="24" /> | ||
| <circle cx="96" cy="136" r="24" fill="none" stroke="currentColor" stroke-width="24" /> | ||
| </svg> | ||
| <span className="sr-only">Open in tweakcn</span> | ||
| </a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disabled button still opens the link
When disabled is true we only add pointer-events-none, so the <a> keeps its href, stays focusable, and still opens via keyboard activation. Users relying on keyboard or assistive tech can’t trust the disabled state. Please strip the href (and adjust focus/ARIA) whenever the control is disabled. (fastbootstrap.com)
Apply this diff to neutralize the link when disabled:
- <a
- href={openInTweakcnUrl}
+ <a
+ href={disabled ? undefined : openInTweakcnUrl}
target="_blank"
rel="noreferrer"
- className={cn("gap-1", disabled && "pointer-events-none opacity-50")}
+ aria-disabled={disabled ? "true" : undefined}
+ tabIndex={disabled ? -1 : undefined}
+ className={cn("gap-1", disabled && "pointer-events-none opacity-50")}
>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <a | |
| href={openInTweakcnUrl} | |
| target="_blank" | |
| rel="noreferrer" | |
| className={cn("gap-1", disabled && "pointer-events-none opacity-50")} | |
| > | |
| Open in{" "} | |
| <svg | |
| xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 256 256" | |
| className="size-5 text-current" | |
| aria-hidden="true" | |
| > | |
| <rect width="256" height="256" fill="none" /> | |
| <line | |
| x1="208" | |
| y1="128" | |
| x2="207.8" | |
| y2="128.2" | |
| stroke="currentColor" | |
| stroke-linecap="round" | |
| stroke-width="24" | |
| /> | |
| <line | |
| x1="168.2" | |
| y1="167.8" | |
| x2="128" | |
| y2="208" | |
| stroke="currentColor" | |
| stroke-linecap="round" | |
| stroke-width="24" | |
| /> | |
| <line | |
| x1="192" | |
| y1="40" | |
| x2="115.8" | |
| y2="116.2" | |
| stroke="currentColor" | |
| stroke-linecap="round" | |
| stroke-width="24" | |
| /> | |
| <line | |
| x1="76.2" | |
| y1="155.8" | |
| x2="40" | |
| y2="192" | |
| stroke="currentColor" | |
| stroke-linecap="round" | |
| stroke-width="24" | |
| /> | |
| <circle cx="188" cy="148" r="24" fill="none" stroke="currentColor" stroke-width="24" /> | |
| <circle cx="96" cy="136" r="24" fill="none" stroke="currentColor" stroke-width="24" /> | |
| </svg> | |
| <span className="sr-only">Open in tweakcn</span> | |
| </a> | |
| <a | |
| href={disabled ? undefined : openInTweakcnUrl} | |
| target="_blank" | |
| rel="noreferrer" | |
| aria-disabled={disabled ? "true" : undefined} | |
| tabIndex={disabled ? -1 : undefined} | |
| className={cn("gap-1", disabled && "pointer-events-none opacity-50")} | |
| > | |
| Open in{" "} | |
| <svg | |
| xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 256 256" | |
| className="size-5 text-current" | |
| aria-hidden="true" | |
| > | |
| <rect width="256" height="256" fill="none" /> | |
| <line | |
| x1="208" | |
| y1="128" | |
| x2="207.8" | |
| y2="128.2" | |
| stroke="currentColor" | |
| stroke-linecap="round" | |
| stroke-width="24" | |
| /> | |
| <line | |
| x1="168.2" | |
| y1="167.8" | |
| x2="128" | |
| y2="208" | |
| stroke="currentColor" | |
| stroke-linecap="round" | |
| stroke-width="24" | |
| /> | |
| <line | |
| x1="192" | |
| y1="40" | |
| x2="115.8" | |
| y2="116.2" | |
| stroke="currentColor" | |
| stroke-linecap="round" | |
| stroke-width="24" | |
| /> | |
| <line | |
| x1="76.2" | |
| y1="155.8" | |
| x2="40" | |
| y2="192" | |
| stroke="currentColor" | |
| stroke-linecap="round" | |
| stroke-width="24" | |
| /> | |
| <circle cx="188" cy="148" r="24" fill="none" stroke="currentColor" stroke-width="24" /> | |
| <circle cx="96" cy="136" r="24" fill="none" stroke="currentColor" stroke-width="24" /> | |
| </svg> | |
| <span className="sr-only">Open in tweakcn</span> | |
| </a> |
🤖 Prompt for AI Agents
In components/open-in-tweakcn-button.tsx around lines 19 to 76, the anchor still
has an href when disabled so it remains focusable and can be activated by
keyboard; remove/omit the href when disabled (e.g., href={disabled ? undefined :
openInTweakcnUrl}), add aria-disabled="true" and tabIndex={disabled ? -1 : 0} so
assistive tech and keyboard users cannot activate it, and keep the visual
disabled styles (pointer-events-none/opacity-50) as-is.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Should we advertise the "Open in tweakcn" button so people know about it? |
|
Yes, I was actually gonna add it to the registry, I think that's the way. For now I was just waiting to know what you thought about it. Also, not sure if tweakcn is part of the shadcn registry directory yet ( |
|
It is! |
What does this PR do?
Uses the URL as the source of truth for custom preview tab. This way, exteral websites can add an "Open in tweakcn" button and redirect to tweakcn adding the preview URL to load in the preview.
Additions:
Changes:
Summary by CodeRabbit
New Features
Refactor