feat: migrate workspace to Tailwind CSS v4 (#377)

* feat: migrate workspace to Tailwind CSS v4

* refactor: move Tailwind v4 setup to CSS directives
This commit is contained in:
KM Koushik
2026-03-15 07:10:37 +11:00
committed by GitHub
parent d7b196c0e3
commit 9a306b1d59
28 changed files with 543 additions and 382 deletions
+15 -15
View File
@@ -53,7 +53,7 @@ const ChartContainer = React.forwardRef<
ref={ref}
className={cn(
"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
className
className,
)}
{...props}
>
@@ -69,7 +69,7 @@ ChartContainer.displayName = "Chart";
const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
const colorConfig = Object.entries(config).filter(
([_, config]) => config.theme || config.color
([_, config]) => config.theme || config.color,
);
if (!colorConfig.length) {
@@ -92,7 +92,7 @@ ${colorConfig
})
.join("\n")}
}
`
`,
)
.join("\n"),
}}
@@ -129,7 +129,7 @@ const ChartTooltipContent = React.forwardRef<
nameKey,
labelKey,
},
ref
ref,
) => {
const { config } = useChart();
@@ -180,7 +180,7 @@ const ChartTooltipContent = React.forwardRef<
ref={ref}
className={cn(
"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
className
className,
)}
>
{!nestLabel ? tooltipLabel : null}
@@ -195,7 +195,7 @@ const ChartTooltipContent = React.forwardRef<
key={item.dataKey}
className={cn(
"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
indicator === "dot" && "items-center"
indicator === "dot" && "items-center",
)}
>
{formatter && item?.value !== undefined && item.name ? (
@@ -208,14 +208,14 @@ const ChartTooltipContent = React.forwardRef<
!hideIndicator && (
<div
className={cn(
"shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]",
"shrink-0 rounded-[2px] border-[var(--color-border)] bg-[var(--color-bg)]",
{
"h-2.5 w-2.5": indicator === "dot",
"w-1": indicator === "line",
"w-0 border-[1.5px] border-dashed bg-transparent":
indicator === "dashed",
"my-0.5": nestLabel && indicator === "dashed",
}
},
)}
style={
{
@@ -229,7 +229,7 @@ const ChartTooltipContent = React.forwardRef<
<div
className={cn(
"flex flex-1 justify-between leading-none",
nestLabel ? "items-end" : "items-center"
nestLabel ? "items-end" : "items-center",
)}
>
<div className="grid gap-1.5">
@@ -252,7 +252,7 @@ const ChartTooltipContent = React.forwardRef<
</div>
</div>
);
}
},
);
ChartTooltipContent.displayName = "ChartTooltip";
@@ -268,7 +268,7 @@ const ChartLegendContent = React.forwardRef<
>(
(
{ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey },
ref
ref,
) => {
const { config } = useChart();
@@ -282,7 +282,7 @@ const ChartLegendContent = React.forwardRef<
className={cn(
"flex items-center justify-center gap-4",
verticalAlign === "top" ? "pb-3" : "pt-3",
className
className,
)}
>
{payload.map((item) => {
@@ -293,7 +293,7 @@ const ChartLegendContent = React.forwardRef<
<div
key={item.value}
className={cn(
"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground",
)}
>
{itemConfig?.icon && !hideIcon ? (
@@ -312,7 +312,7 @@ const ChartLegendContent = React.forwardRef<
})}
</div>
);
}
},
);
ChartLegendContent.displayName = "ChartLegend";
@@ -320,7 +320,7 @@ ChartLegendContent.displayName = "ChartLegend";
function getPayloadConfigFromPayload(
config: ChartConfig,
payload: unknown,
key: string
key: string,
) {
if (typeof payload !== "object" || payload === null) {
return undefined;
+2 -2
View File
@@ -47,7 +47,7 @@ const DropdownMenuSubContent = React.forwardRef<
<DropdownMenuPrimitive.SubContent
ref={ref}
className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]",
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[var(--radix-dropdown-menu-content-transform-origin)]",
className,
)}
{...props}
@@ -65,7 +65,7 @@ const DropdownMenuContent = React.forwardRef<
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-xl border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-dropdown-menu-content-transform-origin]",
"z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-xl border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[var(--radix-dropdown-menu-content-transform-origin)]",
className,
)}
{...props}
+39 -31
View File
@@ -71,7 +71,7 @@ const SidebarProvider = React.forwardRef<
children,
...props
},
ref
ref,
) => {
const isMobile = useIsMobile();
const [openMobile, setOpenMobile] = React.useState(false);
@@ -92,7 +92,7 @@ const SidebarProvider = React.forwardRef<
// This sets the cookie to keep the sidebar state.
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
},
[setOpenProp, open]
[setOpenProp, open],
);
// Helper to toggle the sidebar.
@@ -132,7 +132,15 @@ const SidebarProvider = React.forwardRef<
setOpenMobile,
toggleSidebar,
}),
[state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
[
state,
open,
setOpen,
isMobile,
openMobile,
setOpenMobile,
toggleSidebar,
],
);
return (
@@ -147,8 +155,8 @@ const SidebarProvider = React.forwardRef<
} as React.CSSProperties
}
className={cn(
"group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar",
className
"group/sidebar-wrapper flex min-h-svh w-full min-w-0 overflow-x-hidden has-[[data-variant=inset]]:bg-sidebar",
className,
)}
ref={ref}
{...props}
@@ -158,7 +166,7 @@ const SidebarProvider = React.forwardRef<
</TooltipProvider>
</SidebarContext.Provider>
);
}
},
);
SidebarProvider.displayName = "SidebarProvider";
@@ -179,7 +187,7 @@ const Sidebar = React.forwardRef<
children,
...props
},
ref
ref,
) => {
const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
@@ -187,8 +195,8 @@ const Sidebar = React.forwardRef<
return (
<div
className={cn(
"flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground",
className
"flex h-full w-[var(--sidebar-width)] flex-col bg-sidebar text-sidebar-foreground",
className,
)}
ref={ref}
{...props}
@@ -204,7 +212,7 @@ const Sidebar = React.forwardRef<
<SheetContent
data-sidebar="sidebar"
data-mobile="true"
className="w-[--sidebar-width] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
className="w-[var(--sidebar-width)] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
style={
{
"--sidebar-width": SIDEBAR_WIDTH_MOBILE,
@@ -234,25 +242,25 @@ const Sidebar = React.forwardRef<
{/* This is what handles the sidebar gap on desktop */}
<div
className={cn(
"relative w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear",
"relative w-[var(--sidebar-width)] bg-transparent transition-[width] duration-200 ease-linear",
"group-data-[collapsible=offcanvas]:w-0",
"group-data-[side=right]:rotate-180",
variant === "floating" || variant === "inset"
? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]"
: "group-data-[collapsible=icon]:w-[--sidebar-width-icon]"
: "group-data-[collapsible=icon]:w-[var(--sidebar-width-icon)]",
)}
/>
<div
className={cn(
"fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex",
"fixed inset-y-0 z-10 hidden h-svh w-[var(--sidebar-width)] transition-[left,right,width] duration-200 ease-linear md:flex",
side === "left"
? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
: "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
// Adjust the padding for floating and inset variants.
variant === "floating" || variant === "inset"
? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]"
: "group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l",
className
: "group-data-[collapsible=icon]:w-[var(--sidebar-width-icon)] group-data-[side=left]:border-r group-data-[side=right]:border-l",
className,
)}
{...props}
>
@@ -265,7 +273,7 @@ const Sidebar = React.forwardRef<
</div>
</div>
);
}
},
);
Sidebar.displayName = "Sidebar";
@@ -316,7 +324,7 @@ const SidebarRail = React.forwardRef<
"group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar",
"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
className
className,
)}
{...props}
/>
@@ -332,9 +340,9 @@ const SidebarInset = React.forwardRef<
<main
ref={ref}
className={cn(
"relative flex w-full flex-1 flex-col bg-background",
"relative flex min-w-0 flex-1 flex-col bg-background",
"md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",
className
className,
)}
{...props}
/>
@@ -352,7 +360,7 @@ const SidebarInput = React.forwardRef<
data-sidebar="input"
className={cn(
"h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring",
className
className,
)}
{...props}
/>
@@ -415,7 +423,7 @@ const SidebarContent = React.forwardRef<
data-sidebar="content"
className={cn(
"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
className
className,
)}
{...props}
/>
@@ -451,7 +459,7 @@ const SidebarGroupLabel = React.forwardRef<
className={cn(
"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
className
className,
)}
{...props}
/>
@@ -474,7 +482,7 @@ const SidebarGroupAction = React.forwardRef<
// Increases the hit area of the button on mobile.
"after:absolute after:-inset-2 after:md:hidden",
"group-data-[collapsible=icon]:hidden",
className
className,
)}
{...props}
/>
@@ -540,7 +548,7 @@ const sidebarMenuButtonVariants = cva(
variant: "default",
size: "default",
},
}
},
);
const SidebarMenuButton = React.forwardRef<
@@ -561,7 +569,7 @@ const SidebarMenuButton = React.forwardRef<
className,
...props
},
ref
ref,
) => {
const Comp = asChild ? Slot : "button";
const { isMobile, state } = useSidebar();
@@ -598,7 +606,7 @@ const SidebarMenuButton = React.forwardRef<
/>
</Tooltip>
);
}
},
);
SidebarMenuButton.displayName = "SidebarMenuButton";
@@ -625,7 +633,7 @@ const SidebarMenuAction = React.forwardRef<
"group-data-[collapsible=icon]:hidden",
showOnHover &&
"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0",
className
className,
)}
{...props}
/>
@@ -647,7 +655,7 @@ const SidebarMenuBadge = React.forwardRef<
"peer-data-[size=default]/menu-button:top-1.5",
"peer-data-[size=lg]/menu-button:top-2.5",
"group-data-[collapsible=icon]:hidden",
className
className,
)}
{...props}
/>
@@ -679,7 +687,7 @@ const SidebarMenuSkeleton = React.forwardRef<
/>
)}
<Skeleton
className="h-4 max-w-[--skeleton-width] flex-1"
className="h-4 max-w-[var(--skeleton-width)] flex-1"
data-sidebar="menu-skeleton-text"
style={
{
@@ -702,7 +710,7 @@ const SidebarMenuSub = React.forwardRef<
className={cn(
"mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5",
"group-data-[collapsible=icon]:hidden",
className
className,
)}
{...props}
/>
@@ -737,7 +745,7 @@ const SidebarMenuSubButton = React.forwardRef<
size === "sm" && "text-xs",
size === "md" && "text-sm",
"group-data-[collapsible=icon]:hidden",
className
className,
)}
{...props}
/>