statemorph 1.0.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/index.ts +3 -0
- package/package.json +30 -0
- package/rollup.config.js +43 -0
- package/src/package/index.tsx +49 -0
- package/tsconfig.json +20 -0
package/index.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "statemorph",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Zero-dep React wrapper that eliminates loading/error/empty/success ternary hell.",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"author": "",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"module": "dist/index.mjs",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
12
|
+
"rollup": "rollup -c --bundleConfigAsCjs"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
16
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
17
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
18
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
19
|
+
"@types/react": "^19.2.14",
|
|
20
|
+
"react": "^19.2.4",
|
|
21
|
+
"rollup-plugin-dts": "^6.3.0",
|
|
22
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
23
|
+
"tslib": "^2.8.1",
|
|
24
|
+
"typescript": "^5.9.3"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"rollup": "^4.58.0",
|
|
28
|
+
"rollup-plugin-postcss": "^4.0.2"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import resolve from "@rollup/plugin-node-resolve";
|
|
2
|
+
import commonjs from "@rollup/plugin-commonjs";
|
|
3
|
+
import typescript from "@rollup/plugin-typescript";
|
|
4
|
+
import dts from "rollup-plugin-dts";
|
|
5
|
+
import terser from "@rollup/plugin-terser";
|
|
6
|
+
import peerDepsExternal from "rollup-plugin-peer-deps-external";
|
|
7
|
+
|
|
8
|
+
import postcss from "rollup-plugin-postcss";
|
|
9
|
+
|
|
10
|
+
const packageJson = require("./package.json");
|
|
11
|
+
|
|
12
|
+
export default [
|
|
13
|
+
{
|
|
14
|
+
input: "src/index.ts",
|
|
15
|
+
output: [
|
|
16
|
+
{
|
|
17
|
+
file: packageJson.main,
|
|
18
|
+
format: "cjs",
|
|
19
|
+
sourcemap: true,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
file: packageJson.module,
|
|
23
|
+
format: "esm",
|
|
24
|
+
sourcemap: true,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
plugins: [
|
|
28
|
+
peerDepsExternal(),
|
|
29
|
+
resolve(),
|
|
30
|
+
commonjs(),
|
|
31
|
+
typescript({ tsconfig: "./tsconfig.json" }),
|
|
32
|
+
terser(),
|
|
33
|
+
postcss(),
|
|
34
|
+
],
|
|
35
|
+
external: ["react", "react-dom"],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
input: "src/index.ts",
|
|
39
|
+
output: [{ file: packageJson.types }],
|
|
40
|
+
plugins: [dts.default()],
|
|
41
|
+
external: [/\.css$/],
|
|
42
|
+
},
|
|
43
|
+
];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import React, { memo, type ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface StateConfig<T> {
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
loadingUI?: ReactNode;
|
|
7
|
+
isError: boolean;
|
|
8
|
+
errorUI?: ReactNode;
|
|
9
|
+
isIdle: boolean;
|
|
10
|
+
idleUI?: ReactNode;
|
|
11
|
+
data: T | null;
|
|
12
|
+
emptyUI?: ReactNode;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface StateMorphProps<T> {
|
|
16
|
+
config: StateConfig<T>;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const StateMorph: React.FC<StateMorphProps<any>> = memo(({ config, children }) => {
|
|
21
|
+
const {
|
|
22
|
+
isLoading, loadingUI,
|
|
23
|
+
isError, errorUI,
|
|
24
|
+
isIdle, idleUI,
|
|
25
|
+
data, emptyUI
|
|
26
|
+
} = config;
|
|
27
|
+
|
|
28
|
+
if (isLoading) {
|
|
29
|
+
return <>{loadingUI ?? <div className="animate-pulse p-8 text-center text-gray-500">Loading...</div>}</>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (isError) {
|
|
33
|
+
return <>{errorUI ?? <div className="p-8 text-center text-red-500">Something went wrong. Please try again.</div>}</>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (isIdle) {
|
|
37
|
+
return <>{idleUI ?? <div className="p-8 text-center text-gray-500">Ready to load data</div>}</>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!data || (Array.isArray(data) && data.length === 0) || (data && typeof data === 'object' && Object.keys(data).length === 0)) {
|
|
41
|
+
return <>{emptyUI ?? <div className="p-8 text-center text-gray-500">No data available</div>}</>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return <div>{children}</div>;
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
StateMorph.displayName = 'StateMorph';
|
|
48
|
+
|
|
49
|
+
export default StateMorph;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es5",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"allowSyntheticDefaultImports": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"noFallthroughCasesInSwitch": true,
|
|
12
|
+
"module": "esnext",
|
|
13
|
+
"moduleResolution": "node",
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"jsx": "react-jsx"
|
|
18
|
+
},
|
|
19
|
+
"include": ["src"]
|
|
20
|
+
}
|