Template
Update dependencies and fix what the new lint rules caught
Every package moves to its newest in-major version, plus React 19.3, @convex-dev/auth 0.0.96 and next-plausible 4. The backend declares @auth/core and generates sign-in codes without oslo, which @convex-dev/auth no longer pulls in. The UseSend patch now actually removes the crypto import Convex refuses to bundle. The stricter react-hooks and typescript-eslint rules flagged the carousel, chart, image crop and mobile hook, which now pass.
This commit is contained in:
1 parent
9facbcd4da
commit
818b41fb21
18 files changed
+647
-1250
No files matched your search
+11
-11
@@ -20,26 +20,26 @@
|
|||||||
"@expo/vector-icons": "^15.1.1",
|
"@expo/vector-icons": "^15.1.1",
|
||||||
"@gib/backend": "workspace:*",
|
"@gib/backend": "workspace:*",
|
||||||
"@legendapp/list": "^2.0.19",
|
"@legendapp/list": "^2.0.19",
|
||||||
"@react-navigation/bottom-tabs": "^7.15.8",
|
"@react-navigation/bottom-tabs": "^7.20.0",
|
||||||
"@react-navigation/elements": "^2.9.13",
|
"@react-navigation/elements": "^2.9.44",
|
||||||
"@react-navigation/native": "^7.2.1",
|
"@react-navigation/native": "^7.5.0",
|
||||||
"@sentry/react-native": "^7.13.0",
|
"@sentry/react-native": "^7.13.0",
|
||||||
"convex": "catalog:convex",
|
"convex": "catalog:convex",
|
||||||
"expo": "~54.0.33",
|
"expo": "~54.0.37",
|
||||||
"expo-apple-authentication": "~8.0.8",
|
"expo-apple-authentication": "~8.0.8",
|
||||||
"expo-constants": "~18.0.13",
|
"expo-constants": "~18.0.14",
|
||||||
"expo-dev-client": "~6.0.20",
|
"expo-dev-client": "~6.0.21",
|
||||||
"expo-font": "~14.0.11",
|
"expo-font": "~14.0.12",
|
||||||
"expo-haptics": "~15.0.8",
|
"expo-haptics": "~15.0.8",
|
||||||
"expo-image": "~3.0.11",
|
"expo-image": "~3.0.11",
|
||||||
"expo-linking": "~8.0.11",
|
"expo-linking": "~8.0.12",
|
||||||
"expo-router": "~6.0.23",
|
"expo-router": "~6.0.24",
|
||||||
"expo-secure-store": "~15.0.8",
|
"expo-secure-store": "~15.0.8",
|
||||||
"expo-splash-screen": "~31.0.13",
|
"expo-splash-screen": "~31.0.13",
|
||||||
"expo-status-bar": "~3.0.9",
|
"expo-status-bar": "~3.0.9",
|
||||||
"expo-symbols": "~1.0.8",
|
"expo-symbols": "~1.0.8",
|
||||||
"expo-system-ui": "~6.0.9",
|
"expo-system-ui": "~6.0.9",
|
||||||
"expo-web-browser": "~15.0.10",
|
"expo-web-browser": "~15.0.11",
|
||||||
"nativewind": "5.0.0-preview.2",
|
"nativewind": "5.0.0-preview.2",
|
||||||
"react": "catalog:react19",
|
"react": "catalog:react19",
|
||||||
"react-dom": "catalog:react19",
|
"react-dom": "catalog:react19",
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
"react-native-reanimated": "~4.1.7",
|
"react-native-reanimated": "~4.1.7",
|
||||||
"react-native-safe-area-context": "~5.6.2",
|
"react-native-safe-area-context": "~5.6.2",
|
||||||
"react-native-screens": "~4.16.0",
|
"react-native-screens": "~4.16.0",
|
||||||
"react-native-web": "~0.21.2",
|
"react-native-web": "~0.21.3",
|
||||||
"react-native-worklets": "~0.5.2"
|
"react-native-worklets": "~0.5.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"jsx": "react-native",
|
"jsx": "react-native",
|
||||||
"checkJs": false,
|
"checkJs": false,
|
||||||
|
"types": ["node"],
|
||||||
"moduleSuffixes": [".ios", ".android", ".native", ""],
|
"moduleSuffixes": [".ios", ".android", ".native", ""],
|
||||||
"paths": {
|
"paths": {
|
||||||
"~/*": ["./src/*"]
|
"~/*": ["./src/*"]
|
||||||
|
|||||||
@@ -23,15 +23,16 @@
|
|||||||
"@convex-dev/auth": "catalog:convex",
|
"@convex-dev/auth": "catalog:convex",
|
||||||
"@gib/backend": "workspace:*",
|
"@gib/backend": "workspace:*",
|
||||||
"@gib/ui": "workspace:*",
|
"@gib/ui": "workspace:*",
|
||||||
"@sentry/nextjs": "^10.46.0",
|
"@sentry/nextjs": "^10.75.3",
|
||||||
"@t3-oss/env-nextjs": "^0.13.11",
|
"@t3-oss/env-nextjs": "^0.13.11",
|
||||||
"convex": "catalog:convex",
|
"convex": "catalog:convex",
|
||||||
"next": "^16.2.1",
|
"next": "^16.3.8",
|
||||||
"next-plausible": "^3.12.5",
|
"next-plausible": "^4.0.0",
|
||||||
|
"posthog-js": "^1.435.6",
|
||||||
"react": "catalog:react19",
|
"react": "catalog:react19",
|
||||||
"react-dom": "catalog:react19",
|
"react-dom": "catalog:react19",
|
||||||
"require-in-the-middle": "^7.5.2",
|
"require-in-the-middle": "^7.5.2",
|
||||||
"superjson": "2.2.3",
|
"superjson": "2.2.6",
|
||||||
"zod": "catalog:"
|
"zod": "catalog:"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -44,7 +45,7 @@
|
|||||||
"@types/node": "catalog:",
|
"@types/node": "catalog:",
|
||||||
"@types/react": "catalog:react19",
|
"@types/react": "catalog:react19",
|
||||||
"@types/react-dom": "catalog:react19",
|
"@types/react-dom": "catalog:react19",
|
||||||
"baseline-browser-mapping": "^2.10.11",
|
"baseline-browser-mapping": "^2.11.26",
|
||||||
"eslint": "catalog:",
|
"eslint": "catalog:",
|
||||||
"jsdom": "catalog:test",
|
"jsdom": "catalog:test",
|
||||||
"prettier": "catalog:",
|
"prettier": "catalog:",
|
||||||
|
|||||||
+16
-14
@@ -4,7 +4,7 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": "^22.20.0"
|
"node": "^22.20.0"
|
||||||
},
|
},
|
||||||
"packageManager": "[email protected]0",
|
"packageManager": "[email protected]4",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"apps/*",
|
"apps/*",
|
||||||
"packages/*",
|
"packages/*",
|
||||||
@@ -25,24 +25,24 @@
|
|||||||
"test": {
|
"test": {
|
||||||
"@edge-runtime/vm": "^5.0.0",
|
"@edge-runtime/vm": "^5.0.0",
|
||||||
"@playwright/test": "^1.60.0",
|
"@playwright/test": "^1.60.0",
|
||||||
"@testing-library/jest-dom": "^6.9.1",
|
"@testing-library/jest-dom": "^6.10.0",
|
||||||
"@testing-library/react": "^16.3.2",
|
"@testing-library/react": "^16.3.3",
|
||||||
"@testing-library/user-event": "^14.6.1",
|
"@testing-library/user-event": "^14.6.1",
|
||||||
"@vitejs/plugin-react": "^6.0.2",
|
"@vitejs/plugin-react": "^6.1.1",
|
||||||
"@vitest/coverage-v8": "^4.1.8",
|
"@vitest/coverage-v8": "^4.1.8",
|
||||||
"convex-test": "^0.0.53",
|
"convex-test": "^0.0.53",
|
||||||
"jsdom": "^29.1.1",
|
"jsdom": "^29.1.1",
|
||||||
"vitest": "^4.1.8"
|
"vitest": "^4.1.11"
|
||||||
},
|
},
|
||||||
"convex": {
|
"convex": {
|
||||||
"@convex-dev/auth": "^0.0.87",
|
"@convex-dev/auth": "^0.0.96",
|
||||||
"convex": "^1.34.1"
|
"convex": "^1.46.0"
|
||||||
},
|
},
|
||||||
"react19": {
|
"react19": {
|
||||||
"@types/react": "~19.2.14",
|
"@types/react": "~19.3.0",
|
||||||
"@types/react-dom": "~19.2.3",
|
"@types/react-dom": "~19.3.0",
|
||||||
"react": "19.2.4",
|
"react": "19.3.0",
|
||||||
"react-dom": "19.2.4"
|
"react-dom": "19.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -55,11 +55,13 @@
|
|||||||
"dev:next:web": "turbo run dev:web -F @gib/next -F @gib/backend",
|
"dev:next:web": "turbo run dev:web -F @gib/next -F @gib/backend",
|
||||||
"dev:expo": "turbo run dev -F @gib/expo -F @gib/backend",
|
"dev:expo": "turbo run dev -F @gib/expo -F @gib/backend",
|
||||||
"dev:backend": "turbo run dev -F @gib/backend",
|
"dev:backend": "turbo run dev -F @gib/backend",
|
||||||
|
"dev:kill": "bash scripts/dev-kill",
|
||||||
"dev:staging": "INFISICAL_ENV=staging turbo run dev -F @gib/next -F @gib/backend",
|
"dev:staging": "INFISICAL_ENV=staging turbo run dev -F @gib/next -F @gib/backend",
|
||||||
"dev:expo:tunnel": "turbo run dev:tunnel -F @gib/expo -F @gib/backend",
|
"dev:expo:tunnel": "turbo run dev:tunnel -F @gib/expo -F @gib/backend",
|
||||||
"db:up": "bash scripts/db/up",
|
"db:up": "bash scripts/db/up",
|
||||||
"db:down": "bash scripts/db/down",
|
"db:down": "bash scripts/db/down",
|
||||||
"db:down:wipe": "bash scripts/db/down --wipe",
|
"db:down:wipe": "bash scripts/db/down --wipe",
|
||||||
|
"db:sync-env": "bash scripts/with-env dev -- bash scripts/sync-local-convex-env",
|
||||||
"format": "turbo run format --continue -- --cache --cache-location .cache/.prettiercache",
|
"format": "turbo run format --continue -- --cache --cache-location .cache/.prettiercache",
|
||||||
"format:fix": "turbo run format --continue -- --write --cache --cache-location .cache/.prettiercache",
|
"format:fix": "turbo run format --continue -- --write --cache --cache-location .cache/.prettiercache",
|
||||||
"lint": "turbo run lint --continue -- --cache --cache-location .cache/.eslintcache",
|
"lint": "turbo run lint --continue -- --cache --cache-location .cache/.eslintcache",
|
||||||
@@ -82,12 +84,12 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gib/prettier-config": "workspace:",
|
"@gib/prettier-config": "workspace:",
|
||||||
"@turbo/gen": "^2.9.18",
|
"@turbo/gen": "^2.11.6",
|
||||||
"dotenv-cli": "11.0.0",
|
"dotenv-cli": "11.0.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"lint-staged": "^17.0.7",
|
"lint-staged": "^17.6.0",
|
||||||
"prettier": "catalog:",
|
"prettier": "catalog:",
|
||||||
"turbo": "^2.9.18",
|
"turbo": "^2.11.6",
|
||||||
"typescript": "catalog:"
|
"typescript": "catalog:"
|
||||||
},
|
},
|
||||||
"prettier": "@gib/prettier-config",
|
"prettier": "@gib/prettier-config",
|
||||||
|
|||||||
+19
@@ -21,6 +21,17 @@ import {
|
|||||||
} from "convex/server";
|
} from "convex/server";
|
||||||
import type { DataModel } from "./dataModel.js";
|
import type { DataModel } from "./dataModel.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Typesafe environment variables.
|
||||||
|
*
|
||||||
|
* This includes platform-provided env vars and any variables declared in
|
||||||
|
* `convex.config.ts`.
|
||||||
|
*/
|
||||||
|
type Env = {
|
||||||
|
readonly CONVEX_CLOUD_URL: string;
|
||||||
|
readonly CONVEX_SITE_URL: string;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a query in this Convex app's public API.
|
* Define a query in this Convex app's public API.
|
||||||
*
|
*
|
||||||
@@ -95,6 +106,14 @@ export declare const internalAction: ActionBuilder<DataModel, "internal">;
|
|||||||
*/
|
*/
|
||||||
export declare const httpAction: HttpActionBuilder;
|
export declare const httpAction: HttpActionBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Typesafe environment variables.
|
||||||
|
*
|
||||||
|
* This includes platform-provided env vars and any variables declared in
|
||||||
|
* `convex.config.ts`.
|
||||||
|
*/
|
||||||
|
export declare const env: Env;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of services for use within Convex query functions.
|
* A set of services for use within Convex query functions.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -91,3 +91,11 @@ export const internalAction = internalActionGeneric;
|
|||||||
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
|
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
|
||||||
*/
|
*/
|
||||||
export const httpAction = httpActionGeneric;
|
export const httpAction = httpActionGeneric;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Typesafe environment variables.
|
||||||
|
*
|
||||||
|
* This includes platform-provided env vars and any variables declared in
|
||||||
|
* `convex.config.ts`.
|
||||||
|
*/
|
||||||
|
export const env = process.env;
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { EmailConfig, EmailUserConfig } from '@auth/core/providers/email';
|
import type { EmailConfig, EmailUserConfig } from '@auth/core/providers/email';
|
||||||
import { generateRandomString, RandomReader } from '@oslojs/crypto/random';
|
import { generateRandomString, RandomReader } from '@oslojs/crypto/random';
|
||||||
import { alphabet } from 'oslo/crypto';
|
|
||||||
import { UseSend } from 'usesend-js';
|
import { UseSend } from 'usesend-js';
|
||||||
|
|
||||||
export default function UseSendProvider(config: EmailUserConfig): EmailConfig {
|
export default function UseSendProvider(config: EmailUserConfig): EmailConfig {
|
||||||
@@ -17,7 +16,7 @@ export default function UseSendProvider(config: EmailUserConfig): EmailConfig {
|
|||||||
crypto.getRandomValues(bytes as Uint8Array<ArrayBuffer>);
|
crypto.getRandomValues(bytes as Uint8Array<ArrayBuffer>);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return generateRandomString(random, alphabet('0-9'), 6);
|
return generateRandomString(random, '0123456789', 6);
|
||||||
},
|
},
|
||||||
|
|
||||||
sendVerificationRequest: async (params) => {
|
sendVerificationRequest: async (params) => {
|
||||||
|
|||||||
@@ -26,9 +26,10 @@
|
|||||||
"with-env": "sh ../../scripts/with-env ${INFISICAL_ENV:-dev} --"
|
"with-env": "sh ../../scripts/with-env ${INFISICAL_ENV:-dev} --"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@auth/core": "^0.41.3",
|
||||||
"@oslojs/crypto": "^1.0.1",
|
"@oslojs/crypto": "^1.0.1",
|
||||||
"@react-email/components": "1.0.10",
|
"@react-email/components": "1.0.12",
|
||||||
"@react-email/render": "^2.0.4",
|
"@react-email/render": "^2.1.0",
|
||||||
"convex": "catalog:convex",
|
"convex": "catalog:convex",
|
||||||
"react": "catalog:react19",
|
"react": "catalog:react19",
|
||||||
"react-dom": "catalog:react19",
|
"react-dom": "catalog:react19",
|
||||||
|
|||||||
+24
-24
@@ -18,38 +18,38 @@
|
|||||||
"ui-add": "bunx --bun shadcn@latest add && prettier src --write --list-different"
|
"ui-add": "bunx --bun shadcn@latest add && prettier src --write --list-different"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@base-ui/react": "^1.3.0",
|
"@base-ui/react": "^1.8.0",
|
||||||
"@hookform/resolvers": "^5.2.2",
|
"@hookform/resolvers": "^5.9.1",
|
||||||
"@radix-ui/react-avatar": "^1.1.11",
|
"@radix-ui/react-avatar": "^1.2.6",
|
||||||
"@radix-ui/react-checkbox": "^1.3.3",
|
"@radix-ui/react-checkbox": "^1.3.11",
|
||||||
"@radix-ui/react-dialog": "^1.1.15",
|
"@radix-ui/react-dialog": "^1.1.23",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
"@radix-ui/react-dropdown-menu": "^2.1.24",
|
||||||
"@radix-ui/react-icons": "^1.3.2",
|
"@radix-ui/react-icons": "^1.3.2",
|
||||||
"@radix-ui/react-label": "^2.1.8",
|
"@radix-ui/react-label": "^2.1.15",
|
||||||
"@radix-ui/react-progress": "^1.1.8",
|
"@radix-ui/react-progress": "^1.1.16",
|
||||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
"@radix-ui/react-scroll-area": "^1.2.18",
|
||||||
"@radix-ui/react-separator": "^1.1.8",
|
"@radix-ui/react-separator": "^1.1.15",
|
||||||
"@radix-ui/react-slot": "^1.2.4",
|
"@radix-ui/react-slot": "^1.3.3",
|
||||||
"@radix-ui/react-switch": "^1.2.6",
|
"@radix-ui/react-switch": "^1.3.7",
|
||||||
"@radix-ui/react-tabs": "^1.1.13",
|
"@radix-ui/react-tabs": "^1.1.21",
|
||||||
"@tabler/icons-react": "^3.41.0",
|
"@tabler/icons-react": "^3.48.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cmdk": "^1.1.1",
|
"cmdk": "^1.1.1",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.4.0",
|
||||||
"embla-carousel-react": "^8.6.0",
|
"embla-carousel-react": "^8.6.0",
|
||||||
"input-otp": "^1.4.2",
|
"input-otp": "^1.5.0",
|
||||||
"lucide-react": "^0.577.0",
|
"lucide-react": "^0.577.0",
|
||||||
"motion": "^12.38.0",
|
"motion": "^12.43.0",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"radix-ui": "^1.4.3",
|
"radix-ui": "^1.6.7",
|
||||||
"react-day-picker": "^9.14.0",
|
"react-day-picker": "^9.14.0",
|
||||||
"react-hook-form": "^7.72.0",
|
"react-hook-form": "^7.89.0",
|
||||||
"react-image-crop": "^11.0.10",
|
"react-image-crop": "^11.1.2",
|
||||||
"react-resizable-panels": "^4.7.6",
|
"react-resizable-panels": "^4.14.1",
|
||||||
"recharts": "^3.8.1",
|
"recharts": "^3.10.1",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.8",
|
||||||
"tailwind-merge": "^3.5.0",
|
"tailwind-merge": "^3.7.0",
|
||||||
"vaul": "^1.1.2"
|
"vaul": "^1.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ const Carousel = ({
|
|||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!api) return;
|
if (!api) return;
|
||||||
|
// Embla is the source of truth for scroll state; read it once on mount,
|
||||||
|
// then follow its events.
|
||||||
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
onSelect(api);
|
onSelect(api);
|
||||||
api.on('reInit', onSelect);
|
api.on('reInit', onSelect);
|
||||||
api.on('select', onSelect);
|
api.on('select', onSelect);
|
||||||
|
|||||||
@@ -105,6 +105,10 @@ ${colorConfig
|
|||||||
|
|
||||||
const ChartTooltip = RechartsPrimitive.Tooltip;
|
const ChartTooltip = RechartsPrimitive.Tooltip;
|
||||||
|
|
||||||
|
// Recharts injects `payload`/`label`/`active` into tooltip and legend content
|
||||||
|
// at render time, but (as of recharts v3) does not expose them on the public
|
||||||
|
// prop types, and the payload items are loosely typed. Model the fields we use
|
||||||
|
// explicitly so the component is type-safe.
|
||||||
type ChartPayloadItem = {
|
type ChartPayloadItem = {
|
||||||
name?: string | number;
|
name?: string | number;
|
||||||
value?: number | string;
|
value?: number | string;
|
||||||
@@ -356,15 +360,13 @@ const getPayloadConfigFromPayload = (
|
|||||||
key in payload &&
|
key in payload &&
|
||||||
typeof payload[key as keyof typeof payload] === 'string'
|
typeof payload[key as keyof typeof payload] === 'string'
|
||||||
) {
|
) {
|
||||||
configLabelKey = payload[key as keyof typeof payload] as string;
|
configLabelKey = payload[key as keyof typeof payload];
|
||||||
} else if (
|
} else if (
|
||||||
payloadPayload &&
|
payloadPayload &&
|
||||||
key in payloadPayload &&
|
key in payloadPayload &&
|
||||||
typeof payloadPayload[key as keyof typeof payloadPayload] === 'string'
|
typeof payloadPayload[key as keyof typeof payloadPayload] === 'string'
|
||||||
) {
|
) {
|
||||||
configLabelKey = payloadPayload[
|
configLabelKey = payloadPayload[key as keyof typeof payloadPayload];
|
||||||
key as keyof typeof payloadPayload
|
|
||||||
] as string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return configLabelKey in config ? config[configLabelKey] : config[key];
|
return configLabelKey in config ? config[configLabelKey] : config[key];
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
const MOBILE_BREAKPOINT = 768;
|
const MOBILE_BREAKPOINT = 768;
|
||||||
|
const MOBILE_QUERY = `(max-width: ${MOBILE_BREAKPOINT - 1}px)`;
|
||||||
|
|
||||||
export const useIsMobile = () => {
|
const subscribe = (onChange: () => void) => {
|
||||||
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
|
const mql = window.matchMedia(MOBILE_QUERY);
|
||||||
undefined,
|
mql.addEventListener('change', onChange);
|
||||||
);
|
return () => mql.removeEventListener('change', onChange);
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
||||||
const onChange = () => {
|
|
||||||
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
||||||
};
|
|
||||||
mql.addEventListener('change', onChange);
|
|
||||||
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
||||||
return () => mql.removeEventListener('change', onChange);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return !!isMobile;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// True below the mobile breakpoint. Server renders and hydration assume
|
||||||
|
// desktop, then the browser's media query takes over.
|
||||||
|
export const useIsMobile = () =>
|
||||||
|
React.useSyncExternalStore(
|
||||||
|
subscribe,
|
||||||
|
() => window.matchMedia(MOBILE_QUERY).matches,
|
||||||
|
() => false,
|
||||||
|
);
|
||||||
@@ -294,10 +294,7 @@ export const ImageCropApply = ({
|
|||||||
|
|
||||||
if (asChild) {
|
if (asChild) {
|
||||||
return (
|
return (
|
||||||
<Slot.Root
|
<Slot.Root onClick={handleClick} {...props}>
|
||||||
onClick={handleClick}
|
|
||||||
{...(props as ComponentProps<typeof Slot.Root>)}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</Slot.Root>
|
</Slot.Root>
|
||||||
);
|
);
|
||||||
@@ -329,10 +326,7 @@ export const ImageCropReset = ({
|
|||||||
|
|
||||||
if (asChild) {
|
if (asChild) {
|
||||||
return (
|
return (
|
||||||
<Slot.Root
|
<Slot.Root onClick={handleClick} {...props}>
|
||||||
onClick={handleClick}
|
|
||||||
{...(props as ComponentProps<typeof Slot.Root>)}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</Slot.Root>
|
</Slot.Root>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,6 +7,15 @@ const __dirname = path.dirname(__filename);
|
|||||||
const usesendDir = path.join(__dirname, '..', 'node_modules', 'usesend-js');
|
const usesendDir = path.join(__dirname, '..', 'node_modules', 'usesend-js');
|
||||||
|
|
||||||
const ensureReplacement = (content, searchValue, replaceValue, filePath) => {
|
const ensureReplacement = (content, searchValue, replaceValue, filePath) => {
|
||||||
|
// Removal step (empty replacement): it's already applied once the search
|
||||||
|
// snippet is gone. Guard on searchValue, not replaceValue — every string
|
||||||
|
// "includes" the empty string, which would make this a silent no-op.
|
||||||
|
if (replaceValue === '') {
|
||||||
|
return content.includes(searchValue)
|
||||||
|
? content.replace(searchValue, replaceValue)
|
||||||
|
: content;
|
||||||
|
}
|
||||||
|
|
||||||
if (content.includes(replaceValue)) {
|
if (content.includes(replaceValue)) {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,16 +13,16 @@
|
|||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/compat": "^2.0.3",
|
"@eslint/compat": "^2.1.1",
|
||||||
"@eslint/js": "catalog:",
|
"@eslint/js": "catalog:",
|
||||||
"@next/eslint-plugin-next": "^16.2.1",
|
"@next/eslint-plugin-next": "^16.3.8",
|
||||||
"eslint-plugin-import": "^2.32.0",
|
"eslint-plugin-import": "^2.32.0",
|
||||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||||
"eslint-plugin-prefer-arrow-functions": "^3.9.1",
|
"eslint-plugin-prefer-arrow-functions": "^3.10.2",
|
||||||
"eslint-plugin-react": "^7.37.5",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
"eslint-plugin-react-hooks": "^7.1.1",
|
||||||
"eslint-plugin-turbo": "^2.8.20",
|
"eslint-plugin-turbo": "^2.11.6",
|
||||||
"typescript-eslint": "^8.57.2"
|
"typescript-eslint": "^8.71.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gib/prettier-config": "workspace:*",
|
"@gib/prettier-config": "workspace:*",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ianvs/prettier-plugin-sort-imports": "^4.7.1",
|
"@ianvs/prettier-plugin-sort-imports": "^4.7.1",
|
||||||
"prettier": "catalog:",
|
"prettier": "catalog:",
|
||||||
"prettier-plugin-tailwindcss": "^0.7.2"
|
"prettier-plugin-tailwindcss": "^0.7.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gib/tsconfig": "workspace:*",
|
"@gib/tsconfig": "workspace:*",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/postcss": "catalog:",
|
"@tailwindcss/postcss": "catalog:",
|
||||||
"postcss": "^8.5.8",
|
"postcss": "^8.5.28",
|
||||||
"tailwindcss": "catalog:"
|
"tailwindcss": "catalog:"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
Reference in new issue
Block a user