Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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 .server-changes/tailwind-v4-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: improvement
---

Migrated the webapp to Tailwind CSS v4 with a CSS-first `@theme`. Semantic color tokens are now CSS variables overridable per theme (multi-theme support). Tailwind runs through `@tailwindcss/postcss`; plugins replaced or upgraded to v4-compatible versions.
6 changes: 3 additions & 3 deletions apps/webapp/app/components/AskAI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ function AskAIDialog({ initialQuery, isOpen, onOpenChange, closeAskAI }: AskAIDi
return (
<Dialog open={isOpen} onOpenChange={handleOpenChange}>
<DialogContent className="animated-gradient-glow flex max-h-[90vh] min-h-fit w-full flex-col justify-between gap-0 px-0 pb-0 pt-0 sm:max-w-prose">
<DialogHeader className="flex h-[2.75rem] items-start justify-center rounded-t-md bg-background-bright pl-3">
<DialogHeader className="flex h-11 items-start justify-center rounded-t-md bg-background-bright pl-3">
<div className="flex items-center gap-1">
<AISparkleIcon className="size-5" />
<DialogTitle className="text-sm font-medium text-text-bright">Ask AI</DialogTitle>
Expand Down Expand Up @@ -468,7 +468,7 @@ function ChatInterface({ initialQuery }: { initialQuery?: string }) {
error={error}
addFeedback={addFeedback}
/>
<form onSubmit={handleSubmit} className="flex-shrink-0 border-t border-grid-bright p-4">
<form onSubmit={handleSubmit} className="shrink-0 border-t border-grid-bright p-4">
<div className="flex gap-3">
<input
type="text"
Expand Down Expand Up @@ -531,7 +531,7 @@ function GradientSpinnerBackground({
}) {
return (
<div
className={`flex rounded-full bg-gradient-to-br from-indigo-500 via-purple-500 to-fuchsia-500 p-px ${className}`}
className={`flex rounded-full bg-linear-to-br from-indigo-500 via-purple-500 to-fuchsia-500 p-px ${className}`}
>
<div
className={`flex h-full w-full items-center justify-center rounded-full bg-charcoal-600 ${
Expand Down
6 changes: 3 additions & 3 deletions apps/webapp/app/components/BackgroundWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function BackgroundWrapper({ children }: { children: ReactNode }) {
return (
<div className="relative h-full w-full overflow-hidden bg-background-dimmed lg:bg-transparent">
<div
className="absolute left-0 top-0 hidden w-[260px] bg-contain bg-left-top bg-no-repeat lg:block"
className="absolute left-0 top-0 hidden w-[260px] bg-contain bg-top-left bg-no-repeat lg:block"
style={{
backgroundImage: `url(${blurredDashboardBackgroundMenuTop})`,
aspectRatio: "auto",
Expand All @@ -17,7 +17,7 @@ export function BackgroundWrapper({ children }: { children: ReactNode }) {
/>

<div
className="absolute bottom-0 left-0 hidden w-[260px] bg-contain bg-left-bottom bg-no-repeat lg:block"
className="absolute bottom-0 left-0 hidden w-[260px] bg-contain bg-bottom-left bg-no-repeat lg:block"
style={{
backgroundImage: `url(${blurredDashboardBackgroundMenuBottom})`,
aspectRatio: "auto",
Expand All @@ -27,7 +27,7 @@ export function BackgroundWrapper({ children }: { children: ReactNode }) {
/>

<div
className="absolute top-0 hidden bg-left-top bg-no-repeat lg:block"
className="absolute top-0 hidden bg-top-left bg-no-repeat lg:block"
style={{
left: "260px",
backgroundImage: `url(${blurredDashboardBackgroundTable})`,
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/DefinitionTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function DefinitionTip({
{children}
</span>
</TooltipTrigger>
<TooltipContent align="end" side="right" className="w-[16rem] min-w-[16rem]">
<TooltipContent align="end" side="right" className="w-64 min-w-64">
<Header3 className="mb-1">{title}</Header3>
{typeof content === "string" ? (
<Paragraph variant="small">{content}</Paragraph>
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/Feedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export function Feedback({ button, defaultValue = "bug", onOpenChange }: Feedbac
<DialogHeader>Contact us</DialogHeader>
<div className="mt-2 flex flex-col gap-4">
<div className="flex items-center gap-4">
<Icon icon={EnvelopeIcon} className="size-10 min-w-[2.5rem] text-blue-500" />
<Icon icon={EnvelopeIcon} className="size-10 min-w-10 text-blue-500" />
<Paragraph variant="base/bright">
How can we help? We read every message and will respond as quickly as we can.
</Paragraph>
Expand Down
6 changes: 3 additions & 3 deletions apps/webapp/app/components/GitMetadata.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function GitMetadataBranch({
leadingIconClassName="group-hover/table-row:text-text-bright"
iconSpacing="gap-x-1"
to={git.branchUrl}
className="pl-1 duration-0 [&_span]:duration-0 [&_span]:group-hover/table-row:text-text-bright"
className="pl-1 duration-0 [&_span]:duration-0 group-hover/table-row:[&_span]:text-text-bright"
>
{git.branchName}
</LinkButton>
Expand All @@ -52,7 +52,7 @@ export function GitMetadataCommit({
LeadingIcon={<GitCommitIcon className="size-4" />}
leadingIconClassName="group-hover/table-row:text-text-bright"
iconSpacing="gap-x-1"
className="pl-1 duration-0 [&_span]:duration-0 [&_span]:group-hover/table-row:text-text-bright"
className="pl-1 duration-0 [&_span]:duration-0 group-hover/table-row:[&_span]:text-text-bright"
>
{`${git.shortSha} / ${git.commitMessage}`}
</LinkButton>
Expand All @@ -78,7 +78,7 @@ export function GitMetadataPullRequest({
LeadingIcon={<GitPullRequestIcon className="size-4" />}
leadingIconClassName="group-hover/table-row:text-text-bright"
iconSpacing="gap-x-1"
className="pl-1 duration-0 [&_span]:duration-0 [&_span]:group-hover/table-row:text-text-bright"
className="pl-1 duration-0 [&_span]:duration-0 group-hover/table-row:[&_span]:text-text-bright"
>
#{git.pullRequestNumber} {git.pullRequestTitle}
</LinkButton>
Expand Down
4 changes: 2 additions & 2 deletions apps/webapp/app/components/ListPagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function PreviousButton({ cursor }: { cursor?: string }) {
variant={"secondary/small"}
LeadingIcon={ChevronLeftIcon}
className={cn(
"flex items-center rounded-r-none border-r-0 pl-2 pr-[0.5625rem]",
"flex items-center rounded-r-none border-r-0 pl-2 pr-2.25",
!path && "cursor-not-allowed opacity-50"
)}
onClick={(e) => !path && e.preventDefault()}
Expand All @@ -63,7 +63,7 @@ function NextButton({ cursor }: { cursor?: string }) {
variant={"secondary/small"}
TrailingIcon={ChevronRightIcon}
className={cn(
"flex items-center rounded-l-none border-l-0 pl-[0.5625rem] pr-2",
"flex items-center rounded-l-none border-l-0 pl-2.25 pr-2",
!path && "cursor-not-allowed opacity-50"
)}
onClick={(e) => !path && e.preventDefault()}
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/ProductHuntBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export function ProductHuntBanner() {
<LinkButton
to="https://www.producthunt.com/posts/trigger-dev"
target="_blank"
className="!text-white underline underline-offset-2 transition hover:decoration-charcoal-100 hover:decoration-2"
className="text-white! underline underline-offset-2 transition hover:decoration-charcoal-100 hover:decoration-2"
variant="tertiary/small"
>
Vote for us today only!
Expand Down
6 changes: 3 additions & 3 deletions apps/webapp/app/components/WarmStarts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function WarmStartIconWithTooltip({
}) {
return (
<SimpleTooltip
className="relative z-[9999]"
className="relative z-9999"
button={<WarmStartIcon isWarmStart={isWarmStart} className={className} />}
content={<WarmStartTooltipContent />}
/>
Expand All @@ -42,14 +42,14 @@ function WarmStartTooltipContent() {
<div className="flex max-w-xs flex-col gap-4 p-1">
<div>
<WarmStartCombo isWarmStart={false} className="mb-0.5 text-text-bright" />
<Paragraph variant="small" className="!text-wrap text-text-dimmed">
<Paragraph variant="small" className="text-wrap! text-text-dimmed">
A cold start happens when we need to boot up a new machine for your run to execute. This
takes longer than a warm start.
</Paragraph>
</div>
<div>
<WarmStartCombo isWarmStart={true} className="mb-0.5 text-text-bright" />
<Paragraph variant="small" className="!text-wrap text-text-dimmed">
<Paragraph variant="small" className="text-wrap! text-text-dimmed">
A warm start happens when we can reuse a machine from a run that recently finished. This
takes less time than a cold start.
</Paragraph>
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/code/AIQueryInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export function AIQueryInput({
onChange={(e) => setPrompt(e.target.value)}
disabled={isLoading}
rows={8}
className="m-0 min-h-10 w-full resize-none border-0 bg-background-bright px-3 py-2.5 text-sm text-text-bright scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-text-dimmed focus:border-0 focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"
className="m-0 min-h-10 w-full resize-none border-0 bg-background-bright px-3 py-2.5 text-sm text-text-bright scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-text-dimmed focus:border-0 focus:outline-hidden focus:ring-0 focus-visible:outline-hidden focus-visible:ring-0 focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50"
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey && prompt.trim() && !isLoading) {
e.preventDefault();
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/code/ChartConfigPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ function SeriesColorPicker({
<PopoverTrigger asChild>
<button
type="button"
className="flex-shrink-0 rounded p-0.5 hover:bg-charcoal-700"
className="shrink-0 rounded p-0.5 hover:bg-charcoal-700"
title="Change series color"
>
<span
Expand Down
8 changes: 4 additions & 4 deletions apps/webapp/app/components/code/CodeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
<pre
className={cn(
"relative mr-2 p-2 font-mono text-xs leading-relaxed",
isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:break-words"
isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:wrap-break-word"
)}
dir="ltr"
>
Expand Down Expand Up @@ -502,7 +502,7 @@ function HighlightCode({
const preClasses = cn(
"relative mr-2 font-mono leading-relaxed",
preClassName,
isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:break-words"
isWrapped && "[&_span]:whitespace-pre-wrap [&_span]:wrap-break-word"
);

if (!isLoaded) {
Expand Down Expand Up @@ -531,7 +531,7 @@ function HighlightCode({
}

const lineNumber = index + 1;
const lineProps = getLineProps({ line, key: index });
const lineProps = getLineProps({ line });

let hasAnyHighlights = highlightLines ? highlightLines.length > 0 : false;

Expand Down Expand Up @@ -570,7 +570,7 @@ function HighlightCode({

<div className="flex-1">
{line.map((token, key) => {
const tokenProps = getTokenProps({ token, key });
const tokenProps = getTokenProps({ token });

// Highlight search term matches in token
const content = highlightSearchText(token.content, searchTerm);
Expand Down
12 changes: 6 additions & 6 deletions apps/webapp/app/components/code/TSQLResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ function CopyableCell({
"relative flex h-full w-full items-center overflow-hidden px-2",
"bg-background-bright group-hover/row:bg-charcoal-750",
"font-mono text-xs text-text-dimmed group-hover/row:text-text-bright",
"[&_a:focus-visible]:underline [&_a:focus-visible]:underline-offset-[3px] [&_a:focus-visible]:outline-none",
"[&_a:focus-visible]:underline [&_a:focus-visible]:underline-offset-[3px] [&_a:focus-visible]:outline-hidden",
alignment === "right" && "justify-end"
)}
onMouseEnter={() => setIsHovered(true)}
Expand Down Expand Up @@ -925,7 +925,7 @@ function HeaderCellContent({
})}
>
<span className="truncate text-left">{children}</span>
<span className="flex flex-shrink-0">
<span className="flex shrink-0">
<InfoIconTooltip
content={tooltip}
contentClassName="normal-case tracking-normal"
Expand All @@ -941,7 +941,7 @@ function HeaderCellContent({
{canSort && (
<span
className={cn(
"flex-shrink-0 transition-colors",
"shrink-0 transition-colors",
sortHighlighted ? "text-text-bright" : "text-text-dimmed"
)}
>
Expand All @@ -962,7 +962,7 @@ function HeaderCellContent({
}}
onMouseEnter={() => setIsFilterHovered(true)}
onMouseLeave={() => setIsFilterHovered(false)}
className="flex-shrink-0 rounded text-text-dimmed transition-colors focus-custom hover:text-text-bright"
className="shrink-0 rounded text-text-dimmed transition-colors focus-custom hover:text-text-bright"
title="Toggle column filters"
>
{showFilters ? <IconFilter2X className="size-4" /> : <IconFilter2 className="size-4" />}
Expand Down Expand Up @@ -1006,7 +1006,7 @@ function FilterCell({
className={cn(
"w-full rounded border border-charcoal-700 bg-charcoal-800 px-2 py-1",
"text-xs text-text-bright placeholder:text-text-dimmed",
"focus:border-indigo-500/50 focus:outline-none focus:ring-1 focus:ring-indigo-500/50"
"focus:border-indigo-500/50 focus:outline-hidden focus:ring-1 focus:ring-indigo-500/50"
)}
/>
</div>
Expand Down Expand Up @@ -1249,7 +1249,7 @@ export const TSQLResultsTable = memo(function TSQLResultsTable({
height: `${rowVirtualizer.getTotalSize()}px`,
position: "relative",
}}
className="divide-y divide-charcoal-700 bg-background-bright after:absolute after:bottom-0 after:left-0 after:right-0 after:z-[1] after:h-px after:bg-grid-bright"
className="divide-y divide-charcoal-700 bg-background-bright after:absolute after:bottom-0 after:left-0 after:right-0 after:z-1 after:h-px after:bg-grid-bright"
>
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
const row = tableRows[virtualRow.index];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function DashboardAgentComposer({
}}
placeholder="Type a message…"
className={cn(
"max-h-[40vh] min-h-[40px] flex-1 resize-none border-0 bg-transparent px-2 py-1.5 text-sm text-text-bright placeholder-text-dimmed outline-none ring-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 [field-sizing:content] focus:outline-none focus:ring-0"
"max-h-[40vh] min-h-[40px] flex-1 resize-none border-0 bg-transparent px-2 py-1.5 text-sm text-text-bright placeholder-text-dimmed outline-hidden ring-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600 field-sizing-content focus:outline-hidden focus:ring-0"
)}
/>
{isStreaming ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function DashboardAgentHistory({
<button
type="button"
onClick={() => onSelect(chat.id)}
className="flex min-w-0 flex-1 flex-col items-start gap-0.5 text-left outline-none focus-custom"
className="flex min-w-0 flex-1 flex-col items-start gap-0.5 text-left outline-hidden focus-custom"
>
<span className="line-clamp-1 text-sm text-text-bright">{chat.title}</span>
{chat.lastMessageAt && (
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/logs/LogsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export function LogsTable({
variant="minimal/small"
TrailingIcon={RunsIcon}
trailingIconClassName="text-text-bright"
className="h-[1.375rem] pl-1.5 pr-2"
className="h-5.5 pl-1.5 pr-2"
>
<span className="text-[0.6875rem] text-text-bright">View run</span>
</LinkButton>
Expand Down
2 changes: 1 addition & 1 deletion apps/webapp/app/components/metrics/BigNumber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export function BigNumber({
<div className="flex flex-col justify-between gap-4 rounded-sm border border-grid-dimmed bg-background-bright p-4">
<div className="flex flex-wrap items-center justify-between gap-2">
<Header3 className="leading-6">{title}</Header3>
{accessory && <div className="flex-shrink-0">{accessory}</div>}
{accessory && <div className="shrink-0">{accessory}</div>}
</div>
<div
className={cn(
Expand Down
4 changes: 2 additions & 2 deletions apps/webapp/app/components/metrics/QueryWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export function QueryWidget({
LeadingIcon={Maximize2}
leadingIconClassName="text-text-dimmed group-hover/button:text-text-bright"
onClick={() => setIsFullscreen(true)}
className="!px-1"
className="px-1!"
/>
</span>
}
Expand Down Expand Up @@ -321,7 +321,7 @@ export function QueryWidget({
icon={TrashIcon}
title="Delete chart"
leadingIconClassName="text-error"
className="text-error hover:!bg-error/10"
className="text-error hover:bg-error/10!"
onClick={() => {
onDelete();
setIsMenuOpen(false);
Expand Down
4 changes: 2 additions & 2 deletions apps/webapp/app/components/metrics/SaveToDashboardDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export function SaveToDashboardDialog({
<Dialog open={isOpen} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-sm">
<DialogHeader>Add to dashboard</DialogHeader>
<div className="!mt-1 space-y-4">
<div className="mt-1! space-y-4">
<Paragraph variant="small" className="text-text-dimmed">
You don't have any custom dashboards yet. Create one first from the sidebar menu.
</Paragraph>
Expand Down Expand Up @@ -125,7 +125,7 @@ export function SaveToDashboardDialog({
<input type="hidden" name="query" value={query} />
<input type="hidden" name="config" value={JSON.stringify(config)} />

<div className="!mt-1 space-y-2">
<div className="mt-1! space-y-2">
<Paragraph variant="small" className="text-text-dimmed">
Select a dashboard to add this chart to:
</Paragraph>
Expand Down
4 changes: 2 additions & 2 deletions apps/webapp/app/components/metrics/TitleWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function TitleWidget({
{title}
</span>
{hasMenu && (
<div className="flex-shrink-0 opacity-0 transition-opacity group-hover:opacity-100">
<div className="shrink-0 opacity-0 transition-opacity group-hover:opacity-100">
<Popover open={isMenuOpen} onOpenChange={setIsMenuOpen}>
<PopoverVerticalEllipseTrigger isOpen={isMenuOpen} />
<PopoverContent align="end" className="p-0">
Expand All @@ -70,7 +70,7 @@ export function TitleWidget({
icon={TrashIcon}
title="Delete"
leadingIconClassName="text-error"
className="text-error hover:!bg-error/10"
className="text-error hover:bg-error/10!"
onClick={() => {
onDelete();
setIsMenuOpen(false);
Expand Down
Loading
Loading