@vetc-miniapp/ui-react 0.0.2 → 0.0.4
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/package.json +12 -115
- package/src/dist/ui-react/index.js +2 -1
- package/src/dist/ui-react/index.js.LICENSE.txt +9 -0
- package/src/ui-react/components/app.d.ts +7 -0
- package/src/ui-react/components/app.jsx +75 -0
- package/src/ui-react/components/app.tsx +42 -0
- package/src/ui-react/components/app1.js +101 -0
- package/src/ui-react/hooks/use-app-state.js +35 -0
- package/src/ui-react/hooks/use-app-state.ts +8 -0
- package/src/ui-react/index.js +2 -0
- package/src/ui-react/index.ts +3 -0
- package/src/ui-react/types/app.js +30 -0
- package/src/ui-react/types/app.ts +32 -0
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vetc-miniapp/ui-react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "MiniApp Platform UI React",
|
|
5
|
-
"main": "src/index.js",
|
|
5
|
+
"main": "src/ui-react/index.js",
|
|
6
6
|
"types": "src/ui-react/index.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"files": [
|
|
@@ -20,8 +20,10 @@
|
|
|
20
20
|
"author": "Hieuth052@gmail.com",
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"devDependencies": {
|
|
23
|
+
"@babel/cli": "^7.28.6",
|
|
23
24
|
"@babel/core": "^7.29.0",
|
|
24
25
|
"@babel/preset-env": "^7.29.0",
|
|
26
|
+
"@babel/preset-react": "^7.28.5",
|
|
25
27
|
"@rollup/plugin-commonjs": "^29.0.0",
|
|
26
28
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
27
29
|
"@rollup/plugin-terser": "^0.4.4",
|
|
@@ -31,128 +33,23 @@
|
|
|
31
33
|
"ts-loader": "^9.5.4",
|
|
32
34
|
"typescript": "^5.9.3",
|
|
33
35
|
"webpack": "^5.104.1",
|
|
34
|
-
"webpack-cli": "^6.0.1"
|
|
36
|
+
"webpack-cli": "^6.0.1",
|
|
37
|
+
"react": "^19.0.0",
|
|
38
|
+
"react-dom": "^19.0.0"
|
|
35
39
|
},
|
|
36
40
|
"dependencies": {
|
|
37
41
|
"acorn": "^8.15.0",
|
|
38
42
|
"acorn-import-phases": "^1.0.4",
|
|
39
|
-
"ajv": "^8.17.1",
|
|
40
|
-
"ajv-formats": "^2.1.1",
|
|
41
|
-
"ajv-keywords": "^5.1.0",
|
|
42
43
|
"babel-plugin-polyfill-corejs2": "^0.4.15",
|
|
43
44
|
"babel-plugin-polyfill-corejs3": "^0.14.0",
|
|
44
45
|
"babel-plugin-polyfill-regenerator": "^0.6.6",
|
|
45
46
|
"baseline-browser-mapping": "^2.9.19",
|
|
46
|
-
"browserslist": "^4.28.1",
|
|
47
|
-
"buffer-from": "^1.1.2",
|
|
48
|
-
"caniuse-lite": "^1.0.30001767",
|
|
49
|
-
"chrome-trace-event": "^1.0.4",
|
|
50
|
-
"clone-deep": "^4.0.1",
|
|
51
|
-
"colorette": "^2.0.20",
|
|
52
|
-
"commander": "^2.20.3",
|
|
53
|
-
"commondir": "^1.0.1",
|
|
54
|
-
"convert-source-map": "^2.0.0",
|
|
55
|
-
"core-js-compat": "^3.48.0",
|
|
56
|
-
"cross-spawn": "^7.0.6",
|
|
57
|
-
"debug": "^4.4.3",
|
|
58
|
-
"deepmerge": "^4.3.1",
|
|
59
|
-
"electron-to-chromium": "^1.5.283",
|
|
60
|
-
"enhanced-resolve": "^5.18.4",
|
|
61
|
-
"envinfo": "^7.21.0",
|
|
62
|
-
"es-module-lexer": "^2.0.0",
|
|
63
|
-
"escalade": "^3.2.0",
|
|
64
|
-
"eslint-scope": "^5.1.1",
|
|
65
|
-
"esrecurse": "^4.3.0",
|
|
66
|
-
"estraverse": "^4.3.0",
|
|
67
|
-
"estree-walker": "^2.0.2",
|
|
68
|
-
"esutils": "^2.0.3",
|
|
69
|
-
"events": "^3.3.0",
|
|
70
|
-
"fast-deep-equal": "^3.1.3",
|
|
71
|
-
"fast-uri": "^3.1.0",
|
|
72
|
-
"fastest-levenshtein": "^1.0.16",
|
|
73
|
-
"fdir": "^6.5.0",
|
|
74
|
-
"find-up": "^5.0.0",
|
|
75
|
-
"flat": "^5.0.2",
|
|
76
|
-
"fsevents": "^2.3.3",
|
|
77
|
-
"function-bind": "^1.1.2",
|
|
78
|
-
"gensync": "^1.0.0-beta.2",
|
|
79
|
-
"glob-to-regexp": "^0.4.1",
|
|
80
|
-
"graceful-fs": "^4.2.11",
|
|
81
|
-
"has-flag": "^4.0.0",
|
|
82
|
-
"hasown": "^2.0.2",
|
|
83
|
-
"import-local": "^3.2.0",
|
|
84
|
-
"interpret": "^3.1.1",
|
|
85
|
-
"is-core-module": "^2.16.1",
|
|
86
|
-
"is-module": "^1.0.0",
|
|
87
|
-
"is-plain-object": "^2.0.4",
|
|
88
|
-
"is-reference": "^1.2.1",
|
|
89
|
-
"isexe": "^2.0.0",
|
|
90
|
-
"isobject": "^3.0.1",
|
|
91
|
-
"jest-worker": "^27.5.1",
|
|
92
|
-
"js-tokens": "^4.0.0",
|
|
93
|
-
"jsesc": "^3.1.0",
|
|
94
|
-
"json-parse-even-better-errors": "^2.3.1",
|
|
95
|
-
"json-schema-traverse": "^1.0.0",
|
|
96
|
-
"json5": "^2.2.3",
|
|
97
|
-
"kind-of": "^6.0.3",
|
|
98
|
-
"loader-runner": "^4.3.1",
|
|
99
|
-
"locate-path": "^6.0.0",
|
|
100
|
-
"lodash.debounce": "^4.0.8",
|
|
101
|
-
"lru-cache": "^5.1.1",
|
|
102
|
-
"magic-string": "^0.30.21",
|
|
103
|
-
"merge-stream": "^2.0.0",
|
|
104
|
-
"mime-db": "^1.52.0",
|
|
105
|
-
"mime-types": "^2.1.35",
|
|
106
|
-
"ms": "^2.1.3",
|
|
107
|
-
"neo-async": "^2.6.2",
|
|
108
|
-
"node-releases": "^2.0.27",
|
|
109
|
-
"p-limit": "^3.1.0",
|
|
110
|
-
"p-locate": "^5.0.0",
|
|
111
|
-
"p-try": "^2.2.0",
|
|
112
|
-
"path-exists": "^4.0.0",
|
|
113
|
-
"path-key": "^3.1.1",
|
|
114
|
-
"path-parse": "^1.0.7",
|
|
115
|
-
"picocolors": "^1.1.1",
|
|
116
|
-
"picomatch": "^4.0.3",
|
|
117
|
-
"pkg-dir": "^4.2.0",
|
|
118
|
-
"randombytes": "^2.1.0",
|
|
119
|
-
"rechoir": "^0.8.0",
|
|
120
|
-
"regenerate": "^1.4.2",
|
|
121
|
-
"regenerate-unicode-properties": "^10.2.2",
|
|
122
|
-
"regexpu-core": "^6.4.0",
|
|
123
|
-
"regjsgen": "^0.8.0",
|
|
124
|
-
"regjsparser": "^0.13.0",
|
|
125
|
-
"require-from-string": "^2.0.2",
|
|
126
|
-
"resolve": "^1.22.11",
|
|
127
|
-
"resolve-cwd": "^3.0.0",
|
|
128
|
-
"resolve-from": "^5.0.0",
|
|
129
|
-
"safe-buffer": "^5.2.1",
|
|
130
|
-
"schema-utils": "^4.3.3",
|
|
131
|
-
"semver": "^6.3.1",
|
|
132
|
-
"serialize-javascript": "^6.0.2",
|
|
133
|
-
"shallow-clone": "^3.0.1",
|
|
134
|
-
"shebang-command": "^2.0.0",
|
|
135
|
-
"shebang-regex": "^3.0.0",
|
|
136
|
-
"smob": "^1.5.0",
|
|
137
|
-
"source-map": "^0.6.1",
|
|
138
|
-
"source-map-support": "^0.5.21",
|
|
139
|
-
"supports-color": "^8.1.1",
|
|
140
|
-
"supports-preserve-symlinks-flag": "^1.0.0",
|
|
141
|
-
"tapable": "^2.3.0",
|
|
142
|
-
"terser": "^5.46.0",
|
|
143
|
-
"terser-webpack-plugin": "^5.3.16",
|
|
144
|
-
"undici-types": "^7.16.0",
|
|
145
|
-
"unicode-canonical-property-names-ecmascript": "^2.0.1",
|
|
146
|
-
"unicode-match-property-ecmascript": "^2.0.0",
|
|
147
|
-
"unicode-match-property-value-ecmascript": "^2.2.1",
|
|
148
|
-
"unicode-property-aliases-ecmascript": "^2.2.0",
|
|
149
|
-
"update-browserslist-db": "^1.2.3",
|
|
150
47
|
"watchpack": "^2.5.1",
|
|
151
48
|
"webpack-merge": "^6.0.1",
|
|
152
|
-
"webpack-sources": "^3.3.3"
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
"
|
|
156
|
-
"
|
|
49
|
+
"webpack-sources": "^3.3.3"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"react": ">=19.0.0",
|
|
53
|
+
"react-dom": ">=19.0.0"
|
|
157
54
|
}
|
|
158
55
|
}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
+
!function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r(require("react")):"function"==typeof define&&define.amd?define(["react"],r):"object"==typeof exports?exports["vetc-miniapp/ui-react"]=r(require("react")):e["vetc-miniapp/ui-react"]=r(e.react)}(this,e=>(()=>{"use strict";var r={155(r){r.exports=e},698(e,r){var t=Symbol.for("react.transitional.element"),n=Symbol.for("react.fragment");function o(e,r,n){var o=null;if(void 0!==n&&(o=""+n),void 0!==r.key&&(o=""+r.key),"key"in r)for(var i in n={},r)"key"!==i&&(n[i]=r[i]);else n=r;return r=n.ref,{$$typeof:t,type:e,key:o,ref:void 0!==r?r:null,props:n}}r.Fragment=n,r.jsx=o,r.jsxs=o},848(e,r,t){e.exports=t(698)}},t={};function n(e){var o=t[e];if(void 0!==o)return o.exports;var i=t[e]={exports:{}};return r[e](i,i.exports,n),i.exports}n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var o={};n.r(o),n.d(o,{App:()=>m,appConfig:()=>u,getCurrentPage:()=>y,initRouter:()=>v,setCurrentPath:()=>g,useNavigate:()=>l});var i="undefined"!=typeof window,a=function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=i&&window.flutter_inappwebview?window.flutter_inappwebview:null;return t?t.callHandler("MiniAppBridge",{action:e,payload:r}):Promise.reject(new Error("MiniApp bridge not available"))};function l(){return function(e){a("navigate",{type:"native",route:e,params:arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},options:arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}})}}var u={locale:"vi",theme:"light",pages:[]},c=n(155),f=n(848);function p(e,r){(null==r||r>e.length)&&(r=e.length);for(var t=0,n=Array(r);t<r;t++)n[t]=e[t];return n}var s=new Map,d="/";function v(e){console.log(e),s=new Map(e.pages.map(function(e){return[e.path,e]})),console.log(s)}function y(){return s.get(d)}function g(e){d=e}function m(e){var r,t,n=e.config,o=e.children,i=(r=(0,c.useState)(null),t=2,function(e){if(Array.isArray(e))return e}(r)||function(e,r){var t=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=t){var n,o,i,a,l=[],u=!0,c=!1;try{if(i=(t=t.call(e)).next,0===r){if(Object(t)!==t)return;u=!1}else for(;!(u=(n=i.call(t)).done)&&(l.push(n.value),l.length!==r);u=!0);}catch(e){c=!0,o=e}finally{try{if(!u&&null!=t.return&&(a=t.return(),Object(a)!==a))return}finally{if(c)throw o}}return l}}(r,t)||function(e,r){if(e){if("string"==typeof e)return p(e,r);var t={}.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?p(e,r):void 0}}(r,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),l=i[0],u=i[1];(0,c.useEffect)(function(){var e;if(console.warn("SDK useEffect fired"),null!=n&&null!==(e=n.pages)&&void 0!==e&&e.length){v(n),console.warn(n),g((window.location.path||"/").replace("/miniapp","")||"/");var r=y();console.warn(r),r||(g("/"),r=y()),u(r),a("registerAppConfig",{config:n})}},[n]),console.warn("SDK fired"),l&&l.Component||console.warn("MiniApp: Page not found for current route");var s=l.Component||(0,f.jsx)("div",{});return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(s,{}),o]})}return o})());
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
|
+
import { IAppConfig } from '../types/app';
|
|
3
|
+
|
|
4
|
+
export type IAppProps = ComponentPropsWithRef<'div'> & {
|
|
5
|
+
config: IAppConfig;
|
|
6
|
+
};
|
|
7
|
+
export declare const App: ({ className, config, localesConfig, ...props }: IAppProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// "use client";
|
|
2
|
+
|
|
3
|
+
import React, { useEffect, useState } from "react";
|
|
4
|
+
import { callHost } from "../bridge";
|
|
5
|
+
let routeMap = new Map()
|
|
6
|
+
let currentPath = "/"
|
|
7
|
+
|
|
8
|
+
export function initRouter(config) {
|
|
9
|
+
console.log(config);
|
|
10
|
+
routeMap = new Map(config.pages.map(p => [p.path, p]))
|
|
11
|
+
console.log(routeMap);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function getCurrentPage() {
|
|
15
|
+
return routeMap.get(currentPath)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function setCurrentPath(path) {
|
|
19
|
+
currentPath = path
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* MiniApp Runtime Root
|
|
24
|
+
*/
|
|
25
|
+
export function App({ config, children }) {
|
|
26
|
+
const [page, setPage] = useState(null);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
console.warn("SDK useEffect fired");
|
|
30
|
+
|
|
31
|
+
if (!config?.pages?.length) return;
|
|
32
|
+
|
|
33
|
+
// 1. Init router từ config
|
|
34
|
+
initRouter(config);
|
|
35
|
+
console.warn(config);
|
|
36
|
+
|
|
37
|
+
// 2. Lấy pathname từ URL WebView
|
|
38
|
+
const rawPath = window.location.path || "/";
|
|
39
|
+
const path = rawPath.replace("/miniapp", "") || "/";
|
|
40
|
+
|
|
41
|
+
setCurrentPath(path);
|
|
42
|
+
|
|
43
|
+
// 3. Lấy page tương ứng
|
|
44
|
+
let current = getCurrentPage();
|
|
45
|
+
console.warn(current);
|
|
46
|
+
|
|
47
|
+
// 4. Fallback về root nếu không match
|
|
48
|
+
if (!current) {
|
|
49
|
+
setCurrentPath("/");
|
|
50
|
+
current = getCurrentPage();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
setPage(current);
|
|
54
|
+
|
|
55
|
+
// 5. Gửi config sang Flutter để dựng native header
|
|
56
|
+
callHost("registerAppConfig", { config });
|
|
57
|
+
}, [config]);
|
|
58
|
+
|
|
59
|
+
console.warn("SDK fired");
|
|
60
|
+
|
|
61
|
+
// Tránh crash nếu chưa có page
|
|
62
|
+
if (!page || !page.Component) {
|
|
63
|
+
console.warn("MiniApp: Page not found for current route");
|
|
64
|
+
// return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const Component = page.Component || <div />;
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<>
|
|
71
|
+
<Component />
|
|
72
|
+
{children}
|
|
73
|
+
</>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
let routeMap = new Map()
|
|
3
|
+
let currentPath = "/"
|
|
4
|
+
|
|
5
|
+
export function initRouter(config) {
|
|
6
|
+
routeMap = new Map(config.pages.map(p => [p.pathname, p]))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getCurrentPage() {
|
|
10
|
+
return routeMap.get(currentPath)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function setCurrentPath(path) {
|
|
14
|
+
currentPath = path
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function App({ config }) {
|
|
18
|
+
const [page, setPage] = useState(null)
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
initRouter(config)
|
|
22
|
+
|
|
23
|
+
const rawPath = window.location.pathname || "/"
|
|
24
|
+
const path = rawPath.replace("/miniapp", "") || "/"
|
|
25
|
+
|
|
26
|
+
setCurrentPath(path)
|
|
27
|
+
|
|
28
|
+
let current = getCurrentPage()
|
|
29
|
+
if (!current) {
|
|
30
|
+
setCurrentPath("/")
|
|
31
|
+
current = getCurrentPage()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
setPage(current)
|
|
35
|
+
|
|
36
|
+
callHost("registerAppConfig", { config })
|
|
37
|
+
}, [config])
|
|
38
|
+
|
|
39
|
+
if (!page) return <div />
|
|
40
|
+
const Component = page.Component
|
|
41
|
+
return <Component />
|
|
42
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
//'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('../types/app').IAppConfig} IAppConfig
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {Object} IAppProps
|
|
9
|
+
* @property {IAppConfig} config
|
|
10
|
+
* @property {string=} className
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Root MiniApp wrapper
|
|
15
|
+
* @param {IAppProps & React.HTMLAttributes<HTMLDivElement>} props
|
|
16
|
+
*/
|
|
17
|
+
//import React from "react";
|
|
18
|
+
'use client';
|
|
19
|
+
|
|
20
|
+
import { useEffect } from "react";
|
|
21
|
+
import {callHost} from '../bridge.js';
|
|
22
|
+
////import MiniApp from "miniapp-sdk";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Root MiniApp wrapper
|
|
26
|
+
*/
|
|
27
|
+
export function App({ className, config, localesConfig, ...props }) {
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
// 🚀 Gửi config sang Host khi MiniApp mount
|
|
31
|
+
if (config) {
|
|
32
|
+
console.log(config);
|
|
33
|
+
callHost("registerAppConfig", { config }).catch(console.error);
|
|
34
|
+
}
|
|
35
|
+
//
|
|
36
|
+
// // 🎯 Ví dụ lắng nghe event từ Host
|
|
37
|
+
// const handleStateUpdate = (data) => {
|
|
38
|
+
// console.log("App state updated from host:", data);
|
|
39
|
+
// };
|
|
40
|
+
//
|
|
41
|
+
// MiniApp.on?.("APP_STATE_UPDATE", handleStateUpdate);
|
|
42
|
+
//
|
|
43
|
+
// return () => {
|
|
44
|
+
// MiniApp.off?.("APP_STATE_UPDATE", handleStateUpdate);
|
|
45
|
+
// };
|
|
46
|
+
}, [config]);
|
|
47
|
+
|
|
48
|
+
return props.children;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//'use client'
|
|
52
|
+
//
|
|
53
|
+
//import React, { createContext, useContext, useMemo, useState, useEffect } from "react"
|
|
54
|
+
//import {callHost} from '../bridge.js';
|
|
55
|
+
//
|
|
56
|
+
//const RouterCtx = createContext(null)
|
|
57
|
+
//
|
|
58
|
+
//export function MiniRouterProvider({ config, initialPath, children }) {
|
|
59
|
+
// const [path, setPath] = useState(initialPath || "/")
|
|
60
|
+
//
|
|
61
|
+
// const routeMap = useMemo(
|
|
62
|
+
// () => new Map(config.pages.map(p => [p.pathname, p])),
|
|
63
|
+
// [config.pages]
|
|
64
|
+
// )
|
|
65
|
+
//
|
|
66
|
+
// const value = useMemo(() => ({ path, setPath, routeMap }), [path, routeMap])
|
|
67
|
+
//
|
|
68
|
+
// return <RouterCtx.Provider value={value}>{children}</RouterCtx.Provider>
|
|
69
|
+
//}
|
|
70
|
+
//
|
|
71
|
+
//export function useMiniRouter() {
|
|
72
|
+
// const ctx = useContext(RouterCtx)
|
|
73
|
+
// if (!ctx) throw new Error("useMiniRouter must be used inside MiniRouterProvider")
|
|
74
|
+
// return ctx
|
|
75
|
+
//}
|
|
76
|
+
//
|
|
77
|
+
//function Renderer({ config }) {
|
|
78
|
+
// const { path, routeMap } = useMiniRouter()
|
|
79
|
+
// const page = routeMap.get(path)
|
|
80
|
+
//
|
|
81
|
+
// useEffect(() => {
|
|
82
|
+
// if (!page) return
|
|
83
|
+
// callHost("registerAppConfig", {
|
|
84
|
+
// config
|
|
85
|
+
// })
|
|
86
|
+
// }, [path, page])
|
|
87
|
+
//
|
|
88
|
+
// if (!page) return <div>Page not found</div>
|
|
89
|
+
// const Component = page.Component
|
|
90
|
+
// return <Component />
|
|
91
|
+
//}
|
|
92
|
+
//
|
|
93
|
+
//export function App({ config, initialPath, ...props }) {
|
|
94
|
+
// return (
|
|
95
|
+
// <MiniRouterProvider config={config} initialPath={initialPath}>
|
|
96
|
+
// <Renderer config={config}>{props.children}</Renderer>
|
|
97
|
+
// </MiniRouterProvider>
|
|
98
|
+
// )
|
|
99
|
+
//}
|
|
100
|
+
|
|
101
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {"light" | "dark"} ThemeMode
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {Object} IAppState
|
|
7
|
+
* @property {string=} locale
|
|
8
|
+
* @property {ThemeMode=} theme
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} IPageConfig
|
|
13
|
+
* @property {string} key - Key định danh page dùng cho navigation
|
|
14
|
+
* @property {string=} title - Tên hiển thị (header native)
|
|
15
|
+
* @property {string} url - URL nội bộ miniapp (nếu cần render state)
|
|
16
|
+
* @property {boolean=} canGoBack - Có cho phép back không
|
|
17
|
+
* @property {boolean=} isRoot - Có phải root page không
|
|
18
|
+
* @property {Object<string, any>=} defaultParams - Params mặc định khi mở page
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {Object} IAppConfig
|
|
23
|
+
* @property {IPageConfig[]} pages
|
|
24
|
+
* @property {string=} locale
|
|
25
|
+
* @property {ThemeMode=} theme
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/** @type {IAppConfig} */
|
|
29
|
+
export const appConfig = {
|
|
30
|
+
locale: "vi",
|
|
31
|
+
theme: "light",
|
|
32
|
+
|
|
33
|
+
pages: [
|
|
34
|
+
]
|
|
35
|
+
};
|
package/src/ui-react/index.js
CHANGED
package/src/ui-react/index.ts
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {"light" | "dark"} ThemeMode
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Trạng thái cấp App do Host cung cấp
|
|
7
|
+
* @typedef {Object} IAppState
|
|
8
|
+
* @property {string=} locale
|
|
9
|
+
* @property {ThemeMode=} theme
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Cấu hình 1 page trong MiniApp
|
|
14
|
+
* @typedef {Object} IPageConfig
|
|
15
|
+
* @property {string} key - Key định danh page dùng cho navigation
|
|
16
|
+
* @property {string=} title - Tên hiển thị (header native)
|
|
17
|
+
* @property {string} url - URL nội bộ của page (phục vụ render state)
|
|
18
|
+
* @property {boolean=} canGoBack - Có cho phép back không
|
|
19
|
+
* @property {boolean=} isRoot - Có phải root page không
|
|
20
|
+
* @property {Object<string, any>=} defaultParams - Params mặc định khi mở page
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Cấu hình tổng của MiniApp
|
|
25
|
+
* @typedef {IAppState & {
|
|
26
|
+
* pages: IPageConfig[]
|
|
27
|
+
* }} IAppConfig
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
export {}; // để file được coi là module
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
export type IAppConfig = {
|
|
3
|
+
pages: IPageConfig[];
|
|
4
|
+
// darkMode?: IDarkModeConfig;
|
|
5
|
+
} & IAppState;
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export type IAppState = {
|
|
9
|
+
locale?: string;
|
|
10
|
+
theme?: "light" | "dark";
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type IPageConfig = {
|
|
14
|
+
/** Key định danh page dùng cho navigation */
|
|
15
|
+
key: string;
|
|
16
|
+
|
|
17
|
+
/** Tên hiển thị (optional, dùng cho header native) */
|
|
18
|
+
title?: string;
|
|
19
|
+
|
|
20
|
+
page: React.ComponentType<any>
|
|
21
|
+
|
|
22
|
+
url: string;
|
|
23
|
+
|
|
24
|
+
/** Có cho phép back không */
|
|
25
|
+
canGoBack?: boolean;
|
|
26
|
+
|
|
27
|
+
/** Có phải root page không */
|
|
28
|
+
isRoot?: boolean;
|
|
29
|
+
|
|
30
|
+
/** Params mặc định khi mở page */
|
|
31
|
+
defaultParams?: Record<string, unknown>;
|
|
32
|
+
};
|