@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,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
5
|
+
const stackUi = require("@okam/stack-ui");
|
|
6
|
+
function AdminBarContent({
|
|
7
|
+
children,
|
|
8
|
+
themeName = "adminBar",
|
|
9
|
+
tokens,
|
|
10
|
+
customTheme
|
|
11
|
+
}) {
|
|
12
|
+
return /* @__PURE__ */ jsxRuntime.jsx(stackUi.Box, { themeName: `${themeName}.container`, tokens, customTheme, children: /* @__PURE__ */ jsxRuntime.jsx(stackUi.Box, { themeName: `${themeName}.content`, tokens, children }) });
|
|
13
|
+
}
|
|
14
|
+
exports.AdminBarContent = AdminBarContent;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Box } from "@okam/stack-ui";
|
|
4
|
+
function AdminBarContent({
|
|
5
|
+
children,
|
|
6
|
+
themeName = "adminBar",
|
|
7
|
+
tokens,
|
|
8
|
+
customTheme
|
|
9
|
+
}) {
|
|
10
|
+
return /* @__PURE__ */ jsx(Box, { themeName: `${themeName}.container`, tokens, customTheme, children: /* @__PURE__ */ jsx(Box, { themeName: `${themeName}.content`, tokens, children }) });
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
AdminBarContent
|
|
14
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
3
|
+
const headers = require("next/headers");
|
|
4
|
+
const AdminBarContent = require("./AdminBarContent.js");
|
|
5
|
+
async function AdminBar({
|
|
6
|
+
children,
|
|
7
|
+
themeName = "adminBar",
|
|
8
|
+
tokens,
|
|
9
|
+
customTheme
|
|
10
|
+
}) {
|
|
11
|
+
const { isEnabled } = await headers.draftMode();
|
|
12
|
+
return isEnabled && /* @__PURE__ */ jsxRuntime.jsx(AdminBarContent.AdminBarContent, { themeName, tokens, customTheme, children });
|
|
13
|
+
}
|
|
14
|
+
module.exports = AdminBar;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { draftMode } from "next/headers";
|
|
3
|
+
import { AdminBarContent } from "./AdminBarContent.mjs";
|
|
4
|
+
async function AdminBar({
|
|
5
|
+
children,
|
|
6
|
+
themeName = "adminBar",
|
|
7
|
+
tokens,
|
|
8
|
+
customTheme
|
|
9
|
+
}) {
|
|
10
|
+
const { isEnabled } = await draftMode();
|
|
11
|
+
return isEnabled && /* @__PURE__ */ jsx(AdminBarContent, { themeName, tokens, customTheme, children });
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
AdminBar as default
|
|
15
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const stackUi = require("@okam/stack-ui");
|
|
5
|
+
const index = require("../../hooks/useFilterState/index.js");
|
|
6
|
+
function Filter(props) {
|
|
7
|
+
const {
|
|
8
|
+
// TagGroup-specific props
|
|
9
|
+
children,
|
|
10
|
+
items,
|
|
11
|
+
defaultSelectedKeys,
|
|
12
|
+
selectedKeys,
|
|
13
|
+
selectionBehavior,
|
|
14
|
+
selectionMode = "multiple",
|
|
15
|
+
options,
|
|
16
|
+
description,
|
|
17
|
+
disabledKeys,
|
|
18
|
+
disallowEmptySelection,
|
|
19
|
+
errorMessage,
|
|
20
|
+
onRemove,
|
|
21
|
+
onSelectionChange,
|
|
22
|
+
// Common props
|
|
23
|
+
themeName = "filter",
|
|
24
|
+
tokens,
|
|
25
|
+
customTheme,
|
|
26
|
+
// PopoverButton props with defaults
|
|
27
|
+
type = "dialog",
|
|
28
|
+
placement = "bottom",
|
|
29
|
+
// Remaining PopoverButton props
|
|
30
|
+
...popoverButtonProps
|
|
31
|
+
} = props;
|
|
32
|
+
const tagGroupProps = {
|
|
33
|
+
items,
|
|
34
|
+
selectionBehavior,
|
|
35
|
+
selectionMode,
|
|
36
|
+
description,
|
|
37
|
+
disallowEmptySelection,
|
|
38
|
+
errorMessage,
|
|
39
|
+
onRemove
|
|
40
|
+
};
|
|
41
|
+
const state = index.useFilterState({ ...props, selectionMode });
|
|
42
|
+
return /* @__PURE__ */ jsxRuntime.jsx(stackUi.Box, { themeName: `${themeName}.wrapper`, tokens, customTheme, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
43
|
+
stackUi.PopoverButton,
|
|
44
|
+
{
|
|
45
|
+
themeName: `${themeName}.popover`,
|
|
46
|
+
tokens,
|
|
47
|
+
type,
|
|
48
|
+
placement,
|
|
49
|
+
...popoverButtonProps,
|
|
50
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(stackUi.TagGroup, { themeName: `${themeName}.tagGroup`, tokens, ...tagGroupProps, ...state, children })
|
|
51
|
+
}
|
|
52
|
+
) });
|
|
53
|
+
}
|
|
54
|
+
module.exports = Filter;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Box, PopoverButton, TagGroup } from "@okam/stack-ui";
|
|
4
|
+
import { useFilterState } from "../../hooks/useFilterState/index.mjs";
|
|
5
|
+
function Filter(props) {
|
|
6
|
+
const {
|
|
7
|
+
// TagGroup-specific props
|
|
8
|
+
children,
|
|
9
|
+
items,
|
|
10
|
+
defaultSelectedKeys,
|
|
11
|
+
selectedKeys,
|
|
12
|
+
selectionBehavior,
|
|
13
|
+
selectionMode = "multiple",
|
|
14
|
+
options,
|
|
15
|
+
description,
|
|
16
|
+
disabledKeys,
|
|
17
|
+
disallowEmptySelection,
|
|
18
|
+
errorMessage,
|
|
19
|
+
onRemove,
|
|
20
|
+
onSelectionChange,
|
|
21
|
+
// Common props
|
|
22
|
+
themeName = "filter",
|
|
23
|
+
tokens,
|
|
24
|
+
customTheme,
|
|
25
|
+
// PopoverButton props with defaults
|
|
26
|
+
type = "dialog",
|
|
27
|
+
placement = "bottom",
|
|
28
|
+
// Remaining PopoverButton props
|
|
29
|
+
...popoverButtonProps
|
|
30
|
+
} = props;
|
|
31
|
+
const tagGroupProps = {
|
|
32
|
+
items,
|
|
33
|
+
selectionBehavior,
|
|
34
|
+
selectionMode,
|
|
35
|
+
description,
|
|
36
|
+
disallowEmptySelection,
|
|
37
|
+
errorMessage,
|
|
38
|
+
onRemove
|
|
39
|
+
};
|
|
40
|
+
const state = useFilterState({ ...props, selectionMode });
|
|
41
|
+
return /* @__PURE__ */ jsx(Box, { themeName: `${themeName}.wrapper`, tokens, customTheme, children: /* @__PURE__ */ jsx(
|
|
42
|
+
PopoverButton,
|
|
43
|
+
{
|
|
44
|
+
themeName: `${themeName}.popover`,
|
|
45
|
+
tokens,
|
|
46
|
+
type,
|
|
47
|
+
placement,
|
|
48
|
+
...popoverButtonProps,
|
|
49
|
+
children: /* @__PURE__ */ jsx(TagGroup, { themeName: `${themeName}.tagGroup`, tokens, ...tagGroupProps, ...state, children })
|
|
50
|
+
}
|
|
51
|
+
) });
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
Filter as default
|
|
55
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const stackUi = require("@okam/stack-ui");
|
|
5
|
+
const Image = require("next/image");
|
|
6
|
+
function Img(props) {
|
|
7
|
+
const { src, width, height, themeName = "img", tokens, customTheme, ...rest } = props;
|
|
8
|
+
const theme = stackUi.useThemeContext(themeName, tokens, customTheme);
|
|
9
|
+
if (typeof src === "object") {
|
|
10
|
+
const { blurWidth, blurHeight, width: srcWidth, height: srcHeight, ...withoutBlurDimensions } = src;
|
|
11
|
+
const blur = {
|
|
12
|
+
blurwidth: blurWidth,
|
|
13
|
+
blurheight: blurHeight
|
|
14
|
+
};
|
|
15
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
16
|
+
Image,
|
|
17
|
+
{
|
|
18
|
+
className: theme,
|
|
19
|
+
...withoutBlurDimensions,
|
|
20
|
+
...rest,
|
|
21
|
+
...blur,
|
|
22
|
+
width: srcWidth ?? width,
|
|
23
|
+
height: srcHeight ?? height
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Image, { width, height, className: theme, src, ...rest });
|
|
28
|
+
}
|
|
29
|
+
module.exports = Img;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useThemeContext } from "@okam/stack-ui";
|
|
4
|
+
import Image from "next/image";
|
|
5
|
+
function Img(props) {
|
|
6
|
+
const { src, width, height, themeName = "img", tokens, customTheme, ...rest } = props;
|
|
7
|
+
const theme = useThemeContext(themeName, tokens, customTheme);
|
|
8
|
+
if (typeof src === "object") {
|
|
9
|
+
const { blurWidth, blurHeight, width: srcWidth, height: srcHeight, ...withoutBlurDimensions } = src;
|
|
10
|
+
const blur = {
|
|
11
|
+
blurwidth: blurWidth,
|
|
12
|
+
blurheight: blurHeight
|
|
13
|
+
};
|
|
14
|
+
return /* @__PURE__ */ jsx(
|
|
15
|
+
Image,
|
|
16
|
+
{
|
|
17
|
+
className: theme,
|
|
18
|
+
...withoutBlurDimensions,
|
|
19
|
+
...rest,
|
|
20
|
+
...blur,
|
|
21
|
+
width: srcWidth ?? width,
|
|
22
|
+
height: srcHeight ?? height
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return /* @__PURE__ */ jsx(Image, { width, height, className: theme, src, ...rest });
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
Img as default
|
|
30
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const stackUi = require("@okam/stack-ui");
|
|
5
|
+
const NextLink = require("next/link");
|
|
6
|
+
const index = require("../../hooks/useLink/index.js");
|
|
7
|
+
function Link({ ref, ...props }) {
|
|
8
|
+
const {
|
|
9
|
+
themeName = "link",
|
|
10
|
+
tokens,
|
|
11
|
+
customTheme,
|
|
12
|
+
as = NextLink,
|
|
13
|
+
children,
|
|
14
|
+
locale,
|
|
15
|
+
scroll,
|
|
16
|
+
onPathnameChange,
|
|
17
|
+
onSearchParamsChange,
|
|
18
|
+
onHashChange,
|
|
19
|
+
behavior,
|
|
20
|
+
urlDecorator: urlDecoratorProp,
|
|
21
|
+
href: hrefProp,
|
|
22
|
+
...rest
|
|
23
|
+
} = props;
|
|
24
|
+
const linkProps = index.useLink(props);
|
|
25
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
26
|
+
stackUi.Anchor,
|
|
27
|
+
{
|
|
28
|
+
ref,
|
|
29
|
+
...rest,
|
|
30
|
+
nextLinkProps: linkProps,
|
|
31
|
+
as,
|
|
32
|
+
themeName,
|
|
33
|
+
tokens,
|
|
34
|
+
customTheme,
|
|
35
|
+
children
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
Link.displayName = "Link";
|
|
40
|
+
module.exports = Link;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Anchor } from "@okam/stack-ui";
|
|
4
|
+
import NextLink from "next/link";
|
|
5
|
+
import { useLink } from "../../hooks/useLink/index.mjs";
|
|
6
|
+
function Link({ ref, ...props }) {
|
|
7
|
+
const {
|
|
8
|
+
themeName = "link",
|
|
9
|
+
tokens,
|
|
10
|
+
customTheme,
|
|
11
|
+
as = NextLink,
|
|
12
|
+
children,
|
|
13
|
+
locale,
|
|
14
|
+
scroll,
|
|
15
|
+
onPathnameChange,
|
|
16
|
+
onSearchParamsChange,
|
|
17
|
+
onHashChange,
|
|
18
|
+
behavior,
|
|
19
|
+
urlDecorator: urlDecoratorProp,
|
|
20
|
+
href: hrefProp,
|
|
21
|
+
...rest
|
|
22
|
+
} = props;
|
|
23
|
+
const linkProps = useLink(props);
|
|
24
|
+
return /* @__PURE__ */ jsx(
|
|
25
|
+
Anchor,
|
|
26
|
+
{
|
|
27
|
+
ref,
|
|
28
|
+
...rest,
|
|
29
|
+
nextLinkProps: linkProps,
|
|
30
|
+
as,
|
|
31
|
+
themeName,
|
|
32
|
+
tokens,
|
|
33
|
+
customTheme,
|
|
34
|
+
children
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
Link.displayName = "Link";
|
|
39
|
+
export {
|
|
40
|
+
Link as default
|
|
41
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const nuqs = require("nuqs");
|
|
5
|
+
const radashi = require("radashi");
|
|
6
|
+
const react = require("react");
|
|
7
|
+
const reactStately = require("react-stately");
|
|
8
|
+
const reactUse = require("react-use");
|
|
9
|
+
function useFilterState(props) {
|
|
10
|
+
const {
|
|
11
|
+
id,
|
|
12
|
+
defaultSelectedKeys: defaultSelectedKeysProp = [],
|
|
13
|
+
onSelectionChange,
|
|
14
|
+
selectionMode = "multiple",
|
|
15
|
+
parser = nuqs.parseAsArrayOf(nuqs.parseAsString),
|
|
16
|
+
children,
|
|
17
|
+
items,
|
|
18
|
+
options,
|
|
19
|
+
...rest
|
|
20
|
+
} = props;
|
|
21
|
+
const defaultValue = Array.from(defaultSelectedKeysProp).map((key) => key.toString());
|
|
22
|
+
const queryStateOptions = react.useMemo(
|
|
23
|
+
() => parser.withOptions(options ?? {}).withDefault(defaultValue),
|
|
24
|
+
[parser, options, defaultValue]
|
|
25
|
+
);
|
|
26
|
+
const [selectedKeys, setSelectedKeys] = nuqs.useQueryState(id, queryStateOptions);
|
|
27
|
+
const onSelectedKeysChange = (keys) => {
|
|
28
|
+
onSelectionChange?.(keys);
|
|
29
|
+
const stringKeys = Array.from(keys).map((key) => key.toString());
|
|
30
|
+
void setSelectedKeys(stringKeys);
|
|
31
|
+
};
|
|
32
|
+
const defaultSelectedKeys = /* @__PURE__ */ new Set([...defaultSelectedKeysProp, ...selectedKeys ?? []]);
|
|
33
|
+
const state = reactStately.useListState({
|
|
34
|
+
...rest,
|
|
35
|
+
children,
|
|
36
|
+
items,
|
|
37
|
+
selectionMode,
|
|
38
|
+
defaultSelectedKeys,
|
|
39
|
+
onSelectionChange: onSelectedKeysChange
|
|
40
|
+
});
|
|
41
|
+
reactUse.useUpdateEffect(() => {
|
|
42
|
+
const next = Array.from(state.selectionManager.selectedKeys, String);
|
|
43
|
+
if (radashi.isEqual(next, selectedKeys)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
void setSelectedKeys(next);
|
|
47
|
+
}, [state.selectionManager.selectedKeys]);
|
|
48
|
+
return { ...state, onSelectionChange: onSelectedKeysChange, selectedKeys: selectedKeys ?? void 0, defaultSelectedKeys };
|
|
49
|
+
}
|
|
50
|
+
exports.useFilterState = useFilterState;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { parseAsArrayOf, parseAsString, useQueryState } from "nuqs";
|
|
3
|
+
import { isEqual } from "radashi";
|
|
4
|
+
import { useMemo } from "react";
|
|
5
|
+
import { useListState } from "react-stately";
|
|
6
|
+
import { useUpdateEffect } from "react-use";
|
|
7
|
+
function useFilterState(props) {
|
|
8
|
+
const {
|
|
9
|
+
id,
|
|
10
|
+
defaultSelectedKeys: defaultSelectedKeysProp = [],
|
|
11
|
+
onSelectionChange,
|
|
12
|
+
selectionMode = "multiple",
|
|
13
|
+
parser = parseAsArrayOf(parseAsString),
|
|
14
|
+
children,
|
|
15
|
+
items,
|
|
16
|
+
options,
|
|
17
|
+
...rest
|
|
18
|
+
} = props;
|
|
19
|
+
const defaultValue = Array.from(defaultSelectedKeysProp).map((key) => key.toString());
|
|
20
|
+
const queryStateOptions = useMemo(
|
|
21
|
+
() => parser.withOptions(options ?? {}).withDefault(defaultValue),
|
|
22
|
+
[parser, options, defaultValue]
|
|
23
|
+
);
|
|
24
|
+
const [selectedKeys, setSelectedKeys] = useQueryState(id, queryStateOptions);
|
|
25
|
+
const onSelectedKeysChange = (keys) => {
|
|
26
|
+
onSelectionChange?.(keys);
|
|
27
|
+
const stringKeys = Array.from(keys).map((key) => key.toString());
|
|
28
|
+
void setSelectedKeys(stringKeys);
|
|
29
|
+
};
|
|
30
|
+
const defaultSelectedKeys = /* @__PURE__ */ new Set([...defaultSelectedKeysProp, ...selectedKeys ?? []]);
|
|
31
|
+
const state = useListState({
|
|
32
|
+
...rest,
|
|
33
|
+
children,
|
|
34
|
+
items,
|
|
35
|
+
selectionMode,
|
|
36
|
+
defaultSelectedKeys,
|
|
37
|
+
onSelectionChange: onSelectedKeysChange
|
|
38
|
+
});
|
|
39
|
+
useUpdateEffect(() => {
|
|
40
|
+
const next = Array.from(state.selectionManager.selectedKeys, String);
|
|
41
|
+
if (isEqual(next, selectedKeys)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
void setSelectedKeys(next);
|
|
45
|
+
}, [state.selectionManager.selectedKeys]);
|
|
46
|
+
return { ...state, onSelectionChange: onSelectedKeysChange, selectedKeys: selectedKeys ?? void 0, defaultSelectedKeys };
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
useFilterState
|
|
50
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const react = require("react");
|
|
5
|
+
const reactUse = require("react-use");
|
|
6
|
+
function getHash() {
|
|
7
|
+
if (typeof window === "undefined")
|
|
8
|
+
return "";
|
|
9
|
+
return window.location.hash;
|
|
10
|
+
}
|
|
11
|
+
function useHash() {
|
|
12
|
+
const defaultHash = getHash();
|
|
13
|
+
const [hash, setHash] = react.useState(defaultHash);
|
|
14
|
+
const handleHashChangeEvent = ({ newURL }) => {
|
|
15
|
+
if (!URL.canParse(newURL))
|
|
16
|
+
return;
|
|
17
|
+
const { hash: newHash } = new URL(newURL);
|
|
18
|
+
if (!newHash || newHash === hash)
|
|
19
|
+
return;
|
|
20
|
+
setHash(newHash);
|
|
21
|
+
};
|
|
22
|
+
reactUse.useEvent("hashchange", handleHashChangeEvent);
|
|
23
|
+
return hash;
|
|
24
|
+
}
|
|
25
|
+
exports.useHash = useHash;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useEvent } from "react-use";
|
|
4
|
+
function getHash() {
|
|
5
|
+
if (typeof window === "undefined")
|
|
6
|
+
return "";
|
|
7
|
+
return window.location.hash;
|
|
8
|
+
}
|
|
9
|
+
function useHash() {
|
|
10
|
+
const defaultHash = getHash();
|
|
11
|
+
const [hash, setHash] = useState(defaultHash);
|
|
12
|
+
const handleHashChangeEvent = ({ newURL }) => {
|
|
13
|
+
if (!URL.canParse(newURL))
|
|
14
|
+
return;
|
|
15
|
+
const { hash: newHash } = new URL(newURL);
|
|
16
|
+
if (!newHash || newHash === hash)
|
|
17
|
+
return;
|
|
18
|
+
setHash(newHash);
|
|
19
|
+
};
|
|
20
|
+
useEvent("hashchange", handleHashChangeEvent);
|
|
21
|
+
return hash;
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
useHash
|
|
25
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
|
+
const navigation = require("next/navigation");
|
|
5
|
+
const react = require("react");
|
|
6
|
+
const reactAria = require("react-aria");
|
|
7
|
+
const index = require("../useHash/index.js");
|
|
8
|
+
const _interface = require("./interface.js");
|
|
9
|
+
const EXTERNAL_URL_RE = /^[a-z]+:\/\//i;
|
|
10
|
+
function scrollToTop(behavior) {
|
|
11
|
+
window?.scrollTo?.({ top: 0, behavior });
|
|
12
|
+
}
|
|
13
|
+
function getParamsLocale(params) {
|
|
14
|
+
const { locale } = params ?? {};
|
|
15
|
+
if (Array.isArray(locale))
|
|
16
|
+
return locale[0];
|
|
17
|
+
return locale;
|
|
18
|
+
}
|
|
19
|
+
function useLinkLocale(props) {
|
|
20
|
+
const { locale, i18n } = props;
|
|
21
|
+
const { defaultLocale, localePrefix = "always" } = i18n ?? {};
|
|
22
|
+
const params = navigation.useParams();
|
|
23
|
+
const paramsLocale = getParamsLocale(params);
|
|
24
|
+
const { locale: ctxLocale } = reactAria.useLocale();
|
|
25
|
+
const finalLocale = locale ?? ctxLocale ?? paramsLocale ?? false;
|
|
26
|
+
const shouldDisplayLocale = {
|
|
27
|
+
[_interface.LocalePrefix.Always]: true,
|
|
28
|
+
[_interface.LocalePrefix.AsNeeded]: finalLocale !== defaultLocale
|
|
29
|
+
}[localePrefix];
|
|
30
|
+
const displayLocale = shouldDisplayLocale ? finalLocale : false;
|
|
31
|
+
return displayLocale;
|
|
32
|
+
}
|
|
33
|
+
function localizeHref(href, locale) {
|
|
34
|
+
const hrefString = href.toString();
|
|
35
|
+
const hasTrailingSlash = hrefString.endsWith("/");
|
|
36
|
+
const isAnchor = hrefString.startsWith("#");
|
|
37
|
+
const isExternal = EXTERNAL_URL_RE.test(hrefString) || hrefString.startsWith("//");
|
|
38
|
+
let finalHref;
|
|
39
|
+
if (locale != null && locale !== false && !isExternal && !isAnchor) {
|
|
40
|
+
finalHref = `/${locale}${hrefString}`;
|
|
41
|
+
} else {
|
|
42
|
+
finalHref = hrefString;
|
|
43
|
+
}
|
|
44
|
+
return hasTrailingSlash || isAnchor ? finalHref : `${finalHref}/`;
|
|
45
|
+
}
|
|
46
|
+
function useLink(props) {
|
|
47
|
+
const {
|
|
48
|
+
scroll = true,
|
|
49
|
+
onMouseEnter,
|
|
50
|
+
onTouchStart,
|
|
51
|
+
onClick,
|
|
52
|
+
onNavigate,
|
|
53
|
+
onPathnameChange,
|
|
54
|
+
onHashChange,
|
|
55
|
+
onSearchParamsChange,
|
|
56
|
+
href,
|
|
57
|
+
urlDecorator,
|
|
58
|
+
replace,
|
|
59
|
+
prefetch,
|
|
60
|
+
shallow,
|
|
61
|
+
passHref,
|
|
62
|
+
legacyBehavior,
|
|
63
|
+
behavior = "instant"
|
|
64
|
+
} = props;
|
|
65
|
+
const locale = useLinkLocale(props);
|
|
66
|
+
const localizedHref = localizeHref(href, locale);
|
|
67
|
+
const pathname = navigation.usePathname();
|
|
68
|
+
const searchParams = navigation.useSearchParams();
|
|
69
|
+
const hash = index.useHash();
|
|
70
|
+
const hasWarnedOnPathnameChangeRef = react.useRef(false);
|
|
71
|
+
const isNextScroll = typeof scroll === "boolean";
|
|
72
|
+
const nextScroll = isNextScroll ? scroll : false;
|
|
73
|
+
const handleScroll = react.useCallback(() => {
|
|
74
|
+
if (isNextScroll)
|
|
75
|
+
return;
|
|
76
|
+
scrollToTop(behavior);
|
|
77
|
+
}, [behavior, isNextScroll]);
|
|
78
|
+
const handleClick = (event) => {
|
|
79
|
+
onClick?.(event);
|
|
80
|
+
handleScroll();
|
|
81
|
+
};
|
|
82
|
+
const handleTouchStart = (event) => {
|
|
83
|
+
onTouchStart?.(event);
|
|
84
|
+
handleScroll();
|
|
85
|
+
};
|
|
86
|
+
react.useEffect(() => {
|
|
87
|
+
if (process.env.NODE_ENV === "production" || onPathnameChange == null || hasWarnedOnPathnameChangeRef.current)
|
|
88
|
+
return;
|
|
89
|
+
console.warn("[next-component/Link] `onPathnameChange` is deprecated and will be removed in the next major version. Use `onNavigate` from next/link instead.");
|
|
90
|
+
hasWarnedOnPathnameChangeRef.current = true;
|
|
91
|
+
}, [onPathnameChange]);
|
|
92
|
+
react.useEffect(() => {
|
|
93
|
+
onPathnameChange?.(pathname);
|
|
94
|
+
}, [onPathnameChange, pathname]);
|
|
95
|
+
react.useEffect(() => {
|
|
96
|
+
onSearchParamsChange?.(searchParams);
|
|
97
|
+
}, [onSearchParamsChange, searchParams]);
|
|
98
|
+
react.useEffect(() => {
|
|
99
|
+
onHashChange?.(hash);
|
|
100
|
+
}, [onHashChange, hash]);
|
|
101
|
+
return {
|
|
102
|
+
href: localizedHref.toString(),
|
|
103
|
+
as: urlDecorator,
|
|
104
|
+
replace,
|
|
105
|
+
prefetch,
|
|
106
|
+
shallow,
|
|
107
|
+
onClick: handleClick,
|
|
108
|
+
onNavigate,
|
|
109
|
+
onTouchStart: handleTouchStart,
|
|
110
|
+
onMouseEnter,
|
|
111
|
+
scroll: nextScroll,
|
|
112
|
+
passHref,
|
|
113
|
+
legacyBehavior
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
exports.localizeHref = localizeHref;
|
|
117
|
+
exports.useLink = useLink;
|
|
118
|
+
exports.useLinkLocale = useLinkLocale;
|