) {
);
}
-function TableHead({ className, ...props }: React.ComponentProps<"th">) {
+function TableHead({ className, ...props }: React.ComponentProps<'th'>) {
return (
| [role=checkbox]]:translate-y-[2px]",
+ 'text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
className,
)}
{...props}
@@ -77,12 +77,12 @@ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
);
}
-function TableCell({ className, ...props }: React.ComponentProps<"td">) {
+function TableCell({ className, ...props }: React.ComponentProps<'td'>) {
return (
| [role=checkbox]]:translate-y-[2px]",
+ 'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
className,
)}
{...props}
@@ -93,11 +93,11 @@ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
function TableCaption({
className,
...props
-}: React.ComponentProps<"caption">) {
+}: React.ComponentProps<'caption'>) {
return (
);
diff --git a/packages/ui/src/tabs.tsx b/packages/ui/src/tabs.tsx
index c794ab2..6322ec0 100644
--- a/packages/ui/src/tabs.tsx
+++ b/packages/ui/src/tabs.tsx
@@ -1,8 +1,8 @@
-"use client";
+'use client';
-import * as React from "react";
-import { cn } from "@/lib/utils";
-import * as TabsPrimitive from "@radix-ui/react-tabs";
+import * as React from 'react';
+import { cn } from '@/lib/utils';
+import * as TabsPrimitive from '@radix-ui/react-tabs';
function Tabs({
className,
@@ -11,7 +11,7 @@ function Tabs({
return (
);
@@ -25,7 +25,7 @@ function TabsList({
);
diff --git a/packages/ui/src/theme.tsx b/packages/ui/src/theme.tsx
index 8cc6f38..ed66254 100644
--- a/packages/ui/src/theme.tsx
+++ b/packages/ui/src/theme.tsx
@@ -1,31 +1,31 @@
-"use client";
+'use client';
-import * as React from "react";
-import { DesktopIcon, MoonIcon, SunIcon } from "@radix-ui/react-icons";
-import * as z from "zod/v4";
+import * as React from 'react';
+import { DesktopIcon, MoonIcon, SunIcon } from '@radix-ui/react-icons';
+import * as z from 'zod/v4';
-import { Button } from "./button";
+import { Button } from './button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
-} from "./dropdown-menu";
+} from './dropdown-menu';
-const ThemeModeSchema = z.enum(["light", "dark", "auto"]);
+const ThemeModeSchema = z.enum(['light', 'dark', 'auto']);
-const themeKey = "theme-mode";
+const themeKey = 'theme-mode';
export type ThemeMode = z.output;
-export type ResolvedTheme = Exclude;
+export type ResolvedTheme = Exclude;
const getStoredThemeMode = (): ThemeMode => {
- if (typeof window === "undefined") return "auto";
+ if (typeof window === 'undefined') return 'auto';
try {
const storedTheme = localStorage.getItem(themeKey);
return ThemeModeSchema.parse(storedTheme);
} catch {
- return "auto";
+ return 'auto';
}
};
@@ -39,35 +39,35 @@ const setStoredThemeMode = (theme: ThemeMode) => {
};
const getSystemTheme = () => {
- if (typeof window === "undefined") return "light";
- return window.matchMedia("(prefers-color-scheme: dark)").matches
- ? "dark"
- : "light";
+ if (typeof window === 'undefined') return 'light';
+ return window.matchMedia('(prefers-color-scheme: dark)').matches
+ ? 'dark'
+ : 'light';
};
const updateThemeClass = (themeMode: ThemeMode) => {
const root = document.documentElement;
- root.classList.remove("light", "dark", "auto");
- const newTheme = themeMode === "auto" ? getSystemTheme() : themeMode;
+ root.classList.remove('light', 'dark', 'auto');
+ const newTheme = themeMode === 'auto' ? getSystemTheme() : themeMode;
root.classList.add(newTheme);
- if (themeMode === "auto") {
- root.classList.add("auto");
+ if (themeMode === 'auto') {
+ root.classList.add('auto');
}
};
const setupPreferredListener = () => {
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
- const handler = () => updateThemeClass("auto");
- mediaQuery.addEventListener("change", handler);
- return () => mediaQuery.removeEventListener("change", handler);
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
+ const handler = () => updateThemeClass('auto');
+ mediaQuery.addEventListener('change', handler);
+ return () => mediaQuery.removeEventListener('change', handler);
};
const getNextTheme = (current: ThemeMode): ThemeMode => {
const themes: ThemeMode[] =
- getSystemTheme() === "dark"
- ? ["auto", "light", "dark"]
- : ["auto", "dark", "light"];
+ getSystemTheme() === 'dark'
+ ? ['auto', 'light', 'dark']
+ : ['auto', 'dark', 'light'];
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return themes[(themes.indexOf(current) + 1) % themes.length]!;
};
@@ -75,19 +75,19 @@ const getNextTheme = (current: ThemeMode): ThemeMode => {
export const themeDetectorScript = (function () {
function themeFn() {
const isValidTheme = (theme: string): theme is ThemeMode => {
- const validThemes = ["light", "dark", "auto"] as const;
+ const validThemes = ['light', 'dark', 'auto'] as const;
return validThemes.includes(theme as ThemeMode);
};
- const storedTheme = localStorage.getItem("theme-mode") ?? "auto";
- const validTheme = isValidTheme(storedTheme) ? storedTheme : "auto";
+ const storedTheme = localStorage.getItem('theme-mode') ?? 'auto';
+ const validTheme = isValidTheme(storedTheme) ? storedTheme : 'auto';
- if (validTheme === "auto") {
- const autoTheme = window.matchMedia("(prefers-color-scheme: dark)")
+ if (validTheme === 'auto') {
+ const autoTheme = window.matchMedia('(prefers-color-scheme: dark)')
.matches
- ? "dark"
- : "light";
- document.documentElement.classList.add(autoTheme, "auto");
+ ? 'dark'
+ : 'light';
+ document.documentElement.classList.add(autoTheme, 'auto');
} else {
document.documentElement.classList.add(validTheme);
}
@@ -109,11 +109,11 @@ export function ThemeProvider({ children }: React.PropsWithChildren) {
const [themeMode, setThemeMode] = React.useState(getStoredThemeMode);
React.useEffect(() => {
- if (themeMode !== "auto") return;
+ if (themeMode !== 'auto') return;
return setupPreferredListener();
}, [themeMode]);
- const resolvedTheme = themeMode === "auto" ? getSystemTheme() : themeMode;
+ const resolvedTheme = themeMode === 'auto' ? getSystemTheme() : themeMode;
const setTheme = (newTheme: ThemeMode) => {
setThemeMode(newTheme);
@@ -146,7 +146,7 @@ export function ThemeProvider({ children }: React.PropsWithChildren) {
export function useTheme() {
const context = React.use(ThemeContext);
if (!context) {
- throw new Error("useTheme must be used within a ThemeProvider");
+ throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
}
@@ -169,13 +169,13 @@ export function ThemeToggle() {
- setTheme("light")}>
+ setTheme('light')}>
Light
- setTheme("dark")}>
+ setTheme('dark')}>
Dark
- setTheme("auto")}>
+ setTheme('auto')}>
System
diff --git a/packages/ui/src/toast.tsx b/packages/ui/src/toast.tsx
index 1ab424c..f3a62fe 100644
--- a/packages/ui/src/toast.tsx
+++ b/packages/ui/src/toast.tsx
@@ -1,22 +1,22 @@
-"use client";
+'use client';
-import type { ToasterProps } from "sonner";
-import { Toaster as Sonner, toast } from "sonner";
+import type { ToasterProps } from 'sonner';
+import { Toaster as Sonner, toast } from 'sonner';
-import { useTheme } from "./theme";
+import { useTheme } from './theme';
export const Toaster = ({ ...props }: ToasterProps) => {
const { themeMode } = useTheme();
return (
",
- "^(react/(.*)$)|^(react$)|^(react-native(.*)$)",
- "^(next/(.*)$)|^(next$)",
- "^(expo(.*)$)|^(expo$)",
- "",
- "",
- "^@gib",
- "^@gib/(.*)$",
- "",
- "^[.|..|~]",
- "^~/",
- "^[../]",
- "^[./]",
+ '',
+ '^(react/(.*)$)|^(react$)|^(react-native(.*)$)',
+ '^(next/(.*)$)|^(next$)',
+ '^(expo(.*)$)|^(expo$)',
+ '',
+ '',
+ '^@gib',
+ '^@gib/(.*)$',
+ '',
+ '^[.|..|~]',
+ '^~/',
+ '^[../]',
+ '^[./]',
],
- importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"],
- importOrderTypeScriptVersion: "5.0.0",
+ importOrderParserPlugins: ['typescript', 'jsx', 'decorators-legacy'],
+ importOrderTypeScriptVersion: '5.0.0',
overrides: [
{
- files: "*.json.hbs",
+ files: '*.json.hbs',
options: {
- parser: "json",
+ parser: 'json',
},
},
{
- files: "*.ts.hbs",
+ files: '*.ts.hbs',
options: {
- parser: "babel",
+ parser: 'babel',
},
},
],
diff --git a/tools/tailwind/.cache/.prettiercache b/tools/tailwind/.cache/.prettiercache
new file mode 100644
index 0000000..da07a05
--- /dev/null
+++ b/tools/tailwind/.cache/.prettiercache
@@ -0,0 +1 @@
+[["1","2","3","4","5"],{"key":"6","value":"7"},{"key":"8","value":"9"},{"key":"10","value":"11"},{"key":"12","value":"13"},{"key":"14","value":"15"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/package.json",{"size":851,"mtime":1766222924000,"hash":"16","data":"17"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/postcss-config.js",{"size":70,"mtime":1768155639454,"hash":"18","data":"19"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/eslint.config.ts",{"size":143,"mtime":1768155639344,"hash":"20","data":"21"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/theme.css",{"size":6741,"mtime":1766222924000,"hash":"22","data":"23"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/tsconfig.json",{"size":94,"mtime":1766222924000,"hash":"24","data":"25"},"0d22e47f57739db9de04c6f8420d6fb5",{"hashOfOptions":"26"},"9a944fbda06979be39571bd9bd00b0d9",{"hashOfOptions":"27"},"b8fec960cb32340eea62ca1485093e68",{"hashOfOptions":"28"},"5dd421d25d104c47e1ab36df41ed0f7d",{"hashOfOptions":"29"},"b3c77d33a30318d89c9c2cafcbe00bbe",{"hashOfOptions":"30"},"1821576240","2434669165","2442413358","1994519264","1135731447"]
\ No newline at end of file
diff --git a/tools/tailwind/eslint.config.ts b/tools/tailwind/eslint.config.ts
index 2c8ae6f..524c3fd 100644
--- a/tools/tailwind/eslint.config.ts
+++ b/tools/tailwind/eslint.config.ts
@@ -1,5 +1,5 @@
-import { defineConfig } from "eslint/config";
+import { defineConfig } from 'eslint/config';
-import { baseConfig } from "@gib/eslint-config/base";
+import { baseConfig } from '@gib/eslint-config/base';
export default defineConfig(baseConfig);
diff --git a/tools/tailwind/postcss-config.js b/tools/tailwind/postcss-config.js
index c2ddf74..a34a3d5 100644
--- a/tools/tailwind/postcss-config.js
+++ b/tools/tailwind/postcss-config.js
@@ -1,5 +1,5 @@
export default {
plugins: {
- "@tailwindcss/postcss": {},
+ '@tailwindcss/postcss': {},
},
};
diff --git a/turbo.json b/turbo.json
index c954103..e17958a 100644
--- a/turbo.json
+++ b/turbo.json
@@ -3,33 +3,24 @@
"globalDependencies": ["**/.env.*local"],
"globalEnv": [
"NODE_ENV",
- "CI",
- "SKIP_ENV_VALIDATION",
- "SITE_URL",
"SENTRY_AUTH_TOKEN",
"NEXT_PUBLIC_SITE_URL",
"NEXT_PUBLIC_CONVEX_URL",
+ "NEXT_PUBLIC_PLAUSIBLE_URL",
"NEXT_PUBLIC_SENTRY_DSN",
"NEXT_PUBLIC_SENTRY_URL",
"NEXT_PUBLIC_SENTRY_ORG",
"NEXT_PUBLIC_SENTRY_PROJECT_NAME",
"CONVEX_SELF_HOSTED_URL",
"CONVEX_SELF_HOSTED_ADMIN_KEY",
- "SETUP_SCRIPT_RAN",
- "SITE_URL",
- "AUTH_URL",
+ "CONVEX_SITE_URL",
"USESEND_API_KEY",
"AUTH_AUTHENTIK_ID",
"AUTH_AUTHENTIK_SECRET",
- "AUTH_AUTHENTIK_ISSUER",
- "AUTH_MICROSOFT_ENTRA_ID_ID",
- "AUTH_MICROSOFT_ENTRA_ID_SECRET",
- "AUTH_MICROSOFT_ENTRA_ID_ISSUER",
- "AUTH_MICROSOFT_ENTRA_ID_AUTH_URL"
+ "AUTH_AUTHENTIK_ISSUER"
],
"globalPassThroughEnv": [
- "NODE_ENV",
- "CI"
+ "NODE_ENV"
],
"ui": "tui",
"tasks": {
|