Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion apps/marketing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
},
"devDependencies": {
"@next/eslint-plugin-next": "^15.3.1",
"@tailwindcss/postcss": "^4.1.0",
"@types/eslint": "^9.6.1",
"@types/node": "^22.15.2",
"@types/react": "^19.1.2",
Expand All @@ -37,7 +38,7 @@
"postcss": "^8.5.3",
"prettier": "^3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"tailwindcss": "^3.4.1",
"tailwindcss": "^4.1.0",
"typescript": "^5.8.3"
}
}
3 changes: 1 addition & 2 deletions apps/marketing/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
const config = {
plugins: {
tailwindcss: {},
"@tailwindcss/postcss": {},
},
};

module.exports = config;

4 changes: 4 additions & 0 deletions apps/marketing/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import "tailwindcss";
@import "@usesend/ui/styles/globals.css";

@config "../../tailwind.config.ts";
2 changes: 1 addition & 1 deletion apps/marketing/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import "@usesend/ui/styles/globals.css";
import "./globals.css";

import { Inter } from "next/font/google";
import { JetBrains_Mono } from "next/font/google";
Expand Down
1 change: 0 additions & 1 deletion apps/marketing/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ export default {
`${path.join(require.resolve("@usesend/email-editor"), "..")}/**/*.{ts,tsx}`,
],
} satisfies Config;

3 changes: 2 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
},
"devDependencies": {
"@next/eslint-plugin-next": "^15.3.1",
"@tailwindcss/postcss": "^4.1.0",
"@types/eslint": "^9.6.1",
"@types/html-to-text": "^9.0.4",
"@types/mime-types": "^2.1.4",
Expand All @@ -107,7 +108,7 @@
"postcss": "^8.5.3",
"prettier": "^3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"tailwindcss": "^3.4.1",
"tailwindcss": "^4.1.0",
"typescript": "^5.8.3",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.2.4",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const config = {
plugins: {
tailwindcss: {},
"@tailwindcss/postcss": {},
},
};

Expand Down
27 changes: 24 additions & 3 deletions apps/web/src/app/(dashboard)/dasboard-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
"use client";

import { AppSidebar } from "~/components/AppSideBar";
import { SidebarInset, SidebarProvider, SidebarTrigger } from "@usesend/ui/src/sidebar";
import {
SidebarInset,
SidebarProvider,
SidebarTrigger,
} from "@usesend/ui/src/sidebar";
import { useIsMobile } from "@usesend/ui/src/hooks/use-mobile";
import { UpgradeModal } from "~/components/payments/UpgradeModal";
import { usePathname } from "next/navigation";
import { useEffect, useRef } from "react";

export function DashboardLayout({ children }: { children: React.ReactNode }) {
const isMobile = useIsMobile();
const pathname = usePathname();
const mainRef = useRef<HTMLElement>(null);

useEffect(() => {
if (mainRef.current) {
mainRef.current.scrollLeft = 0;
}

window.scrollTo({ left: 0 });
document.documentElement.scrollLeft = 0;
document.body.scrollLeft = 0;
}, [pathname]);

return (
<div className="h-full bg-sidebar-background">
<SidebarProvider>
<AppSidebar />
<SidebarInset>
<main className="flex-1 overflow-auto h-full p-4 xl:px-40">
<SidebarInset className="min-w-0">
<main
ref={mainRef}
className="h-full flex-1 overflow-y-auto overflow-x-hidden p-4 xl:px-40"
>
{isMobile ? (
<SidebarTrigger className="h-5 w-5 text-muted-foreground" />
) : null}
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/app/(dashboard)/webhooks/add-webhook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ export function AddWebhook() {
<ChevronDown className="ml-2 h-4 w-4 shrink-0" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[--radix-dropdown-menu-trigger-width] h-[30vh] ">
<DropdownMenuContent className="h-[30vh] w-[var(--radix-dropdown-menu-trigger-width)]">
<div className="space-y-3">
<DropdownMenuCheckboxItem
checked={allEventsSelected}
Expand Down Expand Up @@ -362,7 +362,7 @@ export function AddWebhook() {
<ChevronDown className="ml-2 h-4 w-4 shrink-0" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="max-h-[30vh] w-[--radix-dropdown-menu-trigger-width] overflow-y-auto">
<DropdownMenuContent className="max-h-[30vh] w-[var(--radix-dropdown-menu-trigger-width)] overflow-y-auto">
<div className="space-y-3">
<DropdownMenuCheckboxItem
checked={selectedDomainIds.length === 0}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ export function EditWebhookDialog({
<ChevronDown className="ml-2 h-4 w-4 shrink-0" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[--radix-dropdown-menu-trigger-width] h-[30vh]">
<DropdownMenuContent className="h-[30vh] w-[var(--radix-dropdown-menu-trigger-width)]">
<div className="space-y-3">
<DropdownMenuCheckboxItem
checked={allEventsSelected}
Expand Down Expand Up @@ -355,7 +355,7 @@ export function EditWebhookDialog({
<ChevronDown className="ml-2 h-4 w-4 shrink-0" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="max-h-[30vh] w-[--radix-dropdown-menu-trigger-width] overflow-y-auto">
<DropdownMenuContent className="max-h-[30vh] w-[var(--radix-dropdown-menu-trigger-width)] overflow-y-auto">
<div className="space-y-3">
<DropdownMenuCheckboxItem
checked={selectedDomainIds.length === 0}
Expand Down
4 changes: 4 additions & 0 deletions apps/web/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import "tailwindcss";
@import "@usesend/ui/styles/globals.css";

@config "../../tailwind.config.ts";
2 changes: 1 addition & 1 deletion apps/web/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import "@usesend/ui/styles/globals.css";
import "./globals.css";

import { Inter } from "next/font/google";
import { JetBrains_Mono } from "next/font/google";
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/AppSideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ export function NavUser({
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
className="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-xl"
className="w-[var(--radix-dropdown-menu-trigger-width)] min-w-56 rounded-xl"
side={isMobile ? "bottom" : "top"}
sideOffset={4}
>
Expand Down
3 changes: 2 additions & 1 deletion packages/email-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"author": "",
"license": "ISC",
"devDependencies": {
"@tailwindcss/postcss": "^4.1.0",
"@types/eslint": "^9.6.1",
"@types/react": "^19.1.2",
"@usesend/eslint-config": "workspace:*",
Expand All @@ -28,7 +29,7 @@
"prettier": "^3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"react": "^19.1.0",
"tailwindcss": "^3.4.1",
"tailwindcss": "^4.1.0",
"tsup": "^8.4.0",
"typescript": "^5.8.3"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/email-editor/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const config = {
plugins: {
tailwindcss: {},
"@tailwindcss/postcss": {},
},
};

Expand Down
2 changes: 2 additions & 0 deletions packages/email-editor/src/styles/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@reference "tailwindcss";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== CSS files using Tailwind v4 directives =="
rg -n --type=css '@reference|@theme|@source|@utility|@variant|@custom-variant|@config|@apply'

echo
echo "== Stylelint unknown-at-rule configuration =="
rg -n -C2 'scss/at-rule-no-unknown|at-rule-no-unknown|ignoreAtRules' .

echo
echo "== Biome/Stylelint config files =="
fd -HI 'biome.json|biome.jsonc|stylelint.config.*|.stylelintrc.*|.stylelintrc' -x sh -c 'echo "----- {} -----"; sed -n "1,220p" "{}"'

Repository: usesend/useSend

Length of output: 1143


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Finding Biome config files =="
find . -maxdepth 3 -type f \( -name "biome.json" -o -name "biome.jsonc" \) 2>/dev/null || echo "No biome config found"

echo
echo "== Finding Stylelint config files =="
find . -maxdepth 3 -type f \( -name ".stylelintrc*" -o -name "stylelint.config.*" \) 2>/dev/null || echo "No stylelint config found"

echo
echo "== Checking package.json for linting setup =="
find . -maxdepth 2 -name "package.json" -type f -exec grep -l "stylelint\|biome" {} \;

Repository: usesend/useSend

Length of output: 209


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Content of biome.json =="
cat biome.json

echo
echo "== Content of .stylelintrc.json =="
cat .stylelintrc.json

Repository: usesend/useSend

Length of output: 2903


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Checking for GitHub Actions workflows =="
find .github -type f -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -5

echo
echo "== Checking package.json scripts for linting =="
find . -maxdepth 2 -name "package.json" -type f | xargs grep -l "lint" 2>/dev/null | head -3

echo
echo "== Root package.json lint scripts =="
grep -A 10 '"scripts"' ./package.json | grep -E 'lint|stylelint|biome' || echo "No lint scripts found"

Repository: usesend/useSend

Length of output: 387


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== packages/email-editor/package.json =="
cat packages/email-editor/package.json 2>/dev/null || echo "File not found"

echo
echo "== Check for tailwind.config in email-editor =="
find packages/email-editor -name "tailwind.config.*" -o -name "postcss.config.*" 2>/dev/null

echo
echo "== Check for tailwind.config at root =="
ls -la tailwind.config.* postcss.config.* 2>/dev/null || echo "None found"

echo
echo "== All CSS files in email-editor =="
find packages/email-editor -name "*.css" -type f

Repository: usesend/useSend

Length of output: 2328


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== postcss.config.cjs in email-editor =="
cat packages/email-editor/postcss.config.cjs

echo
echo "== tailwind.config.ts in email-editor =="
cat packages/email-editor/tailwind.config.ts

echo
echo "== Checking if Biome is configured to scan email-editor =="
grep -A 20 '"biome"' biome.json || echo "No biome workspace config found"

Repository: usesend/useSend

Length of output: 546


Configure linting tools to support Tailwind v4 at-rules.

The @reference "tailwindcss" directive at line 1 will be flagged as invalid by both Biome and Stylelint without explicit configuration.

Update .stylelintrc.json to add ignoreAtRules: ["reference", "config", "theme", "source", "custom-variant"] to the rules, and configure biome.json to either skip CSS parsing for this file or add support for Tailwind v4 directives.

🧰 Tools
🪛 Biome (2.4.6)

[error] 1-1: Tailwind-specific syntax is disabled.

(parse)

🪛 Stylelint (17.4.0)

[error] 1-1: Unexpected unknown at-rule "@reference" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/email-editor/src/styles/index.css` at line 1, The CSS file uses the
Tailwind v4 at-rule `@reference` "tailwindcss" which will be flagged by linters;
update project lint configs by adding ignoreAtRules:
["reference","config","theme","source","custom-variant"] to .stylelintrc.json
rules and adjust biome.json to either exclude
packages/email-editor/src/styles/index.css from CSS parsing or add support for
Tailwind v4 directives so the `@reference` at-rule is not reported as invalid.


.unsend-editor .unsend-prose p:where([class~="text-sm"]) {
font-size: 16px;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/tailwind-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
"@types/node": "^22.15.2",
"autoprefixer": "^10.4.21",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.1"
"tailwindcss": "^4.1.0"
}
}
5 changes: 3 additions & 2 deletions packages/tailwind-config/tailwind.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Config } from "tailwindcss";
import tailwindcssAnimate from "tailwindcss-animate";

const config = {
darkMode: ["class"],
darkMode: "class",
content: ["./src/**/*.{ts,tsx}"],
prefix: "",
theme: {
Expand Down Expand Up @@ -132,7 +133,7 @@ const config = {
},
},
},
plugins: [require("tailwindcss-animate")],
plugins: [tailwindcssAnimate],
} satisfies Config;

export default config;
4 changes: 2 additions & 2 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"prettier": "^3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"react": "19.1.0",
"tailwindcss": "^3.4.1",
"tailwindcss": "^4.1.0",
"typescript": "^5.8.3"
},
"dependencies": {
Expand Down Expand Up @@ -62,4 +62,4 @@
"tailwindcss-animate": "^1.0.7",
"zod": "^3.24.3"
}
}
}
30 changes: 15 additions & 15 deletions packages/ui/src/charts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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}
>
Expand All @@ -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) {
Expand All @@ -92,7 +92,7 @@ ${colorConfig
})
.join("\n")}
}
`
`,
)
.join("\n"),
}}
Expand Down Expand Up @@ -129,7 +129,7 @@ const ChartTooltipContent = React.forwardRef<
nameKey,
labelKey,
},
ref
ref,
) => {
const { config } = useChart();

Expand Down Expand Up @@ -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}
Expand All @@ -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 ? (
Expand All @@ -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={
{
Expand All @@ -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">
Expand All @@ -252,7 +252,7 @@ const ChartTooltipContent = React.forwardRef<
</div>
</div>
);
}
},
);
ChartTooltipContent.displayName = "ChartTooltip";

Expand All @@ -268,7 +268,7 @@ const ChartLegendContent = React.forwardRef<
>(
(
{ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey },
ref
ref,
) => {
const { config } = useChart();

Expand All @@ -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) => {
Expand All @@ -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 ? (
Expand All @@ -312,15 +312,15 @@ const ChartLegendContent = React.forwardRef<
})}
</div>
);
}
},
);
ChartLegendContent.displayName = "ChartLegend";

// Helper to extract item config from a payload.
function getPayloadConfigFromPayload(
config: ChartConfig,
payload: unknown,
key: string
key: string,
) {
if (typeof payload !== "object" || payload === null) {
return undefined;
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/dropdown-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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}
Expand Down
Loading
Loading