@tpzdsp/next-toolkit 1.2.0 → 1.2.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 (59) hide show
  1. package/package.json +52 -9
  2. package/src/assets/styles/ol.css +10 -10
  3. package/src/components/Button/Button.test.tsx +1 -1
  4. package/src/components/Button/Button.tsx +1 -1
  5. package/src/components/Card/Card.test.tsx +1 -1
  6. package/src/components/ErrorText/ErrorText.test.tsx +1 -1
  7. package/src/components/ErrorText/ErrorText.tsx +1 -1
  8. package/src/components/Heading/Heading.test.tsx +1 -1
  9. package/src/components/Hint/Hint.test.tsx +1 -1
  10. package/src/components/Hint/Hint.tsx +1 -1
  11. package/src/components/Modal/Modal.test.tsx +1 -1
  12. package/src/components/Paragraph/Paragraph.test.tsx +1 -1
  13. package/src/components/SlidingPanel/SlidingPanel.test.tsx +1 -2
  14. package/src/components/accordion/Accordion.test.tsx +1 -1
  15. package/src/components/divider/RuleDivider.test.tsx +1 -1
  16. package/src/components/dropdown/DropdownMenu.test.tsx +1 -1
  17. package/src/components/dropdown/useDropdownMenu.ts +1 -1
  18. package/src/components/index.ts +0 -3
  19. package/src/components/layout/header/Header.tsx +2 -1
  20. package/src/components/layout/header/HeaderAuthClient.tsx +1 -1
  21. package/src/components/layout/header/HeaderNavClient.tsx +1 -1
  22. package/src/components/link/ExternalLink.tsx +1 -1
  23. package/src/components/link/Link.tsx +1 -1
  24. package/src/components/select/Select.test.tsx +1 -1
  25. package/src/components/select/SelectSkeleton.test.tsx +1 -1
  26. package/src/hooks/useClickOutside.test.ts +1 -1
  27. package/src/index.ts +3 -0
  28. package/src/{components/map → map}/Map.tsx +1 -1
  29. package/src/{components/map → map}/MapContext.tsx +1 -1
  30. package/src/{components/map → map}/Popup.tsx +1 -1
  31. package/src/{components/map → map}/map.ts +1 -1
  32. package/src/ol-geocoder.d.ts +1 -0
  33. package/src/test/index.ts +1 -0
  34. package/src/types/api.ts +52 -0
  35. package/src/types/auth.ts +13 -0
  36. package/src/types/index.ts +6 -0
  37. package/src/types/map.ts +26 -0
  38. package/src/types/navigation.ts +8 -0
  39. package/src/types/utils.ts +13 -0
  40. package/src/utils/auth.ts +1 -1
  41. package/src/utils/http.ts +1 -1
  42. package/src/utils/index.ts +0 -1
  43. package/src/utils/utils.ts +1 -1
  44. package/src/types.ts +0 -149
  45. /package/src/{components/map → map}/LayerSwitcherControl.ts +0 -0
  46. /package/src/{components/map → map}/basemaps.ts +0 -0
  47. /package/src/{components/map → map}/geocoder.ts +0 -0
  48. /package/src/{components/map → map}/geometries.ts +0 -0
  49. /package/src/{components/map → map}/images/basemaps/OS.png +0 -0
  50. /package/src/{components/map → map}/images/basemaps/dark.png +0 -0
  51. /package/src/{components/map → map}/images/basemaps/sat-map-tiler.png +0 -0
  52. /package/src/{components/map → map}/images/basemaps/satellite-map-tiler.png +0 -0
  53. /package/src/{components/map → map}/images/basemaps/satellite.png +0 -0
  54. /package/src/{components/map → map}/images/basemaps/streets.png +0 -0
  55. /package/src/{components/map → map}/images/openlayers-logo.png +0 -0
  56. /package/src/{components/map → map}/index.ts +0 -0
  57. /package/src/{components/map → map}/osOpenNamesSearch.ts +0 -0
  58. /package/src/{components/map → map}/projections.ts +0 -0
  59. /package/src/{utils → test}/renderers.tsx +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tpzdsp/next-toolkit",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "A reusable React component library for Next.js applications",
5
5
  "type": "module",
6
6
  "private": false,
@@ -28,14 +28,59 @@
28
28
  "import": "./src/index.ts",
29
29
  "require": "./src/index.ts"
30
30
  },
31
+ "./test": {
32
+ "types": "./src/test/index.ts",
33
+ "import": "./src/test/index.ts",
34
+ "require": "./src/test/index.ts"
35
+ },
36
+ "./utils": {
37
+ "types": "./src/utils/index.ts",
38
+ "import": "./src/utils/index.ts",
39
+ "require": "./src/utils/index.ts"
40
+ },
41
+ "./utils/http": {
42
+ "types": "./src/utils/http.ts",
43
+ "import": "./src/utils/http.ts",
44
+ "require": "./src/utils/http.ts"
45
+ },
46
+ "./components": {
47
+ "types": "./src/components/index.ts",
48
+ "import": "./src/components/index.ts",
49
+ "require": "./src/components/index.ts"
50
+ },
51
+ "./map": {
52
+ "types": "./src/map/index.ts",
53
+ "import": "./src/map/index.ts",
54
+ "require": "./src/map/index.ts"
55
+ },
56
+ "./types": {
57
+ "types": "./src/types/index.ts",
58
+ "import": "./src/types/index.ts",
59
+ "require": "./src/types/index.ts"
60
+ },
61
+ "./types/api": {
62
+ "types": "./src/types/api.ts",
63
+ "import": "./src/types/api.ts",
64
+ "require": "./src/types/api.ts"
65
+ },
66
+ "./types/components": {
67
+ "types": "./src/types/components.ts",
68
+ "import": "./src/types/components.ts",
69
+ "require": "./src/types/components.ts"
70
+ },
71
+ "./types/forms": {
72
+ "types": "./src/types/forms.ts",
73
+ "import": "./src/types/forms.ts",
74
+ "require": "./src/types/forms.ts"
75
+ },
76
+ "./types/auth": {
77
+ "types": "./src/types/auth.ts",
78
+ "import": "./src/types/auth.ts",
79
+ "require": "./src/types/auth.ts"
80
+ },
31
81
  "./styles": "./src/assets/styles/globals.css",
32
82
  "./fonts/*": "./src/assets/fonts/*",
33
- "./images/*": "./src/assets/images/*",
34
- "./types": {
35
- "types": "./src/types.ts",
36
- "import": "./src/types.ts",
37
- "require": "./src/types.ts"
38
- }
83
+ "./images/*": "./src/assets/images/*"
39
84
  },
40
85
  "scripts": {
41
86
  "lint": "eslint .",
@@ -75,7 +120,6 @@
75
120
  "@types/geojson": "^7946.0.16",
76
121
  "@types/jsonwebtoken": "^9.0.10",
77
122
  "@types/node": "^24.0.15",
78
- "@types/proj4": "^2.19.0",
79
123
  "@types/react": "^19.1.8",
80
124
  "@types/react-dom": "^19.1.6",
81
125
  "@typescript-eslint/eslint-plugin": "^8.38.0",
@@ -133,7 +177,6 @@
133
177
  "@turf/turf": "^7.2.0",
134
178
  "@types/geojson": "^7946.0.16",
135
179
  "@types/jsonwebtoken": "^9.0.10",
136
- "@types/proj4": "^2.19.0",
137
180
  "geojson": "^0.5.0",
138
181
  "jsonwebtoken": "^9.0.2",
139
182
  "next": "^15.4.2",
@@ -93,24 +93,24 @@
93
93
  top: unset !important;
94
94
  }
95
95
 
96
- .ol-geocoder ul.gcd-txt-result>li:nth-child(odd) {
96
+ .ol-geocoder ul.gcd-txt-result > li:nth-child(odd) {
97
97
  background-color: #008938;
98
98
  }
99
99
 
100
- .ol-geocoder ul.gcd-txt-result>li:nth-child(even) {
100
+ .ol-geocoder ul.gcd-txt-result > li:nth-child(even) {
101
101
  background-color: #bddabd;
102
102
  }
103
103
 
104
- .ol-geocoder ul.gcd-txt-result>li>a:hover {
105
- background-color: #fff;
104
+ .ol-geocoder ul.gcd-txt-result > li > a:hover {
105
+ background-color: #fff;
106
106
  }
107
107
 
108
108
  /* Change the text color on hover */
109
- .ol-geocoder ul.gcd-txt-result>li>a:hover .gcd-address,
110
- .ol-geocoder ul.gcd-txt-result>li>a:hover .gcd-road,
111
- .ol-geocoder ul.gcd-txt-result>li>a:hover .gcd-city,
112
- .ol-geocoder ul.gcd-txt-result>li>a:hover .gcd-country {
113
- color: #000;
109
+ .ol-geocoder ul.gcd-txt-result > li > a:hover .gcd-address,
110
+ .ol-geocoder ul.gcd-txt-result > li > a:hover .gcd-road,
111
+ .ol-geocoder ul.gcd-txt-result > li > a:hover .gcd-city,
112
+ .ol-geocoder ul.gcd-txt-result > li > a:hover .gcd-country {
113
+ color: #000;
114
114
  }
115
115
 
116
116
  /* Ensure the text color when not hovering */
@@ -118,5 +118,5 @@
118
118
  .ol-geocoder ul.gcd-txt-result .gcd-road,
119
119
  .ol-geocoder ul.gcd-txt-result .gcd-city,
120
120
  .ol-geocoder ul.gcd-txt-result .gcd-country {
121
- color: #fff;
121
+ color: #fff;
122
122
  }
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { Button } from './Button';
4
- import { render, screen } from '../../utils/renderers';
4
+ import { render, screen } from '../../test/renderers';
5
5
 
6
6
  describe('Button', () => {
7
7
  it('renders with primary style', () => {
@@ -1,6 +1,6 @@
1
1
  import { twMerge } from 'tailwind-merge';
2
2
 
3
- import type { ExtendProps } from '../../types';
3
+ import type { ExtendProps } from '../../types/utils';
4
4
 
5
5
  type Props = {
6
6
  type?: 'submit' | 'reset' | 'button';
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { Card } from './Card';
4
- import { render, screen } from '../../utils/renderers';
4
+ import { render, screen } from '../../test/renderers';
5
5
 
6
6
  describe('Card', () => {
7
7
  it('renders with default color blue', () => {
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { ErrorText } from './ErrorText';
4
- import { render, screen } from '../../utils/renderers';
4
+ import { render, screen } from '../../test/renderers';
5
5
 
6
6
  describe('ErrorText', () => {
7
7
  it('renders with default ErrorText', () => {
@@ -1,6 +1,6 @@
1
1
  import { twMerge } from 'tailwind-merge';
2
2
 
3
- import type { ExtendProps } from '../../types';
3
+ import type { ExtendProps } from '../../types/utils';
4
4
 
5
5
  export type ErrorTextProps = ExtendProps<'p'>;
6
6
 
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { Heading, type HeadingProps } from './Heading';
4
- import { render, screen } from '../../utils/renderers';
4
+ import { render, screen } from '../../test/renderers';
5
5
 
6
6
  describe('Heading Component', () => {
7
7
  const headingTypes: HeadingProps['type'][] = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { Hint } from './Hint';
4
- import { render, screen } from '../../utils/renderers';
4
+ import { render, screen } from '../../test/renderers';
5
5
 
6
6
  describe('Hint', () => {
7
7
  it('renders with default Hint message', () => {
@@ -1,6 +1,6 @@
1
1
  import { twMerge } from 'tailwind-merge';
2
2
 
3
- import type { ExtendProps } from '../../types';
3
+ import type { ExtendProps } from '../../types/utils';
4
4
 
5
5
  export type HintProps = ExtendProps<'div'>;
6
6
 
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it, vi } from 'vitest';
2
2
 
3
3
  import { Modal } from './Modal';
4
- import { render, screen, userEvent } from '../../utils/renderers';
4
+ import { render, screen, userEvent } from '../../test/renderers';
5
5
 
6
6
  const MODAL_CONTENT = 'Modal content';
7
7
  const MODAL_ROOT_ID = 'modal-root';
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { Paragraph } from './Paragraph';
4
- import { render, screen } from '../../utils/renderers';
4
+ import { render, screen } from '../../test/renderers';
5
5
 
6
6
  describe('Paragraph', () => {
7
7
  it('renders with text', () => {
@@ -1,8 +1,7 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
 
3
- import { act, render, screen, userEvent, waitFor } from '@tpzdsp/next-toolkit';
4
-
5
3
  import { SlidingPanel } from './SlidingPanel';
4
+ import { act, render, screen, userEvent, waitFor } from '../../test/renderers';
6
5
 
7
6
  const positions = ['center-left', 'center-right', 'center-top', 'center-bottom'] as const;
8
7
 
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { Accordion } from './Accordion';
4
- import { render, screen, userEvent } from '../../utils/renderers';
4
+ import { render, screen, userEvent } from '../../test/renderers';
5
5
 
6
6
  const TEST_CONTENT = 'Test content';
7
7
  const ARIA_EXPANDED = 'aria-expanded';
@@ -1,5 +1,5 @@
1
1
  import { RuleDivider } from './RuleDivider';
2
- import { render, screen } from '../../utils/renderers';
2
+ import { render, screen } from '../../test/renderers';
3
3
 
4
4
  describe('RuleDivider', () => {
5
5
  it('should render with default props', () => {
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { DropdownMenu, type DropdownMenuItem, type DrowndownMenuButton } from './DropdownMenu';
4
- import { render, screen, userEvent, waitFor } from '../../utils/renderers';
4
+ import { render, screen, userEvent, waitFor } from '../../test/renderers';
5
5
 
6
6
  type Item = { label: string };
7
7
 
@@ -10,7 +10,7 @@ import {
10
10
  useCallback,
11
11
  } from 'react';
12
12
 
13
- import type { ExtendProps } from '../../types';
13
+ import type { ExtendProps } from '../../types/utils';
14
14
 
15
15
  /**
16
16
  * The current state of the menu
@@ -40,6 +40,3 @@ export type { AccordionProps } from './accordion/Accordion';
40
40
  // Export layout components
41
41
  export { Header } from './layout/header/Header';
42
42
  export { Footer } from './layout/footer/Footer';
43
-
44
- // Export Map components
45
- export * from './map';
@@ -4,7 +4,8 @@ import { FaHouse } from 'react-icons/fa6';
4
4
 
5
5
  import { HeaderAuthClient } from './HeaderAuthClient';
6
6
  import { HeaderNavClient } from './HeaderNavClient';
7
- import type { Credentials, NavLink } from '../../../types';
7
+ import type { Credentials } from '../../../types/auth';
8
+ import type { NavLink } from '../../../types/navigation';
8
9
  import { DefraLogo } from '../../images/DefraLogo';
9
10
  import { EaLogo } from '../../images/EaLogo';
10
11
  import { ExternalLink } from '../../link/ExternalLink';
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useEffect, useState } from 'react';
4
4
 
5
- import type { Credentials } from '../../../types';
5
+ import type { Credentials } from '../../../types/auth';
6
6
  import { Link } from '../../link/Link';
7
7
 
8
8
  type HeaderAuthClientProps = {
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import type { NavLink } from '../../../types';
3
+ import type { NavLink } from '../../../types/navigation';
4
4
  import { DropdownMenu, type DropdownMenuItem } from '../../dropdown/DropdownMenu';
5
5
  import { ExternalLink } from '../../link/ExternalLink';
6
6
  import { Link } from '../../link/Link';
@@ -2,7 +2,7 @@ import type { ReactNode } from 'react';
2
2
 
3
3
  import { twMerge } from 'tailwind-merge';
4
4
 
5
- import type { ExtendProps } from '../../types';
5
+ import type { ExtendProps } from '../../types/utils';
6
6
 
7
7
  type Props = {
8
8
  children: ReactNode;
@@ -1,7 +1,7 @@
1
1
  import NextLink from 'next/link';
2
2
  import { twMerge } from 'tailwind-merge';
3
3
 
4
- import type { ExtendProps } from '../../types';
4
+ import type { ExtendProps } from '../../types/utils';
5
5
 
6
6
  type Props = {
7
7
  href: string | object;
@@ -1,7 +1,7 @@
1
1
  import selectEvent from 'react-select-event';
2
2
 
3
3
  import { Select } from './Select';
4
- import { render, screen, userEvent, waitFor } from '../../utils/renderers';
4
+ import { render, screen, userEvent, waitFor } from '../../test/renderers';
5
5
 
6
6
  // Suppress act warnings for react-select tests
7
7
  const originalError = console.error;
@@ -1,5 +1,5 @@
1
1
  import { SelectSkeleton } from './SelectSkeleton';
2
- import { render, screen } from '../../utils/renderers';
2
+ import { render, screen } from '../../test/renderers';
3
3
 
4
4
  const LOADING_OPTIONS_LABEL = 'Loading options';
5
5
 
@@ -1,7 +1,7 @@
1
1
  import { useRef } from 'react';
2
2
 
3
3
  import { useClickOutside } from './useClickOutside';
4
- import { renderHook } from '../utils/renderers';
4
+ import { renderHook } from '../test/renderers';
5
5
 
6
6
  describe('useClickOutside', () => {
7
7
  it('should call clickAwayHandler when clicking outside the element', () => {
package/src/index.ts CHANGED
@@ -4,5 +4,8 @@ export * from './components';
4
4
  // Export all utilities (these can be used in both client and server)
5
5
  export * from './utils';
6
6
 
7
+ // Export all map related code (these can be used in both client and server)
8
+ export * from './map';
9
+
7
10
  // Export all types
8
11
  export * from './types';
@@ -12,7 +12,7 @@ import { LayerSwitcherControl } from './LayerSwitcherControl';
12
12
  import { getPopupPositionClass } from './map';
13
13
  import { useMap } from './MapContext';
14
14
  import { Popup } from './Popup';
15
- import type { MapConfig, PopupDirection } from '../../types/map';
15
+ import type { MapConfig, PopupDirection } from '../types/map';
16
16
 
17
17
  export type MapComponentProps = {
18
18
  osMapsApiKey?: string;
@@ -13,7 +13,7 @@ import VectorSource from 'ol/source/Vector';
13
13
 
14
14
  import './projections';
15
15
  import { LAYER_NAMES } from './map';
16
- import type { MapConfig } from '../../types';
16
+ import type { MapConfig } from '../types/map';
17
17
 
18
18
  export type MapContextType = {
19
19
  mapConfig: MapConfig;
@@ -4,7 +4,7 @@ import { Feature } from 'ol';
4
4
  import { GoLinkExternal } from 'react-icons/go';
5
5
  import { IoMdCloseCircle } from 'react-icons/io';
6
6
 
7
- import { ExternalLink } from '../../components/link/ExternalLink';
7
+ import { ExternalLink } from '../components/link/ExternalLink';
8
8
 
9
9
  type PopupProps = {
10
10
  features: Feature[];
@@ -1,6 +1,6 @@
1
1
  import { Map } from 'ol';
2
2
 
3
- import type { PopupDirection } from '../../types';
3
+ import type { PopupDirection } from '../types/map';
4
4
 
5
5
  export const LAYER_NAMES = {
6
6
  Aoi: 'aoi-layer',
@@ -0,0 +1 @@
1
+ declare module 'ol-geocoder';
@@ -0,0 +1 @@
1
+ export * from './renderers';
@@ -0,0 +1,52 @@
1
+ // API related types
2
+ export type ApiResponse<T = unknown> = {
3
+ data: T;
4
+ success: boolean;
5
+ message?: string;
6
+ errors?: Record<string, string[]>;
7
+ };
8
+
9
+ export type PaginationMeta = {
10
+ page: number;
11
+ perPage: number;
12
+ total: number;
13
+ totalPages: number;
14
+ };
15
+
16
+ export type PaginatedResponse<T = unknown> = {
17
+ meta: PaginationMeta;
18
+ } & ApiResponse<T[]>;
19
+
20
+ // Since we only ever fetch a single API we don't need multiple failure types,
21
+ // so defining a global one as the default is fine. This can be changed per-app.
22
+ export type ApiFailure = { message: string };
23
+
24
+ type GenericResponse<Ok, Error> =
25
+ | ({
26
+ readonly ok: true;
27
+ json(): Promise<Ok | null>;
28
+ } & globalThis.Response)
29
+ | ({
30
+ readonly ok: false;
31
+ json(): Promise<Error>;
32
+ } & globalThis.Response);
33
+
34
+ export type Response<Ok, Error> = GenericResponse<Ok, Error>;
35
+
36
+ /**
37
+ * Typesafe version of the normal `fetch` function. It takes 2 generics:
38
+ * - `Ok` which defines type type of a successful request
39
+ * - `Error` which defines the type of a failed request (defaults to the `ApiFailure` type)
40
+ *
41
+ * @param input The URL to fetch
42
+ * @param init Any fetch options, like cache, headers, body, etc.
43
+ */
44
+ export declare function fetch<Ok = never, Error = ApiFailure>(
45
+ input: RequestInfo | URL,
46
+ init?: RequestInit,
47
+ ): Promise<Response<Ok, Error>>;
48
+
49
+ export type WrappedApiResponse<T> = Promise<
50
+ | { success: true; data: T }
51
+ | { success: false; message: string; status?: number; details?: string[] }
52
+ >;
@@ -0,0 +1,13 @@
1
+ // Define an interface for the decoded JWT payload
2
+ export type DecodedJWT = {
3
+ name: string;
4
+ email: string;
5
+ groupInfoIds: string[];
6
+ exp?: number; // Optional: JWT expiration timestamp
7
+ [key: string]: unknown; // Additional claims
8
+ };
9
+
10
+ export type Credentials = {
11
+ token: string;
12
+ user: DecodedJWT;
13
+ };
@@ -0,0 +1,6 @@
1
+ // Barrel export for all types
2
+ export * from './api';
3
+ export * from './auth';
4
+ export * from './navigation';
5
+ export * from './utils';
6
+ export * from './map';
@@ -0,0 +1,26 @@
1
+ export type PopupDirection = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
2
+
3
+ export type MapConfig = {
4
+ center: number[];
5
+ zoom: number;
6
+ };
7
+
8
+ export type Layer = {
9
+ name: string;
10
+ title: string;
11
+ };
12
+
13
+ export type MapSearchResults = {
14
+ results: {
15
+ GAZETTEER_ENTRY: {
16
+ GEOMETRY_Y: number;
17
+ NAME1: string;
18
+ };
19
+ }[];
20
+ };
21
+
22
+ export type TransformedResult = {
23
+ lon: number;
24
+ lat: number;
25
+ address: { name: string };
26
+ }[];
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ export type NavLink = {
4
+ label: string;
5
+ url: string;
6
+ isExternal?: boolean;
7
+ icon?: ReactNode;
8
+ };
@@ -0,0 +1,13 @@
1
+ import type { ComponentProps } from 'react';
2
+
3
+ // Utility types for better developer experience
4
+ export type PropsWithRequired<T, K extends keyof T> = T & Required<Pick<T, K>>;
5
+ export type PropsWithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
6
+
7
+ export type ExtendProps<
8
+ // `ComponentProps` internally constrains `Comp` to be `JSXElementConstructor<any>`,
9
+ // and since our type must have the same constraints to avoid errors, `any` is required here
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ Comp extends keyof React.JSX.IntrinsicElements | React.JSXElementConstructor<any>,
12
+ Props = object,
13
+ > = Props & Omit<ComponentProps<Comp>, keyof Props>;
package/src/utils/auth.ts CHANGED
@@ -5,7 +5,7 @@ import type { NextRequest } from 'next/server';
5
5
 
6
6
  import { COOKIE_NAME } from './constants';
7
7
  import { decodeAuthToken } from './utils';
8
- import type { Credentials } from '../types';
8
+ import type { Credentials } from '../types/auth';
9
9
 
10
10
  export const getCredentials = async (source?: NextRequest | null): Promise<Credentials | null> => {
11
11
  const cookieStore = source ? source?.cookies : await cookies();
package/src/utils/http.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Response, ApiFailure } from '../types';
1
+ import type { Response, ApiFailure } from '../types/api';
2
2
 
3
3
  export const MimeTypes = {
4
4
  Json: 'application/json',
@@ -2,4 +2,3 @@ export * from './utils';
2
2
  export * from './auth';
3
3
  export * from './constants';
4
4
  export * from './http';
5
- export * from './renderers'; // This has testing-library dependencies, so probably need to add them as peer dependencies
@@ -1,7 +1,7 @@
1
1
  import { decode } from 'jsonwebtoken';
2
2
  import { twMerge } from 'tailwind-merge';
3
3
 
4
- import type { Credentials, DecodedJWT } from '../types';
4
+ import type { Credentials, DecodedJWT } from '../types/auth';
5
5
 
6
6
  export const decodeAuthToken = (token: string): Credentials | null => {
7
7
  if (!token) {
package/src/types.ts DELETED
@@ -1,149 +0,0 @@
1
- // Common types used throughout the library and consuming applications
2
- import type { ComponentProps, ReactNode } from 'react';
3
-
4
- export type BaseProps = {
5
- className?: string;
6
- children?: ReactNode;
7
- };
8
-
9
- export type NextLinkProps = {
10
- href: string;
11
- children: ReactNode;
12
- className?: string;
13
- target?: '_blank' | '_self' | '_parent' | '_top';
14
- rel?: string;
15
- };
16
-
17
- export type ThemeContextValue = {
18
- theme: 'light' | 'dark';
19
- toggleTheme: () => void;
20
- };
21
-
22
- // Component variant types
23
- export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost';
24
- export type ButtonSize = 'sm' | 'md' | 'lg';
25
- export type CardVariant = 'default' | 'elevated' | 'outlined';
26
- export type ContainerSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';
27
-
28
- // Common utility types that apps might need
29
- export type Variant = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info';
30
- export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
31
- export type Status = 'idle' | 'loading' | 'success' | 'error';
32
- export type Theme = 'light' | 'dark' | 'system';
33
-
34
- // Form related types
35
- export type FormFieldProps = {
36
- name: string;
37
- label?: string;
38
- error?: string;
39
- required?: boolean;
40
- disabled?: boolean;
41
- className?: string;
42
- };
43
-
44
- // API related types
45
- export type ApiResponse<T = unknown> = {
46
- data: T;
47
- success: boolean;
48
- message?: string;
49
- errors?: Record<string, string[]>;
50
- };
51
-
52
- export type PaginationMeta = {
53
- page: number;
54
- perPage: number;
55
- total: number;
56
- totalPages: number;
57
- };
58
-
59
- export type PaginatedResponse<T = unknown> = {
60
- meta: PaginationMeta;
61
- } & ApiResponse<T[]>;
62
-
63
- // Event handler types
64
- export type ClickHandler = (event: React.MouseEvent<HTMLElement>) => void;
65
- export type ChangeHandler<T = HTMLInputElement> = (event: React.ChangeEvent<T>) => void;
66
- export type SubmitHandler = (event: React.FormEvent<HTMLFormElement>) => void;
67
-
68
- // Utility types for better developer experience
69
- export type PropsWithRequired<T, K extends keyof T> = T & Required<Pick<T, K>>;
70
- export type PropsWithOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
71
-
72
- export type ExtendProps<
73
- // `ComponentProps` internally constrains `Comp` to be `JSXElementConstructor<any>`,
74
- // and since our type must have the same constraints to avoid errors, `any` is required here
75
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
- Comp extends keyof React.JSX.IntrinsicElements | React.JSXElementConstructor<any>,
77
- Props = object,
78
- > = Props & Omit<ComponentProps<Comp>, keyof Props>;
79
-
80
- // Define an interface for the decoded JWT payload
81
- export type DecodedJWT = {
82
- name: string;
83
- email: string;
84
- groupInfoIds: string[];
85
- exp?: number; // Optional: JWT expiration timestamp
86
- [key: string]: unknown; // Additional claims
87
- };
88
-
89
- export type Credentials = {
90
- token: string;
91
- user: DecodedJWT;
92
- };
93
-
94
- export type NavLink = {
95
- label: string;
96
- url: string;
97
- isExternal?: boolean;
98
- icon?: ReactNode;
99
- };
100
-
101
- type GenericResponse<Ok, Error> =
102
- | ({
103
- readonly ok: true;
104
- json(): Promise<Ok | null>;
105
- } & globalThis.Response)
106
- | ({
107
- readonly ok: false;
108
- json(): Promise<Error>;
109
- } & globalThis.Response);
110
-
111
- export type Response<Ok, Error> = GenericResponse<Ok, Error>;
112
-
113
- // Since we only ever fetch a single API we don't need multiple failure types,
114
- // so defining a global one as the default is fine. This can be changed per-app.
115
- export type ApiFailure = { message: string };
116
-
117
- /*
118
- Override the global Response type to be able to take a success/fail type.
119
- It defines it as a tagged union so that we can take advantage of type
120
- narrowing on the `json()` return type when checking `Response.ok`.
121
-
122
- Generally overriding global types is bad, but in this case we are making
123
- a normally non-typesafe feature more typesafe so I think it's acceptable.
124
- */
125
- /**
126
- * Typesafe verion of the `Response` interface.
127
- *
128
- * It takes 2 generics:
129
- * - `Ok` which defines type type of a successful request
130
- * - `Error` which defines the type of a failed request
131
- */
132
-
133
- /**
134
- * Typesafe version of the normal `fetch` function. It takes 2 generics:
135
- * - `Ok` which defines type type of a successful request
136
- * - `Error` which defines the type of a failed request (defaults to the `ApiFailure` type)
137
- *
138
- * @param input The URL to fetch
139
- * @param init Any fetch options, like cache, headers, body, etc.
140
- */
141
- export declare function fetch<Ok = never, Error = ApiFailure>(
142
- input: RequestInfo | URL,
143
- init?: RequestInit,
144
- ): Promise<Response<Ok, Error>>;
145
-
146
- export type WrappedApiResponse<T> = Promise<
147
- | { success: true; data: T }
148
- | { success: false; message: string; status?: number; details?: string[] }
149
- >;
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes