@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.
Files changed (95) hide show
  1. package/LICENSE +26 -0
  2. package/dist/MangThemeProvider-BqdGKBP2.d.ts +34 -0
  3. package/dist/Money-Dw3GnUvX.d.ts +27 -0
  4. package/dist/actions.d.ts +31 -0
  5. package/dist/actions.js +13 -0
  6. package/dist/ai.d.ts +58 -0
  7. package/dist/ai.js +13 -0
  8. package/dist/analytics.d.ts +40 -0
  9. package/dist/analytics.js +15 -0
  10. package/dist/app.d.ts +24 -0
  11. package/dist/app.js +9 -0
  12. package/dist/catalog.d.ts +76 -0
  13. package/dist/catalog.js +1210 -0
  14. package/dist/charts.d.ts +89 -0
  15. package/dist/charts.js +34 -0
  16. package/dist/chunk-3AL4SUFD.js +301 -0
  17. package/dist/chunk-4XNSYKQE.js +142 -0
  18. package/dist/chunk-5Z4VLQKH.js +43 -0
  19. package/dist/chunk-7P2EQZYD.js +59 -0
  20. package/dist/chunk-7WHNIEDV.js +120 -0
  21. package/dist/chunk-ASZKHSMG.js +82 -0
  22. package/dist/chunk-BCBN2EGH.js +216 -0
  23. package/dist/chunk-BLYAFV45.js +320 -0
  24. package/dist/chunk-DLKEXWPA.js +90 -0
  25. package/dist/chunk-DTASXPTB.js +70 -0
  26. package/dist/chunk-FZRXVRC7.js +63 -0
  27. package/dist/chunk-ID233AGM.js +108 -0
  28. package/dist/chunk-IVYXOKMO.js +74 -0
  29. package/dist/chunk-IX3DYETF.js +61 -0
  30. package/dist/chunk-JJB4PJC3.js +166 -0
  31. package/dist/chunk-K5Q3RCV6.js +119 -0
  32. package/dist/chunk-LNRUPJDF.js +161 -0
  33. package/dist/chunk-LZORNMBL.js +0 -0
  34. package/dist/chunk-OBPXCUVF.js +282 -0
  35. package/dist/chunk-OJX2EIMB.js +145 -0
  36. package/dist/chunk-PPOYMKV3.js +170 -0
  37. package/dist/chunk-PQGUWJG4.js +47 -0
  38. package/dist/chunk-RE7OWRA4.js +187 -0
  39. package/dist/chunk-SJF3CHAW.js +108 -0
  40. package/dist/chunk-UF6ANDJZ.js +112 -0
  41. package/dist/chunk-VGC5DMOM.js +107 -0
  42. package/dist/chunk-VP56Z4BS.js +0 -0
  43. package/dist/chunk-VRD66FIA.js +77 -0
  44. package/dist/chunk-X7T2DJLU.js +113 -0
  45. package/dist/chunk-XPV3OOLU.js +147 -0
  46. package/dist/chunk-YN5O6YL6.js +69 -0
  47. package/dist/chunk-Z4ANGBPC.js +94 -0
  48. package/dist/creator.d.ts +55 -0
  49. package/dist/creator.js +20 -0
  50. package/dist/data-room.d.ts +50 -0
  51. package/dist/data-room.js +17 -0
  52. package/dist/editor.d.ts +32 -0
  53. package/dist/editor.js +14 -0
  54. package/dist/feedback.d.ts +48 -0
  55. package/dist/feedback.js +16 -0
  56. package/dist/forms.d.ts +91 -0
  57. package/dist/forms.js +26 -0
  58. package/dist/handoff.d.ts +37 -0
  59. package/dist/handoff.js +13 -0
  60. package/dist/index.css +2 -0
  61. package/dist/index.d.ts +62 -0
  62. package/dist/index.js +338 -0
  63. package/dist/layout.d.ts +57 -0
  64. package/dist/layout.js +22 -0
  65. package/dist/learning.d.ts +46 -0
  66. package/dist/learning.js +15 -0
  67. package/dist/media.d.ts +48 -0
  68. package/dist/media.js +16 -0
  69. package/dist/monetization.d.ts +30 -0
  70. package/dist/monetization.js +14 -0
  71. package/dist/money.d.ts +45 -0
  72. package/dist/money.js +28 -0
  73. package/dist/navigation.d.ts +36 -0
  74. package/dist/navigation.js +14 -0
  75. package/dist/overlay.d.ts +72 -0
  76. package/dist/overlay.js +20 -0
  77. package/dist/platform.d.ts +94 -0
  78. package/dist/platform.js +42 -0
  79. package/dist/primitives.d.ts +83 -0
  80. package/dist/primitives.js +22 -0
  81. package/dist/privacy.d.ts +28 -0
  82. package/dist/privacy.js +15 -0
  83. package/dist/sandbox.d.ts +40 -0
  84. package/dist/sandbox.js +15 -0
  85. package/dist/settings.d.ts +29 -0
  86. package/dist/settings.js +13 -0
  87. package/dist/surface.d.ts +33 -0
  88. package/dist/surface.js +16 -0
  89. package/dist/theme.css +63 -0
  90. package/dist/theme.d.ts +64 -0
  91. package/dist/theme.js +27 -0
  92. package/dist/tokens.css +119 -0
  93. package/dist/tokens.d.ts +128 -0
  94. package/dist/tokens.js +8 -0
  95. package/package.json +151 -0
@@ -0,0 +1,113 @@
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/sandbox/Sandbox.tsx
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ var STYLE_ID = "mang-ui-sandbox";
13
+ var { fontSize, fontWeight, radius, font } = tokens;
14
+ var CSS = (
15
+ /* css */
16
+ `
17
+ .mang-sbx { display: flex; flex-direction: column; border: 1px solid var(--m-line); border-radius: ${radius.lg}; overflow: clip; background: var(--m-surface); }
18
+ .mang-sbx-bar { display: flex; align-items: center; gap: 0.5rem; padding: 0.45rem 0.7rem; background: var(--m-sunken); border-bottom: 1px solid var(--m-line); font-size: ${fontSize.xs}; color: var(--m-text-muted); }
19
+ .mang-sbx-origin { font-family: ui-monospace, monospace; }
20
+ .mang-sbx-body { min-height: 8rem; }
21
+ .mang-sbx-error { display: grid; gap: 0.4rem; justify-items: center; text-align: center; padding: 1.5rem; color: var(--m-danger-on); }
22
+ .mang-scan-badge { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.18rem 0.55rem; border-radius: ${radius.full}; font-family: "${font.heading}", system-ui, sans-serif; font-weight: ${fontWeight.semibold}; font-size: ${fontSize.xs}; }
23
+ .mang-scan-badge[data-level="safe"] { background: var(--m-success-soft); color: var(--m-success-on); }
24
+ .mang-scan-badge[data-level="review"] { background: var(--m-warning-soft); color: var(--m-warning-on); }
25
+ .mang-scan-badge[data-level="blocked"] { background: var(--m-danger-soft); color: var(--m-danger-on); }
26
+ .mang-scan-list { display: grid; gap: 0.4rem; margin: 0; padding: 0; list-style: none; }
27
+ .mang-scan-item { display: flex; gap: 0.5rem; padding: 0.5rem 0.65rem; border: 1px solid var(--m-line); border-radius: ${radius.md}; font-size: ${fontSize.sm}; background: var(--m-sunken); }
28
+ .mang-scan-item[data-sev="error"] { border-left: 3px solid var(--m-danger); }
29
+ .mang-scan-item[data-sev="warn"] { border-left: 3px solid var(--m-warning); }
30
+ `
31
+ );
32
+ function SafetyScanBadge({ level, locale = "vi", theme, className }) {
33
+ useAreaStyles(STYLE_ID, CSS);
34
+ const scope = useScope(theme);
35
+ const label = {
36
+ safe: { vi: "An to\xE0n", en: "Safe" },
37
+ review: { vi: "C\u1EA7n xem", en: "Review" },
38
+ blocked: { vi: "Ch\u1EB7n", en: "Blocked" }
39
+ }[level][locale];
40
+ const icon = { safe: "\u{1F6E1}\uFE0F", review: "\u26A0\uFE0F", blocked: "\u26D4" }[level];
41
+ return /* @__PURE__ */ jsxs(
42
+ "span",
43
+ {
44
+ ...scope,
45
+ className: cx(scope.className, "mang-scan-badge", className),
46
+ "data-level": level,
47
+ children: [
48
+ icon,
49
+ " ",
50
+ label
51
+ ]
52
+ }
53
+ );
54
+ }
55
+ function SandboxFrame({ children, origin, source, theme, className }) {
56
+ useAreaStyles(STYLE_ID, CSS);
57
+ const scope = useScope(theme);
58
+ return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-sbx", className), children: [
59
+ /* @__PURE__ */ jsxs("div", { className: "mang-sbx-bar", children: [
60
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u{1F9EA}" }),
61
+ source,
62
+ origin && /* @__PURE__ */ jsx("span", { className: "mang-sbx-origin", children: origin })
63
+ ] }),
64
+ /* @__PURE__ */ jsx("div", { className: "mang-sbx-body", children })
65
+ ] });
66
+ }
67
+ function SandboxError({ message, theme, className }) {
68
+ useAreaStyles(STYLE_ID, CSS);
69
+ const scope = useScope(theme);
70
+ return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-sbx-error", className), role: "alert", children: [
71
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { fontSize: "1.6rem" }, children: "\u26D4" }),
72
+ /* @__PURE__ */ jsx("span", { children: message ?? "Kh\xF4ng t\u1EA3i \u0111\u01B0\u1EE3c app trong h\u1ED9p c\xE1t." })
73
+ ] });
74
+ }
75
+ function StaticScanResult({
76
+ findings,
77
+ emptyLabel,
78
+ theme,
79
+ className
80
+ }) {
81
+ useAreaStyles(STYLE_ID, CSS);
82
+ const scope = useScope(theme);
83
+ if (findings.length === 0) {
84
+ return /* @__PURE__ */ jsx(
85
+ "div",
86
+ {
87
+ ...scope,
88
+ className: cx(scope.className, className),
89
+ style: { fontSize: tokens.fontSize.sm, color: "var(--m-text-muted)" },
90
+ children: emptyLabel ?? "Kh\xF4ng c\xF3 c\u1EA3nh b\xE1o."
91
+ }
92
+ );
93
+ }
94
+ return /* @__PURE__ */ jsx("ul", { ...scope, className: cx(scope.className, "mang-scan-list", className), children: findings.map((f, i) => /* @__PURE__ */ jsxs(
95
+ "li",
96
+ {
97
+ className: "mang-scan-item",
98
+ "data-sev": f.severity,
99
+ children: [
100
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: f.severity === "error" ? "\u26D4" : f.severity === "warn" ? "\u26A0\uFE0F" : "\u2139\uFE0F" }),
101
+ /* @__PURE__ */ jsx("span", { children: f.message })
102
+ ]
103
+ },
104
+ i
105
+ )) });
106
+ }
107
+
108
+ export {
109
+ SafetyScanBadge,
110
+ SandboxFrame,
111
+ SandboxError,
112
+ StaticScanResult
113
+ };
@@ -0,0 +1,147 @@
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/layout/Layout.tsx
11
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
+ var STYLE_ID = "mang-ui-layout";
13
+ var { fontSize, fontWeight, font, space } = tokens;
14
+ var CSS = (
15
+ /* css */
16
+ `
17
+ .mang-page { width: 100%; max-width: 68rem; margin: 0 auto; padding: clamp(1rem, 3vw, 2rem); }
18
+ .mang-container { width: 100%; max-width: 52rem; margin: 0 auto; }
19
+ .mang-container[data-width="reading"] { max-width: 42rem; }
20
+ .mang-pagehead { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 1rem; }
21
+ .mang-pagehead-titles { display: grid; gap: 0.2rem; }
22
+ .mang-pagehead-eyebrow { font-size: ${fontSize.xs}; font-weight: ${fontWeight.bold}; text-transform: uppercase; letter-spacing: 0.14em; color: var(--m-accent); }
23
+ .mang-pagehead-title { font-family: "${font.heading}", system-ui, sans-serif; font-weight: ${fontWeight.bold}; font-size: ${fontSize["2xl"]}; color: var(--m-text-strong); margin: 0; }
24
+ .mang-pagehead-actions { display: flex; gap: 0.5rem; align-items: center; }
25
+ .mang-sectionhead { font-family: "${font.heading}", system-ui, sans-serif; font-weight: ${fontWeight.semibold}; font-size: ${fontSize.lg}; color: var(--m-text-strong); margin: 0 0 0.5rem; }
26
+ .mang-bottombar { position: sticky; bottom: 0; display: flex; gap: 0.5rem; align-items: center; justify-content: flex-end; padding: 0.7rem clamp(1rem, 3vw, 2rem); background: var(--m-surface); border-top: 1px solid var(--m-line); box-shadow: 0 -8px 24px -18px rgba(0,0,0,0.3); }
27
+ .mang-listrow { display: flex; align-items: center; gap: 0.75rem; width: 100%; box-sizing: border-box; padding: 0.7rem 0.85rem; border-radius: ${tokens.radius.md}; background: var(--m-surface); border: 1px solid var(--m-line); text-align: left; color: var(--m-text); }
28
+ .mang-listrow-lead, .mang-listrow-trail { flex: none; display: flex; align-items: center; }
29
+ .mang-listrow-main { flex: 1; min-width: 0; display: grid; gap: 0.1rem; }
30
+ .mang-listrow-title { font-family: "${font.heading}", system-ui, sans-serif; font-weight: ${fontWeight.semibold}; font-size: ${fontSize.base}; color: var(--m-text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
31
+ .mang-listrow-meta { font-size: ${fontSize.sm}; color: var(--m-text-muted); }
32
+ button.mang-listrow { appearance: none; cursor: pointer; font: inherit; transition: border-color 150ms ${"cubic-bezier(0.16,1,0.3,1)"}, transform 150ms ${"cubic-bezier(0.16,1,0.3,1)"}; }
33
+ button.mang-listrow:hover { border-color: var(--m-accent); }
34
+ button.mang-listrow:active { transform: scale(0.995); }
35
+ button.mang-listrow:focus-visible { outline: 3px solid color-mix(in oklab, ${tokens.color.mangGreen} 45%, transparent); outline-offset: 2px; }
36
+ @media (prefers-reduced-motion: reduce) { button.mang-listrow { transition: none; } }
37
+ `
38
+ );
39
+ function AppFrame({ className, style, children }) {
40
+ return /* @__PURE__ */ jsx(
41
+ "div",
42
+ {
43
+ className,
44
+ style: { display: "flex", flexDirection: "column", minHeight: "100dvh", ...style },
45
+ children
46
+ }
47
+ );
48
+ }
49
+ function Page({ theme, className, children }) {
50
+ useAreaStyles(STYLE_ID, CSS);
51
+ const scope = useScope(theme);
52
+ return /* @__PURE__ */ jsx("div", { ...scope, className: cx(scope.className, "mang-page", className), children });
53
+ }
54
+ function Container({ width = "default", theme, className, children }) {
55
+ useAreaStyles(STYLE_ID, CSS);
56
+ const scope = useScope(theme);
57
+ return /* @__PURE__ */ jsx("div", { ...scope, className: cx(scope.className, "mang-container", className), "data-width": width, children });
58
+ }
59
+ function PageHeader({ eyebrow, title, actions, theme, className }) {
60
+ useAreaStyles(STYLE_ID, CSS);
61
+ const scope = useScope(theme);
62
+ return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-pagehead", className), children: [
63
+ /* @__PURE__ */ jsxs("div", { className: "mang-pagehead-titles", children: [
64
+ eyebrow != null && /* @__PURE__ */ jsx("span", { className: "mang-pagehead-eyebrow", children: eyebrow }),
65
+ /* @__PURE__ */ jsx("h1", { className: "mang-pagehead-title", children: title })
66
+ ] }),
67
+ actions != null && /* @__PURE__ */ jsx("div", { className: "mang-pagehead-actions", children: actions })
68
+ ] });
69
+ }
70
+ function Section({ title, theme, className, children }) {
71
+ useAreaStyles(STYLE_ID, CSS);
72
+ const scope = useScope(theme);
73
+ return /* @__PURE__ */ jsxs(
74
+ "section",
75
+ {
76
+ ...scope,
77
+ className: cx(scope.className, className),
78
+ style: { marginBottom: space[6] },
79
+ children: [
80
+ title != null && /* @__PURE__ */ jsx("h2", { className: "mang-sectionhead", children: title }),
81
+ children
82
+ ]
83
+ }
84
+ );
85
+ }
86
+ function BottomActionBar({ theme, className, children }) {
87
+ useAreaStyles(STYLE_ID, CSS);
88
+ const scope = useScope(theme);
89
+ return /* @__PURE__ */ jsx("div", { ...scope, className: cx(scope.className, "mang-bottombar", className), children });
90
+ }
91
+ function ListRow({
92
+ leading,
93
+ title,
94
+ meta,
95
+ trailing,
96
+ onClick,
97
+ theme,
98
+ className
99
+ }) {
100
+ useAreaStyles(STYLE_ID, CSS);
101
+ const scope = useScope(theme);
102
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
103
+ leading != null && /* @__PURE__ */ jsx("span", { className: "mang-listrow-lead", children: leading }),
104
+ /* @__PURE__ */ jsxs("span", { className: "mang-listrow-main", children: [
105
+ /* @__PURE__ */ jsx("span", { className: "mang-listrow-title", children: title }),
106
+ meta != null && /* @__PURE__ */ jsx("span", { className: "mang-listrow-meta", children: meta })
107
+ ] }),
108
+ trailing != null && /* @__PURE__ */ jsx("span", { className: "mang-listrow-trail", children: trailing })
109
+ ] });
110
+ if (onClick) {
111
+ return /* @__PURE__ */ jsx(
112
+ "button",
113
+ {
114
+ ...scope,
115
+ type: "button",
116
+ className: cx(scope.className, "mang-listrow", className),
117
+ onClick,
118
+ children: inner
119
+ }
120
+ );
121
+ }
122
+ return /* @__PURE__ */ jsx("div", { ...scope, className: cx(scope.className, "mang-listrow", className), children: inner });
123
+ }
124
+ function SafeArea({
125
+ edges = ["top", "bottom", "left", "right"],
126
+ className,
127
+ style,
128
+ children
129
+ }) {
130
+ const pad = {};
131
+ if (edges.includes("top")) pad.paddingTop = "env(safe-area-inset-top)";
132
+ if (edges.includes("bottom")) pad.paddingBottom = "env(safe-area-inset-bottom)";
133
+ if (edges.includes("left")) pad.paddingLeft = "env(safe-area-inset-left)";
134
+ if (edges.includes("right")) pad.paddingRight = "env(safe-area-inset-right)";
135
+ return /* @__PURE__ */ jsx("div", { className, style: { ...pad, ...style }, children });
136
+ }
137
+
138
+ export {
139
+ AppFrame,
140
+ Page,
141
+ Container,
142
+ PageHeader,
143
+ Section,
144
+ BottomActionBar,
145
+ ListRow,
146
+ SafeArea
147
+ };
@@ -0,0 +1,69 @@
1
+ import {
2
+ cx,
3
+ useKitStyles,
4
+ useScope
5
+ } from "./chunk-3AL4SUFD.js";
6
+
7
+ // src/actions/Button.tsx
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ function Button({
10
+ variant = "primary",
11
+ size = "md",
12
+ block,
13
+ icon,
14
+ theme,
15
+ className,
16
+ children,
17
+ type,
18
+ ...rest
19
+ }) {
20
+ useKitStyles();
21
+ const scope = useScope(theme);
22
+ return /* @__PURE__ */ jsxs(
23
+ "button",
24
+ {
25
+ ...rest,
26
+ type: type ?? "button",
27
+ className: cx(scope.className, "mang-btn", className),
28
+ "data-theme": scope["data-theme"],
29
+ "data-density": scope["data-density"],
30
+ "data-variant": variant,
31
+ "data-size": size,
32
+ "data-block": block ? "true" : void 0,
33
+ children: [
34
+ icon != null && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { display: "inline-flex" }, children: icon }),
35
+ children
36
+ ]
37
+ }
38
+ );
39
+ }
40
+ function IconButton({
41
+ label,
42
+ size = "md",
43
+ variant = "ghost",
44
+ className,
45
+ children,
46
+ ...rest
47
+ }) {
48
+ return /* @__PURE__ */ jsx(
49
+ Button,
50
+ {
51
+ ...rest,
52
+ variant,
53
+ size,
54
+ "aria-label": label,
55
+ title: rest.title ?? label,
56
+ className: cx("mang-iconbtn", className),
57
+ children
58
+ }
59
+ );
60
+ }
61
+ function ButtonGroup({ className, children }) {
62
+ return /* @__PURE__ */ jsx("div", { className: cx("mang-btn-group", className), children });
63
+ }
64
+
65
+ export {
66
+ Button,
67
+ IconButton,
68
+ ButtonGroup
69
+ };
@@ -0,0 +1,94 @@
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/editor/Editor.tsx
11
+ import { useState } from "react";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
13
+ var STYLE_ID = "mang-ui-editor";
14
+ var { fontSize, fontWeight, radius, font, lineHeight } = tokens;
15
+ var CSS = (
16
+ /* css */
17
+ `
18
+ .mang-prose { color: var(--m-text); line-height: ${lineHeight.relaxed}; font-size: ${fontSize.base}; }
19
+ .mang-prose :where(h1,h2,h3) { font-family: "${font.heading}", system-ui, sans-serif; color: var(--m-text-strong); line-height: ${lineHeight.tight}; margin: 1.2em 0 0.5em; }
20
+ .mang-prose :where(p,ul,ol) { margin: 0.6em 0; }
21
+ .mang-prose :where(a) { color: var(--m-accent); text-underline-offset: 2px; }
22
+ .mang-prose :where(code) { font-family: ui-monospace, monospace; font-size: 0.9em; background: var(--m-sunken); padding: 0.1em 0.35em; border-radius: ${radius.sm}; }
23
+ .mang-prose :where(blockquote) { margin: 0.8em 0; padding-left: 0.9em; border-left: 3px solid var(--m-line-strong); color: var(--m-text-muted); }
24
+ .mang-codeblock { position: relative; }
25
+ .mang-codeblock pre { margin: 0; overflow: auto; padding: 0.85rem 0.95rem; border-radius: ${radius.md}; background: var(--m-sunken); border: 1px solid var(--m-line); }
26
+ .mang-codeblock code { font-family: ui-monospace, monospace; font-size: ${fontSize.sm}; color: var(--m-text); white-space: pre; }
27
+ .mang-codeblock-copy { position: absolute; top: 0.5rem; right: 0.5rem; appearance: none; cursor: pointer; border: 1px solid var(--m-line-strong); background: var(--m-surface); color: var(--m-text); border-radius: ${radius.sm}; padding: 0.2rem 0.5rem; font-size: ${fontSize.xs}; font-weight: ${fontWeight.semibold}; }
28
+ .mang-kbd { font-family: ui-monospace, monospace; font-size: 0.85em; padding: 0.1em 0.45em; border-radius: ${radius.sm}; border: 1px solid var(--m-line-strong); border-bottom-width: 2px; background: var(--m-surface); color: var(--m-text-strong); }
29
+ .mang-callout { display: flex; gap: 0.6rem; padding: 0.75rem 0.9rem; border-radius: ${radius.md}; font-size: ${fontSize.sm}; border: 1px solid var(--m-line); background: var(--m-sunken); color: var(--m-text); }
30
+ .mang-callout[data-tone="tip"] { background: var(--m-success-soft); color: var(--m-success-on); }
31
+ .mang-callout[data-tone="warn"] { background: var(--m-warning-soft); color: var(--m-warning-on); }
32
+ .mang-callout[data-tone="danger"] { background: var(--m-danger-soft); color: var(--m-danger-on); }
33
+ .mang-callout-icon { flex: none; }
34
+ `
35
+ );
36
+ function Prose({ children, theme, className }) {
37
+ useAreaStyles(STYLE_ID, CSS);
38
+ const scope = useScope(theme);
39
+ return /* @__PURE__ */ jsx("div", { ...scope, className: cx(scope.className, "mang-prose", className), children });
40
+ }
41
+ function CodeBlock({
42
+ code,
43
+ copyable = true,
44
+ locale = "vi",
45
+ theme,
46
+ className
47
+ }) {
48
+ useAreaStyles(STYLE_ID, CSS);
49
+ const scope = useScope(theme);
50
+ const [copied, setCopied] = useState(false);
51
+ return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-codeblock", className), children: [
52
+ /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: code }) }),
53
+ copyable && /* @__PURE__ */ jsx(
54
+ "button",
55
+ {
56
+ type: "button",
57
+ className: "mang-codeblock-copy",
58
+ onClick: () => {
59
+ void navigator.clipboard?.writeText(code).then(() => {
60
+ setCopied(true);
61
+ setTimeout(() => setCopied(false), 1500);
62
+ });
63
+ },
64
+ children: copied ? locale === "vi" ? "\u0110\xE3 ch\xE9p" : "Copied" : locale === "vi" ? "Ch\xE9p" : "Copy"
65
+ }
66
+ )
67
+ ] });
68
+ }
69
+ function Kbd({ children, className }) {
70
+ useAreaStyles(STYLE_ID, CSS);
71
+ return /* @__PURE__ */ jsx("kbd", { className: cx("mang-kbd", className), children });
72
+ }
73
+ function CalloutBlock({
74
+ tone = "note",
75
+ icon,
76
+ children,
77
+ theme,
78
+ className
79
+ }) {
80
+ useAreaStyles(STYLE_ID, CSS);
81
+ const scope = useScope(theme);
82
+ const defaultIcon = { note: "\u2139\uFE0F", tip: "\u{1F4A1}", warn: "\u26A0\uFE0F", danger: "\u26D4" }[tone];
83
+ return /* @__PURE__ */ jsxs("div", { ...scope, className: cx(scope.className, "mang-callout", className), "data-tone": tone, children: [
84
+ /* @__PURE__ */ jsx("span", { className: "mang-callout-icon", "aria-hidden": "true", children: icon ?? defaultIcon }),
85
+ /* @__PURE__ */ jsx("span", { children })
86
+ ] });
87
+ }
88
+
89
+ export {
90
+ Prose,
91
+ CodeBlock,
92
+ Kbd,
93
+ CalloutBlock
94
+ };
@@ -0,0 +1,55 @@
1
+ import * as react from 'react';
2
+ import { Locale } from '@mangtre/core';
3
+ import { ScanLevel, ScanFinding } from './sandbox.js';
4
+ import { T as ThemeMode } from './MangThemeProvider-BqdGKBP2.js';
5
+
6
+ interface Themed {
7
+ theme?: ThemeMode;
8
+ className?: string;
9
+ }
10
+ interface BundleUploadDropzoneProps extends Themed {
11
+ onFile: (file: File) => void;
12
+ /** Accept attribute (default ".js,.mjs"). */
13
+ accept?: string;
14
+ /** Currently selected file (for the "selected" state). */
15
+ file?: {
16
+ name: string;
17
+ size: number;
18
+ } | null;
19
+ locale?: Locale;
20
+ }
21
+ declare function BundleUploadDropzone({ onFile, accept, file, locale, theme, className, }: BundleUploadDropzoneProps): react.JSX.Element;
22
+ interface ManifestSummary {
23
+ id: string;
24
+ name?: string;
25
+ version?: string;
26
+ permissions?: string[];
27
+ surfaces?: string[];
28
+ commands?: string[];
29
+ }
30
+ interface ManifestPreviewProps extends Themed {
31
+ manifest: ManifestSummary;
32
+ }
33
+ declare function ManifestPreview({ manifest, theme, className }: ManifestPreviewProps): react.JSX.Element;
34
+ interface StaticScanPanelProps extends Themed {
35
+ level: ScanLevel;
36
+ findings: ScanFinding[];
37
+ locale?: Locale;
38
+ }
39
+ declare function StaticScanPanel({ level, findings, locale, theme, className, }: StaticScanPanelProps): react.JSX.Element;
40
+ type ReviewStatus = "draft" | "pending_review" | "changes" | "live" | "rejected";
41
+ interface ReviewStatusBadgeProps extends Themed {
42
+ status: ReviewStatus;
43
+ locale?: Locale;
44
+ }
45
+ declare function ReviewStatusBadge({ status, locale, theme, className, }: ReviewStatusBadgeProps): react.JSX.Element;
46
+ interface VersionBadgeProps extends Themed {
47
+ version: string;
48
+ }
49
+ declare function VersionBadge({ version, theme, className }: VersionBadgeProps): react.JSX.Element;
50
+ interface BuildBadgeProps extends Themed {
51
+ sha: string;
52
+ }
53
+ declare function BuildBadge({ sha, theme, className }: BuildBadgeProps): react.JSX.Element;
54
+
55
+ export { BuildBadge, type BuildBadgeProps, BundleUploadDropzone, type BundleUploadDropzoneProps, ManifestPreview, type ManifestPreviewProps, type ManifestSummary, type ReviewStatus, ReviewStatusBadge, type ReviewStatusBadgeProps, StaticScanPanel, type StaticScanPanelProps, VersionBadge, type VersionBadgeProps };
@@ -0,0 +1,20 @@
1
+ import {
2
+ BuildBadge,
3
+ BundleUploadDropzone,
4
+ ManifestPreview,
5
+ ReviewStatusBadge,
6
+ StaticScanPanel,
7
+ VersionBadge
8
+ } from "./chunk-JJB4PJC3.js";
9
+ import "./chunk-X7T2DJLU.js";
10
+ import "./chunk-FZRXVRC7.js";
11
+ import "./chunk-3AL4SUFD.js";
12
+ import "./chunk-PPOYMKV3.js";
13
+ export {
14
+ BuildBadge,
15
+ BundleUploadDropzone,
16
+ ManifestPreview,
17
+ ReviewStatusBadge,
18
+ StaticScanPanel,
19
+ VersionBadge
20
+ };
@@ -0,0 +1,50 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { Locale } from '@mangtre/core';
4
+ import { T as ThemeMode } from './MangThemeProvider-BqdGKBP2.js';
5
+
6
+ type RoomStatus = "offline" | "cloud" | "realtime";
7
+ interface RoomStatusBadgeProps {
8
+ status: RoomStatus;
9
+ /** Connected peers (shown when realtime). */
10
+ peers?: number;
11
+ locale?: Locale;
12
+ theme?: ThemeMode;
13
+ className?: string;
14
+ }
15
+ declare function RoomStatusBadge({ status, peers, locale, theme, className, }: RoomStatusBadgeProps): react.JSX.Element;
16
+ interface RoomShareButtonProps {
17
+ onShare: () => void;
18
+ locale?: Locale;
19
+ theme?: ThemeMode;
20
+ className?: string;
21
+ children?: ReactNode;
22
+ }
23
+ declare function RoomShareButton({ onShare, locale, theme, className, children, }: RoomShareButtonProps): react.JSX.Element;
24
+ interface RoomLinkCardProps {
25
+ url: string;
26
+ onCopy?: () => void;
27
+ locale?: Locale;
28
+ theme?: ThemeMode;
29
+ className?: string;
30
+ }
31
+ declare function RoomLinkCard({ url, onCopy, locale, theme, className }: RoomLinkCardProps): react.JSX.Element;
32
+ interface RoomPresenceProps {
33
+ /** Peer initials/labels (first letter shown). */
34
+ peers: string[];
35
+ /** Cap avatars shown; rest collapse into "+N". */
36
+ max?: number;
37
+ theme?: ThemeMode;
38
+ className?: string;
39
+ }
40
+ declare function RoomPresence({ peers, max, theme, className }: RoomPresenceProps): react.JSX.Element;
41
+ interface RoomConflictNoticeProps {
42
+ onReload: () => void;
43
+ locale?: Locale;
44
+ theme?: ThemeMode;
45
+ className?: string;
46
+ }
47
+ /** Shown when a remote change conflicts with a local edit (P2). */
48
+ declare function RoomConflictNotice({ onReload, locale, theme, className, }: RoomConflictNoticeProps): react.JSX.Element;
49
+
50
+ export { RoomConflictNotice, type RoomConflictNoticeProps, RoomLinkCard, type RoomLinkCardProps, RoomPresence, type RoomPresenceProps, RoomShareButton, type RoomShareButtonProps, type RoomStatus, RoomStatusBadge, type RoomStatusBadgeProps };
@@ -0,0 +1,17 @@
1
+ import {
2
+ RoomConflictNotice,
3
+ RoomLinkCard,
4
+ RoomPresence,
5
+ RoomShareButton,
6
+ RoomStatusBadge
7
+ } from "./chunk-OJX2EIMB.js";
8
+ import "./chunk-YN5O6YL6.js";
9
+ import "./chunk-3AL4SUFD.js";
10
+ import "./chunk-PPOYMKV3.js";
11
+ export {
12
+ RoomConflictNotice,
13
+ RoomLinkCard,
14
+ RoomPresence,
15
+ RoomShareButton,
16
+ RoomStatusBadge
17
+ };
@@ -0,0 +1,32 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { T as ThemeMode } from './MangThemeProvider-BqdGKBP2.js';
4
+ import '@mangtre/core';
5
+
6
+ interface Themed {
7
+ theme?: ThemeMode;
8
+ className?: string;
9
+ }
10
+ declare function Prose({ children, theme, className }: Themed & {
11
+ children: ReactNode;
12
+ }): react.JSX.Element;
13
+ interface CodeBlockProps extends Themed {
14
+ code: string;
15
+ /** Show a copy button. Default true. */
16
+ copyable?: boolean;
17
+ locale?: "vi" | "en";
18
+ }
19
+ declare function CodeBlock({ code, copyable, locale, theme, className, }: CodeBlockProps): react.JSX.Element;
20
+ declare function Kbd({ children, className }: {
21
+ children: ReactNode;
22
+ className?: string;
23
+ }): react.JSX.Element;
24
+ type CalloutTone = "note" | "tip" | "warn" | "danger";
25
+ interface CalloutBlockProps extends Themed {
26
+ tone?: CalloutTone;
27
+ icon?: ReactNode;
28
+ children: ReactNode;
29
+ }
30
+ declare function CalloutBlock({ tone, icon, children, theme, className, }: CalloutBlockProps): react.JSX.Element;
31
+
32
+ export { CalloutBlock, type CalloutBlockProps, type CalloutTone, CodeBlock, type CodeBlockProps, Kbd, Prose };
package/dist/editor.js ADDED
@@ -0,0 +1,14 @@
1
+ import {
2
+ CalloutBlock,
3
+ CodeBlock,
4
+ Kbd,
5
+ Prose
6
+ } from "./chunk-Z4ANGBPC.js";
7
+ import "./chunk-3AL4SUFD.js";
8
+ import "./chunk-PPOYMKV3.js";
9
+ export {
10
+ CalloutBlock,
11
+ CodeBlock,
12
+ Kbd,
13
+ Prose
14
+ };
@@ -0,0 +1,48 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, CSSProperties } from 'react';
3
+ import { T as ThemeMode } from './MangThemeProvider-BqdGKBP2.js';
4
+ import '@mangtre/core';
5
+
6
+ interface StateProps {
7
+ icon?: ReactNode;
8
+ title?: ReactNode;
9
+ description?: ReactNode;
10
+ /** Optional action (e.g. a Button). */
11
+ action?: ReactNode;
12
+ theme?: ThemeMode;
13
+ className?: string;
14
+ }
15
+ interface EmptyStateProps extends StateProps {
16
+ }
17
+ declare function EmptyState({ icon, title, description, action, theme, className, }: EmptyStateProps): react.JSX.Element;
18
+ interface ErrorStateProps extends StateProps {
19
+ }
20
+ declare function ErrorState({ icon, title, description, action, theme, className, }: ErrorStateProps): react.JSX.Element;
21
+ interface SkeletonProps {
22
+ width?: string | number;
23
+ height?: string | number;
24
+ /** Pill shape (e.g. for avatars/lines). */
25
+ rounded?: boolean;
26
+ theme?: ThemeMode;
27
+ className?: string;
28
+ style?: CSSProperties;
29
+ }
30
+ declare function Skeleton({ width, height, rounded, theme, className, style, }: SkeletonProps): react.JSX.Element;
31
+ interface SpinnerProps {
32
+ /** Diameter (px or CSS length). */
33
+ size?: string | number;
34
+ label?: string;
35
+ theme?: ThemeMode;
36
+ className?: string;
37
+ }
38
+ declare function Spinner({ size, label, theme, className }: SpinnerProps): react.JSX.Element;
39
+ interface ProgressProps {
40
+ /** 0–100. Omit for an indeterminate bar. */
41
+ value?: number;
42
+ theme?: ThemeMode;
43
+ className?: string;
44
+ label?: string;
45
+ }
46
+ declare function Progress({ value, theme, className, label }: ProgressProps): react.JSX.Element;
47
+
48
+ export { EmptyState, type EmptyStateProps, ErrorState, type ErrorStateProps, Progress, type ProgressProps, Skeleton, type SkeletonProps, Spinner, type SpinnerProps };