Upgrade React from 18.3 to 19.2
- Upgrade react, react-dom to ^19.2.4 and @types/react, @types/react-dom to v19 - Upgrade @nostrify/react to 0.4.0 (peer deps fix for React 19) - Upgrade vaul to 1.1.2 and react-day-picker to 9.14.0 for React 19 compatibility - Fix useRef() calls to pass explicit initial values (required in React 19) - Update RefObject types to include null (React 19 type change) - Rewrite Calendar component for react-day-picker v9 classNames API - Add npm overrides for @emoji-mart/react (only remaining React 18 holdout)
This commit is contained in:
Generated
+1067
-139
File diff suppressed because it is too large
Load Diff
+13
-8
@@ -54,7 +54,7 @@
|
||||
"@getalby/sdk": "^5.1.1",
|
||||
"@hookform/resolvers": "^5.2.2",
|
||||
"@nostrify/nostrify": "^0.51.0",
|
||||
"@nostrify/react": "^0.3.1",
|
||||
"@nostrify/react": "^0.4.0",
|
||||
"@nostrify/types": "^0.36.9",
|
||||
"@plausible-analytics/tracker": "^0.4.4",
|
||||
"@radix-ui/react-accordion": "^1.2.0",
|
||||
@@ -105,10 +105,10 @@
|
||||
"lucide-react": "^0.462.0",
|
||||
"nostr-tools": "^2.13.0",
|
||||
"qrcode": "^1.5.4",
|
||||
"react": "^18.3.1",
|
||||
"react": "^19.2.4",
|
||||
"react-blurhash": "^0.3.0",
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-day-picker": "^9.14.0",
|
||||
"react-dom": "^19.2.4",
|
||||
"react-easy-crop": "^5.5.6",
|
||||
"react-hook-form": "^7.71.1",
|
||||
"react-intersection-observer": "^9.16.0",
|
||||
@@ -121,7 +121,7 @@
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"uri-templates": "^0.2.0",
|
||||
"vaul": "^0.9.3",
|
||||
"vaul": "^1.1.2",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -132,13 +132,14 @@
|
||||
"@html-eslint/eslint-plugin": "^0.41.0",
|
||||
"@html-eslint/parser": "^0.41.0",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@testing-library/dom": "^10.4.1",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@types/dompurify": "^3.0.5",
|
||||
"@types/node": "^22.5.5",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^6.0.1",
|
||||
"@webbtc/webln-types": "^3.0.0",
|
||||
"@webxdc/types": "^2.1.2",
|
||||
@@ -155,5 +156,9 @@
|
||||
"typescript-eslint": "^8.0.1",
|
||||
"vite": "^8.0.0",
|
||||
"vitest": "^3.1.4"
|
||||
},
|
||||
"overrides": {
|
||||
"react": "$react",
|
||||
"react-dom": "$react-dom"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export function ThemeContent({ event, expanded }: ThemeContentProps) {
|
||||
// Use direct description from event, or fall back to source theme description
|
||||
const resolvedDescription = parsed?.description ?? sourceDescription ?? undefined;
|
||||
|
||||
const previousThemeRef = useRef<{ mode: Theme; config?: ThemeConfig }>();
|
||||
const previousThemeRef = useRef<{ mode: Theme; config?: ThemeConfig } | undefined>(undefined);
|
||||
|
||||
/** Apply the theme directly when clicked. */
|
||||
const handleApplyTheme = useCallback((e: React.MouseEvent) => {
|
||||
|
||||
@@ -57,8 +57,8 @@ interface ZapContentProps {
|
||||
openInWallet: () => void;
|
||||
setAmount: (amount: number | string) => void;
|
||||
setComment: (comment: string) => void;
|
||||
inputRef: React.RefObject<HTMLInputElement>;
|
||||
commentTextareaRef: React.RefObject<HTMLTextAreaElement>;
|
||||
inputRef: React.RefObject<HTMLInputElement | null>;
|
||||
commentTextareaRef: React.RefObject<HTMLTextAreaElement | null>;
|
||||
insertEmoji: (emoji: string) => void;
|
||||
insertAtCursor: (params: { start: number; end: number; replacement: string }) => void;
|
||||
customEmojis: Array<{ shortcode: string; url: string }>;
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
function LetterAttachment({ event }: { event: NostrEvent }) {
|
||||
const { applyCustomTheme, theme, customTheme, setTheme } = useTheme();
|
||||
const [applied, setApplied] = useState(false);
|
||||
const prevRef = useRef<{ mode: typeof theme; config?: ThemeConfig }>();
|
||||
const prevRef = useRef<{ mode: typeof theme; config?: ThemeConfig } | undefined>(undefined);
|
||||
|
||||
const attachment = useMemo(() => {
|
||||
if (event.kind === COLOR_MOMENT_KIND) {
|
||||
|
||||
@@ -165,7 +165,7 @@ export function SendAnimation({
|
||||
const splatId = useId();
|
||||
|
||||
const [t, setT] = useState(0);
|
||||
const cancelRef = useRef<() => void>();
|
||||
const cancelRef = useRef<(() => void) | undefined>(undefined);
|
||||
const onCompleteRef = useRef(onComplete);
|
||||
onCompleteRef.current = onComplete;
|
||||
|
||||
|
||||
@@ -20,40 +20,46 @@ function Calendar({
|
||||
classNames={{
|
||||
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
|
||||
month: "space-y-4",
|
||||
caption: "flex justify-center pt-1 relative items-center",
|
||||
month_caption: "flex justify-center pt-1 relative items-center",
|
||||
caption_label: "text-sm font-medium",
|
||||
nav: "space-x-1 flex items-center",
|
||||
nav_button: cn(
|
||||
button_previous: cn(
|
||||
buttonVariants({ variant: "outline" }),
|
||||
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
|
||||
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute left-1"
|
||||
),
|
||||
nav_button_previous: "absolute left-1",
|
||||
nav_button_next: "absolute right-1",
|
||||
table: "w-full border-collapse space-y-1",
|
||||
head_row: "flex",
|
||||
head_cell:
|
||||
button_next: cn(
|
||||
buttonVariants({ variant: "outline" }),
|
||||
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 absolute right-1"
|
||||
),
|
||||
month_grid: "w-full border-collapse space-y-1",
|
||||
weekdays: "flex",
|
||||
weekday:
|
||||
"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
|
||||
row: "flex w-full mt-2",
|
||||
cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
|
||||
day: cn(
|
||||
week: "flex w-full mt-2",
|
||||
day: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].rdp-range_end)]:rounded-r-md [&:has([aria-selected].rdp-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
|
||||
day_button: cn(
|
||||
buttonVariants({ variant: "ghost" }),
|
||||
"h-9 w-9 p-0 font-normal aria-selected:opacity-100"
|
||||
),
|
||||
day_range_end: "day-range-end",
|
||||
day_selected:
|
||||
range_end: "rdp-range_end",
|
||||
selected:
|
||||
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
|
||||
day_today: "bg-accent text-accent-foreground",
|
||||
day_outside:
|
||||
"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
|
||||
day_disabled: "text-muted-foreground opacity-50",
|
||||
day_range_middle:
|
||||
today: "bg-accent text-accent-foreground",
|
||||
outside:
|
||||
"rdp-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
|
||||
disabled: "text-muted-foreground opacity-50",
|
||||
range_middle:
|
||||
"aria-selected:bg-accent aria-selected:text-accent-foreground",
|
||||
day_hidden: "invisible",
|
||||
hidden: "invisible",
|
||||
...classNames,
|
||||
}}
|
||||
components={{
|
||||
IconLeft: ({ ..._props }) => <ChevronLeft className="h-4 w-4" />,
|
||||
IconRight: ({ ..._props }) => <ChevronRight className="h-4 w-4" />,
|
||||
Chevron: ({ orientation, ...chevronProps }) =>
|
||||
orientation === "left" ? (
|
||||
<ChevronLeft className="h-4 w-4" {...chevronProps} />
|
||||
) : (
|
||||
<ChevronRight className="h-4 w-4" {...chevronProps} />
|
||||
),
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
@@ -104,7 +104,7 @@ async function fetchTenorTrending(pos?: string): Promise<{ results: GifResult[];
|
||||
export function useGifSearch() {
|
||||
const [query, setQuery] = useState('');
|
||||
const [debouncedQuery, setDebouncedQuery] = useState('');
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout>>();
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||
|
||||
const handleQueryChange = useCallback((value: string) => {
|
||||
setQuery(value);
|
||||
|
||||
@@ -31,7 +31,7 @@ export function usePlayerControls({
|
||||
isPlaying,
|
||||
}: UsePlayerControlsOptions): UsePlayerControlsReturn {
|
||||
const [showControls, setShowControls] = useState(true);
|
||||
const hideTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
|
||||
const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||
|
||||
const scheduleHide = useCallback(() => {
|
||||
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
||||
|
||||
@@ -20,8 +20,8 @@ export function useTheme() {
|
||||
const { updateSettings } = useEncryptedSettings();
|
||||
const { setActiveTheme } = usePublishTheme();
|
||||
const { user } = useCurrentUser();
|
||||
const debounceTimer = useRef<NodeJS.Timeout>();
|
||||
const autoPublishTimer = useRef<NodeJS.Timeout>();
|
||||
const debounceTimer = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
const autoPublishTimer = useRef<NodeJS.Timeout | undefined>(undefined);
|
||||
|
||||
const syncToEncrypted = useCallback((patch: { theme?: Theme; customTheme?: ThemeConfig }) => {
|
||||
if (!user) return;
|
||||
|
||||
@@ -474,7 +474,7 @@ function ArchiveSearchBar() {
|
||||
const [query, setQuery] = useState('');
|
||||
const [debouncedQuery, setDebouncedQuery] = useState('');
|
||||
const [dropdownOpen, setDropdownOpen] = useState(false);
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout>>();
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||
|
||||
const { data: results, isFetching } = useArchiveSearch(debouncedQuery);
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ function BlueskySearchBar() {
|
||||
const [query, setQuery] = useState('');
|
||||
const [debouncedQuery, setDebouncedQuery] = useState('');
|
||||
const [dropdownOpen, setDropdownOpen] = useState(false);
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout>>();
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||
|
||||
const { data: results, isFetching } = useBlueskyActorSearch(debouncedQuery);
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ function BookSearchBar() {
|
||||
const [query, setQuery] = useState('');
|
||||
const [debouncedQuery, setDebouncedQuery] = useState('');
|
||||
const [dropdownOpen, setDropdownOpen] = useState(false);
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout>>();
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||
|
||||
const { data: results, isFetching } = useBookSearch(debouncedQuery);
|
||||
|
||||
|
||||
@@ -367,7 +367,7 @@ function WikipediaSearchBar() {
|
||||
const [query, setQuery] = useState('');
|
||||
const [debouncedQuery, setDebouncedQuery] = useState('');
|
||||
const [dropdownOpen, setDropdownOpen] = useState(false);
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout>>();
|
||||
const debounceRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
|
||||
|
||||
const { data: results, isFetching } = useWikipediaSearch(debouncedQuery);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user