@riktajs/react 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +368 -0
- package/dist/index.cjs +316 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +609 -0
- package/dist/index.d.ts +609 -0
- package/dist/index.js +303 -0
- package/dist/index.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context/RouterContext.ts","../src/context/SsrContext.ts","../src/components/RiktaProvider.tsx","../src/hooks/useNavigation.ts","../src/components/Link.tsx","../src/hooks/useParams.ts","../src/hooks/useSearchParams.ts","../src/hooks/useLocation.ts","../src/hooks/useSsrData.ts","../src/hooks/useHydration.ts","../src/hooks/useFetch.ts","../src/hooks/useAction.ts"],"names":["createContext","useState","useCallback","useEffect","useMemo","jsx","useContext","useRef","actionResult"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createContext } from 'react';\nimport type { RouterContextValue } from '../types.js';\n\n/**\n * Default router context value for when no provider is present\n */\nconst defaultRouterContext: RouterContextValue = {\n pathname: '/',\n search: '',\n href: '/',\n navigate: () => {\n console.warn('[RiktaReact] Router context not initialized. Wrap your app with <RiktaProvider>');\n },\n params: {},\n setParams: () => {},\n};\n\n/**\n * React context for router state\n * Provides navigation utilities and current location info\n */\nexport const RouterContext = createContext<RouterContextValue>(defaultRouterContext);\n\nRouterContext.displayName = 'RiktaRouterContext';\n","import { createContext } from 'react';\nimport type { SsrData } from '../types.js';\n\n/**\n * React context for SSR data\n * Holds the server-rendered data passed via window.__SSR_DATA__\n */\nexport const SsrContext = createContext<SsrData | null>(null);\n\nSsrContext.displayName = 'RiktaSsrContext';\n","import { useState, useCallback, useEffect, useMemo, type FC } from 'react';\nimport { RouterContext } from '../context/RouterContext.js';\nimport { SsrContext } from '../context/SsrContext.js';\nimport type { RiktaProviderProps, SsrData, NavigateOptions } from '../types.js';\n\n/**\n * Get current location from window or fallback for SSR\n */\nfunction getLocationInfo() {\n if (typeof window === 'undefined') {\n return { pathname: '/', search: '', href: '/' };\n }\n return {\n pathname: window.location.pathname,\n search: window.location.search.slice(1), // Remove leading ?\n href: window.location.href,\n };\n}\n\n/**\n * Get SSR data from window\n */\nfunction getSsrData(): SsrData | undefined {\n if (typeof window === 'undefined') return undefined;\n return window.__SSR_DATA__;\n}\n\n/**\n * RiktaProvider - Main provider component for Rikta React utilities\n * \n * Provides routing context, SSR data, and navigation utilities to the app.\n * \n * @example\n * ```tsx\n * // In entry-client.tsx\n * import { RiktaProvider } from '@riktajs/react';\n * \n * hydrateRoot(\n * document.getElementById('root')!,\n * <RiktaProvider>\n * <App />\n * </RiktaProvider>\n * );\n * ```\n */\nexport const RiktaProvider: FC<RiktaProviderProps> = ({\n ssrData: initialSsrData,\n initialParams = {},\n children,\n}) => {\n // Initialize SSR data from window or props\n const [ssrData] = useState<SsrData | null>(() => {\n return initialSsrData ?? getSsrData() ?? null;\n });\n\n // Initialize location state\n const [location, setLocation] = useState(getLocationInfo);\n \n // Route params state\n const [params, setParams] = useState<Record<string, string>>(initialParams);\n\n /**\n * Navigate to a new URL using History API\n */\n const navigate = useCallback((url: string, options: NavigateOptions = {}) => {\n const { replace = false, scroll = true, state } = options;\n\n if (typeof window === 'undefined') return;\n\n // Handle full URLs vs relative paths\n let targetUrl: URL;\n try {\n targetUrl = new URL(url, window.location.origin);\n } catch {\n console.error(`[RiktaReact] Invalid URL: ${url}`);\n return;\n }\n\n // Only handle same-origin navigation\n if (targetUrl.origin !== window.location.origin) {\n window.location.href = url;\n return;\n }\n\n // Update history\n if (replace) {\n window.history.replaceState(state ?? null, '', targetUrl.href);\n } else {\n window.history.pushState(state ?? null, '', targetUrl.href);\n }\n\n // Update location state\n setLocation({\n pathname: targetUrl.pathname,\n search: targetUrl.search.slice(1),\n href: targetUrl.href,\n });\n\n // Scroll to top if requested\n if (scroll) {\n window.scrollTo(0, 0);\n }\n\n // Dispatch popstate event for any other listeners\n window.dispatchEvent(new PopStateEvent('popstate', { state }));\n }, []);\n\n // Listen for popstate (browser back/forward)\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handlePopState = () => {\n setLocation(getLocationInfo());\n };\n\n window.addEventListener('popstate', handlePopState);\n return () => window.removeEventListener('popstate', handlePopState);\n }, []);\n\n // Memoize router context value\n const routerValue = useMemo(() => ({\n pathname: location.pathname,\n search: location.search,\n href: location.href,\n navigate,\n params,\n setParams,\n }), [location.pathname, location.search, location.href, navigate, params]);\n\n return (\n <SsrContext.Provider value={ssrData}>\n <RouterContext.Provider value={routerValue}>\n {children}\n </RouterContext.Provider>\n </SsrContext.Provider>\n );\n};\n\nRiktaProvider.displayName = 'RiktaProvider';\n","import { useContext, useCallback } from 'react';\nimport { RouterContext } from '../context/RouterContext.js';\nimport type { NavigateOptions } from '../types.js';\n\n/**\n * Hook for programmatic navigation\n * \n * @returns Object with navigate function and current location info\n * \n * @example\n * ```tsx\n * import { useNavigation } from '@riktajs/react';\n * \n * function MyComponent() {\n * const { navigate, pathname } = useNavigation();\n * \n * const handleSubmit = async () => {\n * await saveData();\n * navigate('/success');\n * };\n * \n * return (\n * <button onClick={handleSubmit}>\n * Submit (current path: {pathname})\n * </button>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // With options\n * const { navigate } = useNavigation();\n * \n * // Replace history entry (for redirects)\n * navigate('/login', { replace: true });\n * \n * // Don't scroll to top\n * navigate('/next', { scroll: false });\n * \n * // Pass state\n * navigate('/edit', { state: { from: 'list' } });\n * ```\n */\nexport function useNavigation() {\n const context = useContext(RouterContext);\n\n const navigate = useCallback(\n (url: string, options?: NavigateOptions) => {\n context.navigate(url, options);\n },\n [context.navigate]\n );\n\n return {\n /** Navigate to a new URL */\n navigate,\n /** Current pathname */\n pathname: context.pathname,\n /** Current search string (without ?) */\n search: context.search,\n /** Full href */\n href: context.href,\n };\n}\n","import { useCallback, type FC, type MouseEvent } from 'react';\nimport { useNavigation } from '../hooks/useNavigation.js';\nimport type { LinkProps } from '../types.js';\n\n/**\n * Link component for client-side navigation\n * \n * Renders an anchor tag that uses the History API for navigation\n * instead of causing a full page reload.\n * \n * @example\n * ```tsx\n * import { Link } from '@riktajs/react';\n * \n * function Nav() {\n * return (\n * <nav>\n * <Link href=\"/\">Home</Link>\n * <Link href=\"/about\">About</Link>\n * <Link href=\"/items/123\">Item 123</Link>\n * </nav>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // With options\n * <Link href=\"/dashboard\" replace scroll={false}>\n * Dashboard\n * </Link>\n * ```\n */\nexport const Link: FC<LinkProps> = ({\n href,\n replace = false,\n scroll = true,\n prefetch = false,\n state,\n children,\n onClick,\n ...restProps\n}) => {\n const { navigate } = useNavigation();\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLAnchorElement>) => {\n // Call user's onClick handler if provided\n onClick?.(e);\n\n // Don't handle if default was prevented\n if (e.defaultPrevented) return;\n\n // Don't handle modified clicks (open in new tab, etc.)\n if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;\n\n // Don't handle right clicks\n if (e.button !== 0) return;\n\n // Don't handle target=\"_blank\" etc.\n const target = (e.currentTarget as HTMLAnchorElement).target;\n if (target && target !== '_self') return;\n\n // Don't handle external links\n try {\n const url = new URL(href, window.location.origin);\n if (url.origin !== window.location.origin) return;\n } catch {\n return;\n }\n\n // Handle the navigation\n e.preventDefault();\n navigate(href, { replace, scroll, state });\n },\n [href, replace, scroll, state, navigate, onClick]\n );\n\n // Prefetch support could be added here in the future\n // using <link rel=\"prefetch\"> or Intersection Observer\n\n return (\n <a href={href} onClick={handleClick} {...restProps}>\n {children}\n </a>\n );\n};\n\nLink.displayName = 'Link';\n","import { useContext } from 'react';\nimport { RouterContext } from '../context/RouterContext.js';\n\n/**\n * Hook to access route parameters\n * \n * Route parameters are extracted from the URL path by the server\n * and passed via SSR data. They're stored in the RouterContext.\n * \n * @returns Object with route parameter values\n * \n * @example\n * ```tsx\n * // For route /item/:id\n * import { useParams } from '@riktajs/react';\n * \n * function ItemPage() {\n * const { id } = useParams<{ id: string }>();\n * \n * return <h1>Item {id}</h1>;\n * }\n * ```\n * \n * @example\n * ```tsx\n * // Multiple params - /users/:userId/posts/:postId\n * function PostPage() {\n * const { userId, postId } = useParams<{ userId: string; postId: string }>();\n * \n * return <h1>Post {postId} by User {userId}</h1>;\n * }\n * ```\n */\nexport function useParams<T extends Record<string, string> = Record<string, string>>(): T {\n const context = useContext(RouterContext);\n return context.params as T;\n}\n","import { useContext, useMemo } from 'react';\nimport { RouterContext } from '../context/RouterContext.js';\n\n/**\n * Hook to access and manipulate URL search parameters\n * \n * @returns Tuple of [URLSearchParams, setSearchParams function]\n * \n * @example\n * ```tsx\n * import { useSearchParams } from '@riktajs/react';\n * \n * function SearchPage() {\n * const [searchParams, setSearchParams] = useSearchParams();\n * const query = searchParams.get('q') ?? '';\n * const page = parseInt(searchParams.get('page') ?? '1', 10);\n * \n * const handleSearch = (newQuery: string) => {\n * setSearchParams({ q: newQuery, page: '1' });\n * };\n * \n * const handleNextPage = () => {\n * setSearchParams({ q: query, page: String(page + 1) });\n * };\n * \n * return (\n * <div>\n * <input \n * value={query} \n * onChange={(e) => handleSearch(e.target.value)} \n * />\n * <button onClick={handleNextPage}>Next Page</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useSearchParams(): [URLSearchParams, (params: Record<string, string> | URLSearchParams) => void] {\n const context = useContext(RouterContext);\n\n const searchParams = useMemo(() => {\n return new URLSearchParams(context.search);\n }, [context.search]);\n\n const setSearchParams = useMemo(() => {\n return (params: Record<string, string> | URLSearchParams) => {\n const newParams = params instanceof URLSearchParams \n ? params \n : new URLSearchParams(params);\n \n const search = newParams.toString();\n const newUrl = search \n ? `${context.pathname}?${search}` \n : context.pathname;\n \n context.navigate(newUrl, { scroll: false });\n };\n }, [context.pathname, context.navigate]);\n\n return [searchParams, setSearchParams];\n}\n","import { useContext } from 'react';\nimport { RouterContext } from '../context/RouterContext.js';\n\n/**\n * Location object returned by useLocation\n */\nexport interface Location {\n /** Current pathname (e.g., /items/123) */\n pathname: string;\n /** Current search string without ? (e.g., page=2&sort=asc) */\n search: string;\n /** Full href */\n href: string;\n /** Parsed search params */\n searchParams: URLSearchParams;\n}\n\n/**\n * Hook to access current location information\n * \n * @returns Location object with pathname, search, href, and searchParams\n * \n * @example\n * ```tsx\n * import { useLocation } from '@riktajs/react';\n * \n * function Breadcrumbs() {\n * const location = useLocation();\n * \n * return (\n * <nav>\n * Current path: {location.pathname}\n * {location.search && <span>?{location.search}</span>}\n * </nav>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // Access search params\n * function FilterDisplay() {\n * const { searchParams } = useLocation();\n * const filter = searchParams.get('filter');\n * \n * return filter ? <span>Filtered by: {filter}</span> : null;\n * }\n * ```\n */\nexport function useLocation(): Location {\n const context = useContext(RouterContext);\n\n return {\n pathname: context.pathname,\n search: context.search,\n href: context.href,\n searchParams: new URLSearchParams(context.search),\n };\n}\n","import { useContext } from 'react';\nimport { SsrContext } from '../context/SsrContext.js';\nimport type { SsrData } from '../types.js';\n\n/**\n * Hook to access SSR data passed from server\n * \n * SSR data is passed via window.__SSR_DATA__ and contains\n * the initial data rendered on the server.\n * \n * @returns SSR data object or null if not available\n * \n * @example\n * ```tsx\n * import { useSsrData } from '@riktajs/react';\n * \n * interface PageData {\n * title: string;\n * items: Array<{ id: string; name: string }>;\n * }\n * \n * function ItemList() {\n * const ssrData = useSsrData<PageData>();\n * \n * if (!ssrData) {\n * return <div>Loading...</div>;\n * }\n * \n * return (\n * <div>\n * <h1>{ssrData.data.title}</h1>\n * <ul>\n * {ssrData.data.items.map(item => (\n * <li key={item.id}>{item.name}</li>\n * ))}\n * </ul>\n * </div>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // Access just the data\n * function MyComponent() {\n * const ssrData = useSsrData<{ user: User }>();\n * const user = ssrData?.data.user;\n * \n * return user ? <UserProfile user={user} /> : <LoginPrompt />;\n * }\n * ```\n */\nexport function useSsrData<T = unknown>(): SsrData<T> | null {\n const context = useContext(SsrContext);\n return context as SsrData<T> | null;\n}\n","import { useState, useEffect } from 'react';\nimport type { HydrationState } from '../types.js';\n\n/**\n * Hook to track hydration state\n * \n * Useful for rendering different content during SSR vs after hydration,\n * or for avoiding hydration mismatches.\n * \n * @returns Hydration state object\n * \n * @example\n * ```tsx\n * import { useHydration } from '@riktajs/react';\n * \n * function TimeDisplay() {\n * const { isHydrated, isServer } = useHydration();\n * \n * // On server and initial render, show static content\n * // After hydration, show dynamic content\n * if (!isHydrated) {\n * return <span>Loading time...</span>;\n * }\n * \n * return <span>{new Date().toLocaleTimeString()}</span>;\n * }\n * ```\n * \n * @example\n * ```tsx\n * // Avoid hydration mismatch with client-only content\n * function ClientOnlyComponent() {\n * const { isHydrated } = useHydration();\n * \n * if (!isHydrated) {\n * return null; // Or a placeholder\n * }\n * \n * return <SomeClientOnlyLibrary />;\n * }\n * ```\n * \n * @example\n * ```tsx\n * // Conditional rendering based on environment\n * function DebugPanel() {\n * const { isServer } = useHydration();\n * \n * // Never render on server, only after client hydration\n * if (isServer) return null;\n * \n * return <DevTools />;\n * }\n * ```\n */\nexport function useHydration(): HydrationState {\n const isServer = typeof window === 'undefined';\n const [isHydrated, setIsHydrated] = useState(false);\n\n useEffect(() => {\n setIsHydrated(true);\n }, []);\n\n return {\n isHydrated,\n isServer,\n };\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport type { FetchState } from '../types.js';\n\n/**\n * Options for useFetch hook\n */\nexport interface UseFetchOptions extends Omit<RequestInit, 'body'> {\n /** Skip initial fetch (useful for conditional fetching) */\n skip?: boolean;\n /** Dependencies that trigger refetch when changed */\n deps?: unknown[];\n /** Transform response before setting data */\n transform?: (data: unknown) => unknown;\n}\n\n/**\n * Hook for data fetching with loading and error states\n * \n * @param url URL to fetch from\n * @param options Fetch options\n * @returns Fetch state with data, loading, error, and refetch function\n * \n * @example\n * ```tsx\n * import { useFetch } from '@riktajs/react';\n * \n * interface User {\n * id: string;\n * name: string;\n * }\n * \n * function UserProfile({ userId }: { userId: string }) {\n * const { data, loading, error, refetch } = useFetch<User>(\n * `/api/users/${userId}`\n * );\n * \n * if (loading) return <Spinner />;\n * if (error) return <Error message={error} />;\n * if (!data) return null;\n * \n * return (\n * <div>\n * <h1>{data.name}</h1>\n * <button onClick={refetch}>Refresh</button>\n * </div>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // With options\n * const { data } = useFetch<Item[]>('/api/items', {\n * headers: { 'Authorization': `Bearer ${token}` },\n * deps: [token], // Refetch when token changes\n * skip: !token, // Don't fetch until we have a token\n * });\n * ```\n * \n * @example\n * ```tsx\n * // With transform\n * const { data } = useFetch<{ results: Item[] }>('/api/search', {\n * transform: (res) => res.results, // Extract just the results array\n * });\n * ```\n */\nexport function useFetch<T = unknown>(\n url: string,\n options: UseFetchOptions = {}\n): FetchState<T> {\n const { skip = false, deps = [], transform, ...fetchOptions } = options;\n \n const [state, setState] = useState<Omit<FetchState<T>, 'refetch'>>({\n data: null,\n loading: !skip,\n error: null,\n });\n\n // Use ref to track if component is mounted\n const mountedRef = useRef(true);\n // Use ref to track current fetch to handle race conditions\n const fetchIdRef = useRef(0);\n\n const fetchData = useCallback(async () => {\n if (skip) return;\n\n const fetchId = ++fetchIdRef.current;\n setState(prev => ({ ...prev, loading: true, error: null }));\n\n try {\n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n let data = await response.json();\n\n // Apply transform if provided\n if (transform) {\n data = transform(data);\n }\n\n // Only update state if this is still the current fetch and component is mounted\n if (fetchId === fetchIdRef.current && mountedRef.current) {\n setState({ data: data as T, loading: false, error: null });\n }\n } catch (err) {\n if (fetchId === fetchIdRef.current && mountedRef.current) {\n const message = err instanceof Error ? err.message : 'An error occurred';\n setState({ data: null, loading: false, error: message });\n }\n }\n }, [url, skip, JSON.stringify(fetchOptions), transform]);\n\n // Fetch on mount and when dependencies change\n useEffect(() => {\n mountedRef.current = true;\n fetchData();\n\n return () => {\n mountedRef.current = false;\n };\n }, [fetchData, ...deps]);\n\n const refetch = useCallback(async () => {\n await fetchData();\n }, [fetchData]);\n\n return {\n ...state,\n refetch,\n };\n}\n","import { useState, useCallback } from 'react';\nimport type { ActionResult, ActionState } from '../types.js';\n\n/**\n * Options for useAction hook\n */\nexport interface UseActionOptions<TResult = unknown> {\n /** Callback on successful action */\n onSuccess?: (result: TResult) => void;\n /** Callback on action error */\n onError?: (error: string) => void;\n /** HTTP method to use */\n method?: 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n /** Additional headers */\n headers?: Record<string, string>;\n}\n\n/**\n * Hook for executing server actions (form submissions, mutations)\n * \n * @param url URL to send the action to\n * @param options Action options\n * @returns Action state with execute, pending, result, and reset\n * \n * @example\n * ```tsx\n * import { useAction } from '@riktajs/react';\n * \n * interface CreateItemInput {\n * name: string;\n * price: number;\n * }\n * \n * interface Item {\n * id: string;\n * name: string;\n * price: number;\n * }\n * \n * function CreateItemForm() {\n * const { execute, pending, result } = useAction<CreateItemInput, Item>(\n * '/api/items',\n * {\n * onSuccess: (item) => {\n * console.log('Created item:', item);\n * },\n * }\n * );\n * \n * const handleSubmit = async (e: FormEvent) => {\n * e.preventDefault();\n * const formData = new FormData(e.target as HTMLFormElement);\n * await execute({\n * name: formData.get('name') as string,\n * price: Number(formData.get('price')),\n * });\n * };\n * \n * return (\n * <form onSubmit={handleSubmit}>\n * <input name=\"name\" required />\n * <input name=\"price\" type=\"number\" required />\n * <button disabled={pending}>\n * {pending ? 'Creating...' : 'Create Item'}\n * </button>\n * {result?.error && <p className=\"error\">{result.error}</p>}\n * {result?.fieldErrors?.name && (\n * <p className=\"error\">{result.fieldErrors.name[0]}</p>\n * )}\n * </form>\n * );\n * }\n * ```\n * \n * @example\n * ```tsx\n * // DELETE action\n * const { execute, pending } = useAction<{ id: string }, void>(\n * '/api/items',\n * { method: 'DELETE' }\n * );\n * \n * const handleDelete = () => execute({ id: itemId });\n * ```\n */\nexport function useAction<TInput = unknown, TResult = unknown>(\n url: string,\n options: UseActionOptions<TResult> = {}\n): ActionState<TInput, TResult> {\n const {\n onSuccess,\n onError,\n method = 'POST',\n headers: customHeaders = {},\n } = options;\n\n const [pending, setPending] = useState(false);\n const [result, setResult] = useState<ActionResult<TResult> | null>(null);\n\n const execute = useCallback(\n async (input: TInput): Promise<ActionResult<TResult>> => {\n setPending(true);\n setResult(null);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...customHeaders,\n },\n body: JSON.stringify(input),\n });\n\n const data = await response.json();\n\n if (!response.ok) {\n // Handle error response\n const actionResult: ActionResult<TResult> = {\n success: false,\n error: data.message || data.error || `HTTP ${response.status}`,\n fieldErrors: data.fieldErrors,\n };\n setResult(actionResult);\n onError?.(actionResult.error!);\n return actionResult;\n }\n\n // Handle success response\n const actionResult: ActionResult<TResult> = {\n success: true,\n data: data as TResult,\n };\n setResult(actionResult);\n onSuccess?.(data as TResult);\n return actionResult;\n } catch (err) {\n const message = err instanceof Error ? err.message : 'An error occurred';\n const actionResult: ActionResult<TResult> = {\n success: false,\n error: message,\n };\n setResult(actionResult);\n onError?.(message);\n return actionResult;\n } finally {\n setPending(false);\n }\n },\n [url, method, JSON.stringify(customHeaders), onSuccess, onError]\n );\n\n const reset = useCallback(() => {\n setResult(null);\n }, []);\n\n return {\n execute,\n pending,\n result,\n reset,\n };\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { FC } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SSR data structure passed from server to client
|
|
6
|
+
* via window.__SSR_DATA__
|
|
7
|
+
*/
|
|
8
|
+
interface SsrData<T = unknown> {
|
|
9
|
+
/** Initial data rendered on server */
|
|
10
|
+
data: T;
|
|
11
|
+
/** Current URL path */
|
|
12
|
+
url: string;
|
|
13
|
+
/** HTTP status code */
|
|
14
|
+
status?: number;
|
|
15
|
+
/** Additional metadata */
|
|
16
|
+
meta?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Router context value interface
|
|
20
|
+
*/
|
|
21
|
+
interface RouterContextValue {
|
|
22
|
+
/** Current URL path */
|
|
23
|
+
pathname: string;
|
|
24
|
+
/** Current search params string (without ?) */
|
|
25
|
+
search: string;
|
|
26
|
+
/** Full URL */
|
|
27
|
+
href: string;
|
|
28
|
+
/** Navigate to a new URL */
|
|
29
|
+
navigate: (url: string, options?: NavigateOptions) => void;
|
|
30
|
+
/** Extracted route params (e.g., { id: '123' } for /item/:id) */
|
|
31
|
+
params: Record<string, string>;
|
|
32
|
+
/** Update route params (used internally by RiktaProvider) */
|
|
33
|
+
setParams: (params: Record<string, string>) => void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Navigation options
|
|
37
|
+
*/
|
|
38
|
+
interface NavigateOptions {
|
|
39
|
+
/** Replace current history entry instead of pushing */
|
|
40
|
+
replace?: boolean;
|
|
41
|
+
/** Scroll to top after navigation */
|
|
42
|
+
scroll?: boolean;
|
|
43
|
+
/** Additional state to store in history */
|
|
44
|
+
state?: unknown;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Result type for server actions
|
|
48
|
+
*/
|
|
49
|
+
interface ActionResult<T = unknown> {
|
|
50
|
+
/** Whether the action was successful */
|
|
51
|
+
success: boolean;
|
|
52
|
+
/** Response data on success */
|
|
53
|
+
data?: T;
|
|
54
|
+
/** Error message on failure */
|
|
55
|
+
error?: string;
|
|
56
|
+
/** Field-specific validation errors */
|
|
57
|
+
fieldErrors?: Record<string, string[]>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Fetch state for useFetch hook
|
|
61
|
+
*/
|
|
62
|
+
interface FetchState<T = unknown> {
|
|
63
|
+
/** Fetched data */
|
|
64
|
+
data: T | null;
|
|
65
|
+
/** Whether fetch is in progress */
|
|
66
|
+
loading: boolean;
|
|
67
|
+
/** Error message if fetch failed */
|
|
68
|
+
error: string | null;
|
|
69
|
+
/** Manually refetch data */
|
|
70
|
+
refetch: () => Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Action state for useAction hook
|
|
74
|
+
*/
|
|
75
|
+
interface ActionState<TInput = unknown, TResult = unknown> {
|
|
76
|
+
/** Execute the action */
|
|
77
|
+
execute: (input: TInput) => Promise<ActionResult<TResult>>;
|
|
78
|
+
/** Whether action is executing */
|
|
79
|
+
pending: boolean;
|
|
80
|
+
/** Last action result */
|
|
81
|
+
result: ActionResult<TResult> | null;
|
|
82
|
+
/** Reset action state */
|
|
83
|
+
reset: () => void;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Link component props
|
|
87
|
+
*/
|
|
88
|
+
interface LinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> {
|
|
89
|
+
/** Target URL */
|
|
90
|
+
href: string;
|
|
91
|
+
/** Replace history entry instead of push */
|
|
92
|
+
replace?: boolean;
|
|
93
|
+
/** Scroll to top after navigation */
|
|
94
|
+
scroll?: boolean;
|
|
95
|
+
/** Prefetch the linked page (future enhancement) */
|
|
96
|
+
prefetch?: boolean;
|
|
97
|
+
/** Additional state to pass to navigation */
|
|
98
|
+
state?: unknown;
|
|
99
|
+
/** Children elements */
|
|
100
|
+
children: React.ReactNode;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* RiktaProvider props
|
|
104
|
+
*/
|
|
105
|
+
interface RiktaProviderProps {
|
|
106
|
+
/** Initial SSR data from server */
|
|
107
|
+
ssrData?: SsrData;
|
|
108
|
+
/** Initial route params extracted from URL */
|
|
109
|
+
initialParams?: Record<string, string>;
|
|
110
|
+
/** Children elements */
|
|
111
|
+
children: React.ReactNode;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Hydration state
|
|
115
|
+
*/
|
|
116
|
+
interface HydrationState {
|
|
117
|
+
/** Whether the app has hydrated on client */
|
|
118
|
+
isHydrated: boolean;
|
|
119
|
+
/** Whether currently running on server */
|
|
120
|
+
isServer: boolean;
|
|
121
|
+
}
|
|
122
|
+
declare global {
|
|
123
|
+
interface Window {
|
|
124
|
+
__SSR_DATA__?: SsrData;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* React context for router state
|
|
130
|
+
* Provides navigation utilities and current location info
|
|
131
|
+
*/
|
|
132
|
+
declare const RouterContext: react.Context<RouterContextValue>;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* React context for SSR data
|
|
136
|
+
* Holds the server-rendered data passed via window.__SSR_DATA__
|
|
137
|
+
*/
|
|
138
|
+
declare const SsrContext: react.Context<SsrData<unknown> | null>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* RiktaProvider - Main provider component for Rikta React utilities
|
|
142
|
+
*
|
|
143
|
+
* Provides routing context, SSR data, and navigation utilities to the app.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```tsx
|
|
147
|
+
* // In entry-client.tsx
|
|
148
|
+
* import { RiktaProvider } from '@riktajs/react';
|
|
149
|
+
*
|
|
150
|
+
* hydrateRoot(
|
|
151
|
+
* document.getElementById('root')!,
|
|
152
|
+
* <RiktaProvider>
|
|
153
|
+
* <App />
|
|
154
|
+
* </RiktaProvider>
|
|
155
|
+
* );
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
declare const RiktaProvider: FC<RiktaProviderProps>;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Link component for client-side navigation
|
|
162
|
+
*
|
|
163
|
+
* Renders an anchor tag that uses the History API for navigation
|
|
164
|
+
* instead of causing a full page reload.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```tsx
|
|
168
|
+
* import { Link } from '@riktajs/react';
|
|
169
|
+
*
|
|
170
|
+
* function Nav() {
|
|
171
|
+
* return (
|
|
172
|
+
* <nav>
|
|
173
|
+
* <Link href="/">Home</Link>
|
|
174
|
+
* <Link href="/about">About</Link>
|
|
175
|
+
* <Link href="/items/123">Item 123</Link>
|
|
176
|
+
* </nav>
|
|
177
|
+
* );
|
|
178
|
+
* }
|
|
179
|
+
* ```
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```tsx
|
|
183
|
+
* // With options
|
|
184
|
+
* <Link href="/dashboard" replace scroll={false}>
|
|
185
|
+
* Dashboard
|
|
186
|
+
* </Link>
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
declare const Link: FC<LinkProps>;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Hook for programmatic navigation
|
|
193
|
+
*
|
|
194
|
+
* @returns Object with navigate function and current location info
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```tsx
|
|
198
|
+
* import { useNavigation } from '@riktajs/react';
|
|
199
|
+
*
|
|
200
|
+
* function MyComponent() {
|
|
201
|
+
* const { navigate, pathname } = useNavigation();
|
|
202
|
+
*
|
|
203
|
+
* const handleSubmit = async () => {
|
|
204
|
+
* await saveData();
|
|
205
|
+
* navigate('/success');
|
|
206
|
+
* };
|
|
207
|
+
*
|
|
208
|
+
* return (
|
|
209
|
+
* <button onClick={handleSubmit}>
|
|
210
|
+
* Submit (current path: {pathname})
|
|
211
|
+
* </button>
|
|
212
|
+
* );
|
|
213
|
+
* }
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```tsx
|
|
218
|
+
* // With options
|
|
219
|
+
* const { navigate } = useNavigation();
|
|
220
|
+
*
|
|
221
|
+
* // Replace history entry (for redirects)
|
|
222
|
+
* navigate('/login', { replace: true });
|
|
223
|
+
*
|
|
224
|
+
* // Don't scroll to top
|
|
225
|
+
* navigate('/next', { scroll: false });
|
|
226
|
+
*
|
|
227
|
+
* // Pass state
|
|
228
|
+
* navigate('/edit', { state: { from: 'list' } });
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
declare function useNavigation(): {
|
|
232
|
+
/** Navigate to a new URL */
|
|
233
|
+
navigate: (url: string, options?: NavigateOptions) => void;
|
|
234
|
+
/** Current pathname */
|
|
235
|
+
pathname: string;
|
|
236
|
+
/** Current search string (without ?) */
|
|
237
|
+
search: string;
|
|
238
|
+
/** Full href */
|
|
239
|
+
href: string;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Hook to access route parameters
|
|
244
|
+
*
|
|
245
|
+
* Route parameters are extracted from the URL path by the server
|
|
246
|
+
* and passed via SSR data. They're stored in the RouterContext.
|
|
247
|
+
*
|
|
248
|
+
* @returns Object with route parameter values
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```tsx
|
|
252
|
+
* // For route /item/:id
|
|
253
|
+
* import { useParams } from '@riktajs/react';
|
|
254
|
+
*
|
|
255
|
+
* function ItemPage() {
|
|
256
|
+
* const { id } = useParams<{ id: string }>();
|
|
257
|
+
*
|
|
258
|
+
* return <h1>Item {id}</h1>;
|
|
259
|
+
* }
|
|
260
|
+
* ```
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```tsx
|
|
264
|
+
* // Multiple params - /users/:userId/posts/:postId
|
|
265
|
+
* function PostPage() {
|
|
266
|
+
* const { userId, postId } = useParams<{ userId: string; postId: string }>();
|
|
267
|
+
*
|
|
268
|
+
* return <h1>Post {postId} by User {userId}</h1>;
|
|
269
|
+
* }
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
declare function useParams<T extends Record<string, string> = Record<string, string>>(): T;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Hook to access and manipulate URL search parameters
|
|
276
|
+
*
|
|
277
|
+
* @returns Tuple of [URLSearchParams, setSearchParams function]
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```tsx
|
|
281
|
+
* import { useSearchParams } from '@riktajs/react';
|
|
282
|
+
*
|
|
283
|
+
* function SearchPage() {
|
|
284
|
+
* const [searchParams, setSearchParams] = useSearchParams();
|
|
285
|
+
* const query = searchParams.get('q') ?? '';
|
|
286
|
+
* const page = parseInt(searchParams.get('page') ?? '1', 10);
|
|
287
|
+
*
|
|
288
|
+
* const handleSearch = (newQuery: string) => {
|
|
289
|
+
* setSearchParams({ q: newQuery, page: '1' });
|
|
290
|
+
* };
|
|
291
|
+
*
|
|
292
|
+
* const handleNextPage = () => {
|
|
293
|
+
* setSearchParams({ q: query, page: String(page + 1) });
|
|
294
|
+
* };
|
|
295
|
+
*
|
|
296
|
+
* return (
|
|
297
|
+
* <div>
|
|
298
|
+
* <input
|
|
299
|
+
* value={query}
|
|
300
|
+
* onChange={(e) => handleSearch(e.target.value)}
|
|
301
|
+
* />
|
|
302
|
+
* <button onClick={handleNextPage}>Next Page</button>
|
|
303
|
+
* </div>
|
|
304
|
+
* );
|
|
305
|
+
* }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
declare function useSearchParams(): [URLSearchParams, (params: Record<string, string> | URLSearchParams) => void];
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Location object returned by useLocation
|
|
312
|
+
*/
|
|
313
|
+
interface Location {
|
|
314
|
+
/** Current pathname (e.g., /items/123) */
|
|
315
|
+
pathname: string;
|
|
316
|
+
/** Current search string without ? (e.g., page=2&sort=asc) */
|
|
317
|
+
search: string;
|
|
318
|
+
/** Full href */
|
|
319
|
+
href: string;
|
|
320
|
+
/** Parsed search params */
|
|
321
|
+
searchParams: URLSearchParams;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Hook to access current location information
|
|
325
|
+
*
|
|
326
|
+
* @returns Location object with pathname, search, href, and searchParams
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* ```tsx
|
|
330
|
+
* import { useLocation } from '@riktajs/react';
|
|
331
|
+
*
|
|
332
|
+
* function Breadcrumbs() {
|
|
333
|
+
* const location = useLocation();
|
|
334
|
+
*
|
|
335
|
+
* return (
|
|
336
|
+
* <nav>
|
|
337
|
+
* Current path: {location.pathname}
|
|
338
|
+
* {location.search && <span>?{location.search}</span>}
|
|
339
|
+
* </nav>
|
|
340
|
+
* );
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* ```tsx
|
|
346
|
+
* // Access search params
|
|
347
|
+
* function FilterDisplay() {
|
|
348
|
+
* const { searchParams } = useLocation();
|
|
349
|
+
* const filter = searchParams.get('filter');
|
|
350
|
+
*
|
|
351
|
+
* return filter ? <span>Filtered by: {filter}</span> : null;
|
|
352
|
+
* }
|
|
353
|
+
* ```
|
|
354
|
+
*/
|
|
355
|
+
declare function useLocation(): Location;
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Hook to access SSR data passed from server
|
|
359
|
+
*
|
|
360
|
+
* SSR data is passed via window.__SSR_DATA__ and contains
|
|
361
|
+
* the initial data rendered on the server.
|
|
362
|
+
*
|
|
363
|
+
* @returns SSR data object or null if not available
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```tsx
|
|
367
|
+
* import { useSsrData } from '@riktajs/react';
|
|
368
|
+
*
|
|
369
|
+
* interface PageData {
|
|
370
|
+
* title: string;
|
|
371
|
+
* items: Array<{ id: string; name: string }>;
|
|
372
|
+
* }
|
|
373
|
+
*
|
|
374
|
+
* function ItemList() {
|
|
375
|
+
* const ssrData = useSsrData<PageData>();
|
|
376
|
+
*
|
|
377
|
+
* if (!ssrData) {
|
|
378
|
+
* return <div>Loading...</div>;
|
|
379
|
+
* }
|
|
380
|
+
*
|
|
381
|
+
* return (
|
|
382
|
+
* <div>
|
|
383
|
+
* <h1>{ssrData.data.title}</h1>
|
|
384
|
+
* <ul>
|
|
385
|
+
* {ssrData.data.items.map(item => (
|
|
386
|
+
* <li key={item.id}>{item.name}</li>
|
|
387
|
+
* ))}
|
|
388
|
+
* </ul>
|
|
389
|
+
* </div>
|
|
390
|
+
* );
|
|
391
|
+
* }
|
|
392
|
+
* ```
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```tsx
|
|
396
|
+
* // Access just the data
|
|
397
|
+
* function MyComponent() {
|
|
398
|
+
* const ssrData = useSsrData<{ user: User }>();
|
|
399
|
+
* const user = ssrData?.data.user;
|
|
400
|
+
*
|
|
401
|
+
* return user ? <UserProfile user={user} /> : <LoginPrompt />;
|
|
402
|
+
* }
|
|
403
|
+
* ```
|
|
404
|
+
*/
|
|
405
|
+
declare function useSsrData<T = unknown>(): SsrData<T> | null;
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Hook to track hydration state
|
|
409
|
+
*
|
|
410
|
+
* Useful for rendering different content during SSR vs after hydration,
|
|
411
|
+
* or for avoiding hydration mismatches.
|
|
412
|
+
*
|
|
413
|
+
* @returns Hydration state object
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```tsx
|
|
417
|
+
* import { useHydration } from '@riktajs/react';
|
|
418
|
+
*
|
|
419
|
+
* function TimeDisplay() {
|
|
420
|
+
* const { isHydrated, isServer } = useHydration();
|
|
421
|
+
*
|
|
422
|
+
* // On server and initial render, show static content
|
|
423
|
+
* // After hydration, show dynamic content
|
|
424
|
+
* if (!isHydrated) {
|
|
425
|
+
* return <span>Loading time...</span>;
|
|
426
|
+
* }
|
|
427
|
+
*
|
|
428
|
+
* return <span>{new Date().toLocaleTimeString()}</span>;
|
|
429
|
+
* }
|
|
430
|
+
* ```
|
|
431
|
+
*
|
|
432
|
+
* @example
|
|
433
|
+
* ```tsx
|
|
434
|
+
* // Avoid hydration mismatch with client-only content
|
|
435
|
+
* function ClientOnlyComponent() {
|
|
436
|
+
* const { isHydrated } = useHydration();
|
|
437
|
+
*
|
|
438
|
+
* if (!isHydrated) {
|
|
439
|
+
* return null; // Or a placeholder
|
|
440
|
+
* }
|
|
441
|
+
*
|
|
442
|
+
* return <SomeClientOnlyLibrary />;
|
|
443
|
+
* }
|
|
444
|
+
* ```
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* ```tsx
|
|
448
|
+
* // Conditional rendering based on environment
|
|
449
|
+
* function DebugPanel() {
|
|
450
|
+
* const { isServer } = useHydration();
|
|
451
|
+
*
|
|
452
|
+
* // Never render on server, only after client hydration
|
|
453
|
+
* if (isServer) return null;
|
|
454
|
+
*
|
|
455
|
+
* return <DevTools />;
|
|
456
|
+
* }
|
|
457
|
+
* ```
|
|
458
|
+
*/
|
|
459
|
+
declare function useHydration(): HydrationState;
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Options for useFetch hook
|
|
463
|
+
*/
|
|
464
|
+
interface UseFetchOptions extends Omit<RequestInit, 'body'> {
|
|
465
|
+
/** Skip initial fetch (useful for conditional fetching) */
|
|
466
|
+
skip?: boolean;
|
|
467
|
+
/** Dependencies that trigger refetch when changed */
|
|
468
|
+
deps?: unknown[];
|
|
469
|
+
/** Transform response before setting data */
|
|
470
|
+
transform?: (data: unknown) => unknown;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Hook for data fetching with loading and error states
|
|
474
|
+
*
|
|
475
|
+
* @param url URL to fetch from
|
|
476
|
+
* @param options Fetch options
|
|
477
|
+
* @returns Fetch state with data, loading, error, and refetch function
|
|
478
|
+
*
|
|
479
|
+
* @example
|
|
480
|
+
* ```tsx
|
|
481
|
+
* import { useFetch } from '@riktajs/react';
|
|
482
|
+
*
|
|
483
|
+
* interface User {
|
|
484
|
+
* id: string;
|
|
485
|
+
* name: string;
|
|
486
|
+
* }
|
|
487
|
+
*
|
|
488
|
+
* function UserProfile({ userId }: { userId: string }) {
|
|
489
|
+
* const { data, loading, error, refetch } = useFetch<User>(
|
|
490
|
+
* `/api/users/${userId}`
|
|
491
|
+
* );
|
|
492
|
+
*
|
|
493
|
+
* if (loading) return <Spinner />;
|
|
494
|
+
* if (error) return <Error message={error} />;
|
|
495
|
+
* if (!data) return null;
|
|
496
|
+
*
|
|
497
|
+
* return (
|
|
498
|
+
* <div>
|
|
499
|
+
* <h1>{data.name}</h1>
|
|
500
|
+
* <button onClick={refetch}>Refresh</button>
|
|
501
|
+
* </div>
|
|
502
|
+
* );
|
|
503
|
+
* }
|
|
504
|
+
* ```
|
|
505
|
+
*
|
|
506
|
+
* @example
|
|
507
|
+
* ```tsx
|
|
508
|
+
* // With options
|
|
509
|
+
* const { data } = useFetch<Item[]>('/api/items', {
|
|
510
|
+
* headers: { 'Authorization': `Bearer ${token}` },
|
|
511
|
+
* deps: [token], // Refetch when token changes
|
|
512
|
+
* skip: !token, // Don't fetch until we have a token
|
|
513
|
+
* });
|
|
514
|
+
* ```
|
|
515
|
+
*
|
|
516
|
+
* @example
|
|
517
|
+
* ```tsx
|
|
518
|
+
* // With transform
|
|
519
|
+
* const { data } = useFetch<{ results: Item[] }>('/api/search', {
|
|
520
|
+
* transform: (res) => res.results, // Extract just the results array
|
|
521
|
+
* });
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
declare function useFetch<T = unknown>(url: string, options?: UseFetchOptions): FetchState<T>;
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Options for useAction hook
|
|
528
|
+
*/
|
|
529
|
+
interface UseActionOptions<TResult = unknown> {
|
|
530
|
+
/** Callback on successful action */
|
|
531
|
+
onSuccess?: (result: TResult) => void;
|
|
532
|
+
/** Callback on action error */
|
|
533
|
+
onError?: (error: string) => void;
|
|
534
|
+
/** HTTP method to use */
|
|
535
|
+
method?: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
536
|
+
/** Additional headers */
|
|
537
|
+
headers?: Record<string, string>;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Hook for executing server actions (form submissions, mutations)
|
|
541
|
+
*
|
|
542
|
+
* @param url URL to send the action to
|
|
543
|
+
* @param options Action options
|
|
544
|
+
* @returns Action state with execute, pending, result, and reset
|
|
545
|
+
*
|
|
546
|
+
* @example
|
|
547
|
+
* ```tsx
|
|
548
|
+
* import { useAction } from '@riktajs/react';
|
|
549
|
+
*
|
|
550
|
+
* interface CreateItemInput {
|
|
551
|
+
* name: string;
|
|
552
|
+
* price: number;
|
|
553
|
+
* }
|
|
554
|
+
*
|
|
555
|
+
* interface Item {
|
|
556
|
+
* id: string;
|
|
557
|
+
* name: string;
|
|
558
|
+
* price: number;
|
|
559
|
+
* }
|
|
560
|
+
*
|
|
561
|
+
* function CreateItemForm() {
|
|
562
|
+
* const { execute, pending, result } = useAction<CreateItemInput, Item>(
|
|
563
|
+
* '/api/items',
|
|
564
|
+
* {
|
|
565
|
+
* onSuccess: (item) => {
|
|
566
|
+
* console.log('Created item:', item);
|
|
567
|
+
* },
|
|
568
|
+
* }
|
|
569
|
+
* );
|
|
570
|
+
*
|
|
571
|
+
* const handleSubmit = async (e: FormEvent) => {
|
|
572
|
+
* e.preventDefault();
|
|
573
|
+
* const formData = new FormData(e.target as HTMLFormElement);
|
|
574
|
+
* await execute({
|
|
575
|
+
* name: formData.get('name') as string,
|
|
576
|
+
* price: Number(formData.get('price')),
|
|
577
|
+
* });
|
|
578
|
+
* };
|
|
579
|
+
*
|
|
580
|
+
* return (
|
|
581
|
+
* <form onSubmit={handleSubmit}>
|
|
582
|
+
* <input name="name" required />
|
|
583
|
+
* <input name="price" type="number" required />
|
|
584
|
+
* <button disabled={pending}>
|
|
585
|
+
* {pending ? 'Creating...' : 'Create Item'}
|
|
586
|
+
* </button>
|
|
587
|
+
* {result?.error && <p className="error">{result.error}</p>}
|
|
588
|
+
* {result?.fieldErrors?.name && (
|
|
589
|
+
* <p className="error">{result.fieldErrors.name[0]}</p>
|
|
590
|
+
* )}
|
|
591
|
+
* </form>
|
|
592
|
+
* );
|
|
593
|
+
* }
|
|
594
|
+
* ```
|
|
595
|
+
*
|
|
596
|
+
* @example
|
|
597
|
+
* ```tsx
|
|
598
|
+
* // DELETE action
|
|
599
|
+
* const { execute, pending } = useAction<{ id: string }, void>(
|
|
600
|
+
* '/api/items',
|
|
601
|
+
* { method: 'DELETE' }
|
|
602
|
+
* );
|
|
603
|
+
*
|
|
604
|
+
* const handleDelete = () => execute({ id: itemId });
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
declare function useAction<TInput = unknown, TResult = unknown>(url: string, options?: UseActionOptions<TResult>): ActionState<TInput, TResult>;
|
|
608
|
+
|
|
609
|
+
export { type ActionResult, type ActionState, type FetchState, type HydrationState, Link, type LinkProps, type Location, type NavigateOptions, RiktaProvider, type RiktaProviderProps, RouterContext, type RouterContextValue, SsrContext, type SsrData, type UseActionOptions, type UseFetchOptions, useAction, useFetch, useHydration, useLocation, useNavigation, useParams, useSearchParams, useSsrData };
|