@teo-garcia/react-shared 0.1.1

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.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +259 -0
  3. package/dist/adapters/environment/index.d.ts +6 -0
  4. package/dist/adapters/environment/index.d.ts.map +1 -0
  5. package/dist/adapters/environment/index.js +5 -0
  6. package/dist/adapters/environment/next.d.ts +17 -0
  7. package/dist/adapters/environment/next.d.ts.map +1 -0
  8. package/dist/adapters/environment/next.js +20 -0
  9. package/dist/adapters/environment/vite.d.ts +17 -0
  10. package/dist/adapters/environment/vite.d.ts.map +1 -0
  11. package/dist/adapters/environment/vite.js +20 -0
  12. package/dist/adapters/index.d.ts +9 -0
  13. package/dist/adapters/index.d.ts.map +1 -0
  14. package/dist/adapters/index.js +8 -0
  15. package/dist/adapters/theme/custom.d.ts +32 -0
  16. package/dist/adapters/theme/custom.d.ts.map +1 -0
  17. package/dist/adapters/theme/custom.js +26 -0
  18. package/dist/adapters/theme/index.d.ts +6 -0
  19. package/dist/adapters/theme/index.d.ts.map +1 -0
  20. package/dist/adapters/theme/index.js +5 -0
  21. package/dist/adapters/theme/next-themes.d.ts +18 -0
  22. package/dist/adapters/theme/next-themes.d.ts.map +1 -0
  23. package/dist/adapters/theme/next-themes.js +23 -0
  24. package/dist/components/error-boundary/error-boundary.d.ts +71 -0
  25. package/dist/components/error-boundary/error-boundary.d.ts.map +1 -0
  26. package/dist/components/error-boundary/error-boundary.js +100 -0
  27. package/dist/components/error-boundary/index.d.ts +2 -0
  28. package/dist/components/error-boundary/index.d.ts.map +1 -0
  29. package/dist/components/error-boundary/index.js +1 -0
  30. package/dist/components/index.d.ts +7 -0
  31. package/dist/components/index.d.ts.map +1 -0
  32. package/dist/components/index.js +6 -0
  33. package/dist/components/theme-switch/index.d.ts +3 -0
  34. package/dist/components/theme-switch/index.d.ts.map +1 -0
  35. package/dist/components/theme-switch/index.js +1 -0
  36. package/dist/components/theme-switch/theme-switch.d.ts +36 -0
  37. package/dist/components/theme-switch/theme-switch.d.ts.map +1 -0
  38. package/dist/components/theme-switch/theme-switch.js +74 -0
  39. package/dist/components/viewport-info/index.d.ts +3 -0
  40. package/dist/components/viewport-info/index.d.ts.map +1 -0
  41. package/dist/components/viewport-info/index.js +1 -0
  42. package/dist/components/viewport-info/viewport-info.d.ts +40 -0
  43. package/dist/components/viewport-info/viewport-info.d.ts.map +1 -0
  44. package/dist/components/viewport-info/viewport-info.js +69 -0
  45. package/dist/hooks/index.d.ts +6 -0
  46. package/dist/hooks/index.d.ts.map +1 -0
  47. package/dist/hooks/index.js +4 -0
  48. package/dist/hooks/use-healthcheck.d.ts +42 -0
  49. package/dist/hooks/use-healthcheck.d.ts.map +1 -0
  50. package/dist/hooks/use-healthcheck.js +53 -0
  51. package/dist/index.d.ts +16 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +20 -0
  54. package/dist/types.d.ts +40 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +1 -0
  57. package/dist/utils/environment.d.ts +71 -0
  58. package/dist/utils/environment.d.ts.map +1 -0
  59. package/dist/utils/environment.js +86 -0
  60. package/dist/utils/index.d.ts +6 -0
  61. package/dist/utils/index.d.ts.map +1 -0
  62. package/dist/utils/index.js +5 -0
  63. package/dist/utils/msw.d.ts +54 -0
  64. package/dist/utils/msw.d.ts.map +1 -0
  65. package/dist/utils/msw.js +62 -0
  66. package/package.json +112 -0
@@ -0,0 +1,100 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Component } from 'react';
4
+ /**
5
+ * ErrorBoundary component - Catches JavaScript errors in child components
6
+ *
7
+ * This component wraps your application (or part of it) to catch runtime errors
8
+ * and display a fallback UI instead of crashing the entire app.
9
+ *
10
+ * Features:
11
+ * - Catches errors in child component tree
12
+ * - Displays custom fallback UI
13
+ * - Optional error callback for logging
14
+ * - Follows React error boundary best practices
15
+ *
16
+ * @example Basic usage
17
+ * ```tsx
18
+ * import { ErrorBoundary } from '@teo-garcia/react-shared/components'
19
+ *
20
+ * function App() {
21
+ * return (
22
+ * <ErrorBoundary fallback={<div>Something went wrong</div>}>
23
+ * <YourApp />
24
+ * </ErrorBoundary>
25
+ * )
26
+ * }
27
+ * ```
28
+ *
29
+ * @example With dynamic fallback
30
+ * ```tsx
31
+ * import { ErrorBoundary } from '@teo-garcia/react-shared/components'
32
+ *
33
+ * function App() {
34
+ * return (
35
+ * <ErrorBoundary
36
+ * fallback={(error) => (
37
+ * <div>
38
+ * <h1>Error: {error.message}</h1>
39
+ * <button onClick={() => window.location.reload()}>Reload</button>
40
+ * </div>
41
+ * )}
42
+ * onError={(error, errorInfo) => {
43
+ * console.error('Error caught:', error, errorInfo)
44
+ * // Send to error tracking service
45
+ * }}
46
+ * >
47
+ * <YourApp />
48
+ * </ErrorBoundary>
49
+ * )
50
+ * }
51
+ * ```
52
+ */
53
+ export class ErrorBoundary extends Component {
54
+ constructor(props) {
55
+ super(props);
56
+ this.state = { hasError: false, error: null };
57
+ }
58
+ /**
59
+ * Static method called when an error is thrown in a child component
60
+ * Updates state to trigger fallback UI rendering
61
+ */
62
+ static getDerivedStateFromError(error) {
63
+ return { hasError: true, error };
64
+ }
65
+ /**
66
+ * Called after an error is caught
67
+ * Used for side effects like logging
68
+ */
69
+ componentDidCatch(error, errorInfo) {
70
+ // Call optional error handler prop
71
+ if (this.props.onError) {
72
+ this.props.onError(error, errorInfo);
73
+ }
74
+ }
75
+ render() {
76
+ // If an error was caught, render fallback UI
77
+ if (this.state.hasError && this.state.error) {
78
+ const { fallback } = this.props;
79
+ // If fallback is a function, call it with the error
80
+ if (typeof fallback === 'function') {
81
+ return fallback(this.state.error);
82
+ }
83
+ // If fallback is provided, render it
84
+ if (fallback) {
85
+ return fallback;
86
+ }
87
+ // Default fallback UI if none provided
88
+ return (_jsxs("div", { role: "alert", style: {
89
+ padding: '20px',
90
+ margin: '20px',
91
+ border: '1px solid #f5c6cb',
92
+ borderRadius: '4px',
93
+ backgroundColor: '#f8d7da',
94
+ color: '#721c24',
95
+ }, children: [_jsx("h2", { style: { marginTop: 0 }, children: "Something went wrong" }), _jsxs("details", { style: { whiteSpace: 'pre-wrap' }, children: [_jsx("summary", { style: { cursor: 'pointer', marginBottom: '10px' }, children: "Error details" }), this.state.error.toString()] })] }));
96
+ }
97
+ // No error, render children normally
98
+ return this.props.children;
99
+ }
100
+ }
@@ -0,0 +1,2 @@
1
+ export { ErrorBoundary } from './error-boundary';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/error-boundary/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1 @@
1
+ export { ErrorBoundary } from './error-boundary';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Components - Reusable React UI components
3
+ */
4
+ export * from './error-boundary';
5
+ export * from './theme-switch';
6
+ export * from './viewport-info';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Components - Reusable React UI components
3
+ */
4
+ export * from './error-boundary';
5
+ export * from './theme-switch';
6
+ export * from './viewport-info';
@@ -0,0 +1,3 @@
1
+ export { ThemeSwitch } from './theme-switch';
2
+ export type { ThemeSwitchProps } from './theme-switch';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/theme-switch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1 @@
1
+ export { ThemeSwitch } from './theme-switch';
@@ -0,0 +1,36 @@
1
+ import type { ThemeAdapter } from '../../types';
2
+ export interface ThemeSwitchProps {
3
+ /** Theme adapter that connects to your theme provider */
4
+ themeAdapter: ThemeAdapter;
5
+ }
6
+ /**
7
+ * ThemeSwitch component - A button that cycles through light, dark, and system themes
8
+ *
9
+ * This component uses the adapter pattern to work with any theme provider.
10
+ * It cycles through themes in the order: light → dark → system → light
11
+ *
12
+ * @example Next.js with next-themes
13
+ * ```tsx
14
+ * import { ThemeSwitch } from '@teo-garcia/react-shared/components'
15
+ * import { useNextThemesAdapter } from '@teo-garcia/react-shared/adapters/theme'
16
+ *
17
+ * function App() {
18
+ * const themeAdapter = useNextThemesAdapter()
19
+ * return <ThemeSwitch themeAdapter={themeAdapter} />
20
+ * }
21
+ * ```
22
+ *
23
+ * @example React Router with custom theme provider
24
+ * ```tsx
25
+ * import { ThemeSwitch } from '@teo-garcia/react-shared/components'
26
+ * import { createCustomThemeAdapter } from '@teo-garcia/react-shared/adapters/theme'
27
+ * import { useTheme } from '~/components/theme-provider'
28
+ *
29
+ * function App() {
30
+ * const themeAdapter = createCustomThemeAdapter(useTheme())
31
+ * return <ThemeSwitch themeAdapter={themeAdapter} />
32
+ * }
33
+ * ```
34
+ */
35
+ export declare const ThemeSwitch: ({ themeAdapter }: ThemeSwitchProps) => import("react/jsx-runtime").JSX.Element;
36
+ //# sourceMappingURL=theme-switch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-switch.d.ts","sourceRoot":"","sources":["../../../src/components/theme-switch/theme-switch.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAa,MAAM,aAAa,CAAA;AAE1D,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,YAAY,EAAE,YAAY,CAAA;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,WAAW,GAAI,kBAAkB,gBAAgB,4CAuD7D,CAAA"}
@@ -0,0 +1,74 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Laptop, Moon, Sun } from 'lucide-react';
4
+ /**
5
+ * ThemeSwitch component - A button that cycles through light, dark, and system themes
6
+ *
7
+ * This component uses the adapter pattern to work with any theme provider.
8
+ * It cycles through themes in the order: light → dark → system → light
9
+ *
10
+ * @example Next.js with next-themes
11
+ * ```tsx
12
+ * import { ThemeSwitch } from '@teo-garcia/react-shared/components'
13
+ * import { useNextThemesAdapter } from '@teo-garcia/react-shared/adapters/theme'
14
+ *
15
+ * function App() {
16
+ * const themeAdapter = useNextThemesAdapter()
17
+ * return <ThemeSwitch themeAdapter={themeAdapter} />
18
+ * }
19
+ * ```
20
+ *
21
+ * @example React Router with custom theme provider
22
+ * ```tsx
23
+ * import { ThemeSwitch } from '@teo-garcia/react-shared/components'
24
+ * import { createCustomThemeAdapter } from '@teo-garcia/react-shared/adapters/theme'
25
+ * import { useTheme } from '~/components/theme-provider'
26
+ *
27
+ * function App() {
28
+ * const themeAdapter = createCustomThemeAdapter(useTheme())
29
+ * return <ThemeSwitch themeAdapter={themeAdapter} />
30
+ * }
31
+ * ```
32
+ */
33
+ export const ThemeSwitch = ({ themeAdapter }) => {
34
+ const { theme, setTheme } = themeAdapter;
35
+ // Ensure we have a valid theme, default to 'system' if undefined
36
+ const activeTheme = (theme ?? 'system');
37
+ /**
38
+ * Cycles to the next theme in the sequence
39
+ * light → dark → system → light
40
+ */
41
+ const getNextTheme = () => {
42
+ switch (activeTheme) {
43
+ case 'light': {
44
+ return 'dark';
45
+ }
46
+ case 'dark': {
47
+ return 'system';
48
+ }
49
+ default: {
50
+ return 'light';
51
+ }
52
+ }
53
+ };
54
+ /**
55
+ * Returns the appropriate icon for the current theme
56
+ */
57
+ const getCurrentIcon = () => {
58
+ switch (activeTheme) {
59
+ case 'light': {
60
+ return _jsx(Sun, { className: "size-5" });
61
+ }
62
+ case 'dark': {
63
+ return _jsx(Moon, { className: "size-5" });
64
+ }
65
+ default: {
66
+ return _jsx(Laptop, { className: "size-5" });
67
+ }
68
+ }
69
+ };
70
+ const handleClick = () => {
71
+ setTheme(getNextTheme());
72
+ };
73
+ return (_jsx("button", { onClick: handleClick, "aria-label": `Theme switcher, current mode: ${activeTheme}`, className: "fixed right-4 top-4 rounded-lg border p-2 md:right-8 md:top-8 transition-colors duration-200 hover:bg-accent hover:text-accent-foreground", title: `Current theme: ${activeTheme}. Click to switch to ${getNextTheme()}`, children: getCurrentIcon() }));
74
+ };
@@ -0,0 +1,3 @@
1
+ export { ViewportInfo } from './viewport-info';
2
+ export type { ViewportInfoProps } from './viewport-info';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/viewport-info/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1 @@
1
+ export { ViewportInfo } from './viewport-info';
@@ -0,0 +1,40 @@
1
+ import type { EnvironmentAdapter } from '../../types';
2
+ export interface ViewportInfoProps {
3
+ /** Environment adapter to detect if running in development mode */
4
+ environmentAdapter: EnvironmentAdapter;
5
+ }
6
+ /**
7
+ * ViewportInfo component - Displays current viewport dimensions and Tailwind breakpoint
8
+ *
9
+ * This component is useful during development to see the current viewport size and
10
+ * which Tailwind breakpoint is active. It automatically hides in production.
11
+ *
12
+ * Features:
13
+ * - Shows viewport width and height in pixels
14
+ * - Displays active Tailwind CSS breakpoint (default, sm, md, lg, xl, 2xl)
15
+ * - Auto-updates on window resize
16
+ * - Only renders in development mode
17
+ * - Fixed position in bottom-right corner
18
+ *
19
+ * @example Next.js
20
+ * ```tsx
21
+ * import { ViewportInfo } from '@teo-garcia/react-shared/components'
22
+ * import { nextEnvironmentAdapter } from '@teo-garcia/react-shared/adapters/environment'
23
+ *
24
+ * function App() {
25
+ * return <ViewportInfo environmentAdapter={nextEnvironmentAdapter} />
26
+ * }
27
+ * ```
28
+ *
29
+ * @example React Router / Vite
30
+ * ```tsx
31
+ * import { ViewportInfo } from '@teo-garcia/react-shared/components'
32
+ * import { viteEnvironmentAdapter } from '@teo-garcia/react-shared/adapters/environment'
33
+ *
34
+ * function App() {
35
+ * return <ViewportInfo environmentAdapter={viteEnvironmentAdapter} />
36
+ * }
37
+ * ```
38
+ */
39
+ export declare const ViewportInfo: ({ environmentAdapter }: ViewportInfoProps) => import("react/jsx-runtime").JSX.Element | null;
40
+ //# sourceMappingURL=viewport-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewport-info.d.ts","sourceRoot":"","sources":["../../../src/components/viewport-info/viewport-info.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAErD,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,kBAAkB,EAAE,kBAAkB,CAAA;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,YAAY,GAAI,wBAAwB,iBAAiB,mDAmDrE,CAAA"}
@@ -0,0 +1,69 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { RulerIcon } from 'lucide-react';
4
+ import { useEffect, useState } from 'react';
5
+ /**
6
+ * ViewportInfo component - Displays current viewport dimensions and Tailwind breakpoint
7
+ *
8
+ * This component is useful during development to see the current viewport size and
9
+ * which Tailwind breakpoint is active. It automatically hides in production.
10
+ *
11
+ * Features:
12
+ * - Shows viewport width and height in pixels
13
+ * - Displays active Tailwind CSS breakpoint (default, sm, md, lg, xl, 2xl)
14
+ * - Auto-updates on window resize
15
+ * - Only renders in development mode
16
+ * - Fixed position in bottom-right corner
17
+ *
18
+ * @example Next.js
19
+ * ```tsx
20
+ * import { ViewportInfo } from '@teo-garcia/react-shared/components'
21
+ * import { nextEnvironmentAdapter } from '@teo-garcia/react-shared/adapters/environment'
22
+ *
23
+ * function App() {
24
+ * return <ViewportInfo environmentAdapter={nextEnvironmentAdapter} />
25
+ * }
26
+ * ```
27
+ *
28
+ * @example React Router / Vite
29
+ * ```tsx
30
+ * import { ViewportInfo } from '@teo-garcia/react-shared/components'
31
+ * import { viteEnvironmentAdapter } from '@teo-garcia/react-shared/adapters/environment'
32
+ *
33
+ * function App() {
34
+ * return <ViewportInfo environmentAdapter={viteEnvironmentAdapter} />
35
+ * }
36
+ * ```
37
+ */
38
+ export const ViewportInfo = ({ environmentAdapter }) => {
39
+ // State to track viewport dimensions
40
+ const [{ width: viewportWidth, height: viewportHeight }, setViewportSize] = useState(() => ({
41
+ width: 0,
42
+ height: 0,
43
+ }));
44
+ useEffect(() => {
45
+ // Guard against SSR - window is not available on the server
46
+ if (globalThis.window == undefined) {
47
+ return;
48
+ }
49
+ // Handler to update viewport dimensions
50
+ const handleResize = () => {
51
+ setViewportSize({
52
+ width: window.innerWidth,
53
+ height: window.innerHeight,
54
+ });
55
+ };
56
+ // Set initial dimensions
57
+ handleResize();
58
+ // Listen for resize events
59
+ window.addEventListener('resize', handleResize);
60
+ // Cleanup listener on unmount
61
+ return () => {
62
+ window.removeEventListener('resize', handleResize);
63
+ };
64
+ }, []);
65
+ // Only show in development mode
66
+ if (!environmentAdapter.isDevelopment())
67
+ return null;
68
+ return (_jsxs("aside", { className: "fixed bottom-0 right-0 flex items-center gap-x-1 rounded-l-lg px-4 py-2 bg-primary text-primary-foreground font-semibold", children: [_jsx(RulerIcon, { className: "size-5" }), _jsxs("p", { className: "text-lg flex gap-x-2", children: [viewportWidth, "px - ", viewportHeight, "px -", _jsx("span", { className: "inline sm:hidden font-semibold", children: "default" }), _jsx("span", { className: "hidden sm:inline md:hidden font-semibold", children: "sm" }), _jsx("span", { className: "hidden md:inline lg:hidden font-semibold", children: "md" }), _jsx("span", { className: "hidden lg:inline xl:hidden font-semibold", children: "lg " }), _jsx("span", { className: "hidden xl:inline 2xl:hidden font-semibold", children: "xl" }), _jsx("span", { className: "hidden 2xl:inline font-semibold", children: "2xl" })] })] }));
69
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Hooks - Reusable React hooks for common functionality
3
+ */
4
+ export { useHealthcheck } from './use-healthcheck';
5
+ export type { UseHealthcheckOptions } from './use-healthcheck';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Hooks - Reusable React hooks for common functionality
3
+ */
4
+ export { useHealthcheck } from './use-healthcheck';
@@ -0,0 +1,42 @@
1
+ export interface UseHealthcheckOptions {
2
+ /** The healthcheck endpoint URL (default: http://localhost:3000/api/healthcheck) */
3
+ url?: string;
4
+ /** Enable/disable the query (default: true) */
5
+ enabled?: boolean;
6
+ }
7
+ /**
8
+ * useHealthcheck hook - Fetches health status from an API endpoint
9
+ *
10
+ * This hook uses React Query to fetch and cache the health status of your API.
11
+ * It's useful for monitoring if your backend is available and responding.
12
+ *
13
+ * @param options - Configuration options
14
+ * @returns React Query result with health status data
15
+ *
16
+ * @example Basic usage
17
+ * ```tsx
18
+ * import { useHealthcheck } from '@teo-garcia/react-shared/hooks'
19
+ *
20
+ * function HealthStatus() {
21
+ * const { data, isLoading, error } = useHealthcheck()
22
+ *
23
+ * if (isLoading) return <div>Checking health...</div>
24
+ * if (error) return <div>Health check failed</div>
25
+ * return <div>Status: {data?.status}</div>
26
+ * }
27
+ * ```
28
+ *
29
+ * @example Custom URL
30
+ * ```tsx
31
+ * import { useHealthcheck } from '@teo-garcia/react-shared/hooks'
32
+ *
33
+ * function HealthStatus() {
34
+ * const { data } = useHealthcheck({
35
+ * url: 'http://localhost:8080/health'
36
+ * })
37
+ * return <div>{data?.status}</div>
38
+ * }
39
+ * ```
40
+ */
41
+ export declare const useHealthcheck: (options?: UseHealthcheckOptions) => import("@tanstack/react-query").UseQueryResult<any, Error>;
42
+ //# sourceMappingURL=use-healthcheck.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-healthcheck.d.ts","sourceRoot":"","sources":["../../src/hooks/use-healthcheck.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,oFAAoF;IACpF,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,cAAc,GAAI,UAAS,qBAA0B,+DAkBjE,CAAA"}
@@ -0,0 +1,53 @@
1
+ import { useQuery } from '@tanstack/react-query';
2
+ /**
3
+ * useHealthcheck hook - Fetches health status from an API endpoint
4
+ *
5
+ * This hook uses React Query to fetch and cache the health status of your API.
6
+ * It's useful for monitoring if your backend is available and responding.
7
+ *
8
+ * @param options - Configuration options
9
+ * @returns React Query result with health status data
10
+ *
11
+ * @example Basic usage
12
+ * ```tsx
13
+ * import { useHealthcheck } from '@teo-garcia/react-shared/hooks'
14
+ *
15
+ * function HealthStatus() {
16
+ * const { data, isLoading, error } = useHealthcheck()
17
+ *
18
+ * if (isLoading) return <div>Checking health...</div>
19
+ * if (error) return <div>Health check failed</div>
20
+ * return <div>Status: {data?.status}</div>
21
+ * }
22
+ * ```
23
+ *
24
+ * @example Custom URL
25
+ * ```tsx
26
+ * import { useHealthcheck } from '@teo-garcia/react-shared/hooks'
27
+ *
28
+ * function HealthStatus() {
29
+ * const { data } = useHealthcheck({
30
+ * url: 'http://localhost:8080/health'
31
+ * })
32
+ * return <div>{data?.status}</div>
33
+ * }
34
+ * ```
35
+ */
36
+ export const useHealthcheck = (options = {}) => {
37
+ const { url = 'http://localhost:3000/api/healthcheck', enabled = true } = options;
38
+ return useQuery({
39
+ queryKey: ['healthcheck', url],
40
+ queryFn: async () => {
41
+ const response = await fetch(url);
42
+ if (!response.ok) {
43
+ throw new Error(`Health check failed: ${response.statusText}`);
44
+ }
45
+ return await response.json();
46
+ },
47
+ enabled,
48
+ // Refetch every 30 seconds to keep health status fresh
49
+ refetchInterval: 30000,
50
+ // Retry failed requests
51
+ retry: 3,
52
+ });
53
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @teo-garcia/react-shared
3
+ *
4
+ * Shared React components, hooks, utilities, and adapters for fullstack web templates.
5
+ *
6
+ * This package provides framework-agnostic React utilities that work across
7
+ * Next.js, React Router, and other React-based frameworks.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ export * from './components';
12
+ export * from './hooks';
13
+ export * from './utils';
14
+ export * from './adapters';
15
+ export * from './types';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,cAAc,cAAc,CAAA;AAG5B,cAAc,SAAS,CAAA;AAGvB,cAAc,SAAS,CAAA;AAGvB,cAAc,YAAY,CAAA;AAG1B,cAAc,SAAS,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @teo-garcia/react-shared
3
+ *
4
+ * Shared React components, hooks, utilities, and adapters for fullstack web templates.
5
+ *
6
+ * This package provides framework-agnostic React utilities that work across
7
+ * Next.js, React Router, and other React-based frameworks.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ // Export all components
12
+ export * from './components';
13
+ // Export all hooks
14
+ export * from './hooks';
15
+ // Export all utilities
16
+ export * from './utils';
17
+ // Export all adapters
18
+ export * from './adapters';
19
+ // Export all types
20
+ export * from './types';
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Theme mode type - represents the three possible theme states
3
+ */
4
+ export type ThemeMode = 'light' | 'dark' | 'system';
5
+ /**
6
+ * ThemeAdapter interface - allows components to work with different theme providers
7
+ * Implementations should map their specific theme library to this interface
8
+ */
9
+ export interface ThemeAdapter {
10
+ /** Current theme mode */
11
+ theme: ThemeMode;
12
+ /** Function to update the theme */
13
+ setTheme: (theme: ThemeMode) => void;
14
+ }
15
+ /**
16
+ * EnvironmentAdapter interface - abstracts environment detection across frameworks
17
+ * Different frameworks (Next.js vs Vite) use different environment variable systems
18
+ */
19
+ export interface EnvironmentAdapter {
20
+ /** Check if running in development mode */
21
+ isDevelopment: () => boolean;
22
+ /** Check if running in production mode */
23
+ isProduction?: () => boolean;
24
+ /** Check if running on server */
25
+ isServer?: () => boolean;
26
+ /** Check if running on client */
27
+ isClient?: () => boolean;
28
+ }
29
+ /**
30
+ * ErrorBoundary fallback render function type
31
+ */
32
+ export interface ErrorBoundaryProps {
33
+ /** The React children to wrap */
34
+ children: React.ReactNode;
35
+ /** Optional fallback UI to render on error */
36
+ fallback?: React.ReactNode | ((error: Error) => React.ReactNode);
37
+ /** Optional callback when an error is caught */
38
+ onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
39
+ }
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEnD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,KAAK,EAAE,SAAS,CAAA;IAChB,mCAAmC;IACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAA;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,aAAa,EAAE,MAAM,OAAO,CAAA;IAC5B,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,OAAO,CAAA;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAA;IACxB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAA;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iCAAiC;IACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,CAAC,SAAS,CAAC,CAAA;IAChE,gDAAgD;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAA;CAC7D"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};