@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.
Files changed (172) hide show
  1. package/dist/bridge.d.ts +11 -0
  2. package/dist/bridge.js +20 -0
  3. package/dist/components/app.d.ts +6 -0
  4. package/dist/components/app.js +34 -0
  5. package/dist/components/avatar/Avatar.d.ts +21 -0
  6. package/dist/components/avatar/Avatar.js +33 -0
  7. package/dist/components/avatar/index.js +1 -0
  8. package/dist/components/bottom-sheet/BottomSheet.d.ts +19 -0
  9. package/dist/components/bottom-sheet/BottomSheet.js +70 -0
  10. package/dist/components/bottom-sheet/index.js +1 -0
  11. package/dist/components/button/Button.d.ts +32 -0
  12. package/dist/components/button/Button.js +165 -0
  13. package/dist/components/button/index.js +1 -0
  14. package/dist/components/button-group/ButtonGroup.d.ts +28 -0
  15. package/dist/components/button-group/ButtonGroup.js +21 -0
  16. package/dist/components/button-group/index.js +1 -0
  17. package/dist/components/card/Card.d.ts +18 -0
  18. package/dist/components/card/Card.js +35 -0
  19. package/dist/components/card/index.js +1 -0
  20. package/dist/components/checkbox/Checkbox.d.ts +41 -0
  21. package/dist/components/checkbox/Checkbox.js +94 -0
  22. package/dist/components/checkbox/index.js +1 -0
  23. package/dist/components/chip/Chip.d.ts +24 -0
  24. package/dist/components/chip/Chip.js +83 -0
  25. package/dist/components/chip/index.js +1 -0
  26. package/dist/components/dialog/Dialog.d.ts +19 -0
  27. package/dist/components/dialog/Dialog.js +51 -0
  28. package/dist/components/dialog/index.js +1 -0
  29. package/dist/components/divider/Divider.d.ts +16 -0
  30. package/dist/components/divider/Divider.js +18 -0
  31. package/dist/components/divider/index.js +1 -0
  32. package/dist/components/input/Input.d.ts +40 -0
  33. package/dist/components/input/Input.js +51 -0
  34. package/dist/components/input/index.js +1 -0
  35. package/dist/components/list/List.d.ts +31 -0
  36. package/dist/components/list/List.js +72 -0
  37. package/dist/components/list/index.js +1 -0
  38. package/dist/components/loading/Loading.d.ts +28 -0
  39. package/dist/components/loading/Loading.js +33 -0
  40. package/dist/components/loading/index.js +1 -0
  41. package/dist/components/modal/Modal.d.ts +38 -0
  42. package/dist/components/modal/Modal.js +50 -0
  43. package/dist/components/modal/index.js +1 -0
  44. package/dist/components/navigation-bar/NavigationBar.d.ts +44 -0
  45. package/dist/components/navigation-bar/NavigationBar.js +70 -0
  46. package/dist/components/navigation-bar/index.js +1 -0
  47. package/dist/components/radio/Radio.d.ts +40 -0
  48. package/dist/components/radio/Radio.js +88 -0
  49. package/dist/components/radio/index.js +1 -0
  50. package/dist/components/select/Select.d.ts +29 -0
  51. package/dist/components/select/Select.js +30 -0
  52. package/dist/components/select/index.js +1 -0
  53. package/dist/components/switch/Switch.d.ts +23 -0
  54. package/dist/components/switch/Switch.js +81 -0
  55. package/dist/components/switch/index.js +1 -0
  56. package/dist/components/tab-bar/TabBar.d.ts +28 -0
  57. package/dist/components/tab-bar/TabBar.js +60 -0
  58. package/dist/components/tab-bar/index.js +1 -0
  59. package/dist/components/textarea/Textarea.d.ts +31 -0
  60. package/dist/components/textarea/Textarea.js +33 -0
  61. package/dist/components/textarea/index.js +1 -0
  62. package/dist/components/toast/Toast.d.ts +41 -0
  63. package/dist/components/toast/Toast.js +61 -0
  64. package/dist/components/toast/index.js +1 -0
  65. package/dist/components/typography/Typography.d.ts +45 -0
  66. package/dist/components/typography/Typography.js +143 -0
  67. package/dist/components/typography/index.js +1 -0
  68. package/dist/hooks/use-app-pause.d.ts +6 -0
  69. package/dist/hooks/use-app-pause.js +29 -0
  70. package/dist/hooks/use-app-resume.d.ts +6 -0
  71. package/dist/hooks/use-app-resume.js +28 -0
  72. package/{src/ui-react/hooks/use-app-state.ts → dist/hooks/use-app-state.d.ts} +0 -1
  73. package/dist/hooks/use-app-state.js +1 -0
  74. package/dist/hooks/use-did-hide.d.ts +6 -0
  75. package/dist/hooks/use-did-hide.js +21 -0
  76. package/dist/hooks/use-did-show.d.ts +6 -0
  77. package/dist/hooks/use-did-show.js +21 -0
  78. package/dist/hooks/use-listener-scan-qr.d.ts +21 -0
  79. package/dist/hooks/use-listener-scan-qr.js +29 -0
  80. package/dist/hooks/use-navigate.d.ts +8 -0
  81. package/dist/hooks/use-navigate.js +23 -0
  82. package/dist/hooks/use-tap-app-bar.d.ts +6 -0
  83. package/dist/hooks/use-tap-app-bar.js +21 -0
  84. package/{src/ui-react/index.ts → dist/index.d.ts} +1 -30
  85. package/dist/index.js +41 -0
  86. package/dist/styles/VETCProvider.d.ts +114 -0
  87. package/dist/styles/VETCProvider.js +124 -0
  88. package/{src/ui-react → dist}/styles/tokens.css +22 -1
  89. package/dist/tokens/colors.d.ts +127 -0
  90. package/dist/tokens/colors.js +75 -0
  91. package/dist/tokens/index.js +3 -0
  92. package/dist/tokens/spacing.d.ts +56 -0
  93. package/dist/tokens/spacing.js +56 -0
  94. package/dist/tokens/typography.d.ts +121 -0
  95. package/dist/tokens/typography.js +57 -0
  96. package/dist/types/app.d.ts +21 -0
  97. package/dist/types/app.js +1 -0
  98. package/package.json +13 -7
  99. package/src/dist/ui-react/index.js +0 -2
  100. package/src/dist/ui-react/index.js.LICENSE.txt +0 -11
  101. package/src/ui-react/bridge.js +0 -36
  102. package/src/ui-react/bridge.ts +0 -48
  103. package/src/ui-react/components/app.d.ts +0 -7
  104. package/src/ui-react/components/app.jsx +0 -80
  105. package/src/ui-react/components/app.tsx +0 -42
  106. package/src/ui-react/components/app1.js +0 -101
  107. package/src/ui-react/components/avatar/Avatar.tsx +0 -88
  108. package/src/ui-react/components/bottom-sheet/BottomSheet.tsx +0 -149
  109. package/src/ui-react/components/button/Button.tsx +0 -246
  110. package/src/ui-react/components/button-group/ButtonGroup.tsx +0 -108
  111. package/src/ui-react/components/card/Card.tsx +0 -77
  112. package/src/ui-react/components/checkbox/Checkbox.tsx +0 -232
  113. package/src/ui-react/components/chip/Chip.tsx +0 -137
  114. package/src/ui-react/components/dialog/Dialog.tsx +0 -135
  115. package/src/ui-react/components/divider/Divider.tsx +0 -54
  116. package/src/ui-react/components/input/Input.tsx +0 -195
  117. package/src/ui-react/components/list/List.tsx +0 -180
  118. package/src/ui-react/components/loading/Loading.tsx +0 -121
  119. package/src/ui-react/components/modal/Modal.tsx +0 -116
  120. package/src/ui-react/components/navigation-bar/NavigationBar.tsx +0 -188
  121. package/src/ui-react/components/radio/Radio.tsx +0 -216
  122. package/src/ui-react/components/select/Select.tsx +0 -109
  123. package/src/ui-react/components/switch/Switch.tsx +0 -164
  124. package/src/ui-react/components/tab-bar/TabBar.tsx +0 -137
  125. package/src/ui-react/components/textarea/Textarea.tsx +0 -109
  126. package/src/ui-react/components/toast/Toast.ts +0 -98
  127. package/src/ui-react/components/typography/Typography.tsx +0 -201
  128. package/src/ui-react/hooks/use-app-pause.js +0 -35
  129. package/src/ui-react/hooks/use-app-pause.ts +0 -33
  130. package/src/ui-react/hooks/use-app-resume.js +0 -37
  131. package/src/ui-react/hooks/use-app-resume.ts +0 -32
  132. package/src/ui-react/hooks/use-app-state.js +0 -35
  133. package/src/ui-react/hooks/use-did-hide.js +0 -25
  134. package/src/ui-react/hooks/use-did-hide.ts +0 -34
  135. package/src/ui-react/hooks/use-did-show.js +0 -26
  136. package/src/ui-react/hooks/use-did-show.ts +0 -34
  137. package/src/ui-react/hooks/use-listener-scan-qr.js +0 -33
  138. package/src/ui-react/hooks/use-listener-scan-qr.ts +0 -52
  139. package/src/ui-react/hooks/use-navigate.js +0 -15
  140. package/src/ui-react/hooks/use-navigate.ts +0 -41
  141. package/src/ui-react/hooks/use-tap-app-bar.js +0 -26
  142. package/src/ui-react/hooks/use-tap-app-bar.ts +0 -34
  143. package/src/ui-react/index.js +0 -9
  144. package/src/ui-react/styles/VETCProvider.tsx +0 -152
  145. package/src/ui-react/tokens/colors.ts +0 -91
  146. package/src/ui-react/tokens/spacing.ts +0 -59
  147. package/src/ui-react/tokens/typography.ts +0 -63
  148. package/src/ui-react/tokens_vetc.json +0 -1517
  149. package/src/ui-react/types/app.js +0 -30
  150. package/src/ui-react/types/app.ts +0 -32
  151. /package/{src/ui-react/components/avatar/index.ts → dist/components/avatar/index.d.ts} +0 -0
  152. /package/{src/ui-react/components/bottom-sheet/index.ts → dist/components/bottom-sheet/index.d.ts} +0 -0
  153. /package/{src/ui-react/components/button/index.ts → dist/components/button/index.d.ts} +0 -0
  154. /package/{src/ui-react/components/button-group/index.ts → dist/components/button-group/index.d.ts} +0 -0
  155. /package/{src/ui-react/components/card/index.ts → dist/components/card/index.d.ts} +0 -0
  156. /package/{src/ui-react/components/checkbox/index.ts → dist/components/checkbox/index.d.ts} +0 -0
  157. /package/{src/ui-react/components/chip/index.ts → dist/components/chip/index.d.ts} +0 -0
  158. /package/{src/ui-react/components/dialog/index.ts → dist/components/dialog/index.d.ts} +0 -0
  159. /package/{src/ui-react/components/divider/index.ts → dist/components/divider/index.d.ts} +0 -0
  160. /package/{src/ui-react/components/input/index.ts → dist/components/input/index.d.ts} +0 -0
  161. /package/{src/ui-react/components/list/index.ts → dist/components/list/index.d.ts} +0 -0
  162. /package/{src/ui-react/components/loading/index.ts → dist/components/loading/index.d.ts} +0 -0
  163. /package/{src/ui-react/components/modal/index.ts → dist/components/modal/index.d.ts} +0 -0
  164. /package/{src/ui-react/components/navigation-bar/index.ts → dist/components/navigation-bar/index.d.ts} +0 -0
  165. /package/{src/ui-react/components/radio/index.ts → dist/components/radio/index.d.ts} +0 -0
  166. /package/{src/ui-react/components/select/index.ts → dist/components/select/index.d.ts} +0 -0
  167. /package/{src/ui-react/components/switch/index.ts → dist/components/switch/index.d.ts} +0 -0
  168. /package/{src/ui-react/components/tab-bar/index.ts → dist/components/tab-bar/index.d.ts} +0 -0
  169. /package/{src/ui-react/components/textarea/index.ts → dist/components/textarea/index.d.ts} +0 -0
  170. /package/{src/ui-react/components/toast/index.ts → dist/components/toast/index.d.ts} +0 -0
  171. /package/{src/ui-react/components/typography/index.ts → dist/components/typography/index.d.ts} +0 -0
  172. /package/{src/ui-react/tokens/index.ts → dist/tokens/index.d.ts} +0 -0
@@ -0,0 +1,41 @@
1
+ /**
2
+ * VETC Toast — tokenized
3
+ * Figma: Toast page (7 variants)
4
+ */
5
+ import React from 'react';
6
+ export type ToastType = 'default' | 'success' | 'error' | 'warning' | 'info';
7
+ export interface ToastOptions {
8
+ message: string;
9
+ description?: string;
10
+ type?: ToastType;
11
+ placement?: 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight';
12
+ /** Duration in seconds (0 = persistent) */
13
+ duration?: number;
14
+ icon?: React.ReactNode;
15
+ onClose?: () => void;
16
+ }
17
+ /**
18
+ * Static programmatic toast API
19
+ * Usage: toast.success('Message')
20
+ */
21
+ export declare const toast: {
22
+ show(opts: ToastOptions): void;
23
+ success: (msg: string, description?: string) => void;
24
+ error: (msg: string, description?: string) => void;
25
+ warning: (msg: string, description?: string) => void;
26
+ info: (msg: string, description?: string) => void;
27
+ };
28
+ /**
29
+ * Hook-based toast — requires VETCProvider (antd App wrapper)
30
+ */
31
+ export declare function useToast(): {
32
+ contextHolder: React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
33
+ toast: {
34
+ show: (opts: ToastOptions) => void;
35
+ success: (msg: string, description?: string) => void;
36
+ error: (msg: string, description?: string) => void;
37
+ warning: (msg: string, description?: string) => void;
38
+ info: (msg: string, description?: string) => void;
39
+ };
40
+ };
41
+ export default toast;
@@ -0,0 +1,61 @@
1
+ import { notification, message } from 'antd';
2
+ /** Shared notification style — references CSS vars */
3
+ const toastStyle = {
4
+ borderRadius: 'var(--vetc-toast-radius)',
5
+ fontFamily: 'var(--vetc-font-family)',
6
+ };
7
+ /**
8
+ * Static programmatic toast API
9
+ * Usage: toast.success('Message')
10
+ */
11
+ export const toast = {
12
+ show(opts) {
13
+ const { type = 'default', message: msg, description, duration = 3, placement = 'top', icon, onClose, } = opts;
14
+ if (type === 'default') {
15
+ message.open({ type: 'info', content: msg, duration, onClose });
16
+ return;
17
+ }
18
+ notification[type]({
19
+ message: msg,
20
+ description,
21
+ duration,
22
+ placement,
23
+ icon,
24
+ onClose,
25
+ style: toastStyle,
26
+ });
27
+ },
28
+ success: (msg, description) => toast.show({ message: msg, description, type: 'success' }),
29
+ error: (msg, description) => toast.show({ message: msg, description, type: 'error' }),
30
+ warning: (msg, description) => toast.show({ message: msg, description, type: 'warning' }),
31
+ info: (msg, description) => toast.show({ message: msg, description, type: 'info' }),
32
+ };
33
+ /**
34
+ * Hook-based toast — requires VETCProvider (antd App wrapper)
35
+ */
36
+ export function useToast() {
37
+ const [api, contextHolder] = notification.useNotification();
38
+ const show = (opts) => {
39
+ const { type = 'info', message: msg, description, duration = 3, placement = 'top', icon, onClose, } = opts;
40
+ api[type === 'default' ? 'info' : type]({
41
+ message: msg,
42
+ description,
43
+ duration,
44
+ placement,
45
+ icon,
46
+ onClose,
47
+ style: toastStyle,
48
+ });
49
+ };
50
+ return {
51
+ contextHolder,
52
+ toast: {
53
+ show,
54
+ success: (msg, description) => show({ message: msg, description, type: 'success' }),
55
+ error: (msg, description) => show({ message: msg, description, type: 'error' }),
56
+ warning: (msg, description) => show({ message: msg, description, type: 'warning' }),
57
+ info: (msg, description) => show({ message: msg, description, type: 'info' }),
58
+ },
59
+ };
60
+ }
61
+ export default toast;
@@ -0,0 +1 @@
1
+ export { toast, useToast } from './Toast';
@@ -0,0 +1,45 @@
1
+ /**
2
+ * VETC Typography Components
3
+ * All style values reference CSS custom properties from tokens.css
4
+ */
5
+ import React from 'react';
6
+ declare const styles: Record<string, React.CSSProperties>;
7
+ export type TypographyVariant = keyof typeof styles;
8
+ export type TextColor = 'primary' | 'secondary' | 'tertiary' | 'disabled' | 'brand' | 'error' | 'warning' | 'success' | 'inherit';
9
+ export interface TypographyProps {
10
+ /** Typography style variant */
11
+ variant?: TypographyVariant;
12
+ /** Text color */
13
+ color?: TextColor;
14
+ /** Strike-through */
15
+ strikethrough?: boolean;
16
+ /** Underline */
17
+ underline?: boolean;
18
+ /** Single-line truncate */
19
+ truncate?: boolean;
20
+ /** Clamp to N lines */
21
+ lines?: number;
22
+ /** Render tag */
23
+ as?: keyof React.JSX.IntrinsicElements;
24
+ children?: React.ReactNode;
25
+ className?: string;
26
+ style?: React.CSSProperties;
27
+ id?: string;
28
+ }
29
+ export declare function Typography({ variant, color, strikethrough, underline, truncate, lines, as: Tag, children, className, style, id, }: TypographyProps): import("react/jsx-runtime").JSX.Element;
30
+ export declare function Display({ level, ...props }: Omit<TypographyProps, 'variant'> & {
31
+ level?: '4xl' | '3xl' | '2xl';
32
+ }): import("react/jsx-runtime").JSX.Element;
33
+ export declare function Headline({ level, ...props }: Omit<TypographyProps, 'variant'> & {
34
+ level?: 'xl' | 'lg';
35
+ }): import("react/jsx-runtime").JSX.Element;
36
+ export declare function Title({ size, ...props }: Omit<TypographyProps, 'variant'> & {
37
+ size?: 'base' | 'sm';
38
+ }): import("react/jsx-runtime").JSX.Element;
39
+ export declare function Label({ size, ...props }: Omit<TypographyProps, 'variant'> & {
40
+ size?: 'base' | 'sm' | 'xs' | 'xxs';
41
+ }): import("react/jsx-runtime").JSX.Element;
42
+ export declare function Body({ size, ...props }: Omit<TypographyProps, 'variant'> & {
43
+ size?: 'base' | 'sm' | 'xs' | '2xs';
44
+ }): import("react/jsx-runtime").JSX.Element;
45
+ export default Typography;
@@ -0,0 +1,143 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // ── Typography style map — dùng CSS vars thay vì hardcode ──────────────────
3
+ const styles = {
4
+ display4xl: {
5
+ fontSize: 'var(--vetc-font-size-4xl)',
6
+ fontWeight: 'var(--vetc-font-weight-bold)',
7
+ lineHeight: 'var(--vetc-line-height-tight)',
8
+ },
9
+ display3xl: {
10
+ fontSize: 'var(--vetc-font-size-3xl)',
11
+ fontWeight: 'var(--vetc-font-weight-bold)',
12
+ lineHeight: 'var(--vetc-line-height-tight)',
13
+ },
14
+ display2xl: {
15
+ fontSize: 'var(--vetc-font-size-2xl)',
16
+ fontWeight: 'var(--vetc-font-weight-bold)',
17
+ lineHeight: 'var(--vetc-line-height-tight)',
18
+ },
19
+ headlineXl: {
20
+ fontSize: 'var(--vetc-font-size-xl)',
21
+ fontWeight: 'var(--vetc-font-weight-bold)',
22
+ lineHeight: 'var(--vetc-line-height-normal)',
23
+ },
24
+ headlineLg: {
25
+ fontSize: 'var(--vetc-font-size-lg)',
26
+ fontWeight: 'var(--vetc-font-weight-semibold)',
27
+ lineHeight: 'var(--vetc-line-height-normal)',
28
+ },
29
+ titleBase: {
30
+ fontSize: 'var(--vetc-font-size-base)',
31
+ fontWeight: 'var(--vetc-font-weight-semibold)',
32
+ lineHeight: 'var(--vetc-line-height-relaxed)',
33
+ letterSpacing: 'var(--vetc-letter-spacing-sm)',
34
+ },
35
+ titleSm: {
36
+ fontSize: 'var(--vetc-font-size-sm)',
37
+ fontWeight: 'var(--vetc-font-weight-semibold)',
38
+ lineHeight: 'var(--vetc-line-height-relaxed)',
39
+ letterSpacing: 'var(--vetc-letter-spacing-sm)',
40
+ },
41
+ labelBase: {
42
+ fontSize: 'var(--vetc-font-size-base)',
43
+ fontWeight: 'var(--vetc-font-weight-semibold)',
44
+ lineHeight: 'var(--vetc-line-height-relaxed)',
45
+ },
46
+ labelSm: {
47
+ fontSize: 'var(--vetc-font-size-sm)',
48
+ fontWeight: 'var(--vetc-font-weight-semibold)',
49
+ lineHeight: 'var(--vetc-line-height-relaxed)',
50
+ letterSpacing: 'var(--vetc-letter-spacing-lg)',
51
+ },
52
+ labelXs: {
53
+ fontSize: 'var(--vetc-font-size-xs)',
54
+ fontWeight: 'var(--vetc-font-weight-semibold)',
55
+ lineHeight: 'var(--vetc-line-height-relaxed)',
56
+ letterSpacing: 'var(--vetc-letter-spacing-lg)',
57
+ },
58
+ labelXxs: {
59
+ fontSize: 'var(--vetc-font-size-2xs)',
60
+ fontWeight: 'var(--vetc-font-weight-semibold)',
61
+ lineHeight: 'var(--vetc-line-height-relaxed)',
62
+ letterSpacing: 'var(--vetc-letter-spacing-lg)',
63
+ },
64
+ bodyBase: {
65
+ fontSize: 'var(--vetc-font-size-base)',
66
+ fontWeight: 'var(--vetc-font-weight-regular)',
67
+ lineHeight: 'var(--vetc-line-height-relaxed)',
68
+ letterSpacing: 'var(--vetc-letter-spacing-sm)',
69
+ },
70
+ bodySm: {
71
+ fontSize: 'var(--vetc-font-size-sm)',
72
+ fontWeight: 'var(--vetc-font-weight-regular)',
73
+ lineHeight: 'var(--vetc-line-height-relaxed)',
74
+ letterSpacing: 'var(--vetc-letter-spacing-md)',
75
+ },
76
+ bodyXs: {
77
+ fontSize: 'var(--vetc-font-size-xs)',
78
+ fontWeight: 'var(--vetc-font-weight-regular)',
79
+ lineHeight: 'var(--vetc-line-height-relaxed)',
80
+ letterSpacing: 'var(--vetc-letter-spacing-lg)',
81
+ },
82
+ body2xs: {
83
+ fontSize: 'var(--vetc-font-size-2xs)',
84
+ fontWeight: 'var(--vetc-font-weight-regular)',
85
+ lineHeight: 'var(--vetc-line-height-relaxed)',
86
+ letterSpacing: 'var(--vetc-letter-spacing-lg)',
87
+ },
88
+ };
89
+ const colorMap = {
90
+ primary: 'var(--vetc-color-text-primary)',
91
+ secondary: 'var(--vetc-color-text-secondary)',
92
+ tertiary: 'var(--vetc-color-text-tertiary)',
93
+ disabled: 'var(--vetc-color-text-disabled)',
94
+ brand: 'var(--vetc-color-brand)',
95
+ error: 'var(--vetc-color-text-error)',
96
+ warning: 'var(--vetc-color-warning)',
97
+ success: 'var(--vetc-color-positive)',
98
+ inherit: 'inherit',
99
+ };
100
+ export function Typography({ variant = 'bodyBase', color = 'primary', strikethrough = false, underline = false, truncate = false, lines, as: Tag = 'span', children, className = '', style, id, }) {
101
+ const variantStyle = styles[variant] ?? styles.bodyBase;
102
+ const colorValue = colorMap[color];
103
+ const combinedStyle = {
104
+ fontFamily: 'var(--vetc-font-family)',
105
+ margin: 0,
106
+ padding: 0,
107
+ ...variantStyle,
108
+ color: colorValue,
109
+ textDecoration: strikethrough ? 'line-through' : underline ? 'underline' : 'none',
110
+ ...(truncate && !lines
111
+ ? { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }
112
+ : {}),
113
+ ...(lines
114
+ ? {
115
+ display: '-webkit-box',
116
+ WebkitLineClamp: lines,
117
+ WebkitBoxOrient: 'vertical',
118
+ overflow: 'hidden',
119
+ }
120
+ : {}),
121
+ ...style,
122
+ };
123
+ return (_jsx(Tag, { id: id, className: `vetc-text vetc-text--${variant} ${className}`, style: combinedStyle, children: children }));
124
+ }
125
+ // ── Convenience shorthands ──────────────────────────────────────────────────
126
+ export function Display({ level = '2xl', ...props }) {
127
+ return _jsx(Typography, { ...props, variant: `display${level}`, as: props.as ?? 'h1' });
128
+ }
129
+ export function Headline({ level = 'xl', ...props }) {
130
+ return _jsx(Typography, { ...props, variant: level === 'xl' ? 'headlineXl' : 'headlineLg', as: props.as ?? 'h2' });
131
+ }
132
+ export function Title({ size = 'base', ...props }) {
133
+ return _jsx(Typography, { ...props, variant: size === 'base' ? 'titleBase' : 'titleSm', as: props.as ?? 'h3' });
134
+ }
135
+ export function Label({ size = 'base', ...props }) {
136
+ const variantMap = { base: 'labelBase', sm: 'labelSm', xs: 'labelXs', xxs: 'labelXxs' };
137
+ return _jsx(Typography, { ...props, variant: variantMap[size], as: props.as ?? 'span' });
138
+ }
139
+ export function Body({ size = 'base', ...props }) {
140
+ const variantMap = { base: 'bodyBase', sm: 'bodySm', xs: 'bodyXs', '2xs': 'body2xs' };
141
+ return _jsx(Typography, { ...props, variant: variantMap[size], as: props.as ?? 'p' });
142
+ }
143
+ export default Typography;
@@ -0,0 +1 @@
1
+ export { Typography, Display, Headline, Title, Label, Body } from './Typography';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * useAppPause
3
+ *
4
+ * Trigger khi Native App đi vào background.
5
+ */
6
+ export declare function useAppPause(callback: () => void): void;
@@ -0,0 +1,29 @@
1
+ import { useEffect, useRef } from "react";
2
+ /**
3
+ * useAppPause
4
+ *
5
+ * Trigger khi Native App đi vào background.
6
+ */
7
+ export function useAppPause(callback) {
8
+ const savedCallback = useRef(callback);
9
+ // giữ callback luôn mới nhất
10
+ useEffect(() => {
11
+ savedCallback.current = callback;
12
+ }, [callback]);
13
+ useEffect(() => {
14
+ if (typeof window === "undefined" || !window.MiniApp)
15
+ return;
16
+ const handler = () => {
17
+ try {
18
+ savedCallback.current?.();
19
+ }
20
+ catch (err) {
21
+ console.error("[useAppPause error]", err);
22
+ }
23
+ };
24
+ window.MiniApp.on("appPause", handler);
25
+ return () => {
26
+ window.MiniApp.off("appPause", handler);
27
+ };
28
+ }, []);
29
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * useAppResume
3
+ *
4
+ * Trigger khi Native App quay lại foreground.
5
+ */
6
+ export declare function useAppResume(callback: () => void): void;
@@ -0,0 +1,28 @@
1
+ import { useEffect, useRef } from "react";
2
+ /**
3
+ * useAppResume
4
+ *
5
+ * Trigger khi Native App quay lại foreground.
6
+ */
7
+ export function useAppResume(callback) {
8
+ const savedCallback = useRef(callback);
9
+ useEffect(() => {
10
+ savedCallback.current = callback;
11
+ }, [callback]);
12
+ useEffect(() => {
13
+ if (typeof window === "undefined" || !window.MiniApp)
14
+ return;
15
+ const handler = () => {
16
+ try {
17
+ savedCallback.current?.();
18
+ }
19
+ catch (err) {
20
+ console.error("[useAppResume error]", err);
21
+ }
22
+ };
23
+ window.MiniApp.on("appResume", handler);
24
+ return () => {
25
+ window.MiniApp.off("appResume", handler);
26
+ };
27
+ }, []);
28
+ }
@@ -1,6 +1,5 @@
1
1
  import { Dispatch, SetStateAction } from 'react';
2
2
  import { IAppState, IAppConfig } from '../types/app';
3
-
4
3
  export declare const useAppState: () => {
5
4
  config: IAppConfig;
6
5
  appState: IAppState;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ type DidHidePayload = {
2
+ route?: string;
3
+ [key: string]: any;
4
+ };
5
+ export declare function useDidHide(route: string, callback: (data?: DidHidePayload) => void): void;
6
+ export {};
@@ -0,0 +1,21 @@
1
+ import { useEffect, useRef } from "react";
2
+ export function useDidHide(route, callback) {
3
+ const saved = useRef(callback);
4
+ // luôn giữ callback mới nhất
5
+ useEffect(() => {
6
+ saved.current = callback;
7
+ }, [callback]);
8
+ useEffect(() => {
9
+ if (typeof window === "undefined" || !window.MiniApp)
10
+ return;
11
+ const handler = (data) => {
12
+ if (data?.route === route) {
13
+ saved.current?.(data);
14
+ }
15
+ };
16
+ window.MiniApp.on("didHide", handler);
17
+ return () => {
18
+ window.MiniApp.off("didHide", handler);
19
+ };
20
+ }, [route]);
21
+ }
@@ -0,0 +1,6 @@
1
+ type DidShowPayload = {
2
+ route?: string;
3
+ [key: string]: any;
4
+ };
5
+ export declare function useDidShow(route: string, callback: (data?: DidShowPayload) => void): void;
6
+ export {};
@@ -0,0 +1,21 @@
1
+ import { useEffect, useRef } from "react";
2
+ export function useDidShow(route, callback) {
3
+ const saved = useRef(callback);
4
+ // luôn giữ callback mới nhất
5
+ useEffect(() => {
6
+ saved.current = callback;
7
+ }, [callback]);
8
+ useEffect(() => {
9
+ if (typeof window === "undefined" || !window.MiniApp)
10
+ return;
11
+ const handler = (data) => {
12
+ if (data?.route === route) {
13
+ saved.current?.(data);
14
+ }
15
+ };
16
+ window.MiniApp.on("didShow", handler);
17
+ return () => {
18
+ window.MiniApp.off("didShow", handler);
19
+ };
20
+ }, [route]);
21
+ }
@@ -0,0 +1,21 @@
1
+ type ScanQrResult = {
2
+ raw: string;
3
+ type?: string;
4
+ [key: string]: any;
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
+ /**
16
+ * useListenerScanQr
17
+ *
18
+ * Lắng nghe kết quả scan QR từ Native
19
+ */
20
+ export declare function useListenerScanQr(callback: (data: ScanQrResult) => void): void;
21
+ export {};
@@ -0,0 +1,29 @@
1
+ import { useEffect, useRef } from "react";
2
+ /**
3
+ * useListenerScanQr
4
+ *
5
+ * Lắng nghe kết quả scan QR từ Native
6
+ */
7
+ export function useListenerScanQr(callback) {
8
+ const savedCallback = useRef(callback);
9
+ // luôn giữ callback mới nhất
10
+ useEffect(() => {
11
+ savedCallback.current = callback;
12
+ }, [callback]);
13
+ useEffect(() => {
14
+ if (typeof window === "undefined" || !window.MiniApp)
15
+ return;
16
+ const handler = (data) => {
17
+ try {
18
+ savedCallback.current?.(data);
19
+ }
20
+ catch (err) {
21
+ console.error("[useListenerScanQr error]", err);
22
+ }
23
+ };
24
+ window.MiniApp.on("scanQrResult", handler);
25
+ return () => {
26
+ window.MiniApp.off("scanQrResult", handler);
27
+ };
28
+ }, []);
29
+ }
@@ -0,0 +1,8 @@
1
+ export type NavigateMode = "push" | "replace";
2
+ export interface NavigateOptions {
3
+ replace?: boolean;
4
+ popTo?: string;
5
+ }
6
+ export type NavigateParams = Record<string, unknown>;
7
+ export type MiniAppRoute = string | number;
8
+ export declare function useNavigate(): (route: MiniAppRoute, params?: NavigateParams, options?: NavigateOptions) => void;
@@ -0,0 +1,23 @@
1
+ import { callHost } from "../bridge";
2
+ /* ================= Hook ================= */
3
+ export function useNavigate() {
4
+ return (route, params = {}, options = {}) => {
5
+ // POP navigation
6
+ if (typeof route === "number") {
7
+ callHost("navigate", {
8
+ type: "native",
9
+ action: "pop",
10
+ delta: Math.abs(route),
11
+ });
12
+ return;
13
+ }
14
+ // Gửi sang native host
15
+ callHost("navigate", {
16
+ type: "native",
17
+ action: "push",
18
+ route,
19
+ params,
20
+ options,
21
+ }).catch(console.error);
22
+ };
23
+ }
@@ -0,0 +1,6 @@
1
+ type TapAppBarPayload = {
2
+ route?: string;
3
+ [key: string]: any;
4
+ };
5
+ export declare function useTapAppBar(route: string, callback: (data?: TapAppBarPayload) => void): void;
6
+ export {};
@@ -0,0 +1,21 @@
1
+ import { useEffect, useRef } from "react";
2
+ export function useTapAppBar(route, callback) {
3
+ const saved = useRef(callback);
4
+ // luôn giữ callback mới nhất
5
+ useEffect(() => {
6
+ saved.current = callback;
7
+ }, [callback]);
8
+ useEffect(() => {
9
+ if (typeof window === "undefined" || !window.MiniApp)
10
+ return;
11
+ const handler = (data) => {
12
+ if (data?.route === route) {
13
+ saved.current?.(data);
14
+ }
15
+ };
16
+ window.MiniApp.on("onTapAppBar", handler);
17
+ return () => {
18
+ window.MiniApp.off("onTapAppBar", handler);
19
+ };
20
+ }, [route]);
21
+ }
@@ -1,80 +1,51 @@
1
- // ─── Styles (import once at app root) ────────────────────────────────────────
2
- // import '@vetc-miniapp/ui-react/src/ui-react/styles/tokens.css';
3
-
4
- // ─── Theme Provider ───────────────────────────────────────────────────────────
5
1
  export { VETCProvider, vetcAntdTheme } from './styles/VETCProvider';
6
2
  export type { VETCProviderProps } from './styles/VETCProvider';
7
-
8
- // ─── Tokens ───────────────────────────────────────────────────────────────────
9
3
  export { colorGlobal, colorAlias } from './tokens/colors';
10
4
  export { fontFamily, fontWeight, fontSize, lineHeight, letterSpacing, textStyle } from './tokens/typography';
11
5
  export { spacing, borderRadius, componentHeight, shadow } from './tokens/spacing';
12
-
13
- // ─── Components ───────────────────────────────────────────────────────────────
14
6
  export { Button } from './components/button';
15
7
  export type { ButtonProps, ButtonStyle, ButtonVariant, ButtonSize, ButtonShape } from './components/button';
16
-
17
8
  export { ButtonGroup } from './components/button-group';
18
9
  export type { ButtonGroupProps, ButtonGroupAction, ButtonGroupLayout, ButtonGroupVariant } from './components/button-group';
19
-
20
10
  export { Typography, Display, Headline, Title, Label, Body } from './components/typography';
21
11
  export type { TypographyProps, TypographyVariant, TextColor } from './components/typography';
22
-
23
12
  export { Input, PasswordInput } from './components/input';
24
13
  export type { InputProps, PasswordInputProps, InputStatus } from './components/input';
25
-
26
14
  export { Textarea } from './components/textarea';
27
15
  export type { TextareaProps } from './components/textarea';
28
-
29
16
  export { Select } from './components/select';
30
17
  export type { SelectProps, SelectOption } from './components/select';
31
-
32
18
  export { Checkbox, CheckboxGroup } from './components/checkbox';
33
19
  export type { CheckboxProps, CheckboxGroupProps, CheckboxOption, CheckboxVariant } from './components/checkbox';
34
-
35
20
  export { Radio, RadioGroup } from './components/radio';
36
21
  export type { RadioProps, RadioGroupProps, RadioOption, RadioVariant } from './components/radio';
37
-
38
22
  export { Switch } from './components/switch';
39
23
  export type { SwitchProps, SwitchVariant } from './components/switch';
40
-
41
24
  export { Chip } from './components/chip';
42
25
  export type { ChipProps, ChipStyle, ChipType, ChipShape } from './components/chip';
43
-
44
26
  export { Avatar } from './components/avatar';
45
27
  export type { AvatarProps, AvatarSize, AvatarShape } from './components/avatar';
46
-
47
28
  export { Card } from './components/card';
48
29
  export type { CardProps, CardElevation } from './components/card';
49
-
50
30
  export { List, ListItem } from './components/list';
51
31
  export type { ListProps, ListItemProps } from './components/list';
52
-
53
32
  export { Divider } from './components/divider';
54
33
  export type { DividerProps } from './components/divider';
55
-
56
34
  export { Spinner, SkeletonLoader } from './components/loading';
57
35
  export type { SpinnerProps, SkeletonProps, SpinnerSize } from './components/loading';
58
-
59
36
  export { toast, useToast } from './components/toast';
60
37
  export type { ToastOptions, ToastType } from './components/toast';
61
-
62
38
  export { Modal, useConfirm } from './components/modal';
63
39
  export type { ModalProps } from './components/modal';
64
-
65
40
  export { Dialog } from './components/dialog';
66
41
  export type { DialogProps } from './components/dialog';
67
-
68
42
  export { BottomSheet } from './components/bottom-sheet';
69
43
  export type { BottomSheetProps } from './components/bottom-sheet';
70
-
71
44
  export { NavigationBar } from './components/navigation-bar';
72
45
  export type { NavigationBarProps, NavigationBarAction } from './components/navigation-bar';
73
-
74
46
  export { TabBar } from './components/tab-bar';
75
47
  export type { TabBarProps, TabBarItem, TabBarVariant } from './components/tab-bar';
76
-
77
- // ─── Hooks (existing) ─────────────────────────────────────────────────────────
48
+ export { App } from './components/app';
78
49
  export * from './hooks/use-app-resume';
79
50
  export * from './hooks/use-app-pause';
80
51
  export * from './hooks/use-did-show';