@mangtre/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +26 -0
- package/dist/MangThemeProvider-BqdGKBP2.d.ts +34 -0
- package/dist/Money-Dw3GnUvX.d.ts +27 -0
- package/dist/actions.d.ts +31 -0
- package/dist/actions.js +13 -0
- package/dist/ai.d.ts +58 -0
- package/dist/ai.js +13 -0
- package/dist/analytics.d.ts +40 -0
- package/dist/analytics.js +15 -0
- package/dist/app.d.ts +24 -0
- package/dist/app.js +9 -0
- package/dist/catalog.d.ts +76 -0
- package/dist/catalog.js +1210 -0
- package/dist/charts.d.ts +89 -0
- package/dist/charts.js +34 -0
- package/dist/chunk-3AL4SUFD.js +301 -0
- package/dist/chunk-4XNSYKQE.js +142 -0
- package/dist/chunk-5Z4VLQKH.js +43 -0
- package/dist/chunk-7P2EQZYD.js +59 -0
- package/dist/chunk-7WHNIEDV.js +120 -0
- package/dist/chunk-ASZKHSMG.js +82 -0
- package/dist/chunk-BCBN2EGH.js +216 -0
- package/dist/chunk-BLYAFV45.js +320 -0
- package/dist/chunk-DLKEXWPA.js +90 -0
- package/dist/chunk-DTASXPTB.js +70 -0
- package/dist/chunk-FZRXVRC7.js +63 -0
- package/dist/chunk-ID233AGM.js +108 -0
- package/dist/chunk-IVYXOKMO.js +74 -0
- package/dist/chunk-IX3DYETF.js +61 -0
- package/dist/chunk-JJB4PJC3.js +166 -0
- package/dist/chunk-K5Q3RCV6.js +119 -0
- package/dist/chunk-LNRUPJDF.js +161 -0
- package/dist/chunk-LZORNMBL.js +0 -0
- package/dist/chunk-OBPXCUVF.js +282 -0
- package/dist/chunk-OJX2EIMB.js +145 -0
- package/dist/chunk-PPOYMKV3.js +170 -0
- package/dist/chunk-PQGUWJG4.js +47 -0
- package/dist/chunk-RE7OWRA4.js +187 -0
- package/dist/chunk-SJF3CHAW.js +108 -0
- package/dist/chunk-UF6ANDJZ.js +112 -0
- package/dist/chunk-VGC5DMOM.js +107 -0
- package/dist/chunk-VP56Z4BS.js +0 -0
- package/dist/chunk-VRD66FIA.js +77 -0
- package/dist/chunk-X7T2DJLU.js +113 -0
- package/dist/chunk-XPV3OOLU.js +147 -0
- package/dist/chunk-YN5O6YL6.js +69 -0
- package/dist/chunk-Z4ANGBPC.js +94 -0
- package/dist/creator.d.ts +55 -0
- package/dist/creator.js +20 -0
- package/dist/data-room.d.ts +50 -0
- package/dist/data-room.js +17 -0
- package/dist/editor.d.ts +32 -0
- package/dist/editor.js +14 -0
- package/dist/feedback.d.ts +48 -0
- package/dist/feedback.js +16 -0
- package/dist/forms.d.ts +91 -0
- package/dist/forms.js +26 -0
- package/dist/handoff.d.ts +37 -0
- package/dist/handoff.js +13 -0
- package/dist/index.css +2 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +338 -0
- package/dist/layout.d.ts +57 -0
- package/dist/layout.js +22 -0
- package/dist/learning.d.ts +46 -0
- package/dist/learning.js +15 -0
- package/dist/media.d.ts +48 -0
- package/dist/media.js +16 -0
- package/dist/monetization.d.ts +30 -0
- package/dist/monetization.js +14 -0
- package/dist/money.d.ts +45 -0
- package/dist/money.js +28 -0
- package/dist/navigation.d.ts +36 -0
- package/dist/navigation.js +14 -0
- package/dist/overlay.d.ts +72 -0
- package/dist/overlay.js +20 -0
- package/dist/platform.d.ts +94 -0
- package/dist/platform.js +42 -0
- package/dist/primitives.d.ts +83 -0
- package/dist/primitives.js +22 -0
- package/dist/privacy.d.ts +28 -0
- package/dist/privacy.js +15 -0
- package/dist/sandbox.d.ts +40 -0
- package/dist/sandbox.js +15 -0
- package/dist/settings.d.ts +29 -0
- package/dist/settings.js +13 -0
- package/dist/surface.d.ts +33 -0
- package/dist/surface.js +16 -0
- package/dist/theme.css +63 -0
- package/dist/theme.d.ts +64 -0
- package/dist/theme.js +27 -0
- package/dist/tokens.css +119 -0
- package/dist/tokens.d.ts +128 -0
- package/dist/tokens.js +8 -0
- package/package.json +151 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cx,
|
|
3
|
+
useAreaStyles,
|
|
4
|
+
useScope
|
|
5
|
+
} from "./chunk-3AL4SUFD.js";
|
|
6
|
+
import {
|
|
7
|
+
tokens
|
|
8
|
+
} from "./chunk-PPOYMKV3.js";
|
|
9
|
+
|
|
10
|
+
// src/media/Media.tsx
|
|
11
|
+
import { useRef, useState } from "react";
|
|
12
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
var STYLE_ID = "mang-ui-media";
|
|
14
|
+
var { color, fontSize, fontWeight, radius, font } = tokens;
|
|
15
|
+
var CSS = (
|
|
16
|
+
/* css */
|
|
17
|
+
`
|
|
18
|
+
.mang-dropzone { display: grid; gap: 0.35rem; justify-items: center; text-align: center; padding: 1.5rem 1.25rem; border: 2px dashed var(--m-line-strong); border-radius: ${radius.lg}; background: var(--m-sunken); color: var(--m-text-muted); cursor: pointer; transition: border-color 140ms, background 140ms; }
|
|
19
|
+
.mang-dropzone[data-over="true"] { border-color: var(--m-accent); background: var(--m-accent-soft); }
|
|
20
|
+
.mang-dropzone-icon { font-size: 1.6rem; }
|
|
21
|
+
.mang-fileprev { display: flex; align-items: center; gap: 0.6rem; padding: 0.55rem 0.7rem; border: 1px solid var(--m-line); border-radius: ${radius.md}; background: var(--m-surface); }
|
|
22
|
+
.mang-fileprev-icon { font-size: 1.25rem; }
|
|
23
|
+
.mang-fileprev-main { flex: 1; min-width: 0; }
|
|
24
|
+
.mang-fileprev-name { font-weight: ${fontWeight.semibold}; font-size: ${fontSize.sm}; color: var(--m-text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
25
|
+
.mang-fileprev-meta { font-size: ${fontSize.xs}; color: var(--m-text-muted); }
|
|
26
|
+
.mang-imgprev { max-width: 100%; border-radius: ${radius.md}; border: 1px solid var(--m-line); display: block; }
|
|
27
|
+
.mang-avatar { display: inline-grid; place-items: center; border-radius: 50%; background: var(--m-accent); color: #fff; font-family: "${font.heading}", system-ui, sans-serif; font-weight: ${fontWeight.bold}; overflow: hidden; flex: none; }
|
|
28
|
+
.mang-avatar img { width: 100%; height: 100%; object-fit: cover; }
|
|
29
|
+
.mang-avatargroup { display: inline-flex; }
|
|
30
|
+
.mang-avatargroup .mang-avatar { margin-left: -0.5rem; box-shadow: 0 0 0 2px var(--m-surface); }
|
|
31
|
+
.mang-avatargroup .mang-avatar:first-child { margin-left: 0; }
|
|
32
|
+
`
|
|
33
|
+
);
|
|
34
|
+
function Dropzone({
|
|
35
|
+
onFiles,
|
|
36
|
+
accept,
|
|
37
|
+
multiple,
|
|
38
|
+
label,
|
|
39
|
+
icon = "\u2B06\uFE0F",
|
|
40
|
+
theme,
|
|
41
|
+
className
|
|
42
|
+
}) {
|
|
43
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
44
|
+
const scope = useScope(theme);
|
|
45
|
+
const inputRef = useRef(null);
|
|
46
|
+
const [over, setOver] = useState(false);
|
|
47
|
+
const emit = (list) => {
|
|
48
|
+
if (list && list.length > 0) onFiles(Array.from(list));
|
|
49
|
+
};
|
|
50
|
+
const onDrop = (e) => {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
setOver(false);
|
|
53
|
+
emit(e.dataTransfer.files);
|
|
54
|
+
};
|
|
55
|
+
const trigger = { role: "button", tabIndex: 0 };
|
|
56
|
+
return /* @__PURE__ */ jsxs(
|
|
57
|
+
"div",
|
|
58
|
+
{
|
|
59
|
+
...scope,
|
|
60
|
+
...trigger,
|
|
61
|
+
className: cx(scope.className, "mang-dropzone", className),
|
|
62
|
+
"data-over": over ? "true" : void 0,
|
|
63
|
+
onClick: () => inputRef.current?.click(),
|
|
64
|
+
onKeyDown: (e) => {
|
|
65
|
+
if (e.key === "Enter" || e.key === " ") inputRef.current?.click();
|
|
66
|
+
},
|
|
67
|
+
onDragOver: (e) => {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
setOver(true);
|
|
70
|
+
},
|
|
71
|
+
onDragLeave: () => setOver(false),
|
|
72
|
+
onDrop,
|
|
73
|
+
children: [
|
|
74
|
+
/* @__PURE__ */ jsx("span", { className: "mang-dropzone-icon", "aria-hidden": "true", children: icon }),
|
|
75
|
+
/* @__PURE__ */ jsx("span", { children: label ?? "K\xE9o th\u1EA3 t\u1EC7p v\xE0o \u0111\xE2y" }),
|
|
76
|
+
/* @__PURE__ */ jsx(
|
|
77
|
+
"input",
|
|
78
|
+
{
|
|
79
|
+
ref: inputRef,
|
|
80
|
+
type: "file",
|
|
81
|
+
accept,
|
|
82
|
+
multiple,
|
|
83
|
+
hidden: true,
|
|
84
|
+
onChange: (e) => {
|
|
85
|
+
emit(e.target.files);
|
|
86
|
+
e.target.value = "";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
function FilePreview({
|
|
95
|
+
name,
|
|
96
|
+
size,
|
|
97
|
+
icon = "\u{1F4C4}",
|
|
98
|
+
action,
|
|
99
|
+
theme,
|
|
100
|
+
className
|
|
101
|
+
}) {
|
|
102
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
103
|
+
const scope = useScope(theme);
|
|
104
|
+
return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-fileprev", className), children: [
|
|
105
|
+
/* @__PURE__ */ jsx("span", { className: "mang-fileprev-icon", "aria-hidden": "true", children: icon }),
|
|
106
|
+
/* @__PURE__ */ jsxs("div", { className: "mang-fileprev-main", children: [
|
|
107
|
+
/* @__PURE__ */ jsx("div", { className: "mang-fileprev-name", children: name }),
|
|
108
|
+
size != null && /* @__PURE__ */ jsxs("div", { className: "mang-fileprev-meta", children: [
|
|
109
|
+
(size / 1024).toFixed(0),
|
|
110
|
+
" KB"
|
|
111
|
+
] })
|
|
112
|
+
] }),
|
|
113
|
+
action
|
|
114
|
+
] });
|
|
115
|
+
}
|
|
116
|
+
function ImagePreview({
|
|
117
|
+
src,
|
|
118
|
+
alt,
|
|
119
|
+
maxHeight = "16rem",
|
|
120
|
+
theme,
|
|
121
|
+
className
|
|
122
|
+
}) {
|
|
123
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
124
|
+
const scope = useScope(theme);
|
|
125
|
+
return /* @__PURE__ */ jsx(
|
|
126
|
+
"img",
|
|
127
|
+
{
|
|
128
|
+
...scope,
|
|
129
|
+
className: cx(scope.className, "mang-imgprev", className),
|
|
130
|
+
src,
|
|
131
|
+
alt,
|
|
132
|
+
style: { maxHeight }
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
function Avatar({ src, name, size = 36, theme, className }) {
|
|
137
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
138
|
+
const scope = useScope(theme);
|
|
139
|
+
const initials = (name ?? "?").trim().slice(0, 1).toUpperCase();
|
|
140
|
+
return /* @__PURE__ */ jsx(
|
|
141
|
+
"span",
|
|
142
|
+
{
|
|
143
|
+
...scope,
|
|
144
|
+
className: cx(scope.className, "mang-avatar", className),
|
|
145
|
+
style: { width: size, height: size, fontSize: size * 0.42 },
|
|
146
|
+
"aria-label": name,
|
|
147
|
+
children: src ? /* @__PURE__ */ jsx("img", { src, alt: name ?? "" }) : initials
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
function AvatarGroup({ people, max = 4, size = 32, theme, className }) {
|
|
152
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
153
|
+
const scope = useScope(theme);
|
|
154
|
+
const shown = people.slice(0, max);
|
|
155
|
+
const extra = people.length - shown.length;
|
|
156
|
+
return /* @__PURE__ */ jsxs("span", { ...scope, className: cx(scope.className, "mang-avatargroup", className), children: [
|
|
157
|
+
shown.map((p, i) => /* @__PURE__ */ jsx(
|
|
158
|
+
Avatar,
|
|
159
|
+
{
|
|
160
|
+
src: p.src,
|
|
161
|
+
name: p.name,
|
|
162
|
+
size,
|
|
163
|
+
theme
|
|
164
|
+
},
|
|
165
|
+
i
|
|
166
|
+
)),
|
|
167
|
+
extra > 0 && /* @__PURE__ */ jsxs(
|
|
168
|
+
"span",
|
|
169
|
+
{
|
|
170
|
+
className: "mang-avatar",
|
|
171
|
+
style: { width: size, height: size, fontSize: size * 0.36, background: color.bamboo },
|
|
172
|
+
children: [
|
|
173
|
+
"+",
|
|
174
|
+
extra
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
)
|
|
178
|
+
] });
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export {
|
|
182
|
+
Dropzone,
|
|
183
|
+
FilePreview,
|
|
184
|
+
ImagePreview,
|
|
185
|
+
Avatar,
|
|
186
|
+
AvatarGroup
|
|
187
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cx,
|
|
3
|
+
useKitStyles,
|
|
4
|
+
useScope
|
|
5
|
+
} from "./chunk-3AL4SUFD.js";
|
|
6
|
+
|
|
7
|
+
// src/navigation/Tabs.tsx
|
|
8
|
+
import {
|
|
9
|
+
createContext,
|
|
10
|
+
useContext,
|
|
11
|
+
useId,
|
|
12
|
+
useState
|
|
13
|
+
} from "react";
|
|
14
|
+
import { jsx } from "react/jsx-runtime";
|
|
15
|
+
var Ctx = createContext(null);
|
|
16
|
+
var useTabs = () => {
|
|
17
|
+
const c = useContext(Ctx);
|
|
18
|
+
if (!c) throw new Error("Tabs subcomponents must be used inside <Tabs>");
|
|
19
|
+
return c;
|
|
20
|
+
};
|
|
21
|
+
function Tabs({
|
|
22
|
+
value,
|
|
23
|
+
defaultValue,
|
|
24
|
+
onValueChange,
|
|
25
|
+
theme,
|
|
26
|
+
className,
|
|
27
|
+
children
|
|
28
|
+
}) {
|
|
29
|
+
useKitStyles();
|
|
30
|
+
const scope = useScope(theme);
|
|
31
|
+
const baseId = useId();
|
|
32
|
+
const [internal, setInternal] = useState(defaultValue ?? "");
|
|
33
|
+
const active = value ?? internal;
|
|
34
|
+
const setValue = (v) => {
|
|
35
|
+
if (value === void 0) setInternal(v);
|
|
36
|
+
onValueChange?.(v);
|
|
37
|
+
};
|
|
38
|
+
return /* @__PURE__ */ jsx(Ctx.Provider, { value: { value: active, setValue, baseId }, children: /* @__PURE__ */ jsx("div", { ...scope, className: cx(scope.className, className), children }) });
|
|
39
|
+
}
|
|
40
|
+
function TabList({ label, className, children }) {
|
|
41
|
+
const onKeyDown = (e) => {
|
|
42
|
+
const tabs = Array.from(
|
|
43
|
+
e.currentTarget.querySelectorAll('[role="tab"]:not(:disabled)')
|
|
44
|
+
);
|
|
45
|
+
const i = tabs.indexOf(document.activeElement);
|
|
46
|
+
if (i < 0) return;
|
|
47
|
+
let next = -1;
|
|
48
|
+
if (e.key === "ArrowRight") next = (i + 1) % tabs.length;
|
|
49
|
+
else if (e.key === "ArrowLeft") next = (i - 1 + tabs.length) % tabs.length;
|
|
50
|
+
else if (e.key === "Home") next = 0;
|
|
51
|
+
else if (e.key === "End") next = tabs.length - 1;
|
|
52
|
+
if (next >= 0) {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
tabs[next]?.focus();
|
|
55
|
+
tabs[next]?.click();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
return /* @__PURE__ */ jsx(
|
|
59
|
+
"div",
|
|
60
|
+
{
|
|
61
|
+
role: "tablist",
|
|
62
|
+
"aria-label": label,
|
|
63
|
+
className: cx("mang-tablist", className),
|
|
64
|
+
onKeyDown,
|
|
65
|
+
children
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
function Tab({ value, disabled, className, children }) {
|
|
70
|
+
const { value: active, setValue, baseId } = useTabs();
|
|
71
|
+
const selected = active === value;
|
|
72
|
+
return /* @__PURE__ */ jsx(
|
|
73
|
+
"button",
|
|
74
|
+
{
|
|
75
|
+
type: "button",
|
|
76
|
+
role: "tab",
|
|
77
|
+
id: `${baseId}-tab-${value}`,
|
|
78
|
+
"aria-selected": selected,
|
|
79
|
+
"aria-controls": `${baseId}-panel-${value}`,
|
|
80
|
+
tabIndex: selected ? 0 : -1,
|
|
81
|
+
disabled,
|
|
82
|
+
className: cx("mang-tab", className),
|
|
83
|
+
onClick: () => setValue(value),
|
|
84
|
+
children
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function TabPanel({ value, className, children }) {
|
|
89
|
+
const { value: active, baseId } = useTabs();
|
|
90
|
+
if (active !== value) return null;
|
|
91
|
+
return /* @__PURE__ */ jsx(
|
|
92
|
+
"div",
|
|
93
|
+
{
|
|
94
|
+
role: "tabpanel",
|
|
95
|
+
id: `${baseId}-panel-${value}`,
|
|
96
|
+
"aria-labelledby": `${baseId}-tab-${value}`,
|
|
97
|
+
className: cx("mang-tabpanel", className),
|
|
98
|
+
children
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export {
|
|
104
|
+
Tabs,
|
|
105
|
+
TabList,
|
|
106
|
+
Tab,
|
|
107
|
+
TabPanel
|
|
108
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import {
|
|
2
|
+
VndText
|
|
3
|
+
} from "./chunk-IX3DYETF.js";
|
|
4
|
+
import {
|
|
5
|
+
Badge
|
|
6
|
+
} from "./chunk-FZRXVRC7.js";
|
|
7
|
+
import {
|
|
8
|
+
Button
|
|
9
|
+
} from "./chunk-YN5O6YL6.js";
|
|
10
|
+
import {
|
|
11
|
+
cx,
|
|
12
|
+
useAreaStyles,
|
|
13
|
+
useScope
|
|
14
|
+
} from "./chunk-3AL4SUFD.js";
|
|
15
|
+
import {
|
|
16
|
+
tokens
|
|
17
|
+
} from "./chunk-PPOYMKV3.js";
|
|
18
|
+
|
|
19
|
+
// src/money/MoneyKit.tsx
|
|
20
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21
|
+
var STYLE_ID = "mang-ui-money";
|
|
22
|
+
var { fontSize, fontWeight, radius, font } = tokens;
|
|
23
|
+
var CSS = (
|
|
24
|
+
/* css */
|
|
25
|
+
`
|
|
26
|
+
.mang-amount { display: grid; gap: 0.15rem; }
|
|
27
|
+
.mang-amount-label { font-size: ${fontSize.xs}; color: var(--m-text-muted); font-weight: ${fontWeight.semibold}; text-transform: uppercase; letter-spacing: 0.07em; }
|
|
28
|
+
.mang-amount-value { font-family: "${font.heading}", system-ui, sans-serif; font-weight: ${fontWeight.bold}; font-size: ${fontSize["3xl"]}; color: var(--m-text-strong); font-variant-numeric: tabular-nums; line-height: 1.05; }
|
|
29
|
+
.mang-explist { display: grid; gap: 0.4rem; }
|
|
30
|
+
.mang-exprow { display: flex; align-items: center; gap: 0.6rem; padding: 0.6rem 0.75rem; border: 1px solid var(--m-line); border-radius: ${radius.md}; background: var(--m-surface); }
|
|
31
|
+
.mang-exprow-main { flex: 1; min-width: 0; }
|
|
32
|
+
.mang-exprow-note { font-weight: ${fontWeight.semibold}; color: var(--m-text-strong); font-size: ${fontSize.sm}; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
33
|
+
.mang-exprow-meta { font-size: ${fontSize.xs}; color: var(--m-text-muted); }
|
|
34
|
+
.mang-settle { display: grid; gap: 0.7rem; padding: 0.9rem 1rem; border: 1px solid var(--m-line); border-radius: ${radius.lg}; background: var(--m-surface); }
|
|
35
|
+
.mang-settle-line { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
|
|
36
|
+
.mang-settle-who { font-size: ${fontSize.sm}; color: var(--m-text); }
|
|
37
|
+
.mang-settle-who b { color: var(--m-text-strong); }
|
|
38
|
+
.mang-settle-qr { justify-self: center; padding: 0.5rem; background: #fff; border-radius: ${radius.md}; line-height: 0; }
|
|
39
|
+
`
|
|
40
|
+
);
|
|
41
|
+
function AmountSummary({
|
|
42
|
+
label,
|
|
43
|
+
amount,
|
|
44
|
+
sign = "none",
|
|
45
|
+
theme,
|
|
46
|
+
className
|
|
47
|
+
}) {
|
|
48
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
49
|
+
const scope = useScope(theme);
|
|
50
|
+
return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-amount", className), children: [
|
|
51
|
+
/* @__PURE__ */ jsx("span", { className: "mang-amount-label", children: label }),
|
|
52
|
+
/* @__PURE__ */ jsx("span", { className: "mang-amount-value", children: /* @__PURE__ */ jsx(VndText, { amount, sign, theme }) })
|
|
53
|
+
] });
|
|
54
|
+
}
|
|
55
|
+
function ExpenseRow({ note, meta, amount, action, theme, className }) {
|
|
56
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
57
|
+
const scope = useScope(theme);
|
|
58
|
+
return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-exprow", className), children: [
|
|
59
|
+
/* @__PURE__ */ jsxs("div", { className: "mang-exprow-main", children: [
|
|
60
|
+
/* @__PURE__ */ jsx("div", { className: "mang-exprow-note", children: note }),
|
|
61
|
+
meta != null && /* @__PURE__ */ jsx("div", { className: "mang-exprow-meta", children: meta })
|
|
62
|
+
] }),
|
|
63
|
+
/* @__PURE__ */ jsx(VndText, { amount, theme }),
|
|
64
|
+
action
|
|
65
|
+
] });
|
|
66
|
+
}
|
|
67
|
+
function ExpenseList({ children, theme, className }) {
|
|
68
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
69
|
+
const scope = useScope(theme);
|
|
70
|
+
return /* @__PURE__ */ jsx("div", { ...scope, className: cx(scope.className, "mang-explist", className), children });
|
|
71
|
+
}
|
|
72
|
+
function PaidBadge({ locale = "vi", theme, className }) {
|
|
73
|
+
return /* @__PURE__ */ jsx(Badge, { tone: "success", icon: "\u2713", theme, className, children: locale === "vi" ? "\u0110\xE3 tr\u1EA3" : "Paid" });
|
|
74
|
+
}
|
|
75
|
+
function UnpaidBadge({ locale = "vi", theme, className }) {
|
|
76
|
+
return /* @__PURE__ */ jsx(Badge, { tone: "neutral", theme, className, children: locale === "vi" ? "Ch\u01B0a tr\u1EA3" : "Unpaid" });
|
|
77
|
+
}
|
|
78
|
+
function SettlementCard({
|
|
79
|
+
from,
|
|
80
|
+
to,
|
|
81
|
+
amount,
|
|
82
|
+
qr,
|
|
83
|
+
paid,
|
|
84
|
+
onMarkPaid,
|
|
85
|
+
locale = "vi",
|
|
86
|
+
theme,
|
|
87
|
+
className
|
|
88
|
+
}) {
|
|
89
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
90
|
+
const scope = useScope(theme);
|
|
91
|
+
return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-settle", className), children: [
|
|
92
|
+
/* @__PURE__ */ jsxs("div", { className: "mang-settle-line", children: [
|
|
93
|
+
/* @__PURE__ */ jsxs("span", { className: "mang-settle-who", children: [
|
|
94
|
+
/* @__PURE__ */ jsx("b", { children: from }),
|
|
95
|
+
" \u2192 ",
|
|
96
|
+
/* @__PURE__ */ jsx("b", { children: to })
|
|
97
|
+
] }),
|
|
98
|
+
paid ? /* @__PURE__ */ jsx(PaidBadge, { locale, theme }) : /* @__PURE__ */ jsx(VndText, { amount, theme })
|
|
99
|
+
] }),
|
|
100
|
+
qr != null && !paid && /* @__PURE__ */ jsx("div", { className: "mang-settle-qr", children: qr }),
|
|
101
|
+
onMarkPaid && !paid && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "secondary", theme, onClick: onMarkPaid, children: locale === "vi" ? "\u0110\xE1nh d\u1EA5u \u0111\xE3 tr\u1EA3" : "Mark as paid" })
|
|
102
|
+
] });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export {
|
|
106
|
+
AmountSummary,
|
|
107
|
+
ExpenseRow,
|
|
108
|
+
ExpenseList,
|
|
109
|
+
PaidBadge,
|
|
110
|
+
UnpaidBadge,
|
|
111
|
+
SettlementCard
|
|
112
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cx,
|
|
3
|
+
useKitStyles,
|
|
4
|
+
useScope
|
|
5
|
+
} from "./chunk-3AL4SUFD.js";
|
|
6
|
+
|
|
7
|
+
// src/feedback/Feedback.tsx
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
function EmptyState({
|
|
10
|
+
icon,
|
|
11
|
+
title,
|
|
12
|
+
description,
|
|
13
|
+
action,
|
|
14
|
+
theme,
|
|
15
|
+
className
|
|
16
|
+
}) {
|
|
17
|
+
useKitStyles();
|
|
18
|
+
const scope = useScope(theme);
|
|
19
|
+
return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-empty", className), children: [
|
|
20
|
+
icon != null && /* @__PURE__ */ jsx("div", { className: "mang-empty-icon", "aria-hidden": "true", children: icon }),
|
|
21
|
+
title != null && /* @__PURE__ */ jsx("div", { className: "mang-empty-title", children: title }),
|
|
22
|
+
description != null && /* @__PURE__ */ jsx("div", { children: description }),
|
|
23
|
+
action
|
|
24
|
+
] });
|
|
25
|
+
}
|
|
26
|
+
function ErrorState({
|
|
27
|
+
icon = "\u26A0\uFE0F",
|
|
28
|
+
title,
|
|
29
|
+
description,
|
|
30
|
+
action,
|
|
31
|
+
theme,
|
|
32
|
+
className
|
|
33
|
+
}) {
|
|
34
|
+
useKitStyles();
|
|
35
|
+
const scope = useScope(theme);
|
|
36
|
+
return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-error-state", className), role: "alert", children: [
|
|
37
|
+
icon != null && /* @__PURE__ */ jsx("div", { className: "mang-empty-icon", "aria-hidden": "true", children: icon }),
|
|
38
|
+
title != null && /* @__PURE__ */ jsx("div", { className: "mang-empty-title", children: title }),
|
|
39
|
+
description != null && /* @__PURE__ */ jsx("div", { children: description }),
|
|
40
|
+
action
|
|
41
|
+
] });
|
|
42
|
+
}
|
|
43
|
+
function Skeleton({
|
|
44
|
+
width,
|
|
45
|
+
height = "1rem",
|
|
46
|
+
rounded,
|
|
47
|
+
theme,
|
|
48
|
+
className,
|
|
49
|
+
style
|
|
50
|
+
}) {
|
|
51
|
+
useKitStyles();
|
|
52
|
+
const scope = useScope(theme);
|
|
53
|
+
return /* @__PURE__ */ jsx(
|
|
54
|
+
"span",
|
|
55
|
+
{
|
|
56
|
+
...scope,
|
|
57
|
+
className: cx(scope.className, "mang-skeleton", className),
|
|
58
|
+
style: { width, height, borderRadius: rounded ? "999px" : void 0, ...style },
|
|
59
|
+
"aria-hidden": "true"
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function Spinner({ size, label = "\u0110ang t\u1EA3i\u2026", theme, className }) {
|
|
64
|
+
useKitStyles();
|
|
65
|
+
const scope = useScope(theme);
|
|
66
|
+
return /* @__PURE__ */ jsx(
|
|
67
|
+
"span",
|
|
68
|
+
{
|
|
69
|
+
...scope,
|
|
70
|
+
className: cx(scope.className, "mang-spinner", className),
|
|
71
|
+
style: size != null ? { width: size, height: size } : void 0,
|
|
72
|
+
role: "status",
|
|
73
|
+
"aria-label": label
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
function Progress({ value, theme, className, label }) {
|
|
78
|
+
useKitStyles();
|
|
79
|
+
const scope = useScope(theme);
|
|
80
|
+
const indeterminate = value == null;
|
|
81
|
+
const pct = indeterminate ? void 0 : Math.max(0, Math.min(100, value));
|
|
82
|
+
const bar = {
|
|
83
|
+
role: "progressbar",
|
|
84
|
+
"aria-label": label,
|
|
85
|
+
"aria-valuenow": pct,
|
|
86
|
+
"aria-valuemin": indeterminate ? void 0 : 0,
|
|
87
|
+
"aria-valuemax": indeterminate ? void 0 : 100
|
|
88
|
+
};
|
|
89
|
+
return /* @__PURE__ */ jsx(
|
|
90
|
+
"div",
|
|
91
|
+
{
|
|
92
|
+
...scope,
|
|
93
|
+
...bar,
|
|
94
|
+
className: cx(scope.className, "mang-progress", className),
|
|
95
|
+
"data-indeterminate": indeterminate ? "true" : void 0,
|
|
96
|
+
children: /* @__PURE__ */ jsx("div", { className: "mang-progress-bar", style: { width: indeterminate ? void 0 : `${pct}%` } })
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export {
|
|
102
|
+
EmptyState,
|
|
103
|
+
ErrorState,
|
|
104
|
+
Skeleton,
|
|
105
|
+
Spinner,
|
|
106
|
+
Progress
|
|
107
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Switch
|
|
3
|
+
} from "./chunk-PQGUWJG4.js";
|
|
4
|
+
import {
|
|
5
|
+
cx,
|
|
6
|
+
useAreaStyles,
|
|
7
|
+
useScope
|
|
8
|
+
} from "./chunk-3AL4SUFD.js";
|
|
9
|
+
import {
|
|
10
|
+
tokens
|
|
11
|
+
} from "./chunk-PPOYMKV3.js";
|
|
12
|
+
|
|
13
|
+
// src/settings/Settings.tsx
|
|
14
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
var STYLE_ID = "mang-ui-settings";
|
|
16
|
+
var { fontSize, fontWeight, radius, font } = tokens;
|
|
17
|
+
var CSS = (
|
|
18
|
+
/* css */
|
|
19
|
+
`
|
|
20
|
+
.mang-set-section { display: grid; gap: 0.1rem; border: 1px solid var(--m-line); border-radius: ${radius.lg}; background: var(--m-surface); overflow: clip; }
|
|
21
|
+
.mang-set-section-title { font-family: "${font.heading}", system-ui, sans-serif; font-weight: ${fontWeight.semibold}; font-size: ${fontSize.sm}; color: var(--m-text-muted); padding: 0.7rem 1rem 0.3rem; text-transform: uppercase; letter-spacing: 0.06em; }
|
|
22
|
+
.mang-set-row { display: flex; align-items: center; gap: 0.75rem; padding: 0.8rem 1rem; border-top: 1px solid var(--m-line); }
|
|
23
|
+
.mang-set-row:first-of-type { border-top: none; }
|
|
24
|
+
.mang-set-row-main { flex: 1; min-width: 0; }
|
|
25
|
+
.mang-set-row-label { font-weight: ${fontWeight.semibold}; font-size: ${fontSize.sm}; color: var(--m-text-strong); }
|
|
26
|
+
.mang-set-row-desc { font-size: ${fontSize.xs}; color: var(--m-text-muted); }
|
|
27
|
+
`
|
|
28
|
+
);
|
|
29
|
+
function SettingsSection({
|
|
30
|
+
title,
|
|
31
|
+
theme,
|
|
32
|
+
className,
|
|
33
|
+
children
|
|
34
|
+
}) {
|
|
35
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
36
|
+
const scope = useScope(theme);
|
|
37
|
+
return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-set-section", className), children: [
|
|
38
|
+
title != null && /* @__PURE__ */ jsx("div", { className: "mang-set-section-title", children: title }),
|
|
39
|
+
children
|
|
40
|
+
] });
|
|
41
|
+
}
|
|
42
|
+
function SettingsRow({ label, description, control, theme, className }) {
|
|
43
|
+
useAreaStyles(STYLE_ID, CSS);
|
|
44
|
+
const scope = useScope(theme);
|
|
45
|
+
return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-set-row", className), children: [
|
|
46
|
+
/* @__PURE__ */ jsxs("div", { className: "mang-set-row-main", children: [
|
|
47
|
+
/* @__PURE__ */ jsx("div", { className: "mang-set-row-label", children: label }),
|
|
48
|
+
description != null && /* @__PURE__ */ jsx("div", { className: "mang-set-row-desc", children: description })
|
|
49
|
+
] }),
|
|
50
|
+
control
|
|
51
|
+
] });
|
|
52
|
+
}
|
|
53
|
+
function SettingsToggle({
|
|
54
|
+
label,
|
|
55
|
+
description,
|
|
56
|
+
checked,
|
|
57
|
+
onChange,
|
|
58
|
+
theme,
|
|
59
|
+
className
|
|
60
|
+
}) {
|
|
61
|
+
return /* @__PURE__ */ jsx(
|
|
62
|
+
SettingsRow,
|
|
63
|
+
{
|
|
64
|
+
theme,
|
|
65
|
+
className,
|
|
66
|
+
label,
|
|
67
|
+
description,
|
|
68
|
+
control: /* @__PURE__ */ jsx(Switch, { theme, checked, onChange: (e) => onChange(e.target.checked) })
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export {
|
|
74
|
+
SettingsSection,
|
|
75
|
+
SettingsRow,
|
|
76
|
+
SettingsToggle
|
|
77
|
+
};
|