@regardio/react 1.2.1 → 1.3.0

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/src/link/link.tsx DELETED
@@ -1,218 +0,0 @@
1
- 'use client';
2
-
3
- import { tv } from '@regardio/tailwind/utils';
4
- import { createContext, useCallback, useContext } from 'react';
5
- import type { NavLinkProps, NavLinkRenderProps } from 'react-router';
6
- import { NavLink } from 'react-router';
7
- import { lowerCaseSzett } from '../utils/text';
8
-
9
- /**
10
- * Context for providing a path resolver function.
11
- * This allows projects to inject their own localization logic.
12
- */
13
- export type PathResolver = (routeKey: string) => string;
14
-
15
- const PathResolverContext = createContext<PathResolver | null>(null);
16
-
17
- export const PathResolverProvider: React.Provider<PathResolver | null> =
18
- PathResolverContext.Provider;
19
-
20
- export function usePathResolver(): PathResolver | null {
21
- return useContext(PathResolverContext);
22
- }
23
-
24
- export interface LinkBaseProps extends Omit<NavLinkProps, 'to'> {
25
- routeKey?: string;
26
- to?: string | Partial<{ pathname?: string; search?: string; hash?: string }> | undefined;
27
- viewTransition?: boolean;
28
- }
29
-
30
- export const LinkBase = ({
31
- className,
32
- to,
33
- routeKey,
34
- children,
35
- onClick,
36
- viewTransition = true,
37
- ...props
38
- }: LinkBaseProps): React.JSX.Element => {
39
- const pathResolver = usePathResolver();
40
-
41
- let path: string;
42
-
43
- if (routeKey && pathResolver) {
44
- path = pathResolver(routeKey);
45
- } else if (typeof to === 'string') {
46
- path = to;
47
- } else {
48
- path = to?.pathname ?? '';
49
- if (to?.search) path += to.search;
50
- if (to?.hash) path += to.hash;
51
- }
52
-
53
- const isExternal =
54
- path.startsWith('tel:')
55
- || path.startsWith('mailto:')
56
- || path.startsWith('#')
57
- || path.startsWith('http');
58
-
59
- const handleClick = useCallback(
60
- (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
61
- onClick?.(event);
62
- if (event.defaultPrevented) return;
63
-
64
- if (path.startsWith('tel:') || path.startsWith('mailto:')) {
65
- return;
66
- }
67
-
68
- if (path.startsWith('#')) {
69
- event.preventDefault();
70
- const element = document.getElementById(path.substring(1));
71
- if (element) {
72
- element.scrollIntoView({ behavior: 'smooth' });
73
- }
74
- return;
75
- }
76
-
77
- if (path.startsWith('http')) {
78
- event.preventDefault();
79
- window.open(path, '_blank', 'noopener,noreferrer');
80
- return;
81
- }
82
- },
83
- [onClick, path],
84
- );
85
-
86
- if (!path) {
87
- return <>{typeof children === 'function' ? null : children}</>;
88
- }
89
-
90
- if (isExternal) {
91
- const externalState: NavLinkRenderProps = {
92
- isActive: false,
93
- isPending: false,
94
- isTransitioning: false,
95
- };
96
- const resolvedClassName =
97
- typeof className === 'function' ? className(externalState) : className;
98
- const resolvedStyle =
99
- typeof props.style === 'function' ? props.style(externalState) : props.style;
100
-
101
- return (
102
- <a
103
- className={resolvedClassName}
104
- href={path}
105
- onClick={handleClick}
106
- style={resolvedStyle}
107
- >
108
- {typeof children === 'function' ? children(externalState) : children}
109
- </a>
110
- );
111
- }
112
-
113
- return (
114
- <NavLink
115
- {...props}
116
- className={className}
117
- onClick={handleClick}
118
- to={path}
119
- viewTransition={viewTransition}
120
- >
121
- {children}
122
- </NavLink>
123
- );
124
- };
125
-
126
- const arrowVariants = {
127
- darr: 'darr',
128
- larr: 'larr',
129
- rarr: 'rarr',
130
- uarr: 'uarr',
131
- } as const;
132
-
133
- const linkVariants = {
134
- button: [
135
- 'block',
136
- 'button',
137
- 'mt-s',
138
- 'relative',
139
- 'rarr',
140
- 'text-right',
141
- 'text-sm',
142
- 'tracking-wider',
143
- 'uppercase',
144
- ],
145
- code: ['font-monospace'],
146
- link: ['rarr', '!bg-transparent', 'uppercase', '!tracking-wider'],
147
- navtitle: ['block', 'uppercase', 'tracking-wider'],
148
- primary: [],
149
- subtitle: ['text-lg'],
150
- } as const;
151
-
152
- const link = tv({
153
- base: [],
154
- defaultVariants: {
155
- variant: 'primary',
156
- },
157
- variants: {
158
- arrow: arrowVariants,
159
- variant: linkVariants,
160
- },
161
- });
162
-
163
- export type LinkArrow = keyof typeof arrowVariants;
164
- export type LinkVariant = keyof typeof linkVariants;
165
-
166
- export interface LinkProps extends Omit<NavLinkProps, 'to'> {
167
- arrow?: LinkArrow;
168
- routeKey?: string;
169
- to?: string | Partial<{ pathname?: string; search?: string; hash?: string }>;
170
- variant?: LinkVariant;
171
- viewTransition?: boolean;
172
- }
173
-
174
- export const Link = ({
175
- arrow,
176
- children,
177
- className,
178
- routeKey,
179
- to,
180
- variant,
181
- viewTransition,
182
- ...props
183
- }: LinkProps): React.JSX.Element => {
184
- return (
185
- <LinkBase
186
- {...props}
187
- className={link({
188
- arrow,
189
- className: typeof className === 'string' ? className : undefined,
190
- variant,
191
- })}
192
- routeKey={routeKey}
193
- to={to}
194
- viewTransition={viewTransition}
195
- >
196
- {lowerCaseSzett(children as React.ReactNode)}
197
- </LinkBase>
198
- );
199
- };
200
-
201
- export interface MarkdownLinkProps extends Omit<LinkProps, 'to'> {
202
- href?: string;
203
- }
204
-
205
- export const MarkdownLink: React.FC<MarkdownLinkProps> = ({ children, href, ...props }) => {
206
- if (href) {
207
- return (
208
- <Link
209
- to={href}
210
- {...props}
211
- >
212
- {children}
213
- </Link>
214
- );
215
- }
216
-
217
- return null;
218
- };