@thatopen/services 0.0.6 → 0.2.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 (68) hide show
  1. package/README.md +59 -46
  2. package/dist/built-in/index.d.ts +723 -0
  3. package/dist/cli/lib/npmrc.d.ts +28 -0
  4. package/dist/cli/lib/npmrc.test.d.ts +1 -0
  5. package/dist/cli.js +103 -7
  6. package/dist/core/client.d.ts +20 -1
  7. package/dist/index.cjs.js +2 -2
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.es.js +130 -102
  10. package/dist/types/files.d.ts +6 -0
  11. package/dist/types/npm.d.ts +14 -0
  12. package/dist/vite-env.d.ts +1 -1
  13. package/docs/builtin/paths.json +22 -6
  14. package/package.json +99 -99
  15. package/resources/AGENTS.md +5 -3
  16. package/src/built-in/AppManager/example.ts +86 -86
  17. package/src/built-in/CDEManager/example.ts +214 -214
  18. package/src/built-in/CDEManager/examples/FileEditing/example.ts +226 -226
  19. package/src/built-in/CDEManager/examples/FileMoves/example.ts +186 -186
  20. package/src/built-in/CDEManager/examples/FileOperations/example.ts +295 -295
  21. package/src/built-in/CDEManager/examples/FileTransfers/example.ts +210 -210
  22. package/src/built-in/CDEManager/examples/FolderManagement/example.ts +230 -230
  23. package/src/built-in/CDEManager/examples/MetadataSchema/example.ts +230 -230
  24. package/src/built-in/CDEManager/examples/MetadataViews/example.ts +166 -166
  25. package/src/built-in/CDEManager/examples/ProjectConfig/example.ts +177 -177
  26. package/src/built-in/FileList/example.ts +107 -107
  27. package/src/built-in/TabbedNavigation/example.ts +115 -115
  28. package/src/built-in/UIManager/src/app/example.ts +99 -0
  29. package/src/built-in/UIManager/src/app/examples/AppState/example.ts +142 -0
  30. package/src/built-in/UIManager/src/app/examples/Contexts/example.ts +125 -0
  31. package/src/built-in/UIManager/src/app/examples/FloatingLayout/example.ts +92 -0
  32. package/src/built-in/UIManager/src/app/examples/Notifications/example.ts +161 -0
  33. package/src/built-in/UIManager/src/app/examples/Sidebar/example.ts +104 -0
  34. package/src/built-in/ViewportsManager/example.ts +106 -106
  35. package/src/built-in/index.ts +755 -755
  36. package/src/cli/templates/app/README.md +241 -241
  37. package/src/cli/templates/app/index.html +27 -27
  38. package/src/cli/templates/app/package.json +27 -25
  39. package/src/cli/templates/app/src/bim-components/CloudRunner/index.ts +87 -91
  40. package/src/cli/templates/app/src/bim-components/CloudRunner/src/index.ts +1 -1
  41. package/src/cli/templates/app/src/bim-components/CloudRunner/src/types.ts +5 -5
  42. package/src/cli/templates/app/src/bim-components/index.ts +1 -1
  43. package/src/cli/templates/app/src/main.ts +56 -89
  44. package/src/cli/templates/app/src/setups/cloud-runner.ts +9 -13
  45. package/src/cli/templates/app/src/setups/fragments.ts +18 -0
  46. package/src/cli/templates/app/src/setups/ifc-loader.ts +12 -0
  47. package/src/cli/templates/app/src/setups/index.ts +3 -3
  48. package/src/cli/templates/app/src/ui-components/AppPanel/index.ts +160 -0
  49. package/src/cli/templates/app/src/ui-components/index.ts +1 -2
  50. package/src/cli/templates/app/tsconfig.json +17 -16
  51. package/src/cli/templates/cloud-component/README.md +205 -205
  52. package/src/cli/templates/cloud-component/_thatopen +5 -5
  53. package/src/cli/templates/cloud-component/declarations.json +4 -4
  54. package/src/cli/templates/cloud-component/package.json +21 -21
  55. package/src/cli/templates/cloud-component/src/main.ts +70 -70
  56. package/src/cli/templates/cloud-component/tsconfig.json +16 -16
  57. package/src/cli/templates/shared/CLAUDE.md +1 -1
  58. package/src/cli/templates/shared/_gitignore +5 -4
  59. package/src/cli/templates/app/src/app.ts +0 -16
  60. package/src/cli/templates/app/src/globals.ts +0 -1
  61. package/src/cli/templates/app/src/setups/ui-manager.ts +0 -27
  62. package/src/cli/templates/app/src/setups/viewports-manager.ts +0 -22
  63. package/src/cli/templates/app/src/ui-components/app-info-section/index.ts +0 -26
  64. package/src/cli/templates/app/src/ui-components/app-info-section/src/index.ts +0 -1
  65. package/src/cli/templates/app/src/ui-components/app-info-section/src/types.ts +0 -15
  66. package/src/cli/templates/app/src/ui-components/cloud-runner-section/index.ts +0 -37
  67. package/src/cli/templates/app/src/ui-components/cloud-runner-section/src/index.ts +0 -1
  68. package/src/cli/templates/app/src/ui-components/cloud-runner-section/src/types.ts +0 -14
@@ -10,6 +10,12 @@ export type HiddenFileEntity = {
10
10
  export type CreateHiddenItemResult = {
11
11
  hiddenFileId: string;
12
12
  };
13
+ export type CreateHiddenItemsBatchResult = {
14
+ results: {
15
+ originalName: string;
16
+ hiddenFileId: string;
17
+ }[];
18
+ };
13
19
  export type MetadataValue = string | number | boolean | null;
14
20
  export type Metadata = Record<string, MetadataValue>;
15
21
  export declare const METADATA_LIMITS: {
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Read-only npm credentials for the private `@thatopen` Founders beta packages.
3
+ * Returned by `GET /api/npm-registry/credentials` to FOUNDING members only.
4
+ */
5
+ export interface NpmCredentials {
6
+ /** Registry the scope is pinned to (e.g. `https://registry.npmjs.org/`). */
7
+ registry: string;
8
+ /** Package scope the token grants read access to (e.g. `@thatopen`). */
9
+ scope: string;
10
+ /** The read-only npm token. */
11
+ token: string;
12
+ /** Ready-to-write `.npmrc` file body (scope pin + auth line). */
13
+ npmrc: string;
14
+ }
@@ -1 +1 @@
1
- /// <reference types="vite/client" />
1
+ /// <reference types="vite/client" />
@@ -1,8 +1,4 @@
1
1
  [
2
- {
3
- "path": "src/built-in/AppManager/example.ts",
4
- "description": ""
5
- },
6
2
  {
7
3
  "path": "src/built-in/CDEManager/example.ts",
8
4
  "description": "CDEManager — CDEManager is the central state machine for a Common Data Environment. It holds files, folders, metadata schemas, viewer groups, and user permissions, and exposes a typed state machine that all file operations — selecting, editing, uploading, viewing — route through. It has no DOM or Three.js dependencies and can run in Node, a browser, or a server-side worker wherever `@thatopen/components` is available."
@@ -48,7 +44,27 @@
48
44
  "description": ""
49
45
  },
50
46
  {
51
- "path": "src/built-in/ViewportsManager/example.ts",
52
- "description": ""
47
+ "path": "src/built-in/UIManager/src/app/example.ts",
48
+ "description": "top-app — Front-end developers building BIM web apps need to coordinate several async initialization steps before the UI can be shown — loading the engine, preparing fragment workers, registering loaders — and users need visible feedback on what is happening during that wait, rather than a blank screen."
49
+ },
50
+ {
51
+ "path": "src/built-in/UIManager/src/app/examples/AppState/example.ts",
52
+ "description": "Shared reactive state with AppState — Developers building interactive BIM panels often need sibling components — a filter selector and a results table, for example — to stay in sync without a shared parent. Lifting state to a common ancestor and threading it down as props works for shallow trees but becomes unwieldy as the component tree grows."
53
+ },
54
+ {
55
+ "path": "src/built-in/UIManager/src/app/examples/Contexts/example.ts",
56
+ "description": "Consuming platform contexts in child components — Developers building custom BIM panels need access to the 3D engine, the platform API, and the current project's metadata — but threading these objects down through props across multiple component layers forces every intermediate element to know about data it doesn't use, making trees brittle and hard to refactor."
57
+ },
58
+ {
59
+ "path": "src/built-in/UIManager/src/app/examples/FloatingLayout/example.ts",
60
+ "description": "Floating layout — Developers building BIM coordination tools often want the 3D model to fill the entire window while control panels float above it — but standard grid layouts give every area equal standing, shrinking the viewer into one cell and leaving visible seams between it and the panels."
61
+ },
62
+ {
63
+ "path": "src/built-in/UIManager/src/app/examples/Notifications/example.ts",
64
+ "description": "Toasts, file drop, and cross-component notifications — Developers building BIM processing UIs need to surface status updates, errors, and file-drop feedback to users from different points in the component tree — but reaching back to the app root to trigger a notification from a deeply nested component requires threading a reference through every layer in between."
65
+ },
66
+ {
67
+ "path": "src/built-in/UIManager/src/app/examples/Sidebar/example.ts",
68
+ "description": "Sidebar navigation — Product teams building BIM apps often need multiple distinct views — a 3D model viewer, a data browser, a settings screen — but wiring a custom nav bar and managing view transitions from scratch adds complexity before any real feature work begins."
53
69
  }
54
70
  ]
package/package.json CHANGED
@@ -1,100 +1,100 @@
1
- {
2
- "name": "@thatopen/services",
3
- "description": "Client library and CLI for building BIM apps and cloud components on the That Open Platform",
4
- "author": "That Open Company",
5
- "license": "MIT",
6
- "homepage": "https://github.com/ThatOpen/engine_services#readme",
7
- "bugs": {
8
- "url": "https://github.com/ThatOpen/engine_services/issues"
9
- },
10
- "repository": {
11
- "type": "git",
12
- "url": "git+https://github.com/ThatOpen/engine_services.git"
13
- },
14
- "publishConfig": {
15
- "access": "public"
16
- },
17
- "private": false,
18
- "version": "0.0.6",
19
- "main": "dist/index.cjs.js",
20
- "module": "dist/index.es.js",
21
- "types": "dist/index.d.ts",
22
- "bin": {
23
- "thatopen": "dist/cli.js"
24
- },
25
- "files": [
26
- "dist",
27
- "src/cli/templates",
28
- "src/built-in",
29
- "docs",
30
- "resources"
31
- ],
32
- "scripts": {
33
- "dev": "vite",
34
- "lint": "eslint src/",
35
- "build": "eslint src/ && tsc && vite build && vite build --config vite.config.cli.mts && node scripts/generate-cli-docs-paths.mjs && node scripts/generate-client-examples-paths.mjs",
36
- "build:lib": "tsc && vite build",
37
- "test": "vitest run",
38
- "test:watch": "vitest",
39
- "build:cli": "vite build --config vite.config.cli.mts",
40
- "preview": "vite preview",
41
- "test:ui": "vite --config test/vite.config.mts",
42
- "test:cli-build-app": "npm run build:cli && node test/setup-test-app.mjs",
43
- "test:cli-serve-app": "cd temp/test-app && thatopen serve",
44
- "test:cli-build-component": "npm run build:cli && node test/setup-test-component.mjs",
45
- "test:cli-run-component": "cd temp/test-component && thatopen run --skip-build",
46
- "test:cli-serve-component": "cd temp/test-component && thatopen local-server",
47
- "template:app": "cd src/cli/templates/app && npm install && cd ../../../.. && node scripts/generate-template-tsconfig.mjs",
48
- "template:app:dev": "cd src/cli/templates/app && npm run dev",
49
- "changeset": "changeset",
50
- "version": "changeset version",
51
- "prepublishOnly": "npm run build"
52
- },
53
- "devDependencies": {
54
- "@changesets/cli": "^2.27.7",
55
- "@thatopen/components": "~3.4.0",
56
- "@thatopen/components-front": "~3.4.0",
57
- "@thatopen/fragments": "~3.4.0",
58
- "@thatopen/ui": "~3.4.0",
59
- "@thatopen/ui-obc": "~3.4.0",
60
- "@types/node": "^20.12.12",
61
- "@types/three": "^0.182.0",
62
- "commander": "^14.0.3",
63
- "esbuild": "^0.27.3",
64
- "eslint": "9.x",
65
- "eslint-config-prettier": "^9.1.0",
66
- "eslint-plugin-prettier": "^5.1.3",
67
- "globals": "^15.3.0",
68
- "jszip": "^3.10.1",
69
- "prettier": "^3.2.5",
70
- "three": "^0.182.0",
71
- "tsx": "^4.16.2",
72
- "typescript": "^5.2.2",
73
- "typescript-eslint": "^7.10.0",
74
- "vite": "^5.2.0",
75
- "vite-plugin-dts": "^3.9.1",
76
- "vite-plugin-eslint": "^1.8.1",
77
- "vitest": "^4.1.4"
78
- },
79
- "dependencies": {
80
- "dotenv": "^16.4.5",
81
- "socket.io": "^4.8.0",
82
- "socket.io-client": "^4.8.0"
83
- },
84
- "peerDependencies": {
85
- "@thatopen/components": "~3.4.0",
86
- "@thatopen/ui": "~3.4.0",
87
- "three": "^0.182.0"
88
- },
89
- "peerDependenciesMeta": {
90
- "@thatopen/components": {
91
- "optional": true
92
- },
93
- "@thatopen/ui": {
94
- "optional": true
95
- },
96
- "three": {
97
- "optional": true
98
- }
99
- }
1
+ {
2
+ "name": "@thatopen/services",
3
+ "description": "Client library and CLI for building BIM apps and cloud components on the That Open Platform",
4
+ "author": "That Open Company",
5
+ "license": "MIT",
6
+ "homepage": "https://github.com/ThatOpen/engine_services#readme",
7
+ "bugs": {
8
+ "url": "https://github.com/ThatOpen/engine_services/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/ThatOpen/engine_services.git"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "private": false,
18
+ "version": "0.2.0",
19
+ "main": "dist/index.cjs.js",
20
+ "module": "dist/index.es.js",
21
+ "types": "dist/index.d.ts",
22
+ "bin": {
23
+ "thatopen": "dist/cli.js"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "src/cli/templates",
28
+ "src/built-in",
29
+ "docs",
30
+ "resources"
31
+ ],
32
+ "scripts": {
33
+ "dev": "vite",
34
+ "lint": "eslint src/",
35
+ "build": "eslint src/ && tsc && vite build && vite build --config vite.config.cli.mts && node scripts/generate-cli-docs-paths.mjs && node scripts/generate-client-examples-paths.mjs",
36
+ "build:lib": "tsc && vite build",
37
+ "test": "vitest run",
38
+ "test:watch": "vitest",
39
+ "build:cli": "vite build --config vite.config.cli.mts",
40
+ "preview": "vite preview",
41
+ "test:ui": "vite --config test/vite.config.mts",
42
+ "test:cli-build-app": "npm run build:cli && node test/setup-test-app.mjs",
43
+ "test:cli-serve-app": "cd temp/test-app && thatopen serve",
44
+ "test:cli-build-component": "npm run build:cli && node test/setup-test-component.mjs",
45
+ "test:cli-run-component": "cd temp/test-component && thatopen run --skip-build",
46
+ "test:cli-serve-component": "cd temp/test-component && thatopen local-server",
47
+ "template:app": "cd src/cli/templates/app && npm install && cd ../../../.. && node scripts/generate-template-tsconfig.mjs",
48
+ "template:app:dev": "cd src/cli/templates/app && npm run dev",
49
+ "changeset": "changeset",
50
+ "version": "changeset version",
51
+ "prepublishOnly": "npm run build"
52
+ },
53
+ "devDependencies": {
54
+ "@changesets/cli": "^2.27.7",
55
+ "@thatopen/components": "~3.4.0",
56
+ "@thatopen/components-front": "~3.4.0",
57
+ "@thatopen/fragments": "~3.4.0",
58
+ "@thatopen/ui": "~3.4.0",
59
+ "@thatopen/ui-obc": "~3.4.0",
60
+ "@types/node": "^20.12.12",
61
+ "@types/three": "^0.182.0",
62
+ "commander": "^14.0.3",
63
+ "esbuild": "^0.27.3",
64
+ "eslint": "9.x",
65
+ "eslint-config-prettier": "^9.1.0",
66
+ "eslint-plugin-prettier": "^5.1.3",
67
+ "globals": "^15.3.0",
68
+ "jszip": "^3.10.1",
69
+ "prettier": "^3.2.5",
70
+ "three": "^0.182.0",
71
+ "tsx": "^4.16.2",
72
+ "typescript": "^5.2.2",
73
+ "typescript-eslint": "^7.10.0",
74
+ "vite": "^5.2.0",
75
+ "vite-plugin-dts": "^3.9.1",
76
+ "vite-plugin-eslint": "^1.8.1",
77
+ "vitest": "^4.1.4"
78
+ },
79
+ "dependencies": {
80
+ "dotenv": "^16.4.5",
81
+ "socket.io": "^4.8.0",
82
+ "socket.io-client": "^4.8.0"
83
+ },
84
+ "peerDependencies": {
85
+ "@thatopen/components": "~3.4.0",
86
+ "@thatopen/ui": "~3.4.0",
87
+ "three": "^0.182.0"
88
+ },
89
+ "peerDependenciesMeta": {
90
+ "@thatopen/components": {
91
+ "optional": true
92
+ },
93
+ "@thatopen/ui": {
94
+ "optional": true
95
+ },
96
+ "three": {
97
+ "optional": true
98
+ }
99
+ }
100
100
  }
@@ -16,15 +16,17 @@ Do this before answering any question or writing any code. These are compact des
16
16
 
17
17
  | What | Where |
18
18
  |---|---|
19
- | Platform built-ins | `docs/builtin/paths.json` |
20
- | Platform client API | `docs/client/paths.json` |
21
- | CLI commands | `docs/cli/paths.json` |
19
+ | Platform built-ins | `node_modules/@thatopen/services/docs/builtin/paths.json` |
20
+ | Platform client API | `node_modules/@thatopen/services/docs/client/paths.json` |
21
+ | CLI commands | `node_modules/@thatopen/services/docs/cli/paths.json` |
22
22
  | Engine components (`OBC`, `OBF`) | `https://raw.githubusercontent.com/ThatOpen/engine_components/refs/heads/main/examples/paths.json` |
23
23
  | Fragments (`FRAGS`) | `https://raw.githubusercontent.com/ThatOpen/engine_fragment/refs/heads/main/examples/paths.json` |
24
24
  | UI components (`BUI`) | `https://raw.githubusercontent.com/ThatOpen/engine_ui-components/refs/heads/main/examples/paths.json` — **skip** entries whose path contains `packages/obc` or `bim-grid` |
25
25
 
26
26
  Once you have these, you know everything available on the platform. Only then fetch a specific example file when you need implementation details.
27
27
 
28
+ > **Path resolution:** all `path` entries inside the local indexes (`docs/`, `src/`) are relative to the `@thatopen/services` package root — prepend `node_modules/@thatopen/services/` when reading any of those files.
29
+
28
30
  ---
29
31
 
30
32
  ## How to work
@@ -1,86 +1,86 @@
1
- import * as OBC from "@thatopen/components";
2
- import * as BUI from "@thatopen/ui";
3
- import appManagerDef from "./index";
4
-
5
- // ── State types ───────────────────────────────────────────────────────
6
-
7
- type Panel1State = { label: string; components: OBC.Components };
8
- type Panel2State = { label: string; components: OBC.Components };
9
-
10
- // ── App type ──────────────────────────────────────────────────────────
11
-
12
- interface MyApp {
13
- icons: ["LOAD", "TREE", "VIEW"];
14
- grid: BUI.Grid<
15
- ["Split", "Viewer"],
16
- [{ name: "panel1"; state: Panel1State }, { name: "panel2"; state: Panel2State }]
17
- >;
18
- }
19
-
20
- // ── Initialise OBC & BUI ──────────────────────────────────────────────
21
-
22
- BUI.Manager.init();
23
- const components = new OBC.Components();
24
-
25
- const AppManager = appManagerDef.componentDefinition;
26
- const app = components.get(AppManager<MyApp>);
27
-
28
- // ── Define element templates ──────────────────────────────────────────
29
-
30
- const panel1Template: BUI.StatefullComponent<Panel1State> = ({ label, components }) => {
31
- const app = components.get(AppManager<MyApp>);
32
- return BUI.html`
33
- <bim-panel active label=${label} style="min-width: 14rem;">
34
- <bim-panel-section label="Actions">
35
- <bim-button icon=${app.icons.LOAD} label="Load School Model"></bim-button>
36
- </bim-panel-section>
37
- <bim-panel-section label="Info">
38
- <bim-label>Use the sidebar to switch layouts.</bim-label>
39
- </bim-panel-section>
40
- </bim-panel>
41
- `;
42
- };
43
-
44
- const panel2Template: BUI.StatefullComponent<Panel2State> = ({ label, components }) => {
45
- const app = components.get(AppManager<MyApp>);
46
- return BUI.html`
47
- <bim-panel active label=${label} style="min-width: 14rem;">
48
- <bim-panel-section label="Settings">
49
- <bim-button icon=${app.icons.VIEW} label="View"></bim-button>
50
- </bim-panel-section>
51
- </bim-panel>
52
- `;
53
- };
54
-
55
- // ── Init ──────────────────────────────────────────────────────────────
56
-
57
- app.init({
58
- icons: {
59
- LOAD: "solar:upload-bold",
60
- TREE: "mdi:file-tree",
61
- VIEW: "mdi:monitor",
62
- },
63
- grid: (grid) => {
64
- grid.elements = {
65
- panel1: { template: panel1Template, initialState: { label: "Models", components } },
66
- panel2: { template: panel2Template, initialState: { label: "Settings", components } },
67
- };
68
- grid.layouts = {
69
- Split: {
70
- template: `
71
- "panel1" 1fr
72
- "panel2" 1fr
73
- / 25rem 1fr`,
74
- icon: app.icons.TREE,
75
- },
76
- Viewer: {
77
- template: `"panel1" 1fr / 1fr`,
78
- icon: app.icons.VIEW,
79
- },
80
- };
81
- grid.layout = "Split";
82
- },
83
- container: document.getElementById("container")!,
84
- });
85
-
86
- app.showSidebar = true;
1
+ import * as OBC from "@thatopen/components";
2
+ import * as BUI from "@thatopen/ui";
3
+ import appManagerDef from "./index";
4
+
5
+ // ── State types ───────────────────────────────────────────────────────
6
+
7
+ type Panel1State = { label: string; components: OBC.Components };
8
+ type Panel2State = { label: string; components: OBC.Components };
9
+
10
+ // ── App type ──────────────────────────────────────────────────────────
11
+
12
+ interface MyApp {
13
+ icons: ["LOAD", "TREE", "VIEW"];
14
+ grid: BUI.Grid<
15
+ ["Split", "Viewer"],
16
+ [{ name: "panel1"; state: Panel1State }, { name: "panel2"; state: Panel2State }]
17
+ >;
18
+ }
19
+
20
+ // ── Initialise OBC & BUI ──────────────────────────────────────────────
21
+
22
+ BUI.Manager.init();
23
+ const components = new OBC.Components();
24
+
25
+ const AppManager = appManagerDef.componentDefinition;
26
+ const app = components.get(AppManager<MyApp>);
27
+
28
+ // ── Define element templates ──────────────────────────────────────────
29
+
30
+ const panel1Template: BUI.StatefullComponent<Panel1State> = ({ label, components }) => {
31
+ const app = components.get(AppManager<MyApp>);
32
+ return BUI.html`
33
+ <bim-panel active label=${label} style="min-width: 14rem;">
34
+ <bim-panel-section label="Actions">
35
+ <bim-button icon=${app.icons.LOAD} label="Load School Model"></bim-button>
36
+ </bim-panel-section>
37
+ <bim-panel-section label="Info">
38
+ <bim-label>Use the sidebar to switch layouts.</bim-label>
39
+ </bim-panel-section>
40
+ </bim-panel>
41
+ `;
42
+ };
43
+
44
+ const panel2Template: BUI.StatefullComponent<Panel2State> = ({ label, components }) => {
45
+ const app = components.get(AppManager<MyApp>);
46
+ return BUI.html`
47
+ <bim-panel active label=${label} style="min-width: 14rem;">
48
+ <bim-panel-section label="Settings">
49
+ <bim-button icon=${app.icons.VIEW} label="View"></bim-button>
50
+ </bim-panel-section>
51
+ </bim-panel>
52
+ `;
53
+ };
54
+
55
+ // ── Init ──────────────────────────────────────────────────────────────
56
+
57
+ app.init({
58
+ icons: {
59
+ LOAD: "solar:upload-bold",
60
+ TREE: "mdi:file-tree",
61
+ VIEW: "mdi:monitor",
62
+ },
63
+ grid: (grid) => {
64
+ grid.elements = {
65
+ panel1: { template: panel1Template, initialState: { label: "Models", components } },
66
+ panel2: { template: panel2Template, initialState: { label: "Settings", components } },
67
+ };
68
+ grid.layouts = {
69
+ Split: {
70
+ template: `
71
+ "panel1" 1fr
72
+ "panel2" 1fr
73
+ / 25rem 1fr`,
74
+ icon: app.icons.TREE,
75
+ },
76
+ Viewer: {
77
+ template: `"panel1" 1fr / 1fr`,
78
+ icon: app.icons.VIEW,
79
+ },
80
+ };
81
+ grid.layout = "Split";
82
+ },
83
+ container: document.getElementById("container")!,
84
+ });
85
+
86
+ app.showSidebar = true;