@maiyunnet/kebab 9.18.2 → 9.19.1

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.
@@ -10,26 +10,22 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
10
  *
11
11
  * 【使用方式】
12
12
  * 在 Ctr 方法中调用 _loadReactPage('view/react', { ...props }),
13
- * 框架自动将 import map、props JSON、水合脚本注入 HTML,组件只写业务逻辑,无需任何框架样板代码。
13
+ * 框架自动将 props JSON、水合脚本注入 HTML,组件只写业务逻辑,无需任何框架样板代码。
14
14
  *
15
15
  * 【多页面 / 共用组件】
16
16
  * 将公共 UI(如 Label/Input/Checkbox)放在 stc/lib/ui/ 目录,各页面 import 进来。
17
17
  * 这和 shadcn/ui 推荐的 components/ui/ 目录结构完全一致。
18
- * tsc watch 会自动将所有 .tsx 编译为同路径的 .js,无需打包工具。
18
+ * tsc watch 会自动将所有 .tsx 编译为同路径的 .js,供服务端 SSR 使用。
19
19
  *
20
20
  * 【编译方式】
21
21
  * 本文件 (.tsx) 已集成到 source/tsconfig.json 的 include 中,
22
- * 开启 `tsc: watch - source/tsconfig.json` 即可自动编译,无需额外命令。
22
+ * 开启 `tsc: watch - source/tsconfig.json` 即可自动编译服务端文件。
23
23
  * 编译输出:stc/view/react.page.js(由 tsc 覆盖写入,勿手动编辑 .js 文件)
24
+ * 客户端水合需执行:node ./source/main build -d source/www/example/stc
24
25
  *
25
26
  * 【运行时机】
26
27
  * - 服务端(Node.js):_loadReactPage() 调用 renderToString(),产出完整 HTML 字符串。
27
- * - 客户端(浏览器):import map 将 bare import 解析到 esm.sh,hydrateRoot 接管 document。
28
- * - 两端使用同一份 JS 文件:服务端从磁盘读,浏览器从静态 URL 下载。
29
- *
30
- * 【第三方包 import map 自动解析】
31
- * 开发模式下,框架会自动扫描入口 JS 及其相对引用中的所有 bare specifier,
32
- * 并通过 esm.sh CDN 自动生成 import map 条目,无需手动配置。
28
+ * - 客户端(浏览器):加载 kebab build 生成的 bundle,由 hydrateRoot 接管 document。
33
29
  *
34
30
  * 【限制】
35
31
  * - 不能包含 Node.js 专属代码(fs/path/lDb 等),数据必须通过 props 传入。
@@ -102,7 +98,7 @@ function ShadcnDemo() {
102
98
  e.preventDefault();
103
99
  setSubmitted(true);
104
100
  }
105
- return (_jsxs("div", { className: "space-y-4", children: [_jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-2", children: "shadcn/ui Components" }), _jsxs("p", { className: "text-slate-500 text-xs leading-relaxed", children: ["All components below are imported from ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "stc/lib/ui/" }), ", following the same ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "components/ui/" }), " structure recommended by shadcn/ui. Built on Radix UI primitives, styled with Tailwind CSS. In dev mode, the framework auto-scans all bare imports and generates the import map automatically."] })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Label + Input" }), _jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { htmlFor: nameId, children: "Username" }), _jsx(Input, { id: nameId, type: "text", placeholder: "Enter your username", value: name, onChange: e => { setName(e.target.value); } })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { htmlFor: emailId, children: "Email" }), _jsx(Input, { id: emailId, type: "email", placeholder: "you@example.com", value: email, onChange: e => { setEmail(e.target.value); } })] })] }), _jsx("p", { className: "text-xs text-slate-400 mt-3", children: "Click the Label text to focus the corresponding input (Radix UI a11y semantics)" })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Checkbox" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: agreeId, checked: agree, onCheckedChange: setAgree }), _jsx(Label, { htmlFor: agreeId, children: "I have read and agree to the Terms of Service" })] }), _jsxs("p", { className: "text-xs text-slate-400 mt-3", children: ["Value: ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: String(agree) }), "\u00A0(supports ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "true | false | 'indeterminate'" }), " tri-state)"] })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Switch" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { id: newsletterId, checked: newsletter, onCheckedChange: setNewsletter }), _jsx(Label, { htmlFor: newsletterId, children: "Subscribe to product updates" })] }), _jsxs("p", { className: "text-xs text-slate-400 mt-3", children: ["Value: ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: newsletter ? 'true' : 'false' })] })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Combined Form (Submit Demo)" }), submitted ? (_jsxs("div", { className: "space-y-2 text-sm", children: [_jsx("p", { className: "text-green-700 font-medium", children: "\u2713 Submitted! Received data:" }), _jsx("pre", { className: "bg-slate-50 border border-slate-200 rounded-lg p-3 text-xs text-slate-700 overflow-auto", children: JSON.stringify({ name, email, agree: Boolean(agree), newsletter }, null, 2) }), _jsx("button", { onClick: () => { setSubmitted(false); }, className: "text-xs text-blue-500 hover:underline cursor-pointer", children: "Reset" })] })) : (_jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [_jsxs("div", { className: "grid gap-1.5", children: [_jsxs(Label, { htmlFor: `${nameId}-form`, children: ["Username ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: `${nameId}-form`, required: true, placeholder: "At least 2 characters", value: name, onChange: e => { setName(e.target.value); } })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsxs(Label, { htmlFor: `${emailId}-form`, children: ["Email ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: `${emailId}-form`, type: "email", required: true, placeholder: "you@example.com", value: email, onChange: e => { setEmail(e.target.value); } })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: `${agreeId}-form`, checked: agree, onCheckedChange: setAgree, required: true }), _jsx(Label, { htmlFor: `${agreeId}-form`, children: "Agree to terms" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { id: `${newsletterId}-form`, checked: newsletter, onCheckedChange: setNewsletter }), _jsx(Label, { htmlFor: `${newsletterId}-form`, children: "Subscribe" })] }), _jsx("button", { type: "submit", className: "inline-flex items-center px-4 py-2 rounded-lg bg-blue-500 hover:bg-blue-600 text-white text-sm font-medium cursor-pointer", children: "Submit" })] }))] })] }));
101
+ return (_jsxs("div", { className: "space-y-4", children: [_jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-2", children: "shadcn/ui Components" }), _jsxs("p", { className: "text-slate-500 text-xs leading-relaxed", children: ["All components below are imported from ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "stc/lib/ui/" }), ", following the same ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "components/ui/" }), " structure recommended by shadcn/ui. Built on Radix UI primitives, styled with Tailwind CSS. Client dependencies are bundled locally by the Kebab build command."] })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Label + Input" }), _jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { htmlFor: nameId, children: "Username" }), _jsx(Input, { id: nameId, type: "text", placeholder: "Enter your username", value: name, onChange: e => { setName(e.target.value); } })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsx(Label, { htmlFor: emailId, children: "Email" }), _jsx(Input, { id: emailId, type: "email", placeholder: "you@example.com", value: email, onChange: e => { setEmail(e.target.value); } })] })] }), _jsx("p", { className: "text-xs text-slate-400 mt-3", children: "Click the Label text to focus the corresponding input (Radix UI a11y semantics)" })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Checkbox" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: agreeId, checked: agree, onCheckedChange: setAgree }), _jsx(Label, { htmlFor: agreeId, children: "I have read and agree to the Terms of Service" })] }), _jsxs("p", { className: "text-xs text-slate-400 mt-3", children: ["Value: ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: String(agree) }), "\u00A0(supports ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "true | false | 'indeterminate'" }), " tri-state)"] })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Switch" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { id: newsletterId, checked: newsletter, onCheckedChange: setNewsletter }), _jsx(Label, { htmlFor: newsletterId, children: "Subscribe to product updates" })] }), _jsxs("p", { className: "text-xs text-slate-400 mt-3", children: ["Value: ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: newsletter ? 'true' : 'false' })] })] }), _jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-4", children: "Combined Form (Submit Demo)" }), submitted ? (_jsxs("div", { className: "space-y-2 text-sm", children: [_jsx("p", { className: "text-green-700 font-medium", children: "\u2713 Submitted! Received data:" }), _jsx("pre", { className: "bg-slate-50 border border-slate-200 rounded-lg p-3 text-xs text-slate-700 overflow-auto", children: JSON.stringify({ name, email, agree: Boolean(agree), newsletter }, null, 2) }), _jsx("button", { onClick: () => { setSubmitted(false); }, className: "text-xs text-blue-500 hover:underline cursor-pointer", children: "Reset" })] })) : (_jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [_jsxs("div", { className: "grid gap-1.5", children: [_jsxs(Label, { htmlFor: `${nameId}-form`, children: ["Username ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: `${nameId}-form`, required: true, placeholder: "At least 2 characters", value: name, onChange: e => { setName(e.target.value); } })] }), _jsxs("div", { className: "grid gap-1.5", children: [_jsxs(Label, { htmlFor: `${emailId}-form`, children: ["Email ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsx(Input, { id: `${emailId}-form`, type: "email", required: true, placeholder: "you@example.com", value: email, onChange: e => { setEmail(e.target.value); } })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Checkbox, { id: `${agreeId}-form`, checked: agree, onCheckedChange: setAgree, required: true }), _jsx(Label, { htmlFor: `${agreeId}-form`, children: "Agree to terms" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { id: `${newsletterId}-form`, checked: newsletter, onCheckedChange: setNewsletter }), _jsx(Label, { htmlFor: `${newsletterId}-form`, children: "Subscribe" })] }), _jsx("button", { type: "submit", className: "inline-flex items-center px-4 py-2 rounded-lg bg-blue-500 hover:bg-blue-600 text-white text-sm font-medium cursor-pointer", children: "Submit" })] }))] })] }));
106
102
  }
107
103
  // ─── 页面主组件 ────────────────────────────────────────────────────────────────
108
104
  /** --- Kebab React 全页面演示 --- */
@@ -153,7 +149,7 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
153
149
  checkbox.tsx # shadcn Checkbox
154
150
  switch.tsx # shadcn Switch
155
151
  view/
156
- react-page.tsx # Page component (import + compose)` }), _jsxs("p", { className: "text-slate-500 text-xs mt-3", children: ["Mirrors the shadcn/ui", ' ', _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "components/ui/" }), " convention. In dev mode, the framework auto-scans imports \u2014 no manual import map configuration needed."] })] })] })), tab === 'routing' && (_jsxs(MemoryRouter, { children: [_jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-1", children: "React Router Demo" }), _jsxs("p", { className: "text-slate-500 text-xs mb-4", children: ["Uses ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "MemoryRouter" }), ' ', "to demonstrate route navigation, dynamic params (useParams), and programmatic navigation (useNavigate). Works on both server SSR and client hydration with no extra server configuration."] }), _jsxs(Routes, { children: [_jsx(Route, { path: "/", element: _jsx(RouterHome, {}) }), _jsx(Route, { path: "/about", element: _jsx(RouterAbout, {}) }), _jsx(Route, { path: "/user/:id", element: _jsx(RouterUser, {}) })] })] }), _jsxs(Card, { className: "mt-4", children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-2", children: "Full-Page BrowserRouter Setup" }), _jsx("p", { className: "text-slate-500 text-xs mb-3", children: "To let React Router manage the real URL (e.g. /app, /app/about), replace MemoryRouter with BrowserRouter and route all sub-paths to the same Ctr method on the server:" }), _jsx("pre", { className: "bg-slate-50 border border-slate-200 rounded-lg p-4 text-xs overflow-auto leading-relaxed text-slate-700", children: `// 1. route.json: 将所有子路径路由到同一 Ctr 方法
152
+ react-page.tsx # Page component (import + compose)` }), _jsxs("p", { className: "text-slate-500 text-xs mt-3", children: ["Mirrors the shadcn/ui", ' ', _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "components/ui/" }), " convention. Client dependencies are bundled locally by the Kebab build command."] })] })] })), tab === 'routing' && (_jsxs(MemoryRouter, { children: [_jsxs(Card, { children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-1", children: "React Router Demo" }), _jsxs("p", { className: "text-slate-500 text-xs mb-4", children: ["Uses ", _jsx("code", { className: "bg-slate-100 px-1 rounded", children: "MemoryRouter" }), ' ', "to demonstrate route navigation, dynamic params (useParams), and programmatic navigation (useNavigate). Works on both server SSR and client hydration with no extra server configuration."] }), _jsxs(Routes, { children: [_jsx(Route, { path: "/", element: _jsx(RouterHome, {}) }), _jsx(Route, { path: "/about", element: _jsx(RouterAbout, {}) }), _jsx(Route, { path: "/user/:id", element: _jsx(RouterUser, {}) })] })] }), _jsxs(Card, { className: "mt-4", children: [_jsx("h2", { className: "font-semibold text-slate-900 mb-2", children: "Full-Page BrowserRouter Setup" }), _jsx("p", { className: "text-slate-500 text-xs mb-3", children: "To let React Router manage the real URL (e.g. /app, /app/about), replace MemoryRouter with BrowserRouter and route all sub-paths to the same Ctr method on the server:" }), _jsx("pre", { className: "bg-slate-50 border border-slate-200 rounded-lg p-4 text-xs overflow-auto leading-relaxed text-slate-700", children: `// 1. route.json: 将所有子路径路由到同一 Ctr 方法
157
153
  {
158
154
  "app": "ctr/app@reactPage",
159
155
  "app\\/.*": "ctr/app@reactPage"
@@ -9,26 +9,22 @@
9
9
  *
10
10
  * 【使用方式】
11
11
  * 在 Ctr 方法中调用 _loadReactPage('view/react', { ...props }),
12
- * 框架自动将 import map、props JSON、水合脚本注入 HTML,组件只写业务逻辑,无需任何框架样板代码。
12
+ * 框架自动将 props JSON、水合脚本注入 HTML,组件只写业务逻辑,无需任何框架样板代码。
13
13
  *
14
14
  * 【多页面 / 共用组件】
15
15
  * 将公共 UI(如 Label/Input/Checkbox)放在 stc/lib/ui/ 目录,各页面 import 进来。
16
16
  * 这和 shadcn/ui 推荐的 components/ui/ 目录结构完全一致。
17
- * tsc watch 会自动将所有 .tsx 编译为同路径的 .js,无需打包工具。
17
+ * tsc watch 会自动将所有 .tsx 编译为同路径的 .js,供服务端 SSR 使用。
18
18
  *
19
19
  * 【编译方式】
20
20
  * 本文件 (.tsx) 已集成到 source/tsconfig.json 的 include 中,
21
- * 开启 `tsc: watch - source/tsconfig.json` 即可自动编译,无需额外命令。
21
+ * 开启 `tsc: watch - source/tsconfig.json` 即可自动编译服务端文件。
22
22
  * 编译输出:stc/view/react.page.js(由 tsc 覆盖写入,勿手动编辑 .js 文件)
23
+ * 客户端水合需执行:node ./source/main build -d source/www/example/stc
23
24
  *
24
25
  * 【运行时机】
25
26
  * - 服务端(Node.js):_loadReactPage() 调用 renderToString(),产出完整 HTML 字符串。
26
- * - 客户端(浏览器):import map 将 bare import 解析到 esm.sh,hydrateRoot 接管 document。
27
- * - 两端使用同一份 JS 文件:服务端从磁盘读,浏览器从静态 URL 下载。
28
- *
29
- * 【第三方包 import map 自动解析】
30
- * 开发模式下,框架会自动扫描入口 JS 及其相对引用中的所有 bare specifier,
31
- * 并通过 esm.sh CDN 自动生成 import map 条目,无需手动配置。
27
+ * - 客户端(浏览器):加载 kebab build 生成的 bundle,由 hydrateRoot 接管 document。
32
28
  *
33
29
  * 【限制】
34
30
  * - 不能包含 Node.js 专属代码(fs/path/lDb 等),数据必须通过 props 传入。
@@ -210,7 +206,7 @@ function ShadcnDemo() {
210
206
  All components below are imported from <code className="bg-slate-100 px-1 rounded">stc/lib/ui/</code>,
211
207
  following the same <code className="bg-slate-100 px-1 rounded">components/ui/</code> structure recommended by shadcn/ui.
212
208
  Built on Radix UI primitives, styled with Tailwind CSS.
213
- In dev mode, the framework auto-scans all bare imports and generates the import map automatically.
209
+ Client dependencies are bundled locally by the Kebab build command.
214
210
  </p>
215
211
  </Card>
216
212
 
@@ -392,8 +388,7 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
392
388
  <meta charSet="UTF-8" />
393
389
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
394
390
  <title>{title}</title>
395
- {/* import map 由框架自动注入在此标签前,无需手动添加 */}
396
- {/* dev: Tailwind Play CDN;prod: 将此行替换为 kebab build 编译的 CSS 文件 */}
391
+ {/* CSS 和客户端水合 bundle 均由 kebab build 生成 */}
397
392
  <link href={`${_urlStc}view/react.page.css?v=${_staticVer}`} rel="stylesheet" />
398
393
  </head>
399
394
  <body className="bg-slate-50 min-h-screen font-sans">
@@ -494,8 +489,7 @@ export default function ReactPage({ title, serverTime, node, _urlBase, _urlStc,
494
489
  <p className="text-slate-500 text-xs mt-3">
495
490
  Mirrors the shadcn/ui{' '}
496
491
  <code className="bg-slate-100 px-1 rounded">components/ui/</code> convention.
497
- In dev mode, the framework auto-scans imports —
498
- no manual import map configuration needed.
492
+ Client dependencies are bundled locally by the Kebab build command.
499
493
  </p>
500
494
  </Card>
501
495