Changeset 0.25.1 (#161)
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# DESIGN — Surface & Extension Architecture
|
||||
|
||||
**Status:** Accepted
|
||||
**Status:** Accepted (Phases 1–2 implemented in v0.25.1)
|
||||
**Scope:** Primitives, Components, Surfaces, Extension hooks, Themes
|
||||
**Depends on:** v0.22.5 (Go template engine), v0.22.7 (ChatPane)
|
||||
**Depends on:** v0.22.5 (Go template engine), v0.22.7 (ChatPane), v0.25.1 (audit)
|
||||
**Informs:** v0.22.8+, EXTENSIONS.md rewrite, ARCHITECTURE.md update, ICD-API, ICD-SURFACE
|
||||
|
||||
---
|
||||
@@ -159,7 +159,9 @@ Primitives.menu({ anchor: el, items: [...], onSelect: fn })
|
||||
Primitives.dialog({ title: 'Confirm', body: el, onConfirm: fn })
|
||||
```
|
||||
|
||||
Current locations: `ui-primitives.js`, `ui-primitives-additions.js`,
|
||||
Current locations: `ui-primitives.js` (factory functions, `esc()`,
|
||||
`createComponentRegistry()`, `componentMixin()`, `showConfirm()`,
|
||||
`showPrompt()`, `Theme`, `mountAvatarUpload()`)
|
||||
and Go template components (`model-select.html`, `team-select.html`,
|
||||
`file-upload.html`). These converge into one coherent set.
|
||||
|
||||
@@ -202,23 +204,42 @@ to interact with.
|
||||
|
||||
### Instance Pattern
|
||||
|
||||
Components use the factory pattern established by ChatPane:
|
||||
Components use `createComponentRegistry()` and `componentMixin()` from
|
||||
`ui-primitives.js` for shared lifecycle (instance tracking, event
|
||||
listener cleanup, destroy):
|
||||
|
||||
```js
|
||||
const pane = ChatPane.create({
|
||||
messagesEl: document.getElementById('editorChatMessages'),
|
||||
inputEl: document.getElementById('editorChatInput'),
|
||||
sendBtnEl: document.getElementById('editorSendBtn'),
|
||||
channelId: workspaceChatId,
|
||||
standalone: true,
|
||||
});
|
||||
const ChatPane = {
|
||||
...createComponentRegistry('ChatPane'),
|
||||
|
||||
// Lifecycle
|
||||
pane.renderMessages(msgs);
|
||||
pane.streamResponse(resp, msgs);
|
||||
pane.destroy();
|
||||
create(opts) {
|
||||
const instance = componentMixin({
|
||||
id: opts.id || 'pane-' + Date.now(),
|
||||
messagesEl: opts.messagesEl,
|
||||
inputEl: opts.inputEl,
|
||||
channelId: opts.channelId || null,
|
||||
// ... domain-specific state
|
||||
|
||||
// Component-specific teardown (called by mixin's destroy())
|
||||
_cleanup() {
|
||||
if (this._cmView) { this._cmView.destroy(); this._cmView = null; }
|
||||
},
|
||||
}, ChatPane);
|
||||
|
||||
ChatPane._register(instance.id, instance);
|
||||
return instance;
|
||||
},
|
||||
|
||||
// Custom queries beyond .get(id)
|
||||
forChannel(channelId) { /* ... */ },
|
||||
};
|
||||
```
|
||||
|
||||
The mixin provides `_on(el, event, handler)` for tracked event binding
|
||||
and `destroy()` which calls `_cleanup()` then removes all listeners and
|
||||
unregisters from the registry. Components that need extra teardown define
|
||||
`_cleanup()`.
|
||||
|
||||
Components can be instantiated multiple times on the same page (editor
|
||||
has a ChatPane, notes has a ChatPane — independent instances).
|
||||
|
||||
@@ -567,7 +588,7 @@ accommodates it without redesign.
|
||||
b. Register hooks (pre-completion, post-render, etc.)
|
||||
c. Register surface injections for current surface
|
||||
d. Initialize tool bridges
|
||||
5. Surface-specific JS runs (app.js for chat, editor-mode.js, etc.)
|
||||
5. Surface-specific JS runs (app.js for chat, editor-surface.js, etc.)
|
||||
```
|
||||
|
||||
`Extensions.boot()` replaces the current chat-specific
|
||||
@@ -672,8 +693,8 @@ post-render hooks use to discover display content from any extension.
|
||||
|
||||
| Current State | Target State |
|
||||
|---------------|-------------|
|
||||
| `ui-primitives.js` + `ui-primitives-additions.js` | Primitive catalog with stable factory API |
|
||||
| `ChatPane.create()` (v0.22.7) | Component catalog with shared instance pattern |
|
||||
| `ui-primitives.js` (merged, with `esc()`, `createComponentRegistry()`, `componentMixin()`) | ✅ Done (v0.25.1) |
|
||||
| `ChatPane.create()` + 5 other components using shared mixin | ✅ Done (v0.25.1) |
|
||||
| 5 Go template routes | Surface registry (hardcoded core, manifest-driven extensions) |
|
||||
| `ctx.ui.replace()` / `ctx.ui.inject()` | Hook 6: Surface Injection with declared mount points |
|
||||
| `ctx.surfaces.register()` | Manifest `surfaces` field → page engine route registration |
|
||||
@@ -688,17 +709,22 @@ post-render hooks use to discover display content from any extension.
|
||||
|
||||
This does not prescribe version numbers. It describes dependency order.
|
||||
|
||||
**Phase 1: Primitive consolidation**
|
||||
- Audit `ui-primitives.js`, `ui-primitives-additions.js`, and Go
|
||||
template components
|
||||
- Define the primitive catalog and factory API
|
||||
- Define the CSS custom property contract (theme API)
|
||||
- Migrate existing callers to the consolidated API
|
||||
**Phase 1: Primitive consolidation** ✅ (v0.25.1)
|
||||
- `ui-primitives-additions.js` deleted, survivors merged into
|
||||
`ui-primitives.js`
|
||||
- `esc()` centralized (13 private copies eliminated)
|
||||
- Badge system unified (24 scattered classes → grouped in primitives.css)
|
||||
- CSS variable names normalized, duplicate selectors resolved
|
||||
- `showConfirm()` is the sole confirm pattern (bare `confirm()` purged)
|
||||
|
||||
**Phase 2: Component formalization**
|
||||
- ChatPane already exists (v0.22.7). Formalize the instance pattern.
|
||||
- Extract NoteEditor, FileTree, ModelSelector as components
|
||||
- Each component gets a Go template partial + JS hydration
|
||||
**Phase 2: Component formalization** ✅ (v0.25.1)
|
||||
- `createComponentRegistry()` + `componentMixin()` extracted
|
||||
- 6 components (ChatPane, ModelSelector, UserMenu, CodeEditor, FileTree,
|
||||
NoteEditor) use the shared mixin. ~100 lines of boilerplate eliminated.
|
||||
- Each component has a Go template partial + JS hydration
|
||||
- `surface-nav.js` deleted; navigation is native in `ui-core.js`
|
||||
- Vendor scripts (`marked.min.js`, `purify.min.js`) and `ui-format.js`
|
||||
moved to `base.html` (loaded once, available to all surfaces)
|
||||
|
||||
**Phase 3: Extension hooks**
|
||||
- `Extensions.boot()` on every surface (v0.22.8)
|
||||
|
||||
Reference in New Issue
Block a user