UI Operations
UI operations cover building UI components, panels, and integrating with UI Core for framework-agnostic UI development.
When to Use
- Creating new UI panels
- Building UI Core components
- Integrating Web Components
- Debugging UI issues
- Understanding UI architecture
UI Architecture
UI Core (Framework-Agnostic)
packages/ui/core/
├── dock.ts # Dock interface
├── overlay.ts # Overlay interface
├── panel.ts # Panel interface
└── types.ts # Type definitions
UI Web (Web Components)
packages/ui/web/
├── elements/
� ├── ThreeLensDock.ts # Dock Web Component
� ├── ThreeLensOverlay.ts # Overlay Web Component
� └── ThreeLensPanel.ts # Panel Web Component
└── styles.ts # Shared styles
Commands
Scaffold a Panel
# Create a new UI panel
3lens scaffold panel my-panel
# Create panel in specific addon
3lens scaffold panel my-panel --addon my-addon
Generates:
- Panel source file
- Query hooks
- Contract compliance checklist
- Test file template
Panel Development
Panel Structure
// packages/ui-core/src/panels/my-panel.ts
import { Panel, PanelConfig } from '../types';
import { LensClient } from '@3lens/runtime';
export interface MyPanelConfig extends PanelConfig {
// Panel-specific config
}
export function createMyPanel(client: LensClient, config: MyPanelConfig): Panel {
return {
id: 'my-panel',
name: 'My Panel',
render(container: HTMLElement) {
// Render panel UI
},
onSelectionChange(selection: Selection) {
// React to selection changes
},
dispose() {
// Cleanup
}
};
}
Panel Requirements
Every panel MUST:
Answer a Clear Question
- What question does this panel answer?
- What entities does it display?
Show Fidelity Badges
function renderMetric(value: number, fidelity: Fidelity) { return ` <span class="metric"> ${value} <span class="fidelity-badge fidelity-${fidelity}"> ${fidelity} </span> </span> `; }Route Through Inspector
// When user clicks something client.select(entityId, { source: 'my-panel' }); // When selection changes onSelectionChange(selection) { this.highlightEntities(selection.entity_ids); }Support Offline Traces
const data = client.isLive ? await client.queryLive(query, params) : await client.queryTrace(query, params);Include Attribution Paths
function renderHotspot(hotspot) { return ` <div ${hotspot.gpuTime}ms <span class="attribution"> ${hotspot.attribution.map(a => a.entityId).join(', ')} </span> </div> `; }
Web Components
Using UI Web Components
<!-- Dock mode -->
<three-lens-dock>
<three-lens-panel id="inspector"></three-lens-panel>
<three-lens-panel id="perf"></three-lens-panel>
</three-lens-dock>
<!-- Overlay mode -->
<three-lens-overlay>
<three-lens-panel id="inspector"></three-lens-panel>
</three-lens-overlay>
Custom Panel Component
// Custom panel Web Component
import { ThreeLensPanel } from '@3lens/ui-web';
class MyCustomPanel extends ThreeLensPanel {
connectedCallback() {
super.connectedCallback();
// Custom initialization
}
render(client: LensClient) {
// Custom rendering
}
}
customElements.define('my-custom-panel', MyCustomPanel);
UI Modes
Dock Mode
// Dock interface
interface Dock {
addPanel(panel: Panel): void;
removePanel(panelId: string): void;
show(): void;
hide(): void;
}
Overlay Mode
// Overlay interface
interface Overlay {
showPanel(panelId: string): void;
hidePanel(panelId: string): void;
toggle(): void;
}
Agent Use Cases
- New panel: "Create a performance timeline panel"
- UI integration: "How do I integrate 3Lens UI into my app?"
- Custom component: "Create a custom panel component"
- Debugging: "My panel isn't rendering, help debug"
Post-Scaffold Steps
After scaffolding, follow the playbook:
Additional Resources
- Contract: .cursor/contracts/ui-surfaces.md
- Contract: .cursor/contracts/inspector.md
- Rule: .cursor/rules/ui-standards.mdc
- Command: .cursor/commands/scaffold-panel.md
- Skill: scaffold-operations
Converted and distributed by TomeVault — claim your Tome and manage your conversions.