@kirill.konshin/next 0.0.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/.ctirc +11 -0
- package/.turbo/turbo-build.log +16 -0
- package/dist/appLink.d.ts +8 -0
- package/dist/appLink.d.ts.map +1 -0
- package/dist/appLink.js +34 -0
- package/dist/appLink.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/measure.d.ts +15 -0
- package/dist/measure.d.ts.map +1 -0
- package/dist/measure.js +9 -0
- package/dist/measure.js.map +1 -0
- package/dist/noSSR.d.ts +29 -0
- package/dist/noSSR.d.ts.map +1 -0
- package/dist/noSSR.js +13 -0
- package/dist/noSSR.js.map +1 -0
- package/dist/redirect.d.ts +6 -0
- package/dist/redirect.d.ts.map +1 -0
- package/dist/useIsInner.d.ts +3 -0
- package/dist/useIsInner.d.ts.map +1 -0
- package/dist/useIsInner.js +15 -0
- package/dist/useIsInner.js.map +1 -0
- package/package.json +63 -0
- package/src/appLink.tsx +40 -0
- package/src/index.ts +5 -0
- package/src/measure.ts +24 -0
- package/src/noSSR.tsx +36 -0
- package/src/redirect.tsx +13 -0
- package/src/useIsInner.ts +13 -0
- package/tsconfig.json +10 -0
- package/turbo.json +10 -0
- package/vite.config.ts +2 -0
package/.ctirc
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[36mvite v7.0.6 [32mbuilding SSR bundle for production...[36m[39m
|
|
2
|
+
create succeeded: /home/runner/work/utils/utils/packages/next/src
|
|
3
|
+
transforming...
|
|
4
|
+
[32m✓[39m 6 modules transformed.
|
|
5
|
+
rendering chunks...
|
|
6
|
+
|
|
7
|
+
[vite:dts] Start generate declaration files...
|
|
8
|
+
[2mdist/[22m[36mnoSSR.js [39m[1m[2m0.33 kB[22m[1m[22m[2m │ map: 1.38 kB[22m
|
|
9
|
+
[2mdist/[22m[36mindex.js [39m[1m[2m0.34 kB[22m[1m[22m[2m │ map: 0.10 kB[22m
|
|
10
|
+
[2mdist/[22m[36museIsInner.js [39m[1m[2m0.37 kB[22m[1m[22m[2m │ map: 0.61 kB[22m
|
|
11
|
+
[2mdist/[22m[36mmeasure.js [39m[1m[2m0.38 kB[22m[1m[22m[2m │ map: 1.04 kB[22m
|
|
12
|
+
[2mdist/[22m[36mappLink.js [39m[1m[2m0.77 kB[22m[1m[22m[2m │ map: 1.58 kB[22m
|
|
13
|
+
[vite:dts] Declaration files built in 1575ms.
|
|
14
|
+
|
|
15
|
+
[32m✓ built in 2.28s[39m
|
|
16
|
+
Updated package.json with exports
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ComponentProps, FC } from 'react';
|
|
2
|
+
import { default as Link, LinkProps } from 'next/link';
|
|
3
|
+
export declare const AppLink: FC<{
|
|
4
|
+
children: any;
|
|
5
|
+
exact?: boolean;
|
|
6
|
+
activeClassName?: any;
|
|
7
|
+
} & LinkProps & ComponentProps<typeof Link>>;
|
|
8
|
+
//# sourceMappingURL=appLink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appLink.d.ts","sourceRoot":"","sources":["../src/appLink.tsx"],"names":[],"mappings":"AAEA,OAAc,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAElD,OAAO,IAAI,EAAE,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAI5C,eAAO,MAAM,OAAO,EAAE,EAAE,CACpB;IACI,QAAQ,EAAE,GAAG,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,GAAG,CAAC;CACzB,GAAG,SAAS,GACT,cAAc,CAAC,OAAO,IAAI,CAAC,CAyBlC,CAAC"}
|
package/dist/appLink.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { usePathname } from "next/navigation";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import clsx from "clsx";
|
|
6
|
+
const AppLink = function AppLink2({
|
|
7
|
+
href,
|
|
8
|
+
children,
|
|
9
|
+
className = "",
|
|
10
|
+
activeClassName = "",
|
|
11
|
+
prefetch = false,
|
|
12
|
+
// set explicit default
|
|
13
|
+
exact = false,
|
|
14
|
+
...props
|
|
15
|
+
}) {
|
|
16
|
+
const pathname = usePathname();
|
|
17
|
+
const hrefPath = typeof href === "string" ? href : href.pathname || "/";
|
|
18
|
+
return /* @__PURE__ */ jsx(
|
|
19
|
+
Link,
|
|
20
|
+
{
|
|
21
|
+
...props,
|
|
22
|
+
href,
|
|
23
|
+
className: clsx(className, {
|
|
24
|
+
[activeClassName]: !exact && pathname.startsWith(hrefPath) || exact && pathname === hrefPath
|
|
25
|
+
}),
|
|
26
|
+
prefetch,
|
|
27
|
+
children
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
AppLink
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=appLink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appLink.js","sources":["../src/appLink.tsx"],"sourcesContent":["'use client';\n\nimport React, { ComponentProps, FC } from 'react';\nimport { usePathname } from 'next/navigation';\nimport Link, { LinkProps } from 'next/link';\nimport clsx from 'clsx';\n\n//TODO Test this\nexport const AppLink: FC<\n {\n children: any;\n exact?: boolean;\n activeClassName?: any;\n } & LinkProps &\n ComponentProps<typeof Link>\n> = function AppLink({\n href,\n children,\n className = '',\n activeClassName = '',\n prefetch = false, // set explicit default\n exact = false,\n ...props\n}) {\n const pathname = usePathname();\n const hrefPath = typeof href === 'string' ? href : href.pathname || '/';\n\n return (\n <Link\n {...props}\n href={href}\n className={clsx(className, {\n [activeClassName]: (!exact && pathname.startsWith(hrefPath)) || (exact && pathname === hrefPath),\n })}\n prefetch={prefetch}\n >\n {children}\n </Link>\n );\n};\n"],"names":["AppLink"],"mappings":";;;;;AAQO,MAAM,UAOT,SAASA,SAAQ;AAAA,EACjB;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,WAAW;AAAA;AAAA,EACX,QAAQ;AAAA,EACR,GAAG;AACP,GAAG;AACC,QAAM,WAAW,YAAA;AACjB,QAAM,WAAW,OAAO,SAAS,WAAW,OAAO,KAAK,YAAY;AAEpE,SACI;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAG;AAAA,MACJ;AAAA,MACA,WAAW,KAAK,WAAW;AAAA,QACvB,CAAC,eAAe,GAAI,CAAC,SAAS,SAAS,WAAW,QAAQ,KAAO,SAAS,aAAa;AAAA,MAAA,CAC1F;AAAA,MACD;AAAA,MAEC;AAAA,IAAA;AAAA,EAAA;AAGb;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AppLink } from "./appLink.js";
|
|
2
|
+
import { isProd, measurer } from "./measure.js";
|
|
3
|
+
import { NoSSR } from "./noSSR.js";
|
|
4
|
+
import "next/navigation";
|
|
5
|
+
import "react";
|
|
6
|
+
import { useIsIndex, useIsInner } from "./useIsInner.js";
|
|
7
|
+
export {
|
|
8
|
+
AppLink,
|
|
9
|
+
NoSSR,
|
|
10
|
+
isProd,
|
|
11
|
+
measurer,
|
|
12
|
+
useIsIndex,
|
|
13
|
+
useIsInner
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const isProd: boolean;
|
|
2
|
+
export declare const measurer: {
|
|
3
|
+
measure: (what: string, step: string, supplemental?: string, ...args: any[]) => {
|
|
4
|
+
done: (result?: string, ...args2: any[]) => void;
|
|
5
|
+
fail: (result?: string, ...args2: any[]) => void;
|
|
6
|
+
log: (...args2: any[]) => void;
|
|
7
|
+
};
|
|
8
|
+
important: (str: any) => any;
|
|
9
|
+
subject: (str: any) => any;
|
|
10
|
+
arg: (str: any) => any;
|
|
11
|
+
sup: (str: any) => any;
|
|
12
|
+
ok: (str: any) => any;
|
|
13
|
+
err: (str: any) => any;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=measure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.d.ts","sourceRoot":"","sources":["../src/measure.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM,EAAE,OACsF,CAAC;AAE5G,eAAO,MAAM,QAAQ,EAAE;IACnB,OAAO,EAAE,CACL,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,EACrB,GAAG,IAAI,EAAE,GAAG,EAAE,KACb;QACD,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;QACjD,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;QACjD,GAAG,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;KAClC,CAAC;IACF,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC;IAC7B,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC;IAC3B,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC;IACvB,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC;IACvB,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC;IACtB,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,CAAC;CACW,CAAC"}
|
package/dist/measure.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createMeasurer } from "@kirill.konshin/core";
|
|
2
|
+
import { PHASE_PRODUCTION_BUILD, PHASE_PRODUCTION_SERVER } from "next/constants";
|
|
3
|
+
const isProd = process.env.NEXT_PHASE === PHASE_PRODUCTION_BUILD || process.env.NEXT_PHASE === PHASE_PRODUCTION_SERVER;
|
|
4
|
+
const measurer = createMeasurer({ colors: isProd });
|
|
5
|
+
export {
|
|
6
|
+
isProd,
|
|
7
|
+
measurer
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=measure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.js","sources":["../src/measure.ts"],"sourcesContent":["import { createMeasurer } from '@kirill.konshin/core';\nimport { PHASE_PRODUCTION_BUILD, PHASE_PRODUCTION_SERVER } from 'next/constants';\n\nexport const isProd: boolean =\n process.env.NEXT_PHASE === PHASE_PRODUCTION_BUILD || process.env.NEXT_PHASE === PHASE_PRODUCTION_SERVER;\n\nexport const measurer: {\n measure: (\n what: string,\n step: string,\n supplemental?: string,\n ...args: any[]\n ) => {\n done: (result?: string, ...args2: any[]) => void;\n fail: (result?: string, ...args2: any[]) => void;\n log: (...args2: any[]) => void;\n };\n important: (str: any) => any;\n subject: (str: any) => any;\n arg: (str: any) => any;\n sup: (str: any) => any;\n ok: (str: any) => any;\n err: (str: any) => any;\n} = createMeasurer({ colors: isProd });\n"],"names":[],"mappings":";;AAGO,MAAM,SACT,QAAQ,IAAI,eAAe,0BAA0B,QAAQ,IAAI,eAAe;AAE7E,MAAM,WAiBT,eAAe,EAAE,QAAQ,QAAQ;"}
|
package/dist/noSSR.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FC, JSX } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Prefer using Next.js `dynamic()` import with `ssr: false` because this will also remove import from server bundle.
|
|
4
|
+
*
|
|
5
|
+
* ```tsx
|
|
6
|
+
* 'use client';
|
|
7
|
+
*
|
|
8
|
+
* import React from 'react';
|
|
9
|
+
* import dynamic from 'next/dynamic';
|
|
10
|
+
*
|
|
11
|
+
* const PageClient = dynamic(() => import('./pageClient'), { ssr: false });
|
|
12
|
+
*
|
|
13
|
+
* export default function Page() {
|
|
14
|
+
* return (
|
|
15
|
+
* <PageClient />
|
|
16
|
+
* );
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* In other cases this component can be used to just prevent server rendering.
|
|
21
|
+
*
|
|
22
|
+
* @see https://github.com/kadirahq/react-no-ssr/blob/master/src/index.js
|
|
23
|
+
* @see https://nextjs.org/docs/messages/react-hydration-error#solution-1-using-useeffect-to-run-on-the-client-only
|
|
24
|
+
*/
|
|
25
|
+
export declare const NoSSR: FC<{
|
|
26
|
+
children: any;
|
|
27
|
+
onSSR?: JSX.Element;
|
|
28
|
+
}>;
|
|
29
|
+
//# sourceMappingURL=noSSR.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noSSR.d.ts","sourceRoot":"","sources":["../src/noSSR.tsx"],"names":[],"mappings":"AAEA,OAAc,EAAE,EAAE,EAAE,GAAG,EAA6B,MAAM,OAAO,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CAAE,CAQ5D,CAAC"}
|
package/dist/noSSR.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useLayoutEffect } from "react";
|
|
3
|
+
const NoSSR = function NoSSR2({ children, onSSR = null }) {
|
|
4
|
+
const [canRender, setCanRender] = useState(false);
|
|
5
|
+
useLayoutEffect(() => {
|
|
6
|
+
setCanRender(true);
|
|
7
|
+
}, []);
|
|
8
|
+
return canRender ? children : onSSR;
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
NoSSR
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=noSSR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noSSR.js","sources":["../src/noSSR.tsx"],"sourcesContent":["'use client';\n\nimport React, { FC, JSX, useLayoutEffect, useState } from 'react';\n\n/**\n * Prefer using Next.js `dynamic()` import with `ssr: false` because this will also remove import from server bundle.\n *\n * ```tsx\n * 'use client';\n *\n * import React from 'react';\n * import dynamic from 'next/dynamic';\n *\n * const PageClient = dynamic(() => import('./pageClient'), { ssr: false });\n *\n * export default function Page() {\n * return (\n * <PageClient />\n * );\n * }\n * ```\n *\n * In other cases this component can be used to just prevent server rendering.\n *\n * @see https://github.com/kadirahq/react-no-ssr/blob/master/src/index.js\n * @see https://nextjs.org/docs/messages/react-hydration-error#solution-1-using-useeffect-to-run-on-the-client-only\n */\nexport const NoSSR: FC<{ children: any; onSSR?: JSX.Element }> = function NoSSR({ children, onSSR = null }): any {\n const [canRender, setCanRender] = useState(false);\n\n useLayoutEffect(() => {\n setCanRender(true);\n }, []);\n\n return canRender ? children : onSSR;\n};\n"],"names":["NoSSR"],"mappings":";;AA2BO,MAAM,QAAoD,SAASA,OAAM,EAAE,UAAU,QAAQ,QAAa;AAC7G,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,kBAAgB,MAAM;AAClB,iBAAa,IAAI;AAAA,EACrB,GAAG,CAAA,CAAE;AAEL,SAAO,YAAY,WAAW;AAClC;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redirect.d.ts","sourceRoot":"","sources":["../src/redirect.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;IAAE,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,QAM1G"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useIsInner.d.ts","sourceRoot":"","sources":["../src/useIsInner.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,UAAU,QAAO,OAG7B,CAAC;AAEF,eAAO,MAAM,UAAU,QAAO,OAG7B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useSelectedLayoutSegments } from "next/navigation";
|
|
3
|
+
const useIsInner = () => {
|
|
4
|
+
const pathname = useSelectedLayoutSegments();
|
|
5
|
+
return pathname.length > 0;
|
|
6
|
+
};
|
|
7
|
+
const useIsIndex = () => {
|
|
8
|
+
const pathname = useSelectedLayoutSegments();
|
|
9
|
+
return pathname.length === 0;
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
useIsIndex,
|
|
13
|
+
useIsInner
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useIsInner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useIsInner.js","sources":["../src/useIsInner.ts"],"sourcesContent":["'use client';\n\nimport { useSelectedLayoutSegments } from 'next/navigation';\n\nexport const useIsInner = (): boolean => {\n const pathname = useSelectedLayoutSegments();\n return pathname.length > 0;\n};\n\nexport const useIsIndex = (): boolean => {\n const pathname = useSelectedLayoutSegments();\n return pathname.length === 0;\n};\n"],"names":[],"mappings":";;AAIO,MAAM,aAAa,MAAe;AACrC,QAAM,WAAW,0BAAA;AACjB,SAAO,SAAS,SAAS;AAC7B;AAEO,MAAM,aAAa,MAAe;AACrC,QAAM,WAAW,0BAAA;AACjB,SAAO,SAAS,WAAW;AAC/B;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kirill.konshin/next",
|
|
3
|
+
"description": "Utilities",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"----- BUILD -----": "",
|
|
8
|
+
"clean": "rm -rf dist .tscache tsconfig.tsbuildinfo",
|
|
9
|
+
"build": "vite build",
|
|
10
|
+
"build:index": "cti create ./src",
|
|
11
|
+
"build:check-types": "attw --pack .",
|
|
12
|
+
"start": "yarn build --watch",
|
|
13
|
+
"wait": "wait-on ./dist/index.js",
|
|
14
|
+
"----- TEST -----": "",
|
|
15
|
+
"test:disabled": "vitest run --coverage",
|
|
16
|
+
"test:watch": "vitest watch --coverage",
|
|
17
|
+
"----- STORYBOOK -----": "",
|
|
18
|
+
"storybook:start": "storybook dev -p 6006",
|
|
19
|
+
"storybook:build": "storybook build"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@kirill.konshin/core": "*",
|
|
23
|
+
"clsx": "^2.1.1",
|
|
24
|
+
"colors": "^1.4.0",
|
|
25
|
+
"file-saver": "^2.0.5",
|
|
26
|
+
"many-keys-map": "^3.0.3",
|
|
27
|
+
"psd": "^3.4.0",
|
|
28
|
+
"sharp": "^0.34.3"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@kirill.konshin/utils-private": "*",
|
|
32
|
+
"next": "^15.4.5",
|
|
33
|
+
"react": "^19.1.1"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"next": "^15",
|
|
37
|
+
"react": "^19"
|
|
38
|
+
},
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"next": {
|
|
41
|
+
"optional": true
|
|
42
|
+
},
|
|
43
|
+
"react": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"author": "Kirill Konshin <kirill@konshin.org> (https://konshin.org)",
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"exports": {
|
|
53
|
+
".": {
|
|
54
|
+
"import": {
|
|
55
|
+
"import": "./dist/index.js",
|
|
56
|
+
"types": "./dist/index.d.ts"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"main": "./dist/index.js",
|
|
61
|
+
"module": "./dist/index.js",
|
|
62
|
+
"types": "./dist/index.d.ts"
|
|
63
|
+
}
|
package/src/appLink.tsx
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { ComponentProps, FC } from 'react';
|
|
4
|
+
import { usePathname } from 'next/navigation';
|
|
5
|
+
import Link, { LinkProps } from 'next/link';
|
|
6
|
+
import clsx from 'clsx';
|
|
7
|
+
|
|
8
|
+
//TODO Test this
|
|
9
|
+
export const AppLink: FC<
|
|
10
|
+
{
|
|
11
|
+
children: any;
|
|
12
|
+
exact?: boolean;
|
|
13
|
+
activeClassName?: any;
|
|
14
|
+
} & LinkProps &
|
|
15
|
+
ComponentProps<typeof Link>
|
|
16
|
+
> = function AppLink({
|
|
17
|
+
href,
|
|
18
|
+
children,
|
|
19
|
+
className = '',
|
|
20
|
+
activeClassName = '',
|
|
21
|
+
prefetch = false, // set explicit default
|
|
22
|
+
exact = false,
|
|
23
|
+
...props
|
|
24
|
+
}) {
|
|
25
|
+
const pathname = usePathname();
|
|
26
|
+
const hrefPath = typeof href === 'string' ? href : href.pathname || '/';
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Link
|
|
30
|
+
{...props}
|
|
31
|
+
href={href}
|
|
32
|
+
className={clsx(className, {
|
|
33
|
+
[activeClassName]: (!exact && pathname.startsWith(hrefPath)) || (exact && pathname === hrefPath),
|
|
34
|
+
})}
|
|
35
|
+
prefetch={prefetch}
|
|
36
|
+
>
|
|
37
|
+
{children}
|
|
38
|
+
</Link>
|
|
39
|
+
);
|
|
40
|
+
};
|
package/src/index.ts
ADDED
package/src/measure.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createMeasurer } from '@kirill.konshin/core';
|
|
2
|
+
import { PHASE_PRODUCTION_BUILD, PHASE_PRODUCTION_SERVER } from 'next/constants';
|
|
3
|
+
|
|
4
|
+
export const isProd: boolean =
|
|
5
|
+
process.env.NEXT_PHASE === PHASE_PRODUCTION_BUILD || process.env.NEXT_PHASE === PHASE_PRODUCTION_SERVER;
|
|
6
|
+
|
|
7
|
+
export const measurer: {
|
|
8
|
+
measure: (
|
|
9
|
+
what: string,
|
|
10
|
+
step: string,
|
|
11
|
+
supplemental?: string,
|
|
12
|
+
...args: any[]
|
|
13
|
+
) => {
|
|
14
|
+
done: (result?: string, ...args2: any[]) => void;
|
|
15
|
+
fail: (result?: string, ...args2: any[]) => void;
|
|
16
|
+
log: (...args2: any[]) => void;
|
|
17
|
+
};
|
|
18
|
+
important: (str: any) => any;
|
|
19
|
+
subject: (str: any) => any;
|
|
20
|
+
arg: (str: any) => any;
|
|
21
|
+
sup: (str: any) => any;
|
|
22
|
+
ok: (str: any) => any;
|
|
23
|
+
err: (str: any) => any;
|
|
24
|
+
} = createMeasurer({ colors: isProd });
|
package/src/noSSR.tsx
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { FC, JSX, useLayoutEffect, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Prefer using Next.js `dynamic()` import with `ssr: false` because this will also remove import from server bundle.
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* 'use client';
|
|
10
|
+
*
|
|
11
|
+
* import React from 'react';
|
|
12
|
+
* import dynamic from 'next/dynamic';
|
|
13
|
+
*
|
|
14
|
+
* const PageClient = dynamic(() => import('./pageClient'), { ssr: false });
|
|
15
|
+
*
|
|
16
|
+
* export default function Page() {
|
|
17
|
+
* return (
|
|
18
|
+
* <PageClient />
|
|
19
|
+
* );
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* In other cases this component can be used to just prevent server rendering.
|
|
24
|
+
*
|
|
25
|
+
* @see https://github.com/kadirahq/react-no-ssr/blob/master/src/index.js
|
|
26
|
+
* @see https://nextjs.org/docs/messages/react-hydration-error#solution-1-using-useeffect-to-run-on-the-client-only
|
|
27
|
+
*/
|
|
28
|
+
export const NoSSR: FC<{ children: any; onSSR?: JSX.Element }> = function NoSSR({ children, onSSR = null }): any {
|
|
29
|
+
const [canRender, setCanRender] = useState(false);
|
|
30
|
+
|
|
31
|
+
useLayoutEffect(() => {
|
|
32
|
+
setCanRender(true);
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
return canRender ? children : onSSR;
|
|
36
|
+
};
|
package/src/redirect.tsx
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useRouter } from 'next/navigation';
|
|
4
|
+
import { useEffect } from 'react';
|
|
5
|
+
import type { LinkProps } from 'next/link';
|
|
6
|
+
|
|
7
|
+
export default function Redirect({ to, replace }: { to: LinkProps['href']; replace?: LinkProps['replace'] }) {
|
|
8
|
+
const router = useRouter();
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
router[replace ? 'replace' : 'push'](to.toString()); //TODO Test this
|
|
11
|
+
}, [replace, router, to]);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useSelectedLayoutSegments } from 'next/navigation';
|
|
4
|
+
|
|
5
|
+
export const useIsInner = (): boolean => {
|
|
6
|
+
const pathname = useSelectedLayoutSegments();
|
|
7
|
+
return pathname.length > 0;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const useIsIndex = (): boolean => {
|
|
11
|
+
const pathname = useSelectedLayoutSegments();
|
|
12
|
+
return pathname.length === 0;
|
|
13
|
+
};
|
package/tsconfig.json
ADDED
package/turbo.json
ADDED
package/vite.config.ts
ADDED