@vetc-miniapp/ui-react 0.0.24 → 0.0.25
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 +11 -0
- package/dist/bridge.js +20 -0
- package/dist/components/app.d.ts +6 -0
- package/dist/components/app.js +34 -0
- package/dist/components/avatar/Avatar.d.ts +21 -0
- package/dist/components/avatar/Avatar.js +33 -0
- package/dist/components/avatar/index.js +1 -0
- package/dist/components/bottom-sheet/BottomSheet.d.ts +19 -0
- package/dist/components/bottom-sheet/BottomSheet.js +70 -0
- package/dist/components/bottom-sheet/index.js +1 -0
- package/dist/components/button/Button.d.ts +32 -0
- package/dist/components/button/Button.js +165 -0
- package/dist/components/button/index.js +1 -0
- package/dist/components/button-group/ButtonGroup.d.ts +28 -0
- package/dist/components/button-group/ButtonGroup.js +21 -0
- package/dist/components/button-group/index.js +1 -0
- package/dist/components/card/Card.d.ts +18 -0
- package/dist/components/card/Card.js +35 -0
- package/dist/components/card/index.js +1 -0
- package/dist/components/checkbox/Checkbox.d.ts +41 -0
- package/dist/components/checkbox/Checkbox.js +94 -0
- package/dist/components/checkbox/index.js +1 -0
- package/dist/components/chip/Chip.d.ts +24 -0
- package/dist/components/chip/Chip.js +83 -0
- package/dist/components/chip/index.js +1 -0
- package/dist/components/dialog/Dialog.d.ts +19 -0
- package/dist/components/dialog/Dialog.js +51 -0
- package/dist/components/dialog/index.js +1 -0
- package/dist/components/divider/Divider.d.ts +16 -0
- package/dist/components/divider/Divider.js +18 -0
- package/dist/components/divider/index.js +1 -0
- package/dist/components/input/Input.d.ts +40 -0
- package/dist/components/input/Input.js +51 -0
- package/dist/components/input/index.js +1 -0
- package/dist/components/list/List.d.ts +31 -0
- package/dist/components/list/List.js +72 -0
- package/dist/components/list/index.js +1 -0
- package/dist/components/loading/Loading.d.ts +28 -0
- package/dist/components/loading/Loading.js +33 -0
- package/dist/components/loading/index.js +1 -0
- package/dist/components/modal/Modal.d.ts +38 -0
- package/dist/components/modal/Modal.js +50 -0
- package/dist/components/modal/index.js +1 -0
- package/dist/components/navigation-bar/NavigationBar.d.ts +44 -0
- package/dist/components/navigation-bar/NavigationBar.js +70 -0
- package/dist/components/navigation-bar/index.js +1 -0
- package/dist/components/radio/Radio.d.ts +40 -0
- package/dist/components/radio/Radio.js +88 -0
- package/dist/components/radio/index.js +1 -0
- package/dist/components/select/Select.d.ts +29 -0
- package/dist/components/select/Select.js +30 -0
- package/dist/components/select/index.js +1 -0
- package/dist/components/switch/Switch.d.ts +23 -0
- package/dist/components/switch/Switch.js +81 -0
- package/dist/components/switch/index.js +1 -0
- package/dist/components/tab-bar/TabBar.d.ts +28 -0
- package/dist/components/tab-bar/TabBar.js +60 -0
- package/dist/components/tab-bar/index.js +1 -0
- package/dist/components/textarea/Textarea.d.ts +31 -0
- package/dist/components/textarea/Textarea.js +33 -0
- package/dist/components/textarea/index.js +1 -0
- package/dist/components/toast/Toast.d.ts +41 -0
- package/dist/components/toast/Toast.js +61 -0
- package/dist/components/toast/index.js +1 -0
- package/dist/components/typography/Typography.d.ts +45 -0
- package/dist/components/typography/Typography.js +143 -0
- package/dist/components/typography/index.js +1 -0
- package/dist/hooks/use-app-pause.d.ts +6 -0
- package/dist/hooks/use-app-pause.js +29 -0
- package/dist/hooks/use-app-resume.d.ts +6 -0
- package/dist/hooks/use-app-resume.js +28 -0
- package/{src/ui-react/hooks/use-app-state.ts → dist/hooks/use-app-state.d.ts} +0 -1
- package/dist/hooks/use-app-state.js +1 -0
- package/dist/hooks/use-did-hide.d.ts +6 -0
- package/dist/hooks/use-did-hide.js +21 -0
- package/dist/hooks/use-did-show.d.ts +6 -0
- package/dist/hooks/use-did-show.js +21 -0
- package/dist/hooks/use-listener-scan-qr.d.ts +21 -0
- package/dist/hooks/use-listener-scan-qr.js +29 -0
- package/dist/hooks/use-navigate.d.ts +8 -0
- package/dist/hooks/use-navigate.js +23 -0
- package/dist/hooks/use-tap-app-bar.d.ts +6 -0
- package/dist/hooks/use-tap-app-bar.js +21 -0
- package/{src/ui-react/index.ts → dist/index.d.ts} +1 -30
- package/dist/index.js +41 -0
- package/dist/styles/VETCProvider.d.ts +114 -0
- package/dist/styles/VETCProvider.js +124 -0
- package/{src/ui-react → dist}/styles/tokens.css +22 -1
- package/dist/tokens/colors.d.ts +127 -0
- package/dist/tokens/colors.js +75 -0
- package/dist/tokens/index.js +3 -0
- package/dist/tokens/spacing.d.ts +56 -0
- package/dist/tokens/spacing.js +56 -0
- package/dist/tokens/typography.d.ts +121 -0
- package/dist/tokens/typography.js +57 -0
- package/dist/types/app.d.ts +21 -0
- package/dist/types/app.js +1 -0
- package/package.json +13 -7
- package/src/dist/ui-react/index.js +0 -2
- package/src/dist/ui-react/index.js.LICENSE.txt +0 -11
- package/src/ui-react/bridge.js +0 -36
- package/src/ui-react/bridge.ts +0 -48
- package/src/ui-react/components/app.d.ts +0 -7
- package/src/ui-react/components/app.jsx +0 -80
- package/src/ui-react/components/app.tsx +0 -42
- package/src/ui-react/components/app1.js +0 -101
- package/src/ui-react/components/avatar/Avatar.tsx +0 -88
- package/src/ui-react/components/bottom-sheet/BottomSheet.tsx +0 -149
- package/src/ui-react/components/button/Button.tsx +0 -246
- package/src/ui-react/components/button-group/ButtonGroup.tsx +0 -108
- package/src/ui-react/components/card/Card.tsx +0 -77
- package/src/ui-react/components/checkbox/Checkbox.tsx +0 -232
- package/src/ui-react/components/chip/Chip.tsx +0 -137
- package/src/ui-react/components/dialog/Dialog.tsx +0 -135
- package/src/ui-react/components/divider/Divider.tsx +0 -54
- package/src/ui-react/components/input/Input.tsx +0 -195
- package/src/ui-react/components/list/List.tsx +0 -180
- package/src/ui-react/components/loading/Loading.tsx +0 -121
- package/src/ui-react/components/modal/Modal.tsx +0 -116
- package/src/ui-react/components/navigation-bar/NavigationBar.tsx +0 -188
- package/src/ui-react/components/radio/Radio.tsx +0 -216
- package/src/ui-react/components/select/Select.tsx +0 -109
- package/src/ui-react/components/switch/Switch.tsx +0 -164
- package/src/ui-react/components/tab-bar/TabBar.tsx +0 -137
- package/src/ui-react/components/textarea/Textarea.tsx +0 -109
- package/src/ui-react/components/toast/Toast.ts +0 -98
- package/src/ui-react/components/typography/Typography.tsx +0 -201
- package/src/ui-react/hooks/use-app-pause.js +0 -35
- package/src/ui-react/hooks/use-app-pause.ts +0 -33
- package/src/ui-react/hooks/use-app-resume.js +0 -37
- package/src/ui-react/hooks/use-app-resume.ts +0 -32
- package/src/ui-react/hooks/use-app-state.js +0 -35
- package/src/ui-react/hooks/use-did-hide.js +0 -25
- package/src/ui-react/hooks/use-did-hide.ts +0 -34
- package/src/ui-react/hooks/use-did-show.js +0 -26
- package/src/ui-react/hooks/use-did-show.ts +0 -34
- package/src/ui-react/hooks/use-listener-scan-qr.js +0 -33
- package/src/ui-react/hooks/use-listener-scan-qr.ts +0 -52
- package/src/ui-react/hooks/use-navigate.js +0 -15
- package/src/ui-react/hooks/use-navigate.ts +0 -41
- package/src/ui-react/hooks/use-tap-app-bar.js +0 -26
- package/src/ui-react/hooks/use-tap-app-bar.ts +0 -34
- package/src/ui-react/index.js +0 -9
- package/src/ui-react/styles/VETCProvider.tsx +0 -152
- package/src/ui-react/tokens/colors.ts +0 -91
- package/src/ui-react/tokens/spacing.ts +0 -59
- package/src/ui-react/tokens/typography.ts +0 -63
- package/src/ui-react/tokens_vetc.json +0 -1517
- package/src/ui-react/types/app.js +0 -30
- package/src/ui-react/types/app.ts +0 -32
- /package/{src/ui-react/components/avatar/index.ts → dist/components/avatar/index.d.ts} +0 -0
- /package/{src/ui-react/components/bottom-sheet/index.ts → dist/components/bottom-sheet/index.d.ts} +0 -0
- /package/{src/ui-react/components/button/index.ts → dist/components/button/index.d.ts} +0 -0
- /package/{src/ui-react/components/button-group/index.ts → dist/components/button-group/index.d.ts} +0 -0
- /package/{src/ui-react/components/card/index.ts → dist/components/card/index.d.ts} +0 -0
- /package/{src/ui-react/components/checkbox/index.ts → dist/components/checkbox/index.d.ts} +0 -0
- /package/{src/ui-react/components/chip/index.ts → dist/components/chip/index.d.ts} +0 -0
- /package/{src/ui-react/components/dialog/index.ts → dist/components/dialog/index.d.ts} +0 -0
- /package/{src/ui-react/components/divider/index.ts → dist/components/divider/index.d.ts} +0 -0
- /package/{src/ui-react/components/input/index.ts → dist/components/input/index.d.ts} +0 -0
- /package/{src/ui-react/components/list/index.ts → dist/components/list/index.d.ts} +0 -0
- /package/{src/ui-react/components/loading/index.ts → dist/components/loading/index.d.ts} +0 -0
- /package/{src/ui-react/components/modal/index.ts → dist/components/modal/index.d.ts} +0 -0
- /package/{src/ui-react/components/navigation-bar/index.ts → dist/components/navigation-bar/index.d.ts} +0 -0
- /package/{src/ui-react/components/radio/index.ts → dist/components/radio/index.d.ts} +0 -0
- /package/{src/ui-react/components/select/index.ts → dist/components/select/index.d.ts} +0 -0
- /package/{src/ui-react/components/switch/index.ts → dist/components/switch/index.d.ts} +0 -0
- /package/{src/ui-react/components/tab-bar/index.ts → dist/components/tab-bar/index.d.ts} +0 -0
- /package/{src/ui-react/components/textarea/index.ts → dist/components/textarea/index.d.ts} +0 -0
- /package/{src/ui-react/components/toast/index.ts → dist/components/toast/index.d.ts} +0 -0
- /package/{src/ui-react/components/typography/index.ts → dist/components/typography/index.d.ts} +0 -0
- /package/{src/ui-react/tokens/index.ts → dist/tokens/index.d.ts} +0 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VETC Design System — Typography Tokens
|
|
3
|
+
* From Figma: Tasco DLS Mini App — Typography page
|
|
4
|
+
* Font weights: Regular=400, Medium=500, SemiBold=600, Bold=700
|
|
5
|
+
* Font sizes: 2XS=10 / XS=12 / SM=14 / Base=16 / LG=20 / XL=24 / 2XL=28 / 3XL=32 / 4XL=36
|
|
6
|
+
*/
|
|
7
|
+
export declare const fontFamily: {
|
|
8
|
+
readonly primary: "\"Roboto\", system-ui, -apple-system, sans-serif";
|
|
9
|
+
};
|
|
10
|
+
export declare const fontWeight: {
|
|
11
|
+
readonly regular: 400;
|
|
12
|
+
readonly medium: 500;
|
|
13
|
+
readonly semibold: 600;
|
|
14
|
+
readonly bold: 700;
|
|
15
|
+
readonly black: 900;
|
|
16
|
+
};
|
|
17
|
+
/** Font sizes from Figma Typography scale */
|
|
18
|
+
export declare const fontSize: {
|
|
19
|
+
readonly '2xs': "10px";
|
|
20
|
+
readonly xs: "12px";
|
|
21
|
+
readonly sm: "14px";
|
|
22
|
+
readonly base: "16px";
|
|
23
|
+
readonly lg: "20px";
|
|
24
|
+
readonly xl: "24px";
|
|
25
|
+
readonly '2xl': "28px";
|
|
26
|
+
readonly '3xl': "32px";
|
|
27
|
+
readonly '4xl': "36px";
|
|
28
|
+
};
|
|
29
|
+
/** Line heights from Figma (pixel ratios per size) */
|
|
30
|
+
export declare const lineHeight: {
|
|
31
|
+
readonly tight: "120%";
|
|
32
|
+
readonly normal: "140%";
|
|
33
|
+
readonly relaxed: "150%";
|
|
34
|
+
};
|
|
35
|
+
export declare const letterSpacing: {
|
|
36
|
+
readonly none: "0";
|
|
37
|
+
readonly sm: "0.1px";
|
|
38
|
+
readonly md: "0.25px";
|
|
39
|
+
readonly lg: "0.5px";
|
|
40
|
+
};
|
|
41
|
+
/** Typography style presets — Figma: Display=bold(700), Headline/Title/Label=semibold(600), Body=regular(400) */
|
|
42
|
+
export declare const textStyle: {
|
|
43
|
+
readonly display4xl: {
|
|
44
|
+
readonly fontSize: "36px";
|
|
45
|
+
readonly fontWeight: 700;
|
|
46
|
+
readonly lineHeight: "120%";
|
|
47
|
+
};
|
|
48
|
+
readonly display3xl: {
|
|
49
|
+
readonly fontSize: "32px";
|
|
50
|
+
readonly fontWeight: 700;
|
|
51
|
+
readonly lineHeight: "120%";
|
|
52
|
+
};
|
|
53
|
+
readonly display2xl: {
|
|
54
|
+
readonly fontSize: "28px";
|
|
55
|
+
readonly fontWeight: 700;
|
|
56
|
+
readonly lineHeight: "120%";
|
|
57
|
+
};
|
|
58
|
+
readonly headlineXl: {
|
|
59
|
+
readonly fontSize: "24px";
|
|
60
|
+
readonly fontWeight: 700;
|
|
61
|
+
readonly lineHeight: "140%";
|
|
62
|
+
};
|
|
63
|
+
readonly headlineLg: {
|
|
64
|
+
readonly fontSize: "20px";
|
|
65
|
+
readonly fontWeight: 600;
|
|
66
|
+
readonly lineHeight: "140%";
|
|
67
|
+
};
|
|
68
|
+
readonly titleBase: {
|
|
69
|
+
readonly fontSize: "16px";
|
|
70
|
+
readonly fontWeight: 600;
|
|
71
|
+
readonly lineHeight: "150%";
|
|
72
|
+
readonly letterSpacing: "0.1px";
|
|
73
|
+
};
|
|
74
|
+
readonly titleSm: {
|
|
75
|
+
readonly fontSize: "14px";
|
|
76
|
+
readonly fontWeight: 600;
|
|
77
|
+
readonly lineHeight: "150%";
|
|
78
|
+
readonly letterSpacing: "0.1px";
|
|
79
|
+
};
|
|
80
|
+
readonly labelBase: {
|
|
81
|
+
readonly fontSize: "16px";
|
|
82
|
+
readonly fontWeight: 600;
|
|
83
|
+
readonly lineHeight: "150%";
|
|
84
|
+
};
|
|
85
|
+
readonly labelSm: {
|
|
86
|
+
readonly fontSize: "14px";
|
|
87
|
+
readonly fontWeight: 600;
|
|
88
|
+
readonly lineHeight: "150%";
|
|
89
|
+
readonly letterSpacing: "0.5px";
|
|
90
|
+
};
|
|
91
|
+
readonly labelXs: {
|
|
92
|
+
readonly fontSize: "12px";
|
|
93
|
+
readonly fontWeight: 600;
|
|
94
|
+
readonly lineHeight: "150%";
|
|
95
|
+
readonly letterSpacing: "0.5px";
|
|
96
|
+
};
|
|
97
|
+
readonly bodyBase: {
|
|
98
|
+
readonly fontSize: "16px";
|
|
99
|
+
readonly fontWeight: 400;
|
|
100
|
+
readonly lineHeight: "150%";
|
|
101
|
+
readonly letterSpacing: "0.1px";
|
|
102
|
+
};
|
|
103
|
+
readonly bodySm: {
|
|
104
|
+
readonly fontSize: "14px";
|
|
105
|
+
readonly fontWeight: 400;
|
|
106
|
+
readonly lineHeight: "150%";
|
|
107
|
+
readonly letterSpacing: "0.25px";
|
|
108
|
+
};
|
|
109
|
+
readonly bodyXs: {
|
|
110
|
+
readonly fontSize: "12px";
|
|
111
|
+
readonly fontWeight: 400;
|
|
112
|
+
readonly lineHeight: "150%";
|
|
113
|
+
readonly letterSpacing: "0.5px";
|
|
114
|
+
};
|
|
115
|
+
readonly body2xs: {
|
|
116
|
+
readonly fontSize: "10px";
|
|
117
|
+
readonly fontWeight: 400;
|
|
118
|
+
readonly lineHeight: "150%";
|
|
119
|
+
readonly letterSpacing: "0.5px";
|
|
120
|
+
};
|
|
121
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VETC Design System — Typography Tokens
|
|
3
|
+
* From Figma: Tasco DLS Mini App — Typography page
|
|
4
|
+
* Font weights: Regular=400, Medium=500, SemiBold=600, Bold=700
|
|
5
|
+
* Font sizes: 2XS=10 / XS=12 / SM=14 / Base=16 / LG=20 / XL=24 / 2XL=28 / 3XL=32 / 4XL=36
|
|
6
|
+
*/
|
|
7
|
+
export const fontFamily = {
|
|
8
|
+
primary: '"Roboto", system-ui, -apple-system, sans-serif',
|
|
9
|
+
};
|
|
10
|
+
export const fontWeight = {
|
|
11
|
+
regular: 400,
|
|
12
|
+
medium: 500,
|
|
13
|
+
semibold: 600,
|
|
14
|
+
bold: 700,
|
|
15
|
+
black: 900,
|
|
16
|
+
};
|
|
17
|
+
/** Font sizes from Figma Typography scale */
|
|
18
|
+
export const fontSize = {
|
|
19
|
+
'2xs': '10px', // 2X-Small
|
|
20
|
+
xs: '12px', // X-Small
|
|
21
|
+
sm: '14px', // Small
|
|
22
|
+
base: '16px', // Base
|
|
23
|
+
lg: '20px', // Large
|
|
24
|
+
xl: '24px', // X-Large
|
|
25
|
+
'2xl': '28px', // 2X-Large
|
|
26
|
+
'3xl': '32px', // 3X-Large
|
|
27
|
+
'4xl': '36px', // 4X-Large
|
|
28
|
+
};
|
|
29
|
+
/** Line heights from Figma (pixel ratios per size) */
|
|
30
|
+
export const lineHeight = {
|
|
31
|
+
tight: '120%', // display: 36→44 ≈ 122%
|
|
32
|
+
normal: '140%', // heading: 20→28 = 140%
|
|
33
|
+
relaxed: '150%', // body/label: 16→24 = 150%
|
|
34
|
+
};
|
|
35
|
+
export const letterSpacing = {
|
|
36
|
+
none: '0',
|
|
37
|
+
sm: '0.1px',
|
|
38
|
+
md: '0.25px',
|
|
39
|
+
lg: '0.5px',
|
|
40
|
+
};
|
|
41
|
+
/** Typography style presets — Figma: Display=bold(700), Headline/Title/Label=semibold(600), Body=regular(400) */
|
|
42
|
+
export const textStyle = {
|
|
43
|
+
display4xl: { fontSize: fontSize['4xl'], fontWeight: fontWeight.bold, lineHeight: lineHeight.tight },
|
|
44
|
+
display3xl: { fontSize: fontSize['3xl'], fontWeight: fontWeight.bold, lineHeight: lineHeight.tight },
|
|
45
|
+
display2xl: { fontSize: fontSize['2xl'], fontWeight: fontWeight.bold, lineHeight: lineHeight.tight },
|
|
46
|
+
headlineXl: { fontSize: fontSize.xl, fontWeight: fontWeight.bold, lineHeight: lineHeight.normal },
|
|
47
|
+
headlineLg: { fontSize: fontSize.lg, fontWeight: fontWeight.semibold, lineHeight: lineHeight.normal },
|
|
48
|
+
titleBase: { fontSize: fontSize.base, fontWeight: fontWeight.semibold, lineHeight: lineHeight.relaxed, letterSpacing: letterSpacing.sm },
|
|
49
|
+
titleSm: { fontSize: fontSize.sm, fontWeight: fontWeight.semibold, lineHeight: lineHeight.relaxed, letterSpacing: letterSpacing.sm },
|
|
50
|
+
labelBase: { fontSize: fontSize.base, fontWeight: fontWeight.semibold, lineHeight: lineHeight.relaxed },
|
|
51
|
+
labelSm: { fontSize: fontSize.sm, fontWeight: fontWeight.semibold, lineHeight: lineHeight.relaxed, letterSpacing: letterSpacing.lg },
|
|
52
|
+
labelXs: { fontSize: fontSize.xs, fontWeight: fontWeight.semibold, lineHeight: lineHeight.relaxed, letterSpacing: letterSpacing.lg },
|
|
53
|
+
bodyBase: { fontSize: fontSize.base, fontWeight: fontWeight.regular, lineHeight: lineHeight.relaxed, letterSpacing: letterSpacing.sm },
|
|
54
|
+
bodySm: { fontSize: fontSize.sm, fontWeight: fontWeight.regular, lineHeight: lineHeight.relaxed, letterSpacing: letterSpacing.md },
|
|
55
|
+
bodyXs: { fontSize: fontSize.xs, fontWeight: fontWeight.regular, lineHeight: lineHeight.relaxed, letterSpacing: letterSpacing.lg },
|
|
56
|
+
body2xs: { fontSize: fontSize['2xs'], fontWeight: fontWeight.regular, lineHeight: lineHeight.relaxed, letterSpacing: letterSpacing.lg },
|
|
57
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type IAppConfig = {
|
|
2
|
+
pages: IPageConfig[];
|
|
3
|
+
} & IAppState;
|
|
4
|
+
export type IAppState = {
|
|
5
|
+
locale?: string;
|
|
6
|
+
theme?: "light" | "dark";
|
|
7
|
+
};
|
|
8
|
+
export type IPageConfig = {
|
|
9
|
+
/** Key định danh page dùng cho navigation */
|
|
10
|
+
key: string;
|
|
11
|
+
/** Tên hiển thị (optional, dùng cho header native) */
|
|
12
|
+
title?: string;
|
|
13
|
+
page: React.ComponentType<any>;
|
|
14
|
+
url: string;
|
|
15
|
+
/** Có cho phép back không */
|
|
16
|
+
canGoBack?: boolean;
|
|
17
|
+
/** Có phải root page không */
|
|
18
|
+
isRoot?: boolean;
|
|
19
|
+
/** Params mặc định khi mở page */
|
|
20
|
+
defaultParams?: Record<string, unknown>;
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vetc-miniapp/ui-react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.25",
|
|
4
4
|
"description": "MiniApp Platform UI React",
|
|
5
|
-
"main": "
|
|
6
|
-
"
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./styles": "./dist/styles/tokens.css"
|
|
14
|
+
},
|
|
7
15
|
"type": "module",
|
|
8
16
|
"files": [
|
|
9
|
-
"
|
|
17
|
+
"dist"
|
|
10
18
|
],
|
|
11
19
|
"scripts": {
|
|
12
|
-
"build": "
|
|
13
|
-
"demo": "webpack serve --config webpack.demo.js",
|
|
14
|
-
"build:demo": "webpack --config webpack.demo.js --mode production"
|
|
20
|
+
"build": "tsc -p tsconfig.build.json && cp src/ui-react/styles/tokens.css dist/styles/tokens.css"
|
|
15
21
|
},
|
|
16
22
|
"keywords": [
|
|
17
23
|
"miniapp",
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
-
!function(n,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("react")):"function"==typeof define&&define.amd?define(["react"],e):"object"==typeof exports?exports["vetc-miniapp/ui-react"]=e(require("react")):n["vetc-miniapp/ui-react"]=e(n.react)}(this,n=>(()=>{"use strict";var e={155(e){e.exports=n},698(n,e){var r=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function o(n,e,t){var o=null;if(void 0!==t&&(o=""+t),void 0!==e.key&&(o=""+e.key),"key"in e)for(var i in t={},e)"key"!==i&&(t[i]=e[i]);else t=e;return e=t.ref,{$$typeof:r,type:n,key:o,ref:void 0!==e?e:null,props:t}}e.Fragment=t,e.jsx=o,e.jsxs=o},848(n,e,r){n.exports=r(698)}},r={};function t(n){var o=r[n];if(void 0!==o)return o.exports;var i=r[n]={exports:{}};return e[n](i,i.exports,t),i.exports}t.d=(n,e)=>{for(var r in e)t.o(e,r)&&!t.o(n,r)&&Object.defineProperty(n,r,{enumerable:!0,get:e[r]})},t.o=(n,e)=>Object.prototype.hasOwnProperty.call(n,e),t.r=n=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})};var o={};t.r(o),t.d(o,{App:()=>x,appConfig:()=>m,useAppPause:()=>u,useAppResume:()=>a,useDidHide:()=>f,useDidShow:()=>c,useListenerScanQr:()=>b,useNavigate:()=>h,useTapAppBar:()=>p});var i=t(155);function u(n){var e=(0,i.useRef)(n);(0,i.useEffect)(function(){e.current=n},[n]),(0,i.useEffect)(function(){if("undefined"!=typeof window&&window.MiniApp){var n=function(){try{e.current&&e.current()}catch(n){console.error("[useAppPause error]",n)}};return window.MiniApp.on("appPause",n),function(){window.MiniApp.off("appPause",n)}}},[])}function a(n){var e=(0,i.useRef)(n);(0,i.useEffect)(function(){e.current=n},[n]),(0,i.useEffect)(function(){if(console.warn("MiniApp: useAppResume"),"undefined"!=typeof window&&window.MiniApp){var n=function(){try{e.current&&e.current()}catch(n){console.error("[useAppResume error]",n)}};return window.MiniApp.on("appResume",n),function(){window.MiniApp.off("appResume",n)}}},[])}function c(n,e){var r=(0,i.useRef)(e);(0,i.useEffect)(function(){r.current=e},[e]),(0,i.useEffect)(function(){if(window.MiniApp){var e=function(e){var t;(null==e?void 0:e.route)===n&&(console.log("didShow",e),null===(t=r.current)||void 0===t||t.call(r,e))};return window.MiniApp.on("didShow",e),function(){window.MiniApp.off("didShow",e)}}},[n])}function f(n,e){var r=(0,i.useRef)(e);(0,i.useEffect)(function(){r.current=e},[e]),(0,i.useEffect)(function(){if(window.MiniApp){var e=function(e){var t;(null==e?void 0:e.route)===n&&(null===(t=r.current)||void 0===t||t.call(r,e))};return window.MiniApp.on("didHide",e),function(){window.MiniApp.off("didHide",e)}}},[n])}function p(n,e){var r=(0,i.useRef)(e);(0,i.useEffect)(function(){r.current=e},[e]),(0,i.useEffect)(function(){if(window.MiniApp){var e=function(e){var t;(null==e?void 0:e.route)===n&&(console.log("onTapAppBar",e),null===(t=r.current)||void 0===t||t.call(r,e))};return window.MiniApp.on("onTapAppBar",e),function(){window.MiniApp.off("onTapAppBar",e)}}},[n])}function l(){var n,e,r="function"==typeof Symbol?Symbol:{},t=r.iterator||"@@iterator",o=r.toStringTag||"@@toStringTag";function i(r,t,o,i){var c=t&&t.prototype instanceof a?t:a,f=Object.create(c.prototype);return s(f,"_invoke",function(r,t,o){var i,a,c,f=0,p=o||[],l=!1,s={p:0,n:0,v:n,a:d,f:d.bind(n,4),d:function(e,r){return i=e,a=0,c=n,s.n=r,u}};function d(r,t){for(a=r,c=t,e=0;!l&&f&&!o&&e<p.length;e++){var o,i=p[e],d=s.p,v=i[2];r>3?(o=v===t)&&(c=i[(a=i[4])?5:(a=3,3)],i[4]=i[5]=n):i[0]<=d&&((o=r<2&&d<i[1])?(a=0,s.v=t,s.n=i[1]):d<v&&(o=r<3||i[0]>t||t>v)&&(i[4]=r,i[5]=t,s.n=v,a=0))}if(o||r>1)return u;throw l=!0,t}return function(o,p,v){if(f>1)throw TypeError("Generator is already running");for(l&&1===p&&d(p,v),a=p,c=v;(e=a<2?n:c)||!l;){i||(a?a<3?(a>1&&(s.n=-1),d(a,c)):s.n=c:s.v=c);try{if(f=2,i){if(a||(o="next"),e=i[o]){if(!(e=e.call(i,c)))throw TypeError("iterator result is not an object");if(!e.done)return e;c=e.value,a<2&&(a=0)}else 1===a&&(e=i.return)&&e.call(i),a<2&&(c=TypeError("The iterator does not provide a '"+o+"' method"),a=1);i=n}else if((e=(l=s.n<0)?c:r.call(t,s))!==u)break}catch(e){i=n,a=1,c=e}finally{f=1}}return{value:e,done:l}}}(r,o,i),!0),f}var u={};function a(){}function c(){}function f(){}e=Object.getPrototypeOf;var p=[][t]?e(e([][t]())):(s(e={},t,function(){return this}),e),d=f.prototype=a.prototype=Object.create(p);function v(n){return Object.setPrototypeOf?Object.setPrototypeOf(n,f):(n.__proto__=f,s(n,o,"GeneratorFunction")),n.prototype=Object.create(d),n}return c.prototype=f,s(d,"constructor",f),s(f,"constructor",c),c.displayName="GeneratorFunction",s(f,o,"GeneratorFunction"),s(d),s(d,o,"Generator"),s(d,t,function(){return this}),s(d,"toString",function(){return"[object Generator]"}),(l=function(){return{w:i,m:v}})()}function s(n,e,r,t){var o=Object.defineProperty;try{o({},"",{})}catch(n){o=0}s=function(n,e,r,t){function i(e,r){s(n,e,function(n){return this._invoke(e,r,n)})}e?o?o(n,e,{value:r,enumerable:!t,configurable:!t,writable:!t}):n[e]=r:(i("next",0),i("throw",1),i("return",2))},s(n,e,r,t)}function d(n,e,r,t,o,i,u){try{var a=n[i](u),c=a.value}catch(n){return void r(n)}a.done?e(c):Promise.resolve(c).then(t,o)}var v="undefined"!=typeof window,w=function(){return v&&window.flutter_inappwebview&&window.flutter_inappwebview.callHandler&&"function"==typeof window.flutter_inappwebview.callHandler?window.flutter_inappwebview:null},y=function(){var n,e=(n=l().m(function n(e){var r,t,o,i,u=arguments;return l().w(function(n){for(;;)switch(n.p=n.n){case 0:if(r=u.length>1&&void 0!==u[1]?u[1]:{},t=w()){n.n=1;break}return n.a(2,{ok:!1,error:"BRIDGE_CALL_FAILED"});case 1:return n.p=1,n.n=2,t.callHandler("MiniAppBridge",{action:e,payload:r});case 2:return o=n.v,n.a(2,o);case 3:return n.p=3,i=n.v,console.error("Bridge error:",i),n.a(2,{ok:!1,error:"BRIDGE_CALL_FAILED"})}},n,null,[[1,3]])}),function(){var e=this,r=arguments;return new Promise(function(t,o){var i=n.apply(e,r);function u(n){d(i,t,o,u,a,"next",n)}function a(n){d(i,t,o,u,a,"throw",n)}u(void 0)})});return function(n){return e.apply(this,arguments)}}();function h(){return function(n){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if("number"==typeof n)return y("navigate",{type:"native",action:"pop",delta:Math.abs(n)});y("navigate",{type:"native",action:"push",route:n,params:e,options:r})}}var m={locale:"vi",theme:"light",pages:[]};function b(n){var e=(0,i.useRef)(n);(0,i.useEffect)(function(){e.current=n},[n]),(0,i.useEffect)(function(){if("undefined"!=typeof window&&window.MiniApp){var n=function(n){try{var r;null===(r=e.current)||void 0===r||r.call(e,n)}catch(n){console.error("[useListenerScanQr error]",n)}};return window.MiniApp.on("onScanQRResult",n),function(){window.MiniApp.off("onScanQRResult",n)}}},[])}var g=t(848);function A(n,e){(null==e||e>n.length)&&(e=n.length);for(var r=0,t=Array(e);r<e;r++)t[r]=n[r];return t}var M=new Map,S="/";function j(){return M.get(S)}function E(n){S=n}function x(n){var e,r,t=n.config,o=n.children,u=(e=(0,i.useState)(null),r=2,function(n){if(Array.isArray(n))return n}(e)||function(n,e){var r=null==n?null:"undefined"!=typeof Symbol&&n[Symbol.iterator]||n["@@iterator"];if(null!=r){var t,o,i,u,a=[],c=!0,f=!1;try{if(i=(r=r.call(n)).next,0===e){if(Object(r)!==r)return;c=!1}else for(;!(c=(t=i.call(r)).done)&&(a.push(t.value),a.length!==e);c=!0);}catch(n){f=!0,o=n}finally{try{if(!c&&null!=r.return&&(u=r.return(),Object(u)!==u))return}finally{if(f)throw o}}return a}}(e,r)||function(n,e){if(n){if("string"==typeof n)return A(n,e);var r={}.toString.call(n).slice(8,-1);return"Object"===r&&n.constructor&&(r=n.constructor.name),"Map"===r||"Set"===r?Array.from(n):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?A(n,e):void 0}}(e,r)||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.")}()),a=u[0],c=u[1],f=(0,i.useRef)(!1);(0,i.useEffect)(function(){var n;if(null!=t&&null!==(n=t.pages)&&void 0!==n&&n.length&&!f.current){f.current=!0,function(n){M=new Map(n.pages.map(function(n){return[n.path,n]}))}(t),E((window.location.pathname||"/").replace("/miniapp","")||"/");var e=j();e||(E("/"),e=j()),c(e||null),y("registerAppConfig",{config:t})}},[t]);var p=(0,i.useMemo)(function(){return a&&a.Component?a.Component:null},[a]);return p?(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(p,{}),o]}):(console.warn("MiniApp: Page not found"),(0,g.jsx)("div",{}))}return o})());
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @license React
|
|
5
|
-
* react-jsx-runtime.production.js
|
|
6
|
-
*
|
|
7
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
8
|
-
*
|
|
9
|
-
* This source code is licensed under the MIT license found in the
|
|
10
|
-
* LICENSE file in the root directory of this source tree.
|
|
11
|
-
*/
|
package/src/ui-react/bridge.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
const isBrowser = typeof window !== "undefined";
|
|
2
|
-
|
|
3
|
-
const getBridge = () => {
|
|
4
|
-
if (!isBrowser || !window.flutter_inappwebview || !window.flutter_inappwebview.callHandler || typeof window.flutter_inappwebview.callHandler != "function") {
|
|
5
|
-
return null;
|
|
6
|
-
}
|
|
7
|
-
return window.flutter_inappwebview;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const callHost = async (action, payload = {}) => {
|
|
11
|
-
const bridge = getBridge();
|
|
12
|
-
if (!bridge) {
|
|
13
|
-
// return Promise.reject(new Error("MiniApp bridge not available"));
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
ok: false,
|
|
17
|
-
error: "BRIDGE_CALL_FAILED"
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
try {
|
|
21
|
-
const response = await bridge.callHandler("MiniAppBridge", {
|
|
22
|
-
action,
|
|
23
|
-
payload,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
return response;
|
|
27
|
-
} catch (error) {
|
|
28
|
-
console.error("Bridge error:", error);
|
|
29
|
-
// throw error;
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
ok: false,
|
|
33
|
-
error: "BRIDGE_CALL_FAILED"
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
};
|
package/src/ui-react/bridge.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/* ================= Types ================= */
|
|
2
|
-
|
|
3
|
-
export interface FlutterInAppWebViewBridge {
|
|
4
|
-
callHandler(
|
|
5
|
-
handlerName: string,
|
|
6
|
-
args?: unknown
|
|
7
|
-
): Promise<unknown>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
declare global {
|
|
11
|
-
interface Window {
|
|
12
|
-
flutter_inappwebview?: FlutterInAppWebViewBridge;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/* ================= Runtime helpers ================= */
|
|
17
|
-
|
|
18
|
-
export const isBrowser: boolean = typeof window !== "undefined";
|
|
19
|
-
|
|
20
|
-
export const getBridge = (): FlutterInAppWebViewBridge | null => {
|
|
21
|
-
if (!isBrowser || !window.flutter_inappwebview || !window.flutter_inappwebview.callHandler || typeof window.flutter_inappwebview.callHandler != "function") {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
return window.flutter_inappwebview;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/* ================= Core bridge call ================= */
|
|
28
|
-
|
|
29
|
-
export const callHost = <T = unknown>(
|
|
30
|
-
action: string,
|
|
31
|
-
payload: Record<string, unknown> = {}
|
|
32
|
-
): Promise<T> => {
|
|
33
|
-
const bridge = getBridge();
|
|
34
|
-
|
|
35
|
-
if (!bridge) {
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
ok: false,
|
|
39
|
-
error: "BRIDGE_CALL_FAILED"
|
|
40
|
-
};
|
|
41
|
-
// return Promise.reject(new Error("MiniApp bridge not available"));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return bridge.callHandler("MiniAppBridge", {
|
|
45
|
-
action,
|
|
46
|
-
payload,
|
|
47
|
-
}) as Promise<T>;
|
|
48
|
-
};
|
|
@@ -1,7 +0,0 @@
|
|
|
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;
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { callHost } from "../bridge";
|
|
5
|
-
|
|
6
|
-
/* ================= ROUTER CORE ================= */
|
|
7
|
-
|
|
8
|
-
let routeMap = new Map();
|
|
9
|
-
let currentPath = "/";
|
|
10
|
-
|
|
11
|
-
function initRouter(config) {
|
|
12
|
-
routeMap = new Map(config.pages.map((p) => [p.path, p]));
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function getCurrentPage() {
|
|
16
|
-
return routeMap.get(currentPath);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function setCurrentPath(path) {
|
|
20
|
-
currentPath = path;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/* ================= APP ================= */
|
|
24
|
-
|
|
25
|
-
export function App({ config, children }) {
|
|
26
|
-
const [page, setPage] = useState(null);
|
|
27
|
-
const initializedRef = useRef(false);
|
|
28
|
-
|
|
29
|
-
/* ================= INIT ONCE ================= */
|
|
30
|
-
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
if (!config?.pages?.length) return;
|
|
33
|
-
if (initializedRef.current) return;
|
|
34
|
-
|
|
35
|
-
initializedRef.current = true;
|
|
36
|
-
|
|
37
|
-
// 1. Init router
|
|
38
|
-
initRouter(config);
|
|
39
|
-
|
|
40
|
-
// 2. Lấy path từ URL
|
|
41
|
-
const rawPath = window.location.pathname || "/";
|
|
42
|
-
const path = rawPath.replace("/miniapp", "") || "/";
|
|
43
|
-
|
|
44
|
-
setCurrentPath(path);
|
|
45
|
-
|
|
46
|
-
// 3. Resolve page
|
|
47
|
-
let current = getCurrentPage();
|
|
48
|
-
|
|
49
|
-
if (!current) {
|
|
50
|
-
setCurrentPath("/");
|
|
51
|
-
current = getCurrentPage();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
setPage(current || null);
|
|
55
|
-
|
|
56
|
-
// 4. Send config to native (chỉ 1 lần)
|
|
57
|
-
callHost("registerAppConfig", { config });
|
|
58
|
-
}, [config]);
|
|
59
|
-
|
|
60
|
-
/* ================= MEMO COMPONENT ================= */
|
|
61
|
-
|
|
62
|
-
const CurrentComponent = useMemo(() => {
|
|
63
|
-
if (!page || !page.Component) return null;
|
|
64
|
-
return page.Component;
|
|
65
|
-
}, [page]);
|
|
66
|
-
|
|
67
|
-
/* ================= RENDER ================= */
|
|
68
|
-
|
|
69
|
-
if (!CurrentComponent) {
|
|
70
|
-
console.warn("MiniApp: Page not found");
|
|
71
|
-
return <div />;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<>
|
|
76
|
-
<CurrentComponent />
|
|
77
|
-
{children}
|
|
78
|
-
</>
|
|
79
|
-
);
|
|
80
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
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
|
-
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VETC Avatar — tokenized
|
|
3
|
-
*/
|
|
4
|
-
import React from 'react';
|
|
5
|
-
import { Avatar as AntAvatar } from 'antd';
|
|
6
|
-
|
|
7
|
-
export type AvatarSize = 'xl' | 'lg' | 'md' | 'sm' | 'xs';
|
|
8
|
-
export type AvatarShape = 'circle' | 'square';
|
|
9
|
-
|
|
10
|
-
// Map size token name to CSS var
|
|
11
|
-
const sizeVarMap: Record<AvatarSize, string> = {
|
|
12
|
-
xl: 'var(--vetc-avatar-size-xl)',
|
|
13
|
-
lg: 'var(--vetc-avatar-size-lg)',
|
|
14
|
-
md: 'var(--vetc-avatar-size-md)',
|
|
15
|
-
sm: 'var(--vetc-avatar-size-sm)',
|
|
16
|
-
xs: 'var(--vetc-avatar-size-xs)',
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
// Pixel values needed for antd size prop (numeric)
|
|
20
|
-
const sizePxMap: Record<AvatarSize, number> = { xl: 56, lg: 48, md: 40, sm: 32, xs: 24 };
|
|
21
|
-
|
|
22
|
-
// Font size scales with avatar size (from Figma)
|
|
23
|
-
const fontSizeMap: Record<AvatarSize, string> = {
|
|
24
|
-
xl: 'var(--vetc-font-size-2xl)',
|
|
25
|
-
lg: 'var(--vetc-font-size-xl)',
|
|
26
|
-
md: 'var(--vetc-font-size-base)',
|
|
27
|
-
sm: 'var(--vetc-font-size-sm)',
|
|
28
|
-
xs: 'var(--vetc-font-size-2xs)',
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export interface AvatarProps {
|
|
32
|
-
src?: string;
|
|
33
|
-
alt?: string;
|
|
34
|
-
initials?: string;
|
|
35
|
-
icon?: React.ReactNode;
|
|
36
|
-
size?: AvatarSize;
|
|
37
|
-
shape?: AvatarShape;
|
|
38
|
-
color?: string;
|
|
39
|
-
className?: string;
|
|
40
|
-
style?: React.CSSProperties;
|
|
41
|
-
onClick?: () => void;
|
|
42
|
-
id?: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function Avatar({
|
|
46
|
-
src,
|
|
47
|
-
alt,
|
|
48
|
-
initials,
|
|
49
|
-
icon,
|
|
50
|
-
size = 'md',
|
|
51
|
-
shape = 'circle',
|
|
52
|
-
color,
|
|
53
|
-
className = '',
|
|
54
|
-
style,
|
|
55
|
-
onClick,
|
|
56
|
-
id,
|
|
57
|
-
}: AvatarProps) {
|
|
58
|
-
return (
|
|
59
|
-
<span
|
|
60
|
-
id={id}
|
|
61
|
-
style={{ display: 'inline-flex', flexShrink: 0, width: sizeVarMap[size], height: sizeVarMap[size] }}
|
|
62
|
-
>
|
|
63
|
-
<AntAvatar
|
|
64
|
-
src={src}
|
|
65
|
-
alt={alt}
|
|
66
|
-
icon={!src && !initials ? icon : undefined}
|
|
67
|
-
size={sizePxMap[size]}
|
|
68
|
-
shape={shape}
|
|
69
|
-
onClick={onClick}
|
|
70
|
-
className={`vetc-avatar vetc-avatar--${size} ${className}`}
|
|
71
|
-
style={{
|
|
72
|
-
backgroundColor: !src ? (color ?? 'var(--vetc-avatar-bg-default)') : undefined,
|
|
73
|
-
fontSize: fontSizeMap[size],
|
|
74
|
-
fontWeight: 'var(--vetc-font-weight-bold)' as any,
|
|
75
|
-
fontFamily: 'var(--vetc-font-family)',
|
|
76
|
-
color: 'var(--vetc-avatar-text-color)',
|
|
77
|
-
cursor: onClick ? 'pointer' : 'default',
|
|
78
|
-
flexShrink: 0,
|
|
79
|
-
...style,
|
|
80
|
-
}}
|
|
81
|
-
>
|
|
82
|
-
{!src && initials ? initials.slice(0, 2).toUpperCase() : undefined}
|
|
83
|
-
</AntAvatar>
|
|
84
|
-
</span>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export default Avatar;
|