@genispace/geniapp 0.1.0 → 0.3.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.
@@ -1,4 +1,4 @@
1
- import { default as GeniSpace } from 'genispace';
1
+ import { default as GeniSpace } from '@genispace/sdk';
2
2
 
3
3
  /**
4
4
  * Platform GeniSpace client for `/teams/members`, `/users/profiles/batch`, etc.
package/dist/hooks.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as a, a as o, b as t, C as r, c as p, D as c, R as i, d as n, e as A, f as E, g as l, h as u, i as m, j as R, k as P, l as C, m as N, n as _, o as d, p as f, q as I, r as L, s as S, t as B, u as D, v as O, w as T, x as b, y as h, z as v, B as y, E as G, F as k, G as H, H as M } from "./CrossAppRecordPicker-BXchXcK5.js";
1
+ import { A as a, a as o, b as t, C as r, c as p, D as c, R as i, d as n, e as A, f as E, g as l, h as u, i as m, j as R, k as P, l as C, m as N, n as _, o as d, p as f, q as I, r as L, s as S, t as B, u as D, v as O, w as T, x as b, y as h, z as v, B as y, E as G, F as k, G as H, H as M } from "./CrossAppRecordPicker-CQVmirWD.js";
2
2
  import { G as x, a as g } from "./shell-DIHnXIUb.js";
3
3
  export {
4
4
  a as AppAccessGate,
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { GENISPACE_SHELL_MESSAGE_VERSION as s, GeniAppShellBridge as p } from "./shell.js";
2
- import { A as o, a as r, b as i, C as n, c as l, D as A, R as c, d as E, e as S, f as m, g as u, h as P, i as d, j as C, k as R, l as f, m as k, n as D, o as I, p as N, q as _, r as L, s as T, t as b, u as g, v as h, w as B, x as G, y, z as O, B as U, E as x, F as H, G as M, H as v } from "./CrossAppRecordPicker-BXchXcK5.js";
2
+ import { A as o, a as r, b as i, C as n, c as l, D as A, R as c, d as E, e as S, f as m, g as u, h as P, i as d, j as C, k as R, l as f, m as k, n as D, o as I, p as N, q as _, r as L, s as T, t as b, u as g, v as h, w as B, x as G, y, z as O, B as U, E as x, F as H, G as M, H as v } from "./CrossAppRecordPicker-CQVmirWD.js";
3
3
  import { A as w, a as V, b as j, c as q, d as z, e as Q, f as Y, g as J, h as K, i as W, j as X, k as Z, l as $, C as ee, D as ae, F as se, G as pe, P as te, Q as oe, S as re, m as ie, T as ne, U as le, n as Ae, o as ce, p as Ee, q as Se, t as me, u as ue } from "./useUserDirectory-CqkyCQoR.js";
4
4
  import { A as de } from "./Page-wHZrMN17.js";
5
5
  import { G as Re, a as fe } from "./shell-DIHnXIUb.js";
package/dist/vite.js CHANGED
@@ -56,13 +56,13 @@ function w(e) {
56
56
  return e.command === "serve" && e.mode === "development" ? "/" : `/${e.identifier}/${e.version}/`;
57
57
  }
58
58
  const F = {
59
- exclude: ["lucide-react", "genispace", "@genispace/geniapp"]
59
+ exclude: ["lucide-react", "@genispace/sdk", "@genispace/geniapp"]
60
60
  };
61
61
  function S(e) {
62
62
  if (e.includes("/node_modules/react/") || e.includes("/node_modules/react-dom/") || e.includes("/node_modules/react-router")) return "react-runtime";
63
63
  if (e.includes("/node_modules/i18next") || e.includes("/node_modules/react-i18next")) return "localization";
64
64
  if (e.includes("/node_modules/lucide-react/")) return "icons";
65
- if (e.includes("/node_modules/@genispace/geniapp/") || e.includes("/node_modules/genispace/")) return "genispace-runtime";
65
+ if (e.includes("/node_modules/@genispace/geniapp/") || e.includes("/node_modules/@genispace/sdk/")) return "genispace-runtime";
66
66
  }
67
67
  export {
68
68
  y as copyGeniAppBundle,
package/dist/vite.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.js","sources":["../src/vite.ts"],"sourcesContent":["import { copyFileSync, cpSync, existsSync, readFileSync, statSync } from 'node:fs';\nimport path from 'node:path';\nimport type { Plugin } from 'vite';\n\nexport type GeniAppBundlePluginOptions = {\n appRoot: string;\n outDir?: string;\n};\n\nfunction contentTypeForDataFile(filePath: string) {\n switch (path.extname(filePath).toLowerCase()) {\n case '.json': return 'application/json; charset=utf-8';\n case '.sql': return 'application/sql; charset=utf-8';\n case '.jpg':\n case '.jpeg': return 'image/jpeg';\n case '.png': return 'image/png';\n case '.webp': return 'image/webp';\n case '.mp4': return 'video/mp4';\n case '.txt': return 'text/plain; charset=utf-8';\n default: return 'application/octet-stream';\n }\n}\n\nfunction safeBundleFile(appRoot: string, requestPath: string) {\n const cleanPath = requestPath.split('?')[0].replace(/^\\/+/, '');\n if (cleanPath === 'manifest.json') return path.join(appRoot, 'manifest.json');\n if (!cleanPath.startsWith('data/')) return null;\n\n const dataRoot = path.resolve(appRoot, 'data');\n const candidate = path.resolve(appRoot, cleanPath);\n if (candidate !== dataRoot && !candidate.startsWith(`${dataRoot}${path.sep}`)) return null;\n return candidate;\n}\n\n/** Serves and copies the complete, installable GeniApp contract bundle. */\nexport function copyGeniAppBundle({ appRoot, outDir = 'dist' }: GeniAppBundlePluginOptions): Plugin {\n const normalizedRoot = path.resolve(appRoot);\n const manifest = path.join(normalizedRoot, 'manifest.json');\n const data = path.join(normalizedRoot, 'data');\n\n return {\n name: 'genispace-copy-geniapp-bundle',\n configureServer(server) {\n server.middlewares.use((request, response, next) => {\n const filePath = safeBundleFile(normalizedRoot, request.url || '');\n if (!filePath || !existsSync(filePath) || !statSync(filePath).isFile()) return next();\n try {\n response.setHeader('Content-Type', contentTypeForDataFile(filePath));\n response.setHeader('Access-Control-Allow-Origin', '*');\n response.statusCode = 200;\n response.end(readFileSync(filePath));\n } catch {\n next();\n }\n });\n },\n closeBundle() {\n const output = path.resolve(normalizedRoot, outDir);\n if (!existsSync(output)) return;\n if (existsSync(manifest)) copyFileSync(manifest, path.join(output, 'manifest.json'));\n if (existsSync(data)) cpSync(data, path.join(output, 'data'), { recursive: true });\n },\n };\n}\n\n/** Backward-compatible name used by the existing GeniApp scaffolds. */\nexport function copyManifestToDist(appRoot: string): Plugin {\n return copyGeniAppBundle({ appRoot });\n}\n\nexport function geniappBasePath(options: {\n command: 'build' | 'serve';\n mode: string;\n identifier: string;\n version: string;\n}) {\n return options.command === 'serve' && options.mode === 'development'\n ? '/'\n : `/${options.identifier}/${options.version}/`;\n}\n\n/** Dependencies that should remain host-resolved instead of pre-bundled in dev. */\nexport const geniappOptimizeDeps = {\n exclude: ['lucide-react', 'genispace', '@genispace/geniapp'],\n};\n\n/** Stable chunk grouping without repository-path aliases. */\nexport function geniappManualChunks(id: string) {\n if (id.includes('/node_modules/react/') || id.includes('/node_modules/react-dom/') || id.includes('/node_modules/react-router')) return 'react-runtime';\n if (id.includes('/node_modules/i18next') || id.includes('/node_modules/react-i18next')) return 'localization';\n if (id.includes('/node_modules/lucide-react/')) return 'icons';\n if (id.includes('/node_modules/@genispace/geniapp/') || id.includes('/node_modules/genispace/')) return 'genispace-runtime';\n return undefined;\n}\n"],"names":["contentTypeForDataFile","filePath","path","safeBundleFile","appRoot","requestPath","cleanPath","dataRoot","candidate","copyGeniAppBundle","outDir","normalizedRoot","manifest","data","server","request","response","next","existsSync","statSync","readFileSync","output","copyFileSync","cpSync","copyManifestToDist","geniappBasePath","options","geniappOptimizeDeps","geniappManualChunks","id"],"mappings":"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"}
1
+ {"version":3,"file":"vite.js","sources":["../src/vite.ts"],"sourcesContent":["import { copyFileSync, cpSync, existsSync, readFileSync, statSync } from 'node:fs';\nimport path from 'node:path';\nimport type { Plugin } from 'vite';\n\nexport type GeniAppBundlePluginOptions = {\n appRoot: string;\n outDir?: string;\n};\n\nfunction contentTypeForDataFile(filePath: string) {\n switch (path.extname(filePath).toLowerCase()) {\n case '.json': return 'application/json; charset=utf-8';\n case '.sql': return 'application/sql; charset=utf-8';\n case '.jpg':\n case '.jpeg': return 'image/jpeg';\n case '.png': return 'image/png';\n case '.webp': return 'image/webp';\n case '.mp4': return 'video/mp4';\n case '.txt': return 'text/plain; charset=utf-8';\n default: return 'application/octet-stream';\n }\n}\n\nfunction safeBundleFile(appRoot: string, requestPath: string) {\n const cleanPath = requestPath.split('?')[0].replace(/^\\/+/, '');\n if (cleanPath === 'manifest.json') return path.join(appRoot, 'manifest.json');\n if (!cleanPath.startsWith('data/')) return null;\n\n const dataRoot = path.resolve(appRoot, 'data');\n const candidate = path.resolve(appRoot, cleanPath);\n if (candidate !== dataRoot && !candidate.startsWith(`${dataRoot}${path.sep}`)) return null;\n return candidate;\n}\n\n/** Serves and copies the complete, installable GeniApp contract bundle. */\nexport function copyGeniAppBundle({ appRoot, outDir = 'dist' }: GeniAppBundlePluginOptions): Plugin {\n const normalizedRoot = path.resolve(appRoot);\n const manifest = path.join(normalizedRoot, 'manifest.json');\n const data = path.join(normalizedRoot, 'data');\n\n return {\n name: 'genispace-copy-geniapp-bundle',\n configureServer(server) {\n server.middlewares.use((request, response, next) => {\n const filePath = safeBundleFile(normalizedRoot, request.url || '');\n if (!filePath || !existsSync(filePath) || !statSync(filePath).isFile()) return next();\n try {\n response.setHeader('Content-Type', contentTypeForDataFile(filePath));\n response.setHeader('Access-Control-Allow-Origin', '*');\n response.statusCode = 200;\n response.end(readFileSync(filePath));\n } catch {\n next();\n }\n });\n },\n closeBundle() {\n const output = path.resolve(normalizedRoot, outDir);\n if (!existsSync(output)) return;\n if (existsSync(manifest)) copyFileSync(manifest, path.join(output, 'manifest.json'));\n if (existsSync(data)) cpSync(data, path.join(output, 'data'), { recursive: true });\n },\n };\n}\n\n/** Backward-compatible name used by the existing GeniApp scaffolds. */\nexport function copyManifestToDist(appRoot: string): Plugin {\n return copyGeniAppBundle({ appRoot });\n}\n\nexport function geniappBasePath(options: {\n command: 'build' | 'serve';\n mode: string;\n identifier: string;\n version: string;\n}) {\n return options.command === 'serve' && options.mode === 'development'\n ? '/'\n : `/${options.identifier}/${options.version}/`;\n}\n\n/** Dependencies that should remain host-resolved instead of pre-bundled in dev. */\nexport const geniappOptimizeDeps = {\n exclude: ['lucide-react', '@genispace/sdk', '@genispace/geniapp'],\n};\n\n/** Stable chunk grouping without repository-path aliases. */\nexport function geniappManualChunks(id: string) {\n if (id.includes('/node_modules/react/') || id.includes('/node_modules/react-dom/') || id.includes('/node_modules/react-router')) return 'react-runtime';\n if (id.includes('/node_modules/i18next') || id.includes('/node_modules/react-i18next')) return 'localization';\n if (id.includes('/node_modules/lucide-react/')) return 'icons';\n if (id.includes('/node_modules/@genispace/geniapp/') || id.includes('/node_modules/@genispace/sdk/')) return 'genispace-runtime';\n return undefined;\n}\n"],"names":["contentTypeForDataFile","filePath","path","safeBundleFile","appRoot","requestPath","cleanPath","dataRoot","candidate","copyGeniAppBundle","outDir","normalizedRoot","manifest","data","server","request","response","next","existsSync","statSync","readFileSync","output","copyFileSync","cpSync","copyManifestToDist","geniappBasePath","options","geniappOptimizeDeps","geniappManualChunks","id"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { WorkbenchConfig } from './types';
2
+
3
+ export declare const mountWorkbench: (root: HTMLElement, config: WorkbenchConfig) => void;
@@ -0,0 +1,197 @@
1
+ :root {
2
+ color-scheme: light;
3
+ font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
4
+ font-synthesis: none;
5
+ --background: 0 0% 98%;
6
+ --foreground: 0 0% 10%;
7
+ --card: 0 0% 100%;
8
+ --card-foreground: 0 0% 10%;
9
+ --muted: 0 0% 94%;
10
+ --muted-foreground: 0 0% 42%;
11
+ --accent: 0 0% 92%;
12
+ --accent-foreground: 0 0% 12%;
13
+ --border: 0 0% 88%;
14
+ --primary: 225 70% 52%;
15
+ --primary-foreground: 0 0% 100%;
16
+ --portable-accent: hsl(var(--primary));
17
+ --portable-accent-soft: hsl(225 70% 96%);
18
+ --portable-surface: hsl(var(--card));
19
+ --portable-line: hsl(var(--border));
20
+ --portable-muted: hsl(var(--muted-foreground));
21
+ --portable-radius: 14px;
22
+ color: hsl(var(--foreground));
23
+ background: hsl(var(--background));
24
+ }
25
+
26
+ :root.dark {
27
+ color-scheme: dark;
28
+ --background: 0 0% 4%;
29
+ --foreground: 0 0% 95%;
30
+ --card: 0 0% 8%;
31
+ --card-foreground: 0 0% 95%;
32
+ --muted: 0 0% 14%;
33
+ --muted-foreground: 0 0% 64%;
34
+ --accent: 0 0% 17%;
35
+ --accent-foreground: 0 0% 96%;
36
+ --border: 0 0% 20%;
37
+ --primary: 225 82% 66%;
38
+ --primary-foreground: 0 0% 100%;
39
+ --portable-accent-soft: hsl(225 30% 18%);
40
+ }
41
+
42
+ * { box-sizing: border-box; }
43
+ html, body, #root { min-height: 100%; margin: 0; }
44
+ body { min-width: 320px; overflow-x: hidden; background: hsl(var(--background)); color: hsl(var(--foreground)); }
45
+ button, input, textarea { font: inherit; }
46
+ button { cursor: pointer; }
47
+ .portable-icon { width: 18px; height: 18px; flex: 0 0 auto; }
48
+
49
+ .portable-shell { min-height: 100vh; background: hsl(var(--background)); }
50
+ .portable-sidebar {
51
+ position: fixed; inset: 0 auto 0 0; z-index: 20; display: flex; width: 256px; flex-direction: column;
52
+ overflow: visible; border-right: 1px solid hsl(var(--border)); background: hsl(var(--muted));
53
+ transition: width 220ms ease, background 180ms ease, border-color 180ms ease;
54
+ }
55
+ .sidebar-collapsed .portable-sidebar { width: 80px; }
56
+ .portable-sidebar-header { display: flex; height: 69px; flex: 0 0 69px; align-items: center; padding: 0 16px; border-bottom: 1px solid hsl(var(--border)); }
57
+ .sidebar-collapsed .portable-sidebar-header { justify-content: center; padding: 0 8px; }
58
+ .portable-brand { display: flex; min-width: 0; align-items: center; gap: 10px; }
59
+ .portable-brand > span { display: grid; width: 36px; height: 36px; flex: 0 0 36px; place-items: center; border-radius: 12px; background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); font-weight: 750; box-shadow: 0 1px 3px rgb(0 0 0 / 0.12); }
60
+ .portable-brand > div { min-width: 0; }
61
+ .portable-brand strong, .portable-brand small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
62
+ .portable-brand strong { color: hsl(var(--foreground)); font-size: 14px; font-weight: 650; }
63
+ .portable-brand small { max-width: 175px; margin-top: 2px; color: hsl(var(--muted-foreground)); font-size: 10px; }
64
+ .portable-sidebar nav, .portable-mobile-drawer nav { display: grid; min-height: 0; flex: 1; align-content: start; gap: 4px; overflow-y: auto; padding: 12px; }
65
+ .portable-nav-item { display: flex; width: 100%; min-height: 44px; align-items: center; gap: 10px; padding: 8px 12px 8px calc(12px + var(--nav-depth, 0) * 14px); border: 0; border-radius: 12px; background: transparent; color: hsl(var(--foreground)); text-align: left; transition: color 150ms ease, background 150ms ease; }
66
+ .portable-nav-item span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; font-weight: 520; }
67
+ .portable-nav-item:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
68
+ .portable-nav-item.active { background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); box-shadow: 0 1px 3px rgb(0 0 0 / 0.12); }
69
+ .sidebar-collapsed .portable-nav-item { width: 44px; justify-content: center; margin-inline: auto; padding: 0; }
70
+ .sidebar-collapsed .portable-nav-item span { display: none; }
71
+ .portable-sidebar footer, .portable-mobile-drawer footer { margin-top: auto; padding: 12px; border-top: 1px solid hsl(var(--border)); }
72
+ .portable-controls { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
73
+ .portable-controls button { display: flex; min-height: 40px; align-items: center; justify-content: center; gap: 7px; border: 1px solid hsl(var(--border)); border-radius: 10px; background: hsl(var(--background)); color: hsl(var(--muted-foreground)); }
74
+ .portable-controls button:hover { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }
75
+ .portable-controls button span { font-size: 11px; font-weight: 650; }
76
+ .sidebar-collapsed .portable-controls { grid-template-columns: 1fr; }
77
+ .sidebar-collapsed .portable-controls button span, .portable-controls.compact button span { display: none; }
78
+ .portable-controls.compact { display: flex; margin-left: auto; }
79
+ .portable-controls.compact button { width: 38px; min-height: 38px; }
80
+ .portable-collapse { position: absolute; z-index: 10; top: 69px; right: -12px; display: grid; width: 24px; height: 24px; place-items: center; transform: translateY(-50%); border: 1px solid hsl(var(--border)); border-radius: 999px; background: hsl(var(--muted)); color: hsl(var(--muted-foreground)); box-shadow: 0 1px 4px rgb(0 0 0 / 0.1); }
81
+ .portable-collapse .portable-icon { width: 15px; height: 15px; }
82
+ .portable-content { min-width: 0; min-height: 100vh; padding-left: 256px; transition: padding-left 220ms ease; }
83
+ .sidebar-collapsed .portable-content { padding-left: 80px; }
84
+ .portable-mobile-header, .portable-mobile-nav { display: none; }
85
+
86
+ .portable-page { min-height: 100vh; padding: 30px clamp(18px, 3vw, 44px) 48px; background: hsl(var(--background)); color: hsl(var(--foreground)); transition: color 180ms ease, background 180ms ease; }
87
+ .portable-page-header { margin-bottom: 22px; }
88
+ .portable-page-header h1 { margin: 4px 0 5px; color: hsl(var(--foreground)); font-size: clamp(24px, 3vw, 34px); letter-spacing: -0.035em; }
89
+ .portable-page-header p { max-width: 760px; margin: 0; color: var(--portable-muted); line-height: 1.6; }
90
+ .portable-eyebrow { color: var(--portable-accent); font-size: 11px; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; }
91
+ .portable-page-grid { display: grid; gap: 18px; }
92
+ .portable-page-grid.grid-24 { grid-template-columns: repeat(24, minmax(0, 1fr)); grid-auto-rows: minmax(48px, auto); align-items: stretch; }
93
+ .portable-placement { min-width: 0; }
94
+ .portable-component { height: 100%; overflow: hidden; padding: 20px; border: 1px solid var(--portable-line); border-radius: var(--portable-radius); background: var(--portable-surface); color: hsl(var(--card-foreground)); box-shadow: 0 5px 18px rgb(0 0 0 / 0.045); transition: color 180ms ease, background 180ms ease, border-color 180ms ease; }
95
+ .dark .portable-component { box-shadow: 0 8px 24px rgb(0 0 0 / 0.22); }
96
+ .portable-type-Typography, .portable-type-Text, .portable-type-Title, .portable-type-Paragraph { padding: 0; border: 0; background: transparent; box-shadow: none; }
97
+ .portable-typography { margin: 0; line-height: 1.55; }
98
+ .portable-typography-title, .portable-typography-h1, .portable-typography-h2 { letter-spacing: -0.03em; }
99
+ .portable-section-heading { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; }
100
+ .portable-section-heading h2 { margin: 0; color: hsl(var(--card-foreground)); font-size: 17px; }
101
+ .portable-section-heading p { margin: 5px 0 0; color: var(--portable-muted); font-size: 13px; }
102
+ .portable-stat-grid { display: grid; grid-template-columns: repeat(var(--stat-columns), minmax(0, 1fr)); gap: 14px; }
103
+ .portable-stat { min-width: 0; padding: 17px; border: 1px solid var(--portable-line); border-radius: 12px; background: hsl(var(--background)); }
104
+ .portable-stat-title { color: var(--portable-muted); font-size: 12px; font-weight: 600; }
105
+ .portable-stat-value { margin-top: 9px; color: hsl(var(--foreground)); font-size: 27px; font-weight: 760; letter-spacing: -0.04em; }
106
+ .portable-stat-trend { margin-top: 7px; color: #07855b; font-size: 12px; font-weight: 700; }
107
+ .portable-stat-trend.down { color: #d64545; }
108
+ .portable-stat-trend span { color: var(--portable-muted); font-weight: 400; }
109
+ .portable-table-wrap { max-width: 100%; overflow: auto; }
110
+ .portable-table-wrap table { width: 100%; border-collapse: collapse; font-size: 13px; }
111
+ .portable-table-wrap th { padding: 11px 13px; color: var(--portable-muted); background: hsl(var(--muted)); text-align: left; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; }
112
+ .portable-table-wrap td { padding: 13px; border-top: 1px solid var(--portable-line); color: hsl(var(--card-foreground)); white-space: nowrap; }
113
+ .portable-table-wrap tr:hover td { background: hsl(var(--accent)); }
114
+ .portable-grid-search { margin-bottom: 14px; }
115
+ .portable-grid-search input { width: min(100%, 360px); padding: 10px 12px; border: 1px solid var(--portable-line); border-radius: 9px; color: hsl(var(--foreground)); background: hsl(var(--background)); }
116
+ .portable-card-grid { display: grid; gap: 10px; }
117
+ .portable-card-grid article { padding: 15px; border: 1px solid var(--portable-line); border-radius: 11px; background: hsl(var(--background)); }
118
+ .portable-card-grid header { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
119
+ .portable-card-grid header strong { color: hsl(var(--foreground)); font-size: 14px; }
120
+ .portable-card-grid header p { margin: 4px 0 0; color: var(--portable-muted); font-size: 12px; }
121
+ .portable-card-grid header > span { color: var(--portable-muted); font-size: 22px; line-height: 1; }
122
+ .portable-card-grid dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px 18px; margin: 14px 0 0; padding-top: 13px; border-top: 1px solid var(--portable-line); }
123
+ .portable-card-grid dl > div { min-width: 0; }
124
+ .portable-card-grid dt { color: var(--portable-muted); font-size: 10px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
125
+ .portable-card-grid dd { display: flex; align-items: center; gap: 7px; margin: 5px 0 0; color: hsl(var(--card-foreground)); font-size: 12px; }
126
+ .portable-progress { width: 72px; height: 6px; overflow: hidden; border-radius: 999px; background: hsl(var(--muted)); }
127
+ .portable-progress > span { display: block; height: 100%; border-radius: inherit; background: var(--portable-accent); }
128
+ .portable-tag { display: inline-flex; padding: 3px 7px; border-radius: 999px; color: hsl(var(--primary)); background: var(--portable-accent-soft); font-size: 11px; font-weight: 700; }
129
+ .portable-chart { width: 100%; overflow: hidden; }
130
+ .portable-chart svg { display: block; width: 100%; max-height: 330px; }
131
+ .portable-chart text { fill: var(--portable-muted); font-size: 11px; }
132
+ .portable-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 15px; }
133
+ .portable-form label { display: grid; gap: 7px; color: var(--portable-muted); font-size: 12px; font-weight: 650; }
134
+ .portable-form input, .portable-form textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--portable-line); border-radius: 9px; color: hsl(var(--foreground)); background: hsl(var(--background)); outline: 0; }
135
+ .portable-form input:focus, .portable-form textarea:focus { border-color: var(--portable-accent); box-shadow: 0 0 0 3px var(--portable-accent-soft); }
136
+ .portable-form textarea { min-height: 92px; resize: vertical; }
137
+ .portable-form button { align-self: end; min-height: 40px; padding: 0 18px; border: 0; border-radius: 9px; color: hsl(var(--primary-foreground)); background: var(--portable-accent); font-weight: 700; }
138
+ .portable-task-input { display: grid; gap: 14px; }
139
+ .portable-task-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
140
+ .portable-task-fields label { display: grid; gap: 6px; color: var(--portable-muted); font-size: 12px; font-weight: 650; }
141
+ .portable-task-fields input { min-width: 0; padding: 10px 12px; border: 1px solid var(--portable-line); border-radius: 9px; color: hsl(var(--foreground)); background: hsl(var(--background)); }
142
+ .portable-file-drop { display: grid; min-height: 150px; place-items: center; align-content: center; gap: 6px; padding: 22px; border: 1px dashed hsl(var(--primary) / 0.5); border-radius: 12px; background: var(--portable-accent-soft); text-align: center; }
143
+ .portable-file-drop input { position: absolute; width: 1px; height: 1px; opacity: 0; }
144
+ .portable-file-drop strong { font-size: 13px; }
145
+ .portable-file-drop small { color: var(--portable-muted); font-size: 11px; font-weight: 400; }
146
+ .portable-file-icon { display: grid; width: 34px; height: 34px; place-items: center; border-radius: 999px; color: hsl(var(--primary-foreground)); background: var(--portable-accent); font-size: 19px; }
147
+ .portable-file-list { display: grid; gap: 7px; }
148
+ .portable-file-list > div { display: flex; justify-content: space-between; gap: 12px; padding: 9px 11px; border: 1px solid var(--portable-line); border-radius: 8px; background: hsl(var(--background)); font-size: 12px; }
149
+ .portable-file-list small { color: var(--portable-muted); }
150
+ .portable-task-submit { justify-self: end; min-height: 40px; padding: 0 18px; border: 0; border-radius: 9px; color: hsl(var(--primary-foreground)); background: var(--portable-accent); font-weight: 700; }
151
+ .portable-list { display: grid; gap: 0; }
152
+ .portable-list article { padding: 13px 2px; border-top: 1px solid var(--portable-line); }
153
+ .portable-list article:first-child { border-top: 0; }
154
+ .portable-list strong { font-size: 13px; }
155
+ .portable-list p { margin: 5px 0 0; color: var(--portable-muted); font-size: 12px; line-height: 1.5; }
156
+ .portable-tab-list { display: flex; gap: 5px; margin: -7px -7px 18px; padding: 6px; overflow-x: auto; border-radius: 10px; background: hsl(var(--muted)); }
157
+ .portable-tab-list button { padding: 8px 13px; border: 0; border-radius: 7px; color: var(--portable-muted); background: transparent; font-size: 12px; font-weight: 650; white-space: nowrap; }
158
+ .portable-tab-list button.active { color: hsl(var(--primary)); background: hsl(var(--card)); box-shadow: 0 2px 7px rgb(0 0 0 / 0.08); }
159
+ .portable-tab-panel, .portable-container { display: grid; gap: 14px; }
160
+ .portable-empty, .portable-unsupported { padding: 24px; color: var(--portable-muted); text-align: center; }
161
+ .portable-unsupported { border: 1px dashed #f0a8a8; border-radius: 9px; color: #b83a3a; background: #fff5f5; }
162
+
163
+ .portable-mobile-backdrop, .portable-mobile-drawer { display: none; }
164
+
165
+ @media (max-width: 1023px) {
166
+ .portable-shell { display: flex; min-height: 100dvh; flex-direction: column; }
167
+ .portable-sidebar { display: none; }
168
+ .portable-content, .sidebar-collapsed .portable-content { min-height: 0; flex: 1; padding-left: 0; }
169
+ .portable-mobile-header { position: sticky; top: 0; z-index: 30; display: flex; min-height: 60px; flex: 0 0 60px; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid hsl(var(--border)); background: hsl(var(--background) / 0.96); backdrop-filter: blur(12px); }
170
+ .portable-mobile-header > button, .portable-mobile-drawer-close button { display: grid; width: 40px; height: 40px; flex: 0 0 40px; place-items: center; border: 1px solid hsl(var(--border)); border-radius: 12px; background: hsl(var(--card)); color: hsl(var(--foreground)); }
171
+ .portable-mobile-header .portable-brand { flex: 1; }
172
+ .portable-mobile-header .portable-brand > span { width: 34px; height: 34px; flex-basis: 34px; }
173
+ .portable-mobile-header .portable-brand small { display: none; }
174
+ .portable-mobile-header .portable-controls { flex: 0 0 auto; }
175
+ .portable-mobile-nav { position: sticky; z-index: 30; bottom: 0; display: flex; min-height: 70px; flex: 0 0 auto; align-items: stretch; padding: 7px 5px max(env(safe-area-inset-bottom, 0px), 10px); border-top: 1px solid hsl(var(--border)); background: hsl(var(--background) / 0.98); backdrop-filter: blur(12px); }
176
+ .portable-mobile-nav button { display: flex; min-width: 0; flex: 1; flex-direction: column; align-items: center; justify-content: center; gap: 3px; padding: 5px 2px; border: 0; background: transparent; color: hsl(var(--muted-foreground)); }
177
+ .portable-mobile-nav button.active { color: hsl(var(--primary)); }
178
+ .portable-mobile-nav button .portable-icon { width: 25px; height: 25px; }
179
+ .portable-mobile-nav button span { width: 100%; overflow: hidden; text-align: center; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; font-weight: 600; }
180
+ .portable-mobile-backdrop { position: fixed; inset: 0; z-index: 300; display: block; background: rgb(10 10 10 / 0.5); backdrop-filter: blur(3px); }
181
+ .portable-mobile-drawer { position: fixed; inset: 0 auto 0 0; z-index: 400; display: flex; width: min(304px, 88vw); flex-direction: column; overflow: hidden; border-right: 1px solid hsl(var(--border)); border-radius: 0 18px 18px 0; background: hsl(var(--background) / 0.98); box-shadow: 0 16px 50px rgb(0 0 0 / 0.25); backdrop-filter: blur(14px); }
182
+ .portable-mobile-drawer-close { display: flex; justify-content: flex-end; padding: 10px 12px; border-bottom: 1px solid hsl(var(--border)); }
183
+ .portable-mobile-drawer .portable-sidebar-header { background: hsl(var(--muted)); }
184
+ .portable-page-grid.grid-24 { grid-template-columns: 1fr; }
185
+ .portable-page-grid.grid-24 > .portable-placement { grid-column: 1 !important; grid-row: auto !important; }
186
+ .portable-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
187
+ }
188
+
189
+ @media (max-width: 560px) {
190
+ .portable-mobile-header { gap: 8px; padding-inline: 10px; }
191
+ .portable-mobile-header .portable-brand strong { max-width: 150px; }
192
+ .portable-page { min-height: 0; padding: 20px 14px 30px; }
193
+ .portable-page-header { margin-bottom: 16px; }
194
+ .portable-page-header h1 { font-size: 25px; }
195
+ .portable-stat-grid, .portable-form, .portable-task-fields, .portable-card-grid dl { grid-template-columns: 1fr; }
196
+ .portable-component { padding: 15px; border-radius: 12px; }
197
+ }
@@ -0,0 +1,48 @@
1
+ export declare const PORTABLE_WORKBENCH_COMPONENT_TYPES: readonly ["Typography", "Text", "Title", "Paragraph", "Statistic", "StatisticGroup", "Table", "EditableTable", "AnalyticsTable", "DataGridCard", "Chart", "EChartsChart", "RadarChart", "Form", "TaskInput", "TaskInputRenderer", "List", "Tabs", "Container", "Card", "CustomContent", "FilterPanel"];
2
+ export type PortableWorkbenchComponentType = typeof PORTABLE_WORKBENCH_COMPONENT_TYPES[number];
3
+ export type WorkbenchNavigationItem = {
4
+ key?: string;
5
+ title?: string | Record<string, string>;
6
+ icon?: string;
7
+ linkedPage?: string;
8
+ children?: WorkbenchNavigationItem[];
9
+ visibility?: {
10
+ devices?: Array<'desktop' | 'mobile'>;
11
+ };
12
+ [key: string]: unknown;
13
+ };
14
+ export type WorkbenchComponentConfig = {
15
+ id: string;
16
+ type: PortableWorkbenchComponentType | string;
17
+ props?: Record<string, unknown>;
18
+ components?: WorkbenchComponentConfig[];
19
+ children?: WorkbenchComponentConfig[];
20
+ customStyles?: Record<string, unknown>;
21
+ mockData?: unknown[];
22
+ [key: string]: unknown;
23
+ };
24
+ export type WorkbenchPageConfig = {
25
+ title?: string | Record<string, string>;
26
+ description?: string | Record<string, string>;
27
+ layout?: Record<string, unknown>;
28
+ components?: WorkbenchComponentConfig[];
29
+ customStyles?: Record<string, unknown>;
30
+ [key: string]: unknown;
31
+ };
32
+ export type WorkbenchAppConfig = {
33
+ appId?: string;
34
+ name?: string | Record<string, string>;
35
+ description?: string | Record<string, string>;
36
+ defaultPage?: string;
37
+ navigation?: {
38
+ items?: WorkbenchNavigationItem[];
39
+ };
40
+ [key: string]: unknown;
41
+ };
42
+ export type WorkbenchConfig = {
43
+ schemaVersion?: number;
44
+ appConfig?: WorkbenchAppConfig;
45
+ pages?: Record<string, WorkbenchPageConfig>;
46
+ metadata?: Record<string, unknown>;
47
+ [key: string]: unknown;
48
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Stable compatibility runtime for GeniApps exported from Workbench.
3
+ *
4
+ * Applications should import only this public entry. The implementation is
5
+ * deliberately independent from the private Workbench editor and API source.
6
+ */
7
+ export { mountWorkbench } from './workbench/runtime';
8
+ export { PORTABLE_WORKBENCH_COMPONENT_TYPES, type PortableWorkbenchComponentType, type WorkbenchAppConfig, type WorkbenchComponentConfig, type WorkbenchConfig, type WorkbenchNavigationItem, type WorkbenchPageConfig, } from './workbench/types';