nexus-shell 0.1.23 → 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.
- package/README.md +148 -107
- package/dist/components/layout/ShellLayout.d.ts +57 -11
- package/dist/components/widgets/ActivityBar.d.ts +48 -1
- package/dist/components/widgets/AppTitle.d.ts +30 -0
- package/dist/components/widgets/ChatPane.d.ts +63 -1
- package/dist/components/widgets/CommandPalette.d.ts +55 -7
- package/dist/components/widgets/ContextMenu.d.ts +34 -3
- package/dist/components/widgets/DataGrid.d.ts +44 -0
- package/dist/components/widgets/MenuBar.d.ts +55 -5
- package/dist/components/widgets/Modal.d.ts +58 -0
- package/dist/components/widgets/QuickSearch.d.ts +66 -0
- package/dist/components/widgets/SearchWidget.d.ts +36 -0
- package/dist/components/widgets/SettingsPanel.d.ts +33 -0
- package/dist/components/widgets/SidebarPane.d.ts +37 -1
- package/dist/components/widgets/StatusBar.d.ts +51 -1
- package/dist/components/widgets/TerminalPane.d.ts +43 -1
- package/dist/components/widgets/ThemeSwitcher.d.ts +35 -5
- package/dist/components/widgets/TreeWidget.d.ts +94 -5
- package/dist/components/widgets/UserProfile.d.ts +75 -6
- package/dist/connected/ConnectedActivityBar.d.ts +10 -0
- package/dist/connected/ConnectedChatPane.d.ts +18 -0
- package/dist/connected/ConnectedCommandPalette.d.ts +18 -0
- package/dist/connected/ConnectedMenuBar.d.ts +12 -0
- package/dist/connected/ConnectedModal.d.ts +15 -0
- package/dist/connected/ConnectedSidebarPane.d.ts +12 -0
- package/dist/connected/ConnectedStatusBar.d.ts +15 -0
- package/dist/connected/ConnectedTerminalPane.d.ts +18 -0
- package/dist/connected/ConnectedThemeSwitcher.d.ts +11 -0
- package/dist/connected/ConnectedUserProfile.d.ts +14 -0
- package/dist/connected/index.d.ts +21 -0
- package/dist/core/registry/MenuRegistry.d.ts +22 -9
- package/dist/core/services/ChatService.d.ts +23 -7
- package/dist/core/services/StatusBarService.d.ts +17 -14
- package/dist/index.d.ts +44 -32
- package/dist/lib/cn.d.ts +12 -0
- package/dist/nexus-shell.es.js +2360 -40
- package/dist/nexus-shell.umd.js +1 -3707
- package/dist/style.css +1 -1
- package/package.json +43 -15
- package/dist/App.d.ts +0 -2
- package/dist/components/layout/NexusWorkspaceShell.d.ts +0 -9
- package/dist/components/widgets/AgentManager.d.ts +0 -18
- package/dist/components/widgets/ArgumentInspectorWidget.d.ts +0 -5
- package/dist/components/widgets/DialogueMapperInspector.d.ts +0 -5
- package/dist/components/widgets/DialogueMapperLibrary.d.ts +0 -11
- package/dist/components/widgets/DialogueMapperLibraryWidget.d.ts +0 -3
- package/dist/components/widgets/DialogueMappingWidget.d.ts +0 -10
- package/dist/components/widgets/FilesSidebar.d.ts +0 -1
- package/dist/components/widgets/FlowControlToolbar.d.ts +0 -18
- package/dist/components/widgets/GlobalModal.d.ts +0 -3
- package/dist/components/widgets/MenuBarSearch.d.ts +0 -11
- package/dist/components/widgets/MockupReviewWidget.d.ts +0 -3
- package/dist/components/widgets/NexusWorkspaceTitle.d.ts +0 -10
- package/dist/components/widgets/ProjectPropertiesWidget.d.ts +0 -8
- package/dist/components/widgets/WargameMap.d.ts +0 -31
- package/dist/components/widgets/WelcomeTab.d.ts +0 -8
- package/dist/components/widgets/dialogue-mapper/IbisNode.d.ts +0 -5
- package/dist/components/widgets/mockup-reviewer/ExecutionOverlay.d.ts +0 -10
- package/dist/components/widgets/mockup-reviewer/HtmlShadowRenderer.d.ts +0 -9
- package/dist/components/widgets/mockup-reviewer/ImplementationPlanWorkspace.d.ts +0 -8
- package/dist/components/widgets/mockup-reviewer/MockupReviewWorkspace.d.ts +0 -10
- package/dist/components/widgets/mockup-reviewer/ReviewSidebar.d.ts +0 -3
- package/dist/components/widgets/mockup-reviewer/ReviewToolbar.d.ts +0 -12
- package/dist/components/widgets/mockup-reviewer/WorkflowMapper.d.ts +0 -7
- package/dist/components/widgets/wiki/AiCoWriterWorkspace.d.ts +0 -3
- package/dist/components/widgets/wiki/SemanticLinkMapper.d.ts +0 -3
- package/dist/components/widgets/wiki/WikiChatWidget.d.ts +0 -3
- package/dist/components/widgets/wiki/WikiEditor.d.ts +0 -3
- package/dist/components/widgets/wiki/WikiHistorySidebar.d.ts +0 -3
- package/dist/components/widgets/wiki/WikiNavigator.d.ts +0 -3
- package/dist/core/Boot.d.ts +0 -4
- package/dist/core/services/DialogueMappingService.d.ts +0 -59
- package/dist/core/services/FileStoreService.d.ts +0 -11
- package/dist/core/services/MockupReviewService.d.ts +0 -58
- package/dist/core/services/dialogue-mapper/DialogueLayoutEngine.d.ts +0 -9
- package/dist/core/services/dialogue-mapper/DialogueMapRepository.d.ts +0 -15
- package/dist/core/services/mockup-reviewer/MockupFixtures.d.ts +0 -11
- package/dist/core/services/useWikiStore.d.ts +0 -33
- package/dist/index-4EyxMz0x.js +0 -78516
- package/dist/main.d.ts +0 -1
- package/dist/maplibre-gl-DJOCpYhv.js +0 -24588
- package/dist/plugins/WikiPlugin.d.ts +0 -3
- package/dist/stories/ActivityBar.stories.d.ts +0 -9
- package/dist/stories/AgentManager.stories.d.ts +0 -25
- package/dist/stories/ChatPane.stories.d.ts +0 -10
- package/dist/stories/CommandPalette.stories.d.ts +0 -9
- package/dist/stories/DataGrid.stories.d.ts +0 -12
- package/dist/stories/DialogueMapperLibrary.stories.d.ts +0 -10
- package/dist/stories/DialogueMappingWidget.stories.d.ts +0 -9
- package/dist/stories/FlowControlToolbar.stories.d.ts +0 -14
- package/dist/stories/GlobalModal.stories.d.ts +0 -7
- package/dist/stories/IbisNode.stories.d.ts +0 -10
- package/dist/stories/MenuBar.stories.d.ts +0 -10
- package/dist/stories/MenuBarSearch.stories.d.ts +0 -7
- package/dist/stories/MockupReviewWidget.stories.d.ts +0 -9
- package/dist/stories/MockupReviewerLayout.stories.d.ts +0 -8
- package/dist/stories/NexusWorkspaceShell.stories.d.ts +0 -9
- package/dist/stories/NexusWorkspaceTitle.stories.d.ts +0 -11
- package/dist/stories/SearchWidget.stories.d.ts +0 -9
- package/dist/stories/ShellLayout.stories.d.ts +0 -13
- package/dist/stories/SidebarPane.stories.d.ts +0 -8
- package/dist/stories/StatusBar.stories.d.ts +0 -10
- package/dist/stories/TerminalPane.stories.d.ts +0 -9
- package/dist/stories/ThemeSwitcher.stories.d.ts +0 -10
- package/dist/stories/TreeWidget.stories.d.ts +0 -8
- package/dist/stories/UserProfile.stories.d.ts +0 -11
- package/dist/stories/WargameMap.stories.d.ts +0 -14
- package/dist/stories/wiki/WikiComposition.stories.d.ts +0 -6
- package/dist/stories/wiki/WikiWidgets.stories.d.ts +0 -11
package/README.md
CHANGED
|
@@ -1,147 +1,188 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Nexus Shell
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[](https://github.com/techmuch/nexus-shell/actions/workflows/deploy-storybook.yml)
|
|
6
|
-
[](https://techmuch.github.io/nexus-shell/?path=/docs/introduction--docs)
|
|
3
|
+
React components for building IDE-style application shells — menu bar, activity
|
|
4
|
+
bar, sidebar, docking layout, terminal, chat pane and status bar.
|
|
7
5
|
|
|
8
|
-
|
|
6
|
+
**[Documentation and live examples →](https://techmuch.github.io/nexus-shell/)** ·
|
|
7
|
+
[Storybook](https://techmuch.github.io/nexus-shell/storybook/)
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
```bash
|
|
10
|
+
npm install nexus-shell
|
|
11
|
+
```
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
```ts
|
|
14
|
+
import 'nexus-shell/style.css';
|
|
15
|
+
```
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
Explore the live documentation, interactive component playground, prop definitions, and layout compositions at:
|
|
16
|
-
👉 **[Live Storybook Documentation Site](https://techmuch.github.io/nexus-shell/?path=/docs/introduction--docs)**
|
|
17
|
+
React 19 is a peer dependency.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
## Two tiers
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
**Primitives** are pure and prop-driven. No global state, no registry lookups.
|
|
22
|
+
You pass data in, you get callbacks out.
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
```tsx
|
|
25
|
+
import { StatusBar, ActivityBar, SidebarPane, TreeWidget } from 'nexus-shell';
|
|
26
|
+
|
|
27
|
+
const [active, setActive] = useState<string | null>('files');
|
|
28
|
+
|
|
29
|
+
<div className="theme-light flex h-screen flex-col">
|
|
30
|
+
<div className="flex flex-1">
|
|
31
|
+
<ActivityBar
|
|
32
|
+
items={panels}
|
|
33
|
+
activeId={active}
|
|
34
|
+
onSelect={(id) => setActive(id === active ? null : id)}
|
|
35
|
+
/>
|
|
36
|
+
{active && (
|
|
37
|
+
<SidebarPane title="Explorer" onClose={() => setActive(null)}>
|
|
38
|
+
<TreeWidget data={files} onToggle={toggle} onActivate={open} />
|
|
39
|
+
</SidebarPane>
|
|
40
|
+
)}
|
|
41
|
+
<main className="flex-1">{children}</main>
|
|
42
|
+
</div>
|
|
43
|
+
<StatusBar widgets={[{ id: 'branch', label: 'main', alignment: 'left' }]} />
|
|
44
|
+
</div>;
|
|
45
|
+
```
|
|
26
46
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-

|
|
30
|
-
*(Above: Light Theme workspace showing responsive menus, active tab headers, and the account widget)*
|
|
47
|
+
**`ShellLayout`** is the assembled frame — the same components, wired to a set of
|
|
48
|
+
zustand stores and registries so you configure declaratively:
|
|
31
49
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-

|
|
35
|
-
*(Above: A complex Mockup Reviewer workstation running canvas drawing tools and terminal consoles side-by-side)*
|
|
50
|
+
```tsx
|
|
51
|
+
import { ShellLayout, componentRegistry } from 'nexus-shell';
|
|
36
52
|
|
|
37
|
-
|
|
38
|
-
Reorganized story taxonomy allowing you to build, test, and preview widgets in isolation or combined.
|
|
39
|
-

|
|
53
|
+
componentRegistry.register('editor', Editor);
|
|
40
54
|
|
|
41
|
-
|
|
55
|
+
<ShellLayout
|
|
56
|
+
title={<Logo />}
|
|
57
|
+
panels={[{ id: 'files', label: 'Explorer', icon: Files, component: FileTree }]}
|
|
58
|
+
menuConfig={{ File: [{ id: 'save', label: 'Save', commandId: 'file.save' }] }}
|
|
59
|
+
statusBarConfig={[{ id: 'branch', label: 'main', alignment: 'left' }]}
|
|
60
|
+
/>;
|
|
61
|
+
```
|
|
42
62
|
|
|
43
|
-
|
|
63
|
+
Each primitive also has a `Connected*` variant that binds it to the matching
|
|
64
|
+
store. `ShellLayout` is built out of those, and they're exported, so you can mix
|
|
65
|
+
tiers freely.
|
|
44
66
|
|
|
45
|
-
|
|
46
|
-
| :--- | :--- |
|
|
47
|
-
| **IDE/Workbench Web Apps** | A complete drag-and-drop tab layout engine with splits, resizing, and sidebars (`flexlayout-react` integration). |
|
|
48
|
-
| **Modular Dashboard Interfaces** | Inversion of Control registries (`componentRegistry`, `commandRegistry`, `menuRegistry`) so features register themselves dynamically. |
|
|
49
|
-
| **Complex Geospatial/Tactical Maps** | High-performance maps (`WargameMap`) combining `react-map-gl`, `deck.gl`, and `h3-js` for hexagonal grid overlays and MIL-STD military icons. |
|
|
50
|
-
| **AI Orchestration Workbenches** | State-driven workflow templates, agent nodes, and drawing canvas mockups built with React Flow. |
|
|
67
|
+
## Components
|
|
51
68
|
|
|
52
|
-
|
|
69
|
+
| Primitive | What it is |
|
|
70
|
+
| :-- | :-- |
|
|
71
|
+
| `ActivityBar` | Vertical icon rail for switching sidebar panels |
|
|
72
|
+
| `ChatPane` | Docked chat transcript with slash-command autocomplete |
|
|
73
|
+
| `CommandPalette` | Filterable, keyboard-navigable command list |
|
|
74
|
+
| `ContextMenu` | Floating menu positioned at viewport coordinates |
|
|
75
|
+
| `DataGrid` | Sortable, filterable table with optional virtualisation |
|
|
76
|
+
| `MenuBar` | Application menu bar with submenus and content slots |
|
|
77
|
+
| `Modal` | Alert / confirm / prompt dialog |
|
|
78
|
+
| `QuickSearch` | Compact search field with grouped results, for the menu bar |
|
|
79
|
+
| `SearchWidget` | Full-height search panel with autocomplete, for the sidebar |
|
|
80
|
+
| `SettingsPanel` | Theme picker body for the settings sidebar |
|
|
81
|
+
| `SidebarPane` | Titled, closable container for sidebar content |
|
|
82
|
+
| `StatusBar` | Footer with left / center / right item groups |
|
|
83
|
+
| `TerminalPane` | Bottom-docked terminal log and input |
|
|
84
|
+
| `ThemeSwitcher` | Segmented theme control |
|
|
85
|
+
| `TreeWidget` | Virtualised file tree with drag-to-move and a data-driven menu |
|
|
86
|
+
| `UserProfile` | Avatar and identity widget |
|
|
53
87
|
|
|
54
|
-
|
|
88
|
+
`ShellLayout` composes all of them.
|
|
55
89
|
|
|
56
|
-
|
|
57
|
-
- **Inversion of Control (IoC) Registries**: Add new menu items, hotkeys, or tab contents programmatically from anywhere in your code without touching the layout container.
|
|
58
|
-
- **Zustand State Persistence**: Automatically restores the user's workspace structure, theme preference, and pane configurations across page reloads.
|
|
59
|
-
- **Accessibility & Contrast First**: Built to look beautiful and professional under three default themes (`theme-light`, `theme-dark`, and `theme-gt` for Georgia Tech fans) while satisfying AA/AAA color contrast ratios.
|
|
60
|
-
- **Pre-Integrated Widgets**: A library of reusable layout widgets including terminal consoles, chat panels, tree file explorers, virtualized grids, and hex maps.
|
|
90
|
+
## Theming
|
|
61
91
|
|
|
62
|
-
|
|
92
|
+
Three themes ship in the stylesheet: `theme-light`, `theme-dark`, `theme-gt`.
|
|
93
|
+
Colors are CSS custom properties scoped to those classes, so switching themes is
|
|
94
|
+
a class on an ancestor — no React context, no provider.
|
|
63
95
|
|
|
64
|
-
|
|
96
|
+
Add your own by defining a `.theme-yourname` block with the same properties.
|
|
65
97
|
|
|
66
|
-
|
|
98
|
+
## Development
|
|
67
99
|
|
|
68
100
|
```bash
|
|
69
|
-
npm install
|
|
101
|
+
npm install
|
|
102
|
+
|
|
103
|
+
npm run site # documentation site at :5173
|
|
104
|
+
npm run storybook # component workbench at :6006
|
|
105
|
+
npm run dev # showcase app at :5173
|
|
106
|
+
|
|
107
|
+
npm run typecheck # library sources
|
|
108
|
+
npm test # vitest — unit and architecture tests
|
|
109
|
+
npm run site:test # renders every site route and demo
|
|
110
|
+
npm run build # library build to dist/
|
|
111
|
+
npm run build-storybook
|
|
112
|
+
npm run site:build # documentation site to website/dist/
|
|
113
|
+
npm run e2e # Playwright against the showcase app
|
|
70
114
|
```
|
|
71
115
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
In your main entry point (e.g., `main.tsx` or `App.tsx`):
|
|
116
|
+
`npm run typecheck` covers `src/` only. To include the examples:
|
|
75
117
|
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
import ReactDOM from 'react-dom/client';
|
|
79
|
-
import { ShellLayout, initializeShell } from 'nexus-shell';
|
|
80
|
-
import 'nexus-shell/style.css'; // Essential styling properties
|
|
81
|
-
|
|
82
|
-
// Initialize core registries and default welcome workspace
|
|
83
|
-
initializeShell();
|
|
84
|
-
|
|
85
|
-
export default function App() {
|
|
86
|
-
return (
|
|
87
|
-
<div className="h-screen w-screen bg-background text-foreground">
|
|
88
|
-
<ShellLayout
|
|
89
|
-
title={<div className="font-bold text-lg">My Custom IDE</div>}
|
|
90
|
-
/>
|
|
91
|
-
</div>
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
|
|
118
|
+
```bash
|
|
119
|
+
npx tsc --noEmit -p tsconfig.examples.json
|
|
96
120
|
```
|
|
97
121
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
## 🏗 Registry-Driven Customization
|
|
122
|
+
CI runs all of the above on every push and pull request.
|
|
101
123
|
|
|
102
|
-
|
|
124
|
+
### Layout
|
|
103
125
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
126
|
+
```
|
|
127
|
+
src/
|
|
128
|
+
components/ Primitives — pure, prop-driven, the public API
|
|
129
|
+
connected/ Store-bound wrappers used by ShellLayout
|
|
130
|
+
core/ Stores (zustand) and registries
|
|
131
|
+
lib/ Shared utilities
|
|
132
|
+
stories/ MDX documentation pages
|
|
133
|
+
examples/
|
|
134
|
+
showcase/ Demo apps built on the library — not published
|
|
135
|
+
dialogue-mapper/
|
|
136
|
+
mockup-reviewer/
|
|
137
|
+
wiki/
|
|
138
|
+
wargame/
|
|
139
|
+
e2e/ Playwright specs for the showcase app
|
|
140
|
+
basic-app/ Minimal integration example
|
|
141
|
+
website/
|
|
142
|
+
src/demos/ Live examples — the source shown on the site
|
|
143
|
+
src/content/ The component gallery, as data
|
|
144
|
+
scripts/ Generates the props tables from the library's types
|
|
114
145
|
```
|
|
115
146
|
|
|
116
|
-
###
|
|
117
|
-
```typescript
|
|
118
|
-
import { componentRegistry } from 'nexus-shell';
|
|
147
|
+
### Documentation site
|
|
119
148
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
</div>
|
|
125
|
-
));
|
|
126
|
-
```
|
|
149
|
+
`website/` is a Vite app that imports the library from `../src`, not from
|
|
150
|
+
`dist`. Every example on the site is rendered by the current source, so a demo
|
|
151
|
+
that no longer compiles against the real API fails the build rather than
|
|
152
|
+
quietly documenting an API that no longer exists.
|
|
127
153
|
|
|
128
|
-
|
|
154
|
+
Two generation steps keep it honest:
|
|
129
155
|
|
|
130
|
-
|
|
156
|
+
- **Props tables** come from `website/scripts/generate-api.mjs`, which parses
|
|
157
|
+
the component sources for prop names, types, defaults and JSDoc. Nothing is
|
|
158
|
+
hand-written.
|
|
159
|
+
- **Code samples** are extracted from the demo files by `#region` marker, so the
|
|
160
|
+
snippet a visitor copies is provably the code that produced the thing they
|
|
161
|
+
just interacted with.
|
|
131
162
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
npm run dev:all
|
|
163
|
+
Adding a component to the site is one entry in `website/src/content/components.ts`
|
|
164
|
+
plus a demo file. There is no per-component page to keep in sync.
|
|
135
165
|
|
|
136
|
-
|
|
137
|
-
|
|
166
|
+
The site ships no dependencies of its own — routing, syntax highlighting and the
|
|
167
|
+
copy button are all local, so the docs can't drag the repo's install surface
|
|
168
|
+
around.
|
|
138
169
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
170
|
+
**Deployment.** `.github/workflows/deploy-pages.yml` builds the site and
|
|
171
|
+
Storybook on every push to `main` and publishes them as one Pages artifact — the
|
|
172
|
+
site at the root, Storybook under `/storybook/`. First-time setup needs your
|
|
173
|
+
credentials: run `./scripts/setup-pages.sh`.
|
|
174
|
+
|
|
175
|
+
The split between `components/` and `connected/` is the load-bearing one. A
|
|
176
|
+
component that reads a global store can't be configured by its caller, rendered
|
|
177
|
+
twice with different data, or documented — its props table is empty because it
|
|
178
|
+
has no props. Everything in `components/` is therefore forbidden from importing
|
|
179
|
+
`core/services`, and the tests in `components/__tests__` exist to keep it that
|
|
180
|
+
way.
|
|
142
181
|
|
|
143
|
-
|
|
182
|
+
Anything under `examples/` is a consumer of the library, not part of it. It's
|
|
183
|
+
built and documented alongside the components to prove the primitives are
|
|
184
|
+
sufficient, but it ships to nobody.
|
|
144
185
|
|
|
145
|
-
##
|
|
186
|
+
## License
|
|
146
187
|
|
|
147
|
-
MIT
|
|
188
|
+
MIT
|
|
@@ -1,17 +1,63 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
1
2
|
import { Model } from 'flexlayout-react';
|
|
3
|
+
import { IMenuItemConfig } from '../../core/registry/MenuRegistry';
|
|
4
|
+
import { ISlashCommandConfig } from '../../core/services/ChatService';
|
|
2
5
|
import { ISidebarPanel } from '../../core/services/SidebarService';
|
|
3
|
-
import {
|
|
4
|
-
import { IStatusBarWidget } from '../../core/services/StatusBarService';
|
|
5
|
-
import { IMenuItem } from '../../core/registry/MenuRegistry';
|
|
6
|
+
import { IStatusBarWidgetConfig } from '../../core/services/StatusBarService';
|
|
6
7
|
|
|
7
|
-
interface ShellLayoutProps {
|
|
8
|
+
export interface ShellLayoutProps {
|
|
9
|
+
/**
|
|
10
|
+
* Sidebar panels to register. Each becomes an icon in the activity bar and
|
|
11
|
+
* renders its `component` in the sidebar when selected.
|
|
12
|
+
*/
|
|
8
13
|
panels?: ISidebarPanel[];
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
/** Slash commands available in the chat pane. */
|
|
15
|
+
slashCommands?: ISlashCommandConfig[];
|
|
16
|
+
/** Menu structure, keyed by top-level menu name. Items dispatch by `commandId`. */
|
|
17
|
+
menuConfig?: Record<string, IMenuItemConfig[]>;
|
|
18
|
+
/** Items for the status bar, grouped by their `alignment`. */
|
|
19
|
+
statusBarConfig?: IStatusBarWidgetConfig[];
|
|
20
|
+
/** Branding shown at the far left of the menu bar. */
|
|
21
|
+
title?: ReactNode;
|
|
22
|
+
/** Slot at the far right of the menu bar, for actions or a theme switcher. */
|
|
23
|
+
rightMenuBarContent?: ReactNode;
|
|
24
|
+
/** Widget rendered between the menus and the right slot, sized for search. */
|
|
25
|
+
centerMenuBarContent?: ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* Take control of the docking layout. When provided, the shell renders this
|
|
28
|
+
* model and stops writing changes to `useLayoutStore` — useful for tests and
|
|
29
|
+
* stories. Omit it to use the store's persisted model.
|
|
30
|
+
*/
|
|
14
31
|
layoutModel?: Model;
|
|
32
|
+
disableLocalStorage?: boolean;
|
|
33
|
+
initialLayoutJson?: any;
|
|
34
|
+
onLayoutChange?: (layout: any) => void;
|
|
15
35
|
}
|
|
16
|
-
|
|
17
|
-
|
|
36
|
+
/**
|
|
37
|
+
* The complete application shell: menu bar, activity bar, sidebar, a
|
|
38
|
+
* `flexlayout-react` docking area, terminal, chat pane and status bar.
|
|
39
|
+
*
|
|
40
|
+
* This is the batteries-included composition. It registers whatever you pass
|
|
41
|
+
* into the shell stores on mount, then renders the `Connected*` component
|
|
42
|
+
* variants, which read from those stores. Tab contents come from the
|
|
43
|
+
* {@link componentRegistry}, so plugins can contribute views without the shell
|
|
44
|
+
* importing them.
|
|
45
|
+
*
|
|
46
|
+
* If you want the pieces without the wiring, import the individual components
|
|
47
|
+
* and compose them yourself — every one of them is prop-driven and works
|
|
48
|
+
* standalone.
|
|
49
|
+
*
|
|
50
|
+
* Closing a tab marked dirty via `useLayoutStore().setTabDirty` prompts for
|
|
51
|
+
* confirmation before the tab is removed.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```tsx
|
|
55
|
+
* <ShellLayout
|
|
56
|
+
* title={<Logo />}
|
|
57
|
+
* panels={[{ id: 'files', label: 'Explorer', icon: Files, component: FileTree }]}
|
|
58
|
+
* menuConfig={{ File: [{ id: 'save', label: 'Save', commandId: 'file.save' }] }}
|
|
59
|
+
* statusBarConfig={[{ id: 'branch', label: 'main', alignment: 'left' }]}
|
|
60
|
+
* />
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare const ShellLayout: ({ panels, slashCommands, menuConfig, statusBarConfig, title, rightMenuBarContent, centerMenuBarContent, layoutModel, }: ShellLayoutProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
import { LucideIcon } from 'lucide-react';
|
|
2
|
+
|
|
3
|
+
/** A single icon button in the {@link ActivityBar}. */
|
|
4
|
+
export interface IActivityBarItem {
|
|
5
|
+
/** Stable identifier reported to `onSelect`. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Accessible label and tooltip text. */
|
|
8
|
+
label: string;
|
|
9
|
+
/** `lucide-react` icon rendered at 20px. */
|
|
10
|
+
icon: LucideIcon;
|
|
11
|
+
}
|
|
12
|
+
export interface ActivityBarProps {
|
|
13
|
+
/** Items rendered in the main (top) group, in order. */
|
|
14
|
+
items?: IActivityBarItem[];
|
|
15
|
+
/**
|
|
16
|
+
* Items rendered in the bottom group, below the flex spacer. Defaults to a
|
|
17
|
+
* single Settings item. Pass `[]` to render no bottom group.
|
|
18
|
+
*/
|
|
19
|
+
bottomItems?: IActivityBarItem[];
|
|
20
|
+
/** Id of the currently active item, or `null` when nothing is selected. */
|
|
21
|
+
activeId?: string | null;
|
|
22
|
+
/**
|
|
23
|
+
* Called with the clicked item's id. Toggling — clicking the active item to
|
|
24
|
+
* deselect it — is the caller's decision, not the component's.
|
|
25
|
+
*/
|
|
26
|
+
onSelect?: (id: string) => void;
|
|
27
|
+
/** Extra classes merged onto the root `<aside>`. */
|
|
28
|
+
className?: string;
|
|
29
|
+
/** Accessible label for the landmark. Defaults to `"Activity Bar"`. */
|
|
30
|
+
'aria-label'?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The narrow vertical icon rail on the left edge of the shell, used to switch
|
|
34
|
+
* which panel the sidebar shows.
|
|
35
|
+
*
|
|
36
|
+
* Controlled — it holds no selection state. For the store-backed variant used
|
|
37
|
+
* by `ShellLayout`, see `ConnectedActivityBar`.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <ActivityBar
|
|
42
|
+
* items={[{ id: 'files', label: 'Explorer', icon: Files }]}
|
|
43
|
+
* activeId={active}
|
|
44
|
+
* onSelect={(id) => setActive(id === active ? null : id)}
|
|
45
|
+
* />
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare const ActivityBar: ({ items, bottomItems, activeId, onSelect, className, "aria-label": ariaLabel, }: ActivityBarProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface AppTitleProps {
|
|
4
|
+
/** Primary line. Rendered uppercase in a mono face. */
|
|
5
|
+
title: string;
|
|
6
|
+
/** Secondary line beneath the title. Omit to render a single line. */
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Element shown in the leading badge, typically a 16px `lucide-react` icon.
|
|
10
|
+
* Omit to render no badge at all.
|
|
11
|
+
*/
|
|
12
|
+
icon?: React.ReactNode;
|
|
13
|
+
/** Extra classes merged onto the root element. */
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A branding lockup — icon badge, title and subtitle — sized for the
|
|
18
|
+
* {@link MenuBar}'s `title` slot.
|
|
19
|
+
*
|
|
20
|
+
* Purely presentational. Pass whatever branding your app needs; the library
|
|
21
|
+
* supplies no default copy.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* <MenuBar
|
|
26
|
+
* title={<AppTitle title="Acme Studio" subtitle="Design System" icon={<Boxes size={16} />} />}
|
|
27
|
+
* />
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare const AppTitle: ({ title, subtitle, icon, className }: AppTitleProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1,63 @@
|
|
|
1
|
-
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
/** A single message in the {@link ChatPane} transcript. */
|
|
4
|
+
export interface IChatMessage {
|
|
5
|
+
/** Stable identifier. Used as the React key. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Who sent it. `'user'` right-aligns; anything else left-aligns. */
|
|
8
|
+
role: 'user' | 'assistant';
|
|
9
|
+
/** Message body. Rendered as plain text with newlines preserved. */
|
|
10
|
+
text: string;
|
|
11
|
+
/** Optional display name shown above the bubble. Defaults from `role`. */
|
|
12
|
+
author?: string;
|
|
13
|
+
}
|
|
14
|
+
/** A `/`-prefixed shortcut offered in the composer's autocomplete. */
|
|
15
|
+
export interface ISlashCommand {
|
|
16
|
+
/** Command word without the leading slash, e.g. `"clear"`. */
|
|
17
|
+
command: string;
|
|
18
|
+
/** One-line description shown beside the command in the suggestion list. */
|
|
19
|
+
description: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ChatPaneProps {
|
|
22
|
+
/** Messages to display, oldest first. */
|
|
23
|
+
messages?: IChatMessage[];
|
|
24
|
+
/**
|
|
25
|
+
* Called with the trimmed message text on send. The component clears its
|
|
26
|
+
* composer but does not append to `messages` — that is the caller's job.
|
|
27
|
+
*/
|
|
28
|
+
onSend?: (text: string) => void;
|
|
29
|
+
/** Slash commands offered once the composer starts with `/`. */
|
|
30
|
+
slashCommands?: ISlashCommand[];
|
|
31
|
+
/** Called when a slash command is picked from the suggestion list. */
|
|
32
|
+
onSlashCommand?: (command: ISlashCommand) => void;
|
|
33
|
+
/** Called when the close button is pressed. Omit to hide the button. */
|
|
34
|
+
onClose?: () => void;
|
|
35
|
+
/** Title shown in the pane header. Defaults to `"Chat"`. */
|
|
36
|
+
title?: string;
|
|
37
|
+
/** Placeholder for the composer. */
|
|
38
|
+
placeholder?: string;
|
|
39
|
+
/** Shown in place of the transcript when `messages` is empty. */
|
|
40
|
+
emptyState?: React.ReactNode;
|
|
41
|
+
/** Extra classes merged onto the root element. */
|
|
42
|
+
className?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A docked chat panel: a scrolling transcript over a composer with slash-command
|
|
46
|
+
* autocomplete.
|
|
47
|
+
*
|
|
48
|
+
* Fully controlled — it owns only the in-progress input and the suggestion
|
|
49
|
+
* highlight. Messages, sending and visibility belong to the caller, so the same
|
|
50
|
+
* component works against a local array, a websocket, or an LLM endpoint. For
|
|
51
|
+
* the store-backed variant used by `ShellLayout`, see `ConnectedChatPane`.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```tsx
|
|
55
|
+
* <ChatPane
|
|
56
|
+
* messages={messages}
|
|
57
|
+
* onSend={(text) => send(text)}
|
|
58
|
+
* slashCommands={[{ command: 'clear', description: 'Clear the transcript' }]}
|
|
59
|
+
* onClose={() => setOpen(false)}
|
|
60
|
+
* />
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare const ChatPane: ({ messages, onSend, slashCommands, onSlashCommand, onClose, title, placeholder, emptyState, className, }: ChatPaneProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,8 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/** An entry in the {@link CommandPalette} list. */
|
|
2
|
+
export interface ICommandItem {
|
|
3
|
+
/** Stable identifier. Also matched against the query. */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Human-readable name shown in the list and matched against the query. */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Optional keybinding hint rendered on the right, e.g. `"⌘K"`. */
|
|
8
|
+
keybinding?: string;
|
|
6
9
|
}
|
|
7
|
-
export
|
|
8
|
-
|
|
10
|
+
export interface CommandPaletteProps<T extends ICommandItem = ICommandItem> {
|
|
11
|
+
/** Whether the palette is showing. */
|
|
12
|
+
open: boolean;
|
|
13
|
+
/** Commands to offer. Filtered against the query by `label` and `id`. */
|
|
14
|
+
commands: T[];
|
|
15
|
+
/** Called with the chosen command on click or Enter. */
|
|
16
|
+
onSelect: (command: T) => void;
|
|
17
|
+
/** Called on Escape and on backdrop click. */
|
|
18
|
+
onClose?: () => void;
|
|
19
|
+
/**
|
|
20
|
+
* Render inline instead of as a fixed overlay. Useful for documenting the
|
|
21
|
+
* palette in Storybook, or embedding it in a page. Defaults to `false`.
|
|
22
|
+
*/
|
|
23
|
+
inline?: boolean;
|
|
24
|
+
/** Placeholder for the query input. */
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Custom filter. Receives every command and the current query; return `true`
|
|
28
|
+
* to keep. Defaults to a case-insensitive substring match on `label` and `id`.
|
|
29
|
+
*/
|
|
30
|
+
filter?: (command: T, query: string) => boolean;
|
|
31
|
+
/** Extra classes merged onto the palette surface. */
|
|
32
|
+
className?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A VS Code-style command palette: a fuzzy-filtered, keyboard-navigable list of
|
|
36
|
+
* commands over a dimmed backdrop.
|
|
37
|
+
*
|
|
38
|
+
* Fully controlled — it owns only the query text and the highlighted row.
|
|
39
|
+
* Visibility, the command list and execution are the caller's. It also binds no
|
|
40
|
+
* global keyboard shortcut; for the store-backed variant that reads the
|
|
41
|
+
* {@link commandRegistry} and binds `Cmd/Ctrl+Shift+P`, see
|
|
42
|
+
* `ConnectedCommandPalette`.
|
|
43
|
+
*
|
|
44
|
+
* Arrow keys move the highlight, Enter selects, Escape closes.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```tsx
|
|
48
|
+
* <CommandPalette
|
|
49
|
+
* open={open}
|
|
50
|
+
* commands={[{ id: 'file.save', label: 'Save File', keybinding: '⌘S' }]}
|
|
51
|
+
* onSelect={(cmd) => { run(cmd.id); setOpen(false); }}
|
|
52
|
+
* onClose={() => setOpen(false)}
|
|
53
|
+
* />
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare const CommandPalette: <T extends ICommandItem = ICommandItem>({ open, commands, onSelect, onClose, inline, placeholder, filter, className, }: CommandPaletteProps<T>) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,16 +1,47 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
|
|
3
|
+
/** An entry in a {@link ContextMenu}. */
|
|
3
4
|
export interface IContextMenuItem {
|
|
5
|
+
/** Label shown for the entry. */
|
|
4
6
|
label: string;
|
|
7
|
+
/** Optional element rendered before the label, e.g. `<Plus size={14} />`. */
|
|
5
8
|
icon?: React.ReactNode;
|
|
9
|
+
/** Runs on click. The menu closes afterwards. */
|
|
6
10
|
onClick: () => void;
|
|
11
|
+
/** Draw a separator above this entry. */
|
|
7
12
|
divider?: boolean;
|
|
13
|
+
/** Render the entry greyed out and non-interactive. */
|
|
14
|
+
disabled?: boolean;
|
|
8
15
|
}
|
|
9
|
-
interface ContextMenuProps {
|
|
16
|
+
export interface ContextMenuProps {
|
|
17
|
+
/** Viewport x coordinate, typically `event.clientX`. */
|
|
10
18
|
x: number;
|
|
19
|
+
/** Viewport y coordinate, typically `event.clientY`. */
|
|
11
20
|
y: number;
|
|
21
|
+
/** Entries to show, in order. */
|
|
12
22
|
items: IContextMenuItem[];
|
|
23
|
+
/** Called on outside click, on Escape, and after any entry is chosen. */
|
|
13
24
|
onClose: () => void;
|
|
25
|
+
/** Extra classes merged onto the menu surface. */
|
|
26
|
+
className?: string;
|
|
14
27
|
}
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
/**
|
|
29
|
+
* A floating menu positioned at viewport coordinates, for right-click menus.
|
|
30
|
+
*
|
|
31
|
+
* Renders `position: fixed` at the given point and closes on outside click or
|
|
32
|
+
* Escape. It does not decide when to appear — mount it conditionally from your
|
|
33
|
+
* own `onContextMenu` handler and store the coordinates yourself.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* {menu && (
|
|
38
|
+
* <ContextMenu
|
|
39
|
+
* x={menu.x}
|
|
40
|
+
* y={menu.y}
|
|
41
|
+
* items={[{ label: 'Delete', onClick: () => remove(menu.id) }]}
|
|
42
|
+
* onClose={() => setMenu(null)}
|
|
43
|
+
* />
|
|
44
|
+
* )}
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const ContextMenu: ({ x, y, items, onClose, className }: ContextMenuProps) => import("react/jsx-runtime").JSX.Element;
|