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:
Gabriel Brown committed 2026-10-01 14:41:58 -04:00
1 parent a4d4355886
commit 1af6b43b1a
19 files changed
+799 -1328

No files matched your search

+3
View File
@@ -93,6 +93,9 @@ const Carousel = ({
React.useEffect(() => {
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);
api.on('reInit', onSelect);
api.on('select', onSelect);
+6 -4
View File
@@ -105,6 +105,10 @@ ${colorConfig
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 = {
name?: string | number;
value?: number | string;
@@ -356,15 +360,13 @@ const getPayloadConfigFromPayload = (
key in payload &&
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 (
payloadPayload &&
key in payloadPayload &&
typeof payloadPayload[key as keyof typeof payloadPayload] === 'string'
) {
configLabelKey = payloadPayload[
key as keyof typeof payloadPayload
] as string;
configLabelKey = payloadPayload[key as keyof typeof payloadPayload];
}
return configLabelKey in config ? config[configLabelKey] : config[key];
+14 -16
View File
@@ -1,21 +1,19 @@
import * as React from 'react';
const MOBILE_BREAKPOINT = 768;
const MOBILE_QUERY = `(max-width: ${MOBILE_BREAKPOINT - 1}px)`;
export const useIsMobile = () => {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined,
);
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;
const subscribe = (onChange: () => void) => {
const mql = window.matchMedia(MOBILE_QUERY);
mql.addEventListener('change', onChange);
return () => mql.removeEventListener('change', onChange);
};
// 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,
);
+2 -8
View File
@@ -294,10 +294,7 @@ export const ImageCropApply = ({
if (asChild) {
return (
<Slot.Root
onClick={handleClick}
{...(props as ComponentProps<typeof Slot.Root>)}
>
<Slot.Root onClick={handleClick} {...props}>
{children}
</Slot.Root>
);
@@ -329,10 +326,7 @@ export const ImageCropReset = ({
if (asChild) {
return (
<Slot.Root
onClick={handleClick}
{...(props as ComponentProps<typeof Slot.Root>)}
>
<Slot.Root onClick={handleClick} {...props}>
{children}
</Slot.Root>
);