@vetc-miniapp/ui-react 0.0.25 → 0.0.26

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/dist/bridge.d.ts CHANGED
@@ -1,9 +1,15 @@
1
1
  export interface FlutterInAppWebViewBridge {
2
2
  callHandler(handlerName: string, args?: unknown): Promise<unknown>;
3
3
  }
4
+ export interface MiniAppBridge {
5
+ on(event: string, callback: (data: any) => void): void;
6
+ off(event: string, callback: (data: any) => void): void;
7
+ _emit?: (event: string, data?: any) => void;
8
+ }
4
9
  declare global {
5
10
  interface Window {
6
11
  flutter_inappwebview?: FlutterInAppWebViewBridge;
12
+ MiniApp?: MiniAppBridge;
7
13
  }
8
14
  }
9
15
  export declare const isBrowser: boolean;
@@ -1,6 +1,17 @@
1
- export declare function initRouter(config: any): void;
2
- export declare function getCurrentPage(): any;
3
- export declare function setCurrentPath(path: any): void;
1
+ import React from "react";
2
+ interface PageConfig {
3
+ pathname: string;
4
+ Component: React.ComponentType<any>;
5
+ [key: string]: any;
6
+ }
7
+ interface AppConfig {
8
+ pages: PageConfig[];
9
+ [key: string]: any;
10
+ }
11
+ export declare function initRouter(config: AppConfig): void;
12
+ export declare function getCurrentPage(): PageConfig | undefined;
13
+ export declare function setCurrentPath(path: string): void;
4
14
  export declare function App({ config }: {
5
- config: any;
15
+ config: AppConfig;
6
16
  }): import("react/jsx-runtime").JSX.Element;
17
+ export {};
@@ -4,7 +4,7 @@ import { callHost } from "../bridge";
4
4
  let routeMap = new Map();
5
5
  let currentPath = "/";
6
6
  export function initRouter(config) {
7
- routeMap = new Map(config.pages.map(p => [p.pathname, p]));
7
+ routeMap = new Map(config.pages.map((p) => [p.pathname, p]));
8
8
  }
9
9
  export function getCurrentPage() {
10
10
  return routeMap.get(currentPath);
@@ -19,10 +19,10 @@ export function App({ config }) {
19
19
  const rawPath = window.location.pathname || "/";
20
20
  const path = rawPath.replace("/miniapp", "") || "/";
21
21
  setCurrentPath(path);
22
- let current = getCurrentPage();
22
+ let current = getCurrentPage() ?? null;
23
23
  if (!current) {
24
24
  setCurrentPath("/");
25
- current = getCurrentPage();
25
+ current = getCurrentPage() ?? null;
26
26
  }
27
27
  setPage(current);
28
28
  callHost("registerAppConfig", { config });
@@ -15,5 +15,5 @@ export interface DialogProps {
15
15
  /** Close dialog when clicking outside (default: true) */
16
16
  maskClosable?: boolean;
17
17
  }
18
- export declare function Dialog({ open, image, title, description, okText, cancelText, okDisabled, okLoading, okDanger, onOk, onCancel, maskClosable, }: DialogProps): React.ReactPortal;
18
+ export declare function Dialog({ open, image, title, description, okText, cancelText, okDisabled, okLoading, okDanger, onOk, onCancel, maskClosable, }: DialogProps): import("react/jsx-runtime").JSX.Element;
19
19
  export default Dialog;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useEffect } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
4
  import { Button } from '../button';
@@ -13,39 +13,39 @@ export function Dialog({ open, image, title, description, okText = 'Xác nhận'
13
13
  if (!open)
14
14
  return null;
15
15
  const hasContent = title || description;
16
- return createPortal(_jsx("div", { style: {
17
- position: 'fixed',
18
- inset: 0,
19
- backgroundColor: 'var(--vetc-dialog-overlay)',
20
- display: 'flex',
21
- alignItems: 'center',
22
- justifyContent: 'center',
23
- zIndex: 1000,
24
- padding: '0 var(--vetc-space-24)',
25
- }, onClick: maskClosable ? onCancel : undefined, children: _jsxs("div", { style: {
26
- width: '100%',
27
- maxWidth: 'var(--vetc-dialog-width)',
28
- backgroundColor: 'var(--vetc-dialog-bg)',
29
- borderRadius: 'var(--vetc-dialog-radius)',
30
- overflow: 'hidden',
31
- boxShadow: 'var(--vetc-shadow-lg)',
32
- fontFamily: 'var(--vetc-font-family)',
33
- }, onClick: e => e.stopPropagation(), children: [image && (_jsx("div", { style: { width: '100%', height: 'var(--vetc-dialog-image-height)', overflow: 'hidden', flexShrink: 0 }, children: _jsx("img", { src: image, alt: "", style: { width: '100%', height: '100%', objectFit: 'cover', display: 'block' } }) })), hasContent && (_jsxs("div", { style: { padding: 'var(--vetc-dialog-padding)' }, children: [title && (_jsx("div", { style: {
34
- fontSize: 'var(--vetc-dialog-title-size)',
35
- fontWeight: 'var(--vetc-dialog-title-weight)',
36
- color: 'var(--vetc-color-text-primary)',
37
- lineHeight: 'var(--vetc-line-height-relaxed)',
38
- marginBottom: description ? 'var(--vetc-space-8)' : 0,
39
- }, children: title })), description && (_jsx("div", { style: {
40
- fontSize: 'var(--vetc-dialog-desc-size)',
41
- color: 'var(--vetc-dialog-desc-color)',
42
- lineHeight: 'var(--vetc-line-height-relaxed)',
43
- }, children: description }))] })), _jsxs("div", { style: {
44
- display: 'flex',
45
- gap: 'var(--vetc-dialog-btn-gap)',
46
- padding: hasContent
47
- ? `0 var(--vetc-dialog-padding) var(--vetc-dialog-padding)`
48
- : 'var(--vetc-dialog-padding)',
49
- }, children: [onCancel && (_jsx(Button, { block: true, style: "outlined", variant: "neutral", onClick: onCancel, children: cancelText })), _jsx(Button, { block: true, style: okDanger ? 'danger' : 'filled', loading: okLoading, disabled: okDisabled, onClick: onOk, children: okText })] })] }) }), document.body);
16
+ return _jsx(_Fragment, { children: createPortal(_jsx("div", { style: {
17
+ position: 'fixed',
18
+ inset: 0,
19
+ backgroundColor: 'var(--vetc-dialog-overlay)',
20
+ display: 'flex',
21
+ alignItems: 'center',
22
+ justifyContent: 'center',
23
+ zIndex: 1000,
24
+ padding: '0 var(--vetc-space-24)',
25
+ }, onClick: maskClosable ? onCancel : undefined, children: _jsxs("div", { style: {
26
+ width: '100%',
27
+ maxWidth: 'var(--vetc-dialog-width)',
28
+ backgroundColor: 'var(--vetc-dialog-bg)',
29
+ borderRadius: 'var(--vetc-dialog-radius)',
30
+ overflow: 'hidden',
31
+ boxShadow: 'var(--vetc-shadow-lg)',
32
+ fontFamily: 'var(--vetc-font-family)',
33
+ }, onClick: e => e.stopPropagation(), children: [image && (_jsx("div", { style: { width: '100%', height: 'var(--vetc-dialog-image-height)', overflow: 'hidden', flexShrink: 0 }, children: _jsx("img", { src: image, alt: "", style: { width: '100%', height: '100%', objectFit: 'cover', display: 'block' } }) })), hasContent && (_jsxs("div", { style: { padding: 'var(--vetc-dialog-padding)' }, children: [title && (_jsx("div", { style: {
34
+ fontSize: 'var(--vetc-dialog-title-size)',
35
+ fontWeight: 'var(--vetc-dialog-title-weight)',
36
+ color: 'var(--vetc-color-text-primary)',
37
+ lineHeight: 'var(--vetc-line-height-relaxed)',
38
+ marginBottom: description ? 'var(--vetc-space-8)' : 0,
39
+ }, children: title })), description && (_jsx("div", { style: {
40
+ fontSize: 'var(--vetc-dialog-desc-size)',
41
+ color: 'var(--vetc-dialog-desc-color)',
42
+ lineHeight: 'var(--vetc-line-height-relaxed)',
43
+ }, children: description }))] })), _jsxs("div", { style: {
44
+ display: 'flex',
45
+ gap: 'var(--vetc-dialog-btn-gap)',
46
+ padding: hasContent
47
+ ? `0 var(--vetc-dialog-padding) var(--vetc-dialog-padding)`
48
+ : 'var(--vetc-dialog-padding)',
49
+ }, children: [onCancel && (_jsx(Button, { block: true, style: "outlined", variant: "neutral", onClick: onCancel, children: cancelText })), _jsx(Button, { block: true, style: okDanger ? 'danger' : 'filled', loading: okLoading, disabled: okDisabled, onClick: onOk, children: okText })] })] }) }), document.body) });
50
50
  }
51
51
  export default Dialog;
@@ -1,6 +1,4 @@
1
1
  /**
2
- * useAppPause
3
- *
4
- * Trigger khi Native App đi vào background.
2
+ * useAppPause — trigger khi Native App đi vào background.
5
3
  */
6
4
  export declare function useAppPause(callback: () => void): void;
@@ -1,18 +1,16 @@
1
1
  import { useEffect, useRef } from "react";
2
2
  /**
3
- * useAppPause
4
- *
5
- * Trigger khi Native App đi vào background.
3
+ * useAppPause — trigger khi Native App đi vào background.
6
4
  */
7
5
  export function useAppPause(callback) {
8
6
  const savedCallback = useRef(callback);
9
- // giữ callback luôn mới nhất
10
7
  useEffect(() => {
11
8
  savedCallback.current = callback;
12
9
  }, [callback]);
13
10
  useEffect(() => {
14
11
  if (typeof window === "undefined" || !window.MiniApp)
15
12
  return;
13
+ const bridge = window.MiniApp;
16
14
  const handler = () => {
17
15
  try {
18
16
  savedCallback.current?.();
@@ -21,9 +19,7 @@ export function useAppPause(callback) {
21
19
  console.error("[useAppPause error]", err);
22
20
  }
23
21
  };
24
- window.MiniApp.on("appPause", handler);
25
- return () => {
26
- window.MiniApp.off("appPause", handler);
27
- };
22
+ bridge.on("appPause", handler);
23
+ return () => bridge.off("appPause", handler);
28
24
  }, []);
29
25
  }
@@ -1,6 +1,4 @@
1
1
  /**
2
- * useAppResume
3
- *
4
- * Trigger khi Native App quay lại foreground.
2
+ * useAppResume — trigger khi Native App quay lại foreground.
5
3
  */
6
4
  export declare function useAppResume(callback: () => void): void;
@@ -1,8 +1,6 @@
1
1
  import { useEffect, useRef } from "react";
2
2
  /**
3
- * useAppResume
4
- *
5
- * Trigger khi Native App quay lại foreground.
3
+ * useAppResume — trigger khi Native App quay lại foreground.
6
4
  */
7
5
  export function useAppResume(callback) {
8
6
  const savedCallback = useRef(callback);
@@ -12,6 +10,7 @@ export function useAppResume(callback) {
12
10
  useEffect(() => {
13
11
  if (typeof window === "undefined" || !window.MiniApp)
14
12
  return;
13
+ const bridge = window.MiniApp;
15
14
  const handler = () => {
16
15
  try {
17
16
  savedCallback.current?.();
@@ -20,9 +19,7 @@ export function useAppResume(callback) {
20
19
  console.error("[useAppResume error]", err);
21
20
  }
22
21
  };
23
- window.MiniApp.on("appResume", handler);
24
- return () => {
25
- window.MiniApp.off("appResume", handler);
26
- };
22
+ bridge.on("appResume", handler);
23
+ return () => bridge.off("appResume", handler);
27
24
  }, []);
28
25
  }
@@ -8,14 +8,13 @@ export function useDidHide(route, callback) {
8
8
  useEffect(() => {
9
9
  if (typeof window === "undefined" || !window.MiniApp)
10
10
  return;
11
+ const bridge = window.MiniApp;
11
12
  const handler = (data) => {
12
13
  if (data?.route === route) {
13
14
  saved.current?.(data);
14
15
  }
15
16
  };
16
- window.MiniApp.on("didHide", handler);
17
- return () => {
18
- window.MiniApp.off("didHide", handler);
19
- };
17
+ bridge.on("didHide", handler);
18
+ return () => bridge.off("didHide", handler);
20
19
  }, [route]);
21
20
  }
@@ -8,14 +8,13 @@ export function useDidShow(route, callback) {
8
8
  useEffect(() => {
9
9
  if (typeof window === "undefined" || !window.MiniApp)
10
10
  return;
11
+ const bridge = window.MiniApp;
11
12
  const handler = (data) => {
12
13
  if (data?.route === route) {
13
14
  saved.current?.(data);
14
15
  }
15
16
  };
16
- window.MiniApp.on("didShow", handler);
17
- return () => {
18
- window.MiniApp.off("didShow", handler);
19
- };
17
+ bridge.on("didShow", handler);
18
+ return () => bridge.off("didShow", handler);
20
19
  }, [route]);
21
20
  }
@@ -3,19 +3,8 @@ type ScanQrResult = {
3
3
  type?: string;
4
4
  [key: string]: any;
5
5
  };
6
- type MiniAppBridge = {
7
- on: (event: string, callback: (data: any) => void) => void;
8
- off: (event: string, callback: (data: any) => void) => void;
9
- };
10
- declare global {
11
- interface Window {
12
- MiniApp?: MiniAppBridge;
13
- }
14
- }
15
6
  /**
16
- * useListenerScanQr
17
- *
18
- * Lắng nghe kết quả scan QR từ Native
7
+ * useListenerScanQr — lắng nghe kết quả scan QR từ Native.
19
8
  */
20
9
  export declare function useListenerScanQr(callback: (data: ScanQrResult) => void): void;
21
10
  export {};
@@ -1,18 +1,16 @@
1
1
  import { useEffect, useRef } from "react";
2
2
  /**
3
- * useListenerScanQr
4
- *
5
- * Lắng nghe kết quả scan QR từ Native
3
+ * useListenerScanQr — lắng nghe kết quả scan QR từ Native.
6
4
  */
7
5
  export function useListenerScanQr(callback) {
8
6
  const savedCallback = useRef(callback);
9
- // luôn giữ callback mới nhất
10
7
  useEffect(() => {
11
8
  savedCallback.current = callback;
12
9
  }, [callback]);
13
10
  useEffect(() => {
14
11
  if (typeof window === "undefined" || !window.MiniApp)
15
12
  return;
13
+ const bridge = window.MiniApp;
16
14
  const handler = (data) => {
17
15
  try {
18
16
  savedCallback.current?.(data);
@@ -21,9 +19,7 @@ export function useListenerScanQr(callback) {
21
19
  console.error("[useListenerScanQr error]", err);
22
20
  }
23
21
  };
24
- window.MiniApp.on("scanQrResult", handler);
25
- return () => {
26
- window.MiniApp.off("scanQrResult", handler);
27
- };
22
+ bridge.on("scanQrResult", handler);
23
+ return () => bridge.off("scanQrResult", handler);
28
24
  }, []);
29
25
  }
@@ -8,14 +8,13 @@ export function useTapAppBar(route, callback) {
8
8
  useEffect(() => {
9
9
  if (typeof window === "undefined" || !window.MiniApp)
10
10
  return;
11
+ const bridge = window.MiniApp;
11
12
  const handler = (data) => {
12
13
  if (data?.route === route) {
13
14
  saved.current?.(data);
14
15
  }
15
16
  };
16
- window.MiniApp.on("onTapAppBar", handler);
17
- return () => {
18
- window.MiniApp.off("onTapAppBar", handler);
19
- };
17
+ bridge.on("onTapAppBar", handler);
18
+ return () => bridge.off("onTapAppBar", handler);
20
19
  }, [route]);
21
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vetc-miniapp/ui-react",
3
- "version": "0.0.25",
3
+ "version": "0.0.26",
4
4
  "description": "MiniApp Platform UI React",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",