@tpzdsp/next-toolkit 1.1.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.
- package/package.json +70 -8
- package/src/assets/styles/globals.css +2 -0
- package/src/assets/styles/ol.css +122 -0
- package/src/components/Button/Button.test.tsx +1 -1
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Card/Card.test.tsx +1 -1
- package/src/components/ErrorText/ErrorText.test.tsx +1 -1
- package/src/components/ErrorText/ErrorText.tsx +1 -1
- package/src/components/Heading/Heading.test.tsx +1 -1
- package/src/components/Hint/Hint.test.tsx +1 -1
- package/src/components/Hint/Hint.tsx +1 -1
- package/src/components/Modal/Modal.stories.tsx +252 -0
- package/src/components/Modal/Modal.test.tsx +248 -0
- package/src/components/Modal/Modal.tsx +61 -0
- package/src/components/Paragraph/Paragraph.test.tsx +1 -1
- package/src/components/SlidingPanel/SlidingPanel.test.tsx +1 -2
- package/src/components/accordion/Accordion.stories.tsx +235 -0
- package/src/components/accordion/Accordion.test.tsx +199 -0
- package/src/components/accordion/Accordion.tsx +47 -0
- package/src/components/divider/RuleDivider.stories.tsx +255 -0
- package/src/components/divider/RuleDivider.test.tsx +164 -0
- package/src/components/divider/RuleDivider.tsx +18 -0
- package/src/components/dropdown/DropdownMenu.test.tsx +1 -1
- package/src/components/dropdown/useDropdownMenu.ts +1 -1
- package/src/components/index.ts +6 -2
- package/src/components/layout/header/Header.tsx +2 -1
- package/src/components/layout/header/HeaderAuthClient.tsx +17 -9
- package/src/components/layout/header/HeaderNavClient.tsx +3 -3
- package/src/components/link/ExternalLink.tsx +1 -1
- package/src/components/link/Link.tsx +1 -1
- package/src/components/select/Select.stories.tsx +336 -0
- package/src/components/select/Select.test.tsx +473 -0
- package/src/components/select/Select.tsx +132 -0
- package/src/components/select/SelectSkeleton.stories.tsx +195 -0
- package/src/components/select/SelectSkeleton.test.tsx +105 -0
- package/src/components/select/SelectSkeleton.tsx +16 -0
- package/src/components/select/common.ts +4 -0
- package/src/contexts/index.ts +0 -5
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useClickOutside.test.ts +290 -0
- package/src/hooks/useClickOutside.ts +26 -0
- package/src/index.ts +3 -0
- package/src/map/LayerSwitcherControl.ts +147 -0
- package/src/map/Map.tsx +230 -0
- package/src/map/MapContext.tsx +211 -0
- package/src/map/Popup.tsx +74 -0
- package/src/map/basemaps.ts +79 -0
- package/src/map/geocoder.ts +61 -0
- package/src/map/geometries.ts +60 -0
- package/src/map/images/basemaps/OS.png +0 -0
- package/src/map/images/basemaps/dark.png +0 -0
- package/src/map/images/basemaps/sat-map-tiler.png +0 -0
- package/src/map/images/basemaps/satellite-map-tiler.png +0 -0
- package/src/map/images/basemaps/satellite.png +0 -0
- package/src/map/images/basemaps/streets.png +0 -0
- package/src/map/images/openlayers-logo.png +0 -0
- package/src/map/index.ts +10 -0
- package/src/map/map.ts +40 -0
- package/src/map/osOpenNamesSearch.ts +54 -0
- package/src/map/projections.ts +14 -0
- package/src/ol-geocoder.d.ts +1 -0
- package/src/test/index.ts +1 -0
- package/src/types/api.ts +52 -0
- package/src/types/auth.ts +13 -0
- package/src/types/index.ts +6 -0
- package/src/types/map.ts +26 -0
- package/src/types/navigation.ts +8 -0
- package/src/types/utils.ts +13 -0
- package/src/utils/auth.ts +1 -1
- package/src/utils/http.ts +143 -0
- package/src/utils/index.ts +1 -1
- package/src/utils/utils.ts +1 -1
- package/src/components/link/NextLinkWrapper.tsx +0 -66
- package/src/contexts/ThemeContext.tsx +0 -72
- package/src/types.ts +0 -99
- /package/src/{utils → test}/renderers.tsx +0 -0
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import type { ReactNode } from 'react';
|
|
4
|
-
|
|
5
|
-
import Link from 'next/link';
|
|
6
|
-
|
|
7
|
-
import { cn } from '../../utils';
|
|
8
|
-
|
|
9
|
-
export type NextLinkWrapperProps = {
|
|
10
|
-
href: string;
|
|
11
|
-
children: ReactNode;
|
|
12
|
-
className?: string;
|
|
13
|
-
target?: '_blank' | '_self' | '_parent' | '_top';
|
|
14
|
-
rel?: string;
|
|
15
|
-
prefetch?: boolean;
|
|
16
|
-
replace?: boolean;
|
|
17
|
-
scroll?: boolean;
|
|
18
|
-
shallow?: boolean;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export const NextLinkWrapper = ({
|
|
22
|
-
href,
|
|
23
|
-
children,
|
|
24
|
-
className,
|
|
25
|
-
target,
|
|
26
|
-
rel,
|
|
27
|
-
prefetch,
|
|
28
|
-
replace,
|
|
29
|
-
scroll,
|
|
30
|
-
shallow,
|
|
31
|
-
...props
|
|
32
|
-
}: NextLinkWrapperProps) => {
|
|
33
|
-
// Handle external links
|
|
34
|
-
const isExternal =
|
|
35
|
-
href.startsWith('http') || href.startsWith('mailto:') || href.startsWith('tel:');
|
|
36
|
-
|
|
37
|
-
if (isExternal) {
|
|
38
|
-
return (
|
|
39
|
-
<a
|
|
40
|
-
href={href}
|
|
41
|
-
className={cn('text-blue-600 hover:text-blue-800 transition-colors', className)}
|
|
42
|
-
target={target ?? '_blank'}
|
|
43
|
-
rel={rel ?? 'noopener noreferrer'}
|
|
44
|
-
{...props}
|
|
45
|
-
>
|
|
46
|
-
{children}
|
|
47
|
-
</a>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<Link
|
|
53
|
-
href={href}
|
|
54
|
-
className={cn('text-blue-600 hover:text-blue-800 transition-colors', className)}
|
|
55
|
-
prefetch={prefetch}
|
|
56
|
-
replace={replace}
|
|
57
|
-
scroll={scroll}
|
|
58
|
-
shallow={shallow}
|
|
59
|
-
target={target}
|
|
60
|
-
rel={rel}
|
|
61
|
-
{...props}
|
|
62
|
-
>
|
|
63
|
-
{children}
|
|
64
|
-
</Link>
|
|
65
|
-
);
|
|
66
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
'use client'; // This is necessary for Next.js to treat this file as a client-side component
|
|
2
|
-
|
|
3
|
-
import { createContext, useContext, useState, useEffect } from 'react';
|
|
4
|
-
import type { ReactNode } from 'react';
|
|
5
|
-
|
|
6
|
-
import type { ThemeContextValue } from '../types';
|
|
7
|
-
|
|
8
|
-
export const ThemeContext = createContext<ThemeContextValue | undefined>(undefined);
|
|
9
|
-
|
|
10
|
-
type ThemeProviderProps = {
|
|
11
|
-
children: ReactNode;
|
|
12
|
-
defaultTheme?: 'light' | 'dark';
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const ThemeProvider = ({ children, defaultTheme = 'light' }: ThemeProviderProps) => {
|
|
16
|
-
const [theme, setTheme] = useState<'light' | 'dark'>(() => {
|
|
17
|
-
if (typeof window === 'undefined') {
|
|
18
|
-
return defaultTheme;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Check localStorage first
|
|
22
|
-
const savedTheme = localStorage.getItem('theme') as 'light' | 'dark';
|
|
23
|
-
|
|
24
|
-
if (savedTheme) {
|
|
25
|
-
return savedTheme;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Check system preference
|
|
29
|
-
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
30
|
-
return 'dark';
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return defaultTheme;
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const toggleTheme = () => {
|
|
37
|
-
const newTheme = theme === 'light' ? 'dark' : 'light';
|
|
38
|
-
|
|
39
|
-
setTheme(newTheme);
|
|
40
|
-
|
|
41
|
-
if (typeof window !== 'undefined') {
|
|
42
|
-
localStorage.setItem('theme', newTheme);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
// Add theme class to document element
|
|
48
|
-
if (typeof window !== 'undefined') {
|
|
49
|
-
const root = window.document.documentElement;
|
|
50
|
-
|
|
51
|
-
root.classList.remove('light', 'dark');
|
|
52
|
-
root.classList.add(theme);
|
|
53
|
-
}
|
|
54
|
-
}, [theme]);
|
|
55
|
-
|
|
56
|
-
const value: ThemeContextValue = {
|
|
57
|
-
theme,
|
|
58
|
-
toggleTheme,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const useTheme = (): ThemeContextValue => {
|
|
65
|
-
const context = useContext(ThemeContext);
|
|
66
|
-
|
|
67
|
-
if (context === undefined) {
|
|
68
|
-
throw new Error('useTheme must be used within a ThemeProvider');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return context;
|
|
72
|
-
};
|
package/src/types.ts
DELETED
|
@@ -1,99 +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
|
-
};
|
|
File without changes
|