@okam/next-component 2.1.0 → 2.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.
- package/components/AdminBar/AdminBarContent.d.ts +3 -0
- package/components/AdminBar/AdminBarContent.js +14 -0
- package/components/AdminBar/AdminBarContent.mjs +14 -0
- package/components/AdminBar/index.js +14 -0
- package/components/AdminBar/index.mjs +15 -0
- package/components/Filter/index.js +54 -0
- package/components/Filter/index.mjs +55 -0
- package/components/Img/index.js +29 -0
- package/components/Img/index.mjs +30 -0
- package/components/Link/index.js +40 -0
- package/components/Link/index.mjs +41 -0
- package/hooks/useFilterState/index.js +50 -0
- package/hooks/useFilterState/index.mjs +50 -0
- package/hooks/useHash/index.js +25 -0
- package/hooks/useHash/index.mjs +25 -0
- package/hooks/useLink/index.js +118 -0
- package/hooks/useLink/index.mjs +118 -0
- package/hooks/useLink/interface.d.ts +61 -1
- package/hooks/useLink/interface.js +8 -0
- package/hooks/useLink/interface.mjs +8 -0
- package/index.d.ts +2 -1
- package/index.js +20 -590
- package/index.mjs +17 -587
- package/lib/createServerContext/index.js +12 -0
- package/lib/createServerContext/index.mjs +12 -0
- package/package.json +5 -5
- package/providers/AdminBar/index.js +17 -0
- package/providers/AdminBar/index.mjs +17 -0
- package/{index-DV6W6v68.js → providers/DraftMode/index.js} +2 -0
- package/{index-Ber8Ecgv.mjs → providers/DraftMode/index.mjs} +3 -2
- package/providers/DraftMode/server.js +10 -0
- package/providers/DraftMode/server.mjs +11 -0
- package/server.d.ts +1 -0
- package/server.js +8 -30
- package/server.mjs +7 -29
- package/theme/AdminBar/index.js +120 -0
- package/theme/AdminBar/index.mjs +120 -0
- package/theme/Button/index.js +75 -0
- package/theme/Button/index.mjs +76 -0
- package/theme/Filter/index.js +72 -0
- package/theme/Filter/index.mjs +73 -0
- package/theme/Typography/index.js +43 -0
- package/theme/Typography/index.mjs +44 -0
- package/theme/index.js +16 -0
- package/theme/index.mjs +17 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { usePathname, useSearchParams, useParams } from "next/navigation";
|
|
3
|
+
import { useRef, useCallback, useEffect } from "react";
|
|
4
|
+
import { useLocale } from "react-aria";
|
|
5
|
+
import { useHash } from "../useHash/index.mjs";
|
|
6
|
+
import { LocalePrefix } from "./interface.mjs";
|
|
7
|
+
const EXTERNAL_URL_RE = /^[a-z]+:\/\//i;
|
|
8
|
+
function scrollToTop(behavior) {
|
|
9
|
+
window?.scrollTo?.({ top: 0, behavior });
|
|
10
|
+
}
|
|
11
|
+
function getParamsLocale(params) {
|
|
12
|
+
const { locale } = params ?? {};
|
|
13
|
+
if (Array.isArray(locale))
|
|
14
|
+
return locale[0];
|
|
15
|
+
return locale;
|
|
16
|
+
}
|
|
17
|
+
function useLinkLocale(props) {
|
|
18
|
+
const { locale, i18n } = props;
|
|
19
|
+
const { defaultLocale, localePrefix = "always" } = i18n ?? {};
|
|
20
|
+
const params = useParams();
|
|
21
|
+
const paramsLocale = getParamsLocale(params);
|
|
22
|
+
const { locale: ctxLocale } = useLocale();
|
|
23
|
+
const finalLocale = locale ?? ctxLocale ?? paramsLocale ?? false;
|
|
24
|
+
const shouldDisplayLocale = {
|
|
25
|
+
[LocalePrefix.Always]: true,
|
|
26
|
+
[LocalePrefix.AsNeeded]: finalLocale !== defaultLocale
|
|
27
|
+
}[localePrefix];
|
|
28
|
+
const displayLocale = shouldDisplayLocale ? finalLocale : false;
|
|
29
|
+
return displayLocale;
|
|
30
|
+
}
|
|
31
|
+
function localizeHref(href, locale) {
|
|
32
|
+
const hrefString = href.toString();
|
|
33
|
+
const hasTrailingSlash = hrefString.endsWith("/");
|
|
34
|
+
const isAnchor = hrefString.startsWith("#");
|
|
35
|
+
const isExternal = EXTERNAL_URL_RE.test(hrefString) || hrefString.startsWith("//");
|
|
36
|
+
let finalHref;
|
|
37
|
+
if (locale != null && locale !== false && !isExternal && !isAnchor) {
|
|
38
|
+
finalHref = `/${locale}${hrefString}`;
|
|
39
|
+
} else {
|
|
40
|
+
finalHref = hrefString;
|
|
41
|
+
}
|
|
42
|
+
return hasTrailingSlash || isAnchor ? finalHref : `${finalHref}/`;
|
|
43
|
+
}
|
|
44
|
+
function useLink(props) {
|
|
45
|
+
const {
|
|
46
|
+
scroll = true,
|
|
47
|
+
onMouseEnter,
|
|
48
|
+
onTouchStart,
|
|
49
|
+
onClick,
|
|
50
|
+
onNavigate,
|
|
51
|
+
onPathnameChange,
|
|
52
|
+
onHashChange,
|
|
53
|
+
onSearchParamsChange,
|
|
54
|
+
href,
|
|
55
|
+
urlDecorator,
|
|
56
|
+
replace,
|
|
57
|
+
prefetch,
|
|
58
|
+
shallow,
|
|
59
|
+
passHref,
|
|
60
|
+
legacyBehavior,
|
|
61
|
+
behavior = "instant"
|
|
62
|
+
} = props;
|
|
63
|
+
const locale = useLinkLocale(props);
|
|
64
|
+
const localizedHref = localizeHref(href, locale);
|
|
65
|
+
const pathname = usePathname();
|
|
66
|
+
const searchParams = useSearchParams();
|
|
67
|
+
const hash = useHash();
|
|
68
|
+
const hasWarnedOnPathnameChangeRef = useRef(false);
|
|
69
|
+
const isNextScroll = typeof scroll === "boolean";
|
|
70
|
+
const nextScroll = isNextScroll ? scroll : false;
|
|
71
|
+
const handleScroll = useCallback(() => {
|
|
72
|
+
if (isNextScroll)
|
|
73
|
+
return;
|
|
74
|
+
scrollToTop(behavior);
|
|
75
|
+
}, [behavior, isNextScroll]);
|
|
76
|
+
const handleClick = (event) => {
|
|
77
|
+
onClick?.(event);
|
|
78
|
+
handleScroll();
|
|
79
|
+
};
|
|
80
|
+
const handleTouchStart = (event) => {
|
|
81
|
+
onTouchStart?.(event);
|
|
82
|
+
handleScroll();
|
|
83
|
+
};
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (process.env.NODE_ENV === "production" || onPathnameChange == null || hasWarnedOnPathnameChangeRef.current)
|
|
86
|
+
return;
|
|
87
|
+
console.warn("[next-component/Link] `onPathnameChange` is deprecated and will be removed in the next major version. Use `onNavigate` from next/link instead.");
|
|
88
|
+
hasWarnedOnPathnameChangeRef.current = true;
|
|
89
|
+
}, [onPathnameChange]);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
onPathnameChange?.(pathname);
|
|
92
|
+
}, [onPathnameChange, pathname]);
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
onSearchParamsChange?.(searchParams);
|
|
95
|
+
}, [onSearchParamsChange, searchParams]);
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
onHashChange?.(hash);
|
|
98
|
+
}, [onHashChange, hash]);
|
|
99
|
+
return {
|
|
100
|
+
href: localizedHref.toString(),
|
|
101
|
+
as: urlDecorator,
|
|
102
|
+
replace,
|
|
103
|
+
prefetch,
|
|
104
|
+
shallow,
|
|
105
|
+
onClick: handleClick,
|
|
106
|
+
onNavigate,
|
|
107
|
+
onTouchStart: handleTouchStart,
|
|
108
|
+
onMouseEnter,
|
|
109
|
+
scroll: nextScroll,
|
|
110
|
+
passHref,
|
|
111
|
+
legacyBehavior
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
localizeHref,
|
|
116
|
+
useLink,
|
|
117
|
+
useLinkLocale
|
|
118
|
+
};
|
|
@@ -1,6 +1,65 @@
|
|
|
1
1
|
import { LinkProps as NextLinkProps } from 'next/link';
|
|
2
2
|
import { ReadonlyURLSearchParams } from 'next/navigation';
|
|
3
|
-
|
|
3
|
+
import { UrlObject } from 'node:url';
|
|
4
|
+
export declare enum LocalePrefix {
|
|
5
|
+
/**
|
|
6
|
+
* The pathname will be prefixed with the locale only when it is not the default locale
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const linkI18nConfig = {
|
|
11
|
+
* localePrefix: 'as-needed',
|
|
12
|
+
* defaultLocale: 'en',
|
|
13
|
+
* }
|
|
14
|
+
*
|
|
15
|
+
* // <Link locale="en" href="/products/1" />
|
|
16
|
+
* // output: /products/1
|
|
17
|
+
*
|
|
18
|
+
* // <Link href="/products/1" />
|
|
19
|
+
* // output: /products/1
|
|
20
|
+
*
|
|
21
|
+
* // <Link locale="fr" href="/produits/1" />
|
|
22
|
+
* // output: /fr/produits/1
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
AsNeeded = "as-needed",
|
|
26
|
+
/**
|
|
27
|
+
* The pathname will always be prefixed by the locale
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const linkI18nConfig = {
|
|
32
|
+
* localePrefix: 'always',
|
|
33
|
+
* defaultLocale: 'en',
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* // <Link locale="en" href="/products/1" />
|
|
37
|
+
* // output: /en/products/1
|
|
38
|
+
*
|
|
39
|
+
* // <Link href="/products/1" />
|
|
40
|
+
* // output: /en/products/1
|
|
41
|
+
*
|
|
42
|
+
* // <Link locale="fr" href="/produits/1" />
|
|
43
|
+
* // output: /fr/produits/1
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
Always = "always"
|
|
47
|
+
}
|
|
48
|
+
export type TLinkI18nConfig = ({
|
|
49
|
+
defaultLocale: string;
|
|
50
|
+
/**
|
|
51
|
+
* {@link LocalePrefix}
|
|
52
|
+
*/
|
|
53
|
+
localePrefix: `${LocalePrefix.AsNeeded}`;
|
|
54
|
+
} | {
|
|
55
|
+
defaultLocale?: string;
|
|
56
|
+
/**
|
|
57
|
+
* {@link LocalePrefix}
|
|
58
|
+
*/
|
|
59
|
+
localePrefix?: `${LocalePrefix.Always}` | undefined;
|
|
60
|
+
});
|
|
61
|
+
export interface TLink extends Omit<NextLinkProps, 'scroll' | 'as' | 'hre'> {
|
|
62
|
+
href: string | UrlObject;
|
|
4
63
|
/**
|
|
5
64
|
* @default true
|
|
6
65
|
* - `true`: Scrolls to the top of the clicked anchor (default Next.js behavior)
|
|
@@ -20,6 +79,7 @@ export interface TLink extends Omit<NextLinkProps, 'scroll' | 'as'> {
|
|
|
20
79
|
onPathnameChange?: (_pathname: string) => void;
|
|
21
80
|
onSearchParamsChange?: (_searchParams: ReadonlyURLSearchParams) => void;
|
|
22
81
|
onHashChange?: (_hash: string) => void;
|
|
82
|
+
i18n?: TLinkI18nConfig;
|
|
23
83
|
}
|
|
24
84
|
export interface TUseLinkReturn extends Omit<NextLinkProps, 'href' | 'locale'> {
|
|
25
85
|
href: string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
var LocalePrefix = /* @__PURE__ */ ((LocalePrefix2) => {
|
|
4
|
+
LocalePrefix2["AsNeeded"] = "as-needed";
|
|
5
|
+
LocalePrefix2["Always"] = "always";
|
|
6
|
+
return LocalePrefix2;
|
|
7
|
+
})(LocalePrefix || {});
|
|
8
|
+
exports.LocalePrefix = LocalePrefix;
|
package/index.d.ts
CHANGED
|
@@ -8,7 +8,8 @@ export { useFilterState } from './hooks/useFilterState';
|
|
|
8
8
|
export type { TFilter } from './hooks/useFilterState/interface';
|
|
9
9
|
export { useHash } from './hooks/useHash';
|
|
10
10
|
export { useLink } from './hooks/useLink';
|
|
11
|
-
export type { TLink } from './hooks/useLink/interface';
|
|
11
|
+
export type { TLink, TLinkI18nConfig, TUseLinkReturn } from './hooks/useLink/interface';
|
|
12
|
+
export { LocalePrefix } from './hooks/useLink/interface';
|
|
12
13
|
export { AdminBarContextProvider, useAdminBar } from './providers/AdminBar';
|
|
13
14
|
export { DraftModeContextProvider, useDraftMode } from './providers/DraftMode';
|
|
14
15
|
export { default as ThemeProvider } from './theme';
|