Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/quiet-demo-surfaces.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@tanstack/create": patch
"@tanstack/cli": patch
---

Normalize generated demo pages to use the base template styling instead of bespoke full-page gradients and mismatched color treatments.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function Messages({ messages }: { messages: ChatMessages }) {

if (!messages.length) {
return (
<div className="flex-1 flex items-center justify-center text-gray-400 text-sm">
<div className="demo-muted flex flex-1 items-center justify-center text-sm">
Ask me anything! I'm here to help.
</div>
)
Expand All @@ -36,25 +36,23 @@ function Messages({ messages }: { messages: ChatMessages }) {
<div
key={id}
className={`py-3 ${
role === 'assistant'
? 'bg-linear-to-r from-orange-500/5 to-red-600/5'
: 'bg-transparent'
role === 'assistant' ? 'bg-[var(--chip-bg)]' : 'bg-transparent'
}`}
>
{parts.map((part, index) => {
if (part.type === 'text' && part.content) {
return (
<div key={index} className="flex items-start gap-2 px-4">
{role === 'assistant' ? (
<div className="w-6 h-6 rounded-lg bg-linear-to-r from-orange-500 to-red-600 flex items-center justify-center text-xs font-medium text-white flex-shrink-0">
<div className="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-lg bg-[var(--lagoon-deep)] text-xs font-medium text-white">
AI
</div>
) : (
<div className="w-6 h-6 rounded-lg bg-gray-700 flex items-center justify-center text-xs font-medium text-white flex-shrink-0">
<div className="flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-lg bg-[var(--sea-ink-soft)] text-xs font-medium text-white">
Y
</div>
)}
<div className="flex-1 min-w-0 text-white prose dark:prose-invert max-w-none prose-sm">
<div className="min-w-0 flex-1 max-w-none text-sm text-[var(--sea-ink)]">
<Streamdown>{part.content}</Streamdown>
</div>
</div>
Expand Down Expand Up @@ -87,7 +85,7 @@ export default function AIAssistant() {
<div className="relative z-50">
<button
onClick={() => showAIAssistant.setState((state) => !state)}
className="w-full flex items-center justify-between px-4 py-2.5 rounded-lg bg-linear-to-r from-green-700 to-green-900 text-white hover:opacity-90 transition-opacity"
className="demo-button w-full justify-between px-4 py-2.5"
>
<div className="flex items-center gap-2">
<BotIcon size={24} />
Expand All @@ -97,20 +95,22 @@ export default function AIAssistant() {
</button>

{isOpen && (
<div className="absolute bottom-0 left-full ml-2 w-[700px] h-[600px] bg-gray-900 rounded-lg shadow-xl border border-orange-500/20 flex flex-col">
<div className="flex items-center justify-between p-3 border-b border-orange-500/20">
<h3 className="font-semibold text-white">AI Assistant</h3>
<div className="demo-panel absolute bottom-0 left-full ml-2 flex h-[600px] w-[700px] flex-col overflow-hidden p-0">
<div className="flex items-center justify-between border-b border-[var(--line)] p-3">
<h3 className="font-semibold text-[var(--sea-ink)]">
AI Assistant
</h3>
<button
onClick={() => showAIAssistant.setState((state) => !state)}
className="text-gray-400 hover:text-white transition-colors"
className="demo-muted transition-colors hover:text-[var(--sea-ink)]"
>
<X className="w-4 h-4" />
</button>
</div>

<Messages messages={messages} />

<div className="p-3 border-t border-orange-500/20">
<div className="border-t border-[var(--line)] p-3">
<form
onSubmit={(e) => {
e.preventDefault()
Expand All @@ -125,7 +125,7 @@ export default function AIAssistant() {
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type your message..."
className="w-full rounded-lg border border-orange-500/20 bg-gray-800/50 pl-3 pr-10 py-2 text-sm text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-orange-500/50 focus:border-transparent resize-none overflow-hidden"
className="demo-textarea pr-10 text-sm"
rows={1}
style={{ minHeight: '36px', maxHeight: '120px' }}
onInput={(e) => {
Expand All @@ -145,7 +145,7 @@ export default function AIAssistant() {
<button
type="submit"
disabled={!input.trim()}
className="absolute right-2 top-1/2 -translate-y-1/2 p-1.5 text-orange-500 hover:text-orange-400 disabled:text-gray-500 transition-colors focus:outline-none"
className="absolute right-2 top-1/2 -translate-y-1/2 p-1.5 text-[var(--lagoon-deep)] transition-colors hover:text-[var(--sea-ink)] disabled:text-[var(--sea-ink-soft)]"
>
<Send className="w-4 h-4" />
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default function GuitarRecommendation({ id }: { id: string }) {
return null
}
return (
<div className="my-4 rounded-lg overflow-hidden border border-orange-500/20 bg-gray-800/50">
<div className="demo-card my-4 overflow-hidden p-0">
<div className="aspect-[4/3] relative overflow-hidden">
<img
src={guitar.image}
Expand All @@ -20,23 +20,25 @@ export default function GuitarRecommendation({ id }: { id: string }) {
/>
</div>
<div className="p-4">
<h3 className="text-lg font-semibold text-white mb-2">{guitar.name}</h3>
<p className="text-sm text-gray-300 mb-3 line-clamp-2">
<h3 className="mb-2 text-lg font-semibold text-[var(--sea-ink)]">
{guitar.name}
</h3>
<p className="demo-muted mb-3 line-clamp-2 text-sm">
{guitar.shortDescription}
</p>
<div className="flex items-center justify-between">
<div className="text-lg font-bold text-emerald-400">
<div className="text-lg font-bold text-[var(--lagoon-deep)]">
${guitar.price}
</div>
<button
onClick={() => {
navigate({
to: '/example/guitars/$guitarId',
to: '/demo/guitars/$guitarId',
params: { guitarId: guitar.id.toString() },
})
showAIAssistant.setState(() => false)
}}
className="bg-gradient-to-r from-orange-500 to-red-600 text-white px-4 py-1.5 rounded-lg text-sm hover:opacity-90 transition-opacity"
className="demo-button px-4 py-1.5 text-sm"
>
View Details
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import 'tailwindcss';
@import 'highlight.js/styles/github-dark.css';
@import 'highlight.js/styles/github.css';
@source "../../../../node_modules/streamdown/dist/*.js";

/* Custom scrollbar styles */
Expand Down Expand Up @@ -28,7 +28,7 @@ html {
/* Markdown content styles */
.prose {
max-width: none;
color: #e5e7eb; /* text-gray-200 */
color: var(--sea-ink-soft);
}

/* .prose p {
Expand All @@ -37,15 +37,15 @@ html {
} */

.prose code {
color: #e5e7eb;
background-color: rgba(31, 41, 55, 0.5);
color: var(--sea-ink);
background-color: var(--chip-bg);
padding: 0.2em 0.4em;
border-radius: 0.375rem;
font-size: 0.875em;
}

.prose pre {
background-color: rgba(31, 41, 55, 0.5);
background-color: var(--chip-bg);
border-radius: 0.5rem;
padding: 1rem;
margin: 1.25em 0;
Expand All @@ -63,7 +63,7 @@ html {
.prose h2,
.prose h3,
.prose h4 {
color: #f9fafb; /* text-gray-50 */
color: var(--sea-ink);
/* margin-top: 2em; */
/* margin-bottom: 1em; */
}
Expand All @@ -81,27 +81,27 @@ html {
}

.prose blockquote {
border-left-color: #f97316; /* orange-500 */
background-color: rgba(249, 115, 22, 0.1);
border-left-color: var(--lagoon-deep);
background-color: var(--chip-bg);
padding: 1em;
margin: 1.25em 0;
border-radius: 0.5rem;
}

.prose hr {
border-color: rgba(249, 115, 22, 0.2);
border-color: var(--line);
margin: 2em 0;
}

.prose a {
color: #f97316; /* orange-500 */
color: var(--lagoon-deep);
text-decoration: underline;
text-decoration-thickness: 0.1em;
text-underline-offset: 0.2em;
}

.prose a:hover {
color: #fb923c; /* orange-400 */
color: var(--sea-ink);
}

.prose table {
Expand All @@ -113,11 +113,11 @@ html {
.prose th,
.prose td {
padding: 0.75em;
border: 1px solid rgba(249, 115, 22, 0.2);
border: 1px solid var(--line);
}

.prose th {
background-color: rgba(249, 115, 22, 0.1);
background-color: var(--chip-bg);
font-weight: 600;
}

Expand Down Expand Up @@ -181,16 +181,16 @@ html {

.prose th,
.prose td {
border: 1px solid rgba(249, 115, 22, 0.2);
border: 1px solid var(--line);
padding: 0.5em;
}

.prose th {
background-color: rgba(249, 115, 22, 0.1);
background-color: var(--chip-bg);
}

.prose strong {
color: #f9fafb; /* text-gray-50 */
color: var(--sea-ink);
font-weight: 600;
}

Expand All @@ -199,23 +199,23 @@ html {
}

.prose blockquote {
border-left: 4px solid #f97316; /* orange-500 */
border-left: 4px solid var(--lagoon-deep);
padding-left: 1em;
margin: 1em 0;
color: #d1d5db; /* text-gray-300 */
color: var(--sea-ink-soft);
}

/* Ensure code blocks match the AI's formatting */
.prose code {
color: #e5e7eb;
background-color: rgba(31, 41, 55, 0.5);
color: var(--sea-ink);
background-color: var(--chip-bg);
padding: 0.2em 0.4em;
border-radius: 0.375rem;
font-size: 0.875em;
}

.prose pre {
background-color: rgba(31, 41, 55, 0.5);
background-color: var(--chip-bg);
border-radius: 0.5rem;
padding: 1rem;
margin: 1em 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ function InitialLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex-1 flex items-center justify-center px-4">
<div className="text-center max-w-3xl mx-auto w-full">
<h1 className="text-6xl font-bold mb-4 bg-linear-to-r from-orange-500 to-red-600 text-transparent bg-clip-text uppercase">
<span className="text-white">TanStack</span> Chat
</h1>
<p className="text-gray-400 mb-6 w-2/3 mx-auto text-lg">
<h1 className="demo-title mb-4">TanStack Chat</h1>
<p className="demo-muted mb-6 mx-auto max-w-2xl text-lg">
You can ask me about anything, I might or might not have a good
answer, but you can still ask.
</p>
Expand All @@ -39,7 +37,7 @@ function InitialLayout({ children }: { children: React.ReactNode }) {

function ChattingLayout({ children }: { children: React.ReactNode }) {
return (
<div className="sticky bottom-0 left-0 right-0 bg-gray-900/80 backdrop-blur-sm border-t border-orange-500/10 z-10">
<div className="sticky bottom-0 left-0 right-0 z-10 border-t border-[var(--line)] bg-[var(--header-bg)] backdrop-blur-sm">
<div className="max-w-3xl mx-auto w-full px-4 py-3">{children}</div>
</div>
)
Expand Down Expand Up @@ -96,17 +94,17 @@ function Messages({
key={message.id}
className={`p-4 ${
message.role === 'assistant'
? 'bg-linear-to-r from-orange-500/5 to-red-600/5'
? 'bg-[var(--chip-bg)]'
: 'bg-transparent'
}`}
>
<div className="flex items-start gap-4 max-w-3xl mx-auto w-full">
{message.role === 'assistant' ? (
<div className="w-8 h-8 rounded-lg bg-linear-to-r from-orange-500 to-red-600 mt-2 flex items-center justify-center text-sm font-medium text-white flex-shrink-0">
<div className="mt-2 flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-[var(--lagoon-deep)] text-sm font-medium text-white">
AI
</div>
) : (
<div className="w-8 h-8 rounded-lg bg-gray-700 flex items-center justify-center text-sm font-medium text-white flex-shrink-0">
<div className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-lg bg-[var(--sea-ink-soft)] text-sm font-medium text-white">
Y
</div>
)}
Expand All @@ -115,7 +113,7 @@ function Messages({
if (part.type === 'text' && part.content) {
return (
<div
className="flex-1 min-w-0 prose dark:prose-invert max-w-none prose-sm"
className="prose prose-sm min-w-0 max-w-none flex-1"
key={index}
>
<Streamdown>{part.content}</Streamdown>
Expand Down Expand Up @@ -145,7 +143,7 @@ function Messages({
? onStopSpeak()
: onSpeak(textContent, message.id)
}
className="flex-shrink-0 p-2 text-gray-400 hover:text-orange-400 transition-colors"
className="demo-muted flex-shrink-0 p-2 transition-colors hover:text-[var(--lagoon-deep)]"
title={isPlaying ? 'Stop speaking' : 'Read aloud'}
>
{isPlaying ? (
Expand Down Expand Up @@ -190,7 +188,7 @@ function ChatPage() {
const Layout = messages.length ? ChattingLayout : InitialLayout

return (
<div className="relative flex h-[calc(100vh-80px)] bg-gray-900">
<div className="relative flex h-[calc(100vh-12rem)] min-h-[32rem]">
<div className="flex-1 flex flex-col min-h-0">
<Messages
messages={messages}
Expand All @@ -205,7 +203,7 @@ function ChatPage() {
<div className="flex items-center justify-center">
<button
onClick={stop}
className="px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg text-sm font-medium transition-colors flex items-center gap-2"
className="demo-button demo-button-danger"
>
<Square className="w-4 h-4 fill-current" />
Stop
Expand All @@ -226,10 +224,8 @@ function ChatPage() {
type="button"
onClick={handleMicClick}
disabled={isLoading || isTranscribing}
className={`p-3 rounded-lg transition-colors ${
isRecording
? 'bg-red-600 hover:bg-red-700 text-white'
: 'bg-gray-800/50 text-gray-400 hover:text-orange-400 border border-orange-500/20'
className={`demo-button p-3 ${
isRecording ? 'demo-button-danger' : 'demo-button-secondary'
} disabled:opacity-50`}
title={isRecording ? 'Stop recording' : 'Start recording'}
>
Expand All @@ -247,7 +243,7 @@ function ChatPage() {
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type something clever..."
className="w-full rounded-lg border border-orange-500/20 bg-gray-800/50 pl-4 pr-12 py-3 text-sm text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-orange-500/50 focus:border-transparent resize-none overflow-hidden shadow-lg"
className="demo-textarea pr-12 text-sm"
rows={1}
style={{ minHeight: '44px', maxHeight: '200px' }}
disabled={isLoading}
Expand All @@ -268,7 +264,7 @@ function ChatPage() {
<button
type="submit"
disabled={!input.trim() || isLoading}
className="absolute right-2 top-1/2 -translate-y-1/2 p-2 text-orange-500 hover:text-orange-400 disabled:text-gray-500 transition-colors focus:outline-none"
className="absolute right-2 top-1/2 -translate-y-1/2 p-2 text-[var(--lagoon-deep)] transition-colors hover:text-[var(--sea-ink)] disabled:text-[var(--sea-ink-soft)]"
>
<Send className="w-4 h-4" />
</button>
Expand Down
Loading
Loading