This guide covers migrating from Pika 0.16.x to 0.17.0. Version 0.17.0 introduces new rendering contexts, companion mode for application-first UX, and a comprehensive event system.
Overview
Section titled “Overview”Pika 0.17.0 focuses on enabling "application-first with chat assistance" experiences:
- Hero Context - New singleton widget area for dominant UI elements
- Companion Mode - Compact chat pane when canvas widgets are primary
- Event System - Subscribe to framework state changes
- Canvas Options - Full control mode, close configuration, companion mode
- Chat Pane Minimize - User can minimize chat to a strip
Breaking Changes
Section titled “Breaking Changes”This release is fully backward compatible. All existing widgets and configurations continue to work without modification.
New Features
Section titled “New Features”Hero Rendering Context
Section titled “Hero Rendering Context”A new rendering context for singleton dominant widgets displayed below the spotlight:
// Render a widget in hero contextawait chatAppState.renderTag('acme.dashboard', 'hero', { userId: '123' });
// Control hero visibilitychatAppState.showHero();chatAppState.hideHero();chatAppState.closeHero(); // Destroys the widgetHero vs Spotlight:
| Feature | Hero | Spotlight |
|---|---|---|
| Instances | Singleton (one at a time) | Multiple widgets |
| Lifecycle | Can be destroyed | Persistent during session |
| Purpose | Dominant display widget | Quick access carousel |
| Visibility | API-controlled show/hide | Always visible |
Companion Mode
Section titled “Companion Mode”Enables canvas widgets to become the primary focus while chat becomes a compact assistant:
// Render canvas in companion modeawait chatAppState.renderTag('acme.ide', 'canvas', { companionMode: true, chatPaneMinimized: false // Optional: start minimized});
// Check companion mode stateif (chatAppState.isCompanionMode) { // Adjust for compact chat UI}
// Minimize/expand chat pane programmaticallychatAppState.setChatPaneMinimized(true);Companion Mode Behavior:
- Chat pane becomes compact with reduced padding
- Spotlight widgets are hidden
- Hero widget is hidden
- Chat history panel is minimized
- User can minimize chat to ~20px strip
Event System
Section titled “Event System”Subscribe to framework state changes for reactive widgets:
// Available eventstype ChatAppEvents = { widgetOpen: { tagId: string; instanceId: string; renderingContext: WidgetRenderingContextType }; widgetClose: { tagId: string; instanceId: string; renderingContext: WidgetRenderingContextType }; canvasOpen: { tagId: string; instanceId: string }; canvasClose: { tagId: string; instanceId: string }; chatPaneMinimized: undefined; chatPaneExpanded: undefined; companionModeEnter: undefined; companionModeExit: undefined; heroShow: { tagId: string; instanceId: string }; heroHide: { tagId: string; instanceId: string };};
// Subscribe with automatic cleanup (recommended)const unsubscribe = chatAppState.addEventListener('canvasOpen', (data) => { console.log(`Canvas opened: ${data.tagId}`);}, instanceId); // Pass instanceId for auto-cleanup
// Or manage subscription manuallyconst unsubscribe = chatAppState.addEventListener('companionModeEnter', () => { this.classList.add('expanded');});// Later: unsubscribe();Full Control Canvas Widgets
Section titled “Full Control Canvas Widgets”Widgets can now provide their own chrome (title bar, close button):
// Render with full controlawait chatAppState.renderTag('acme.editor', 'canvas', { fullControl: true, closeConfig: { confirmOnClose: true, confirmTitle: 'Unsaved Changes', confirmMessage: 'You have unsaved work. Close anyway?' }});
// In your widget's close handlerasync function handleClose() { const shouldClose = await context.chatAppState.requestCanvasClose(); // Framework handles confirmation and closes if user confirms}Close Configuration
Section titled “Close Configuration”Configure confirmation dialogs for canvas close:
interface CanvasCloseConfig { confirmOnClose?: boolean; confirmTitle?: string; confirmMessage?: string; confirmButtonLabel?: string; cancelButtonLabel?: string;}New IChatAppState Methods
Section titled “New IChatAppState Methods”Hero Control
Section titled “Hero Control”interface IChatAppState { // Show the hero widget (if one is loaded) showHero(): void;
// Hide the hero widget (keeps in memory) hideHero(): void;
// Destroy the hero widget closeHero(): void;}Companion Mode
Section titled “Companion Mode”interface IChatAppState { // Check if companion mode is active readonly isCompanionMode: boolean;
// Check if chat pane is minimized readonly isChatPaneMinimized: boolean;
// Minimize or expand chat pane setChatPaneMinimized(minimized: boolean): void;}Event System
Section titled “Event System”interface IChatAppState { // Subscribe to an event addEventListener<K extends keyof ChatAppEvents>( event: K, handler: ChatAppEventHandler<K>, instanceId?: string // Pass for auto-cleanup ): () => void; // Returns unsubscribe function
// Unsubscribe from an event removeEventListener<K extends keyof ChatAppEvents>( event: K, handler: ChatAppEventHandler<K> ): void;}Canvas Control
Section titled “Canvas Control”interface IChatAppState { // Request canvas close (for fullControl widgets) // Returns true if close proceeded, false if cancelled requestCanvasClose(): Promise<boolean>;}Updated renderTag Signature
Section titled “Updated renderTag Signature”The renderTag method now accepts 'hero' as a context:
// Before (still works)renderTag(tagId: string, context: 'spotlight' | 'inline' | 'dialog' | 'canvas' | 'static', data?, metadata?): Promise<void>;
// After (with hero)renderTag(tagId: string, context: 'spotlight' | 'inline' | 'dialog' | 'canvas' | 'static' | 'hero', data?, metadata?): Promise<void>;New Types
Section titled “New Types”CanvasWidgetOptions
Section titled “CanvasWidgetOptions”interface CanvasWidgetOptions { companionMode?: boolean; chatPaneMinimized?: boolean; fullControl?: boolean; closeConfig?: CanvasCloseConfig;}HeroContextConfig
Section titled “HeroContextConfig”interface HeroContextConfig { enabled: boolean; sizing?: { minHeight?: number; maxHeight?: number; preferredHeight?: number | 'auto'; };}ChatAppEvents
Section titled “ChatAppEvents”interface ChatAppEvents { widgetOpen: { tagId: string; instanceId: string; renderingContext: WidgetRenderingContextType }; widgetClose: { tagId: string; instanceId: string; renderingContext: WidgetRenderingContextType }; canvasOpen: { tagId: string; instanceId: string }; canvasClose: { tagId: string; instanceId: string }; chatPaneMinimized: undefined; chatPaneExpanded: undefined; companionModeEnter: undefined; companionModeExit: undefined; heroShow: { tagId: string; instanceId: string }; heroHide: { tagId: string; instanceId: string };}CSS Variables for Companion Mode
Section titled “CSS Variables for Companion Mode”New CSS variables are available when companion mode is active:
/* Applied when data-companion-mode="true" */--companion-padding: 0.5rem;--companion-font-size: 0.875rem;--companion-spacing: 0.25rem;Migration Steps
Section titled “Migration Steps”For Most Users: No Action Required
Section titled “For Most Users: No Action Required”If you're not using the new features, your existing code continues to work unchanged.
To Adopt Hero Context
Section titled “To Adopt Hero Context”- Identify widgets that should be dominant display elements
- Update your orchestrator/static widget to call
renderTagwith'hero'context - Optionally configure hero sizing in tag definition
To Adopt Companion Mode
Section titled “To Adopt Companion Mode”- Identify canvas widgets that should be "primary application" experiences
- Pass
companionMode: truein yourrenderTagdata - Optionally implement event listeners for mode changes
- Test UI in both normal and companion modes
To Adopt Event System
Section titled “To Adopt Event System”- Identify places where widgets need to react to framework state
- Add event listeners with
instanceIdfor automatic cleanup - Remove any manual state polling
Best Practices
Section titled “Best Practices”Event Handler Cleanup
Section titled “Event Handler Cleanup”// GOOD: Pass instanceId for automatic cleanupchatAppState.addEventListener('canvasClose', handler, instanceId);
// ACCEPTABLE: Manual cleanup when widget lifecycle is managedconst unsubscribe = chatAppState.addEventListener('canvasClose', handler);// Later in disconnectedCallback:unsubscribe();
// BAD: No cleanup leads to memory leakschatAppState.addEventListener('canvasClose', handler);Full Control Widget Design
Section titled “Full Control Widget Design”When using fullControl: true:
- Provide clear visual affordances for closing
- Use
requestCanvasClose()to respectcloseConfig - Handle the case where close is cancelled
- Consider adding a visible title/header
Companion Mode UX
Section titled “Companion Mode UX”When designing for companion mode:
- Ensure your canvas widget works at various widths
- Consider the minimized chat strip state
- Provide ways for users to interact with chat when needed
- Test responsive behavior as users resize panes
Troubleshooting
Section titled “Troubleshooting”Hero Not Showing
Section titled “Hero Not Showing”- Verify you're calling
renderTagwith'hero'context - Check that companion mode isn't active (hero is hidden in companion mode)
- Ensure widget loaded successfully (check console for errors)
Events Not Firing
Section titled “Events Not Firing”- Verify event name matches exactly (case-sensitive)
- Ensure handler isn't being removed elsewhere
- Check that the triggering action actually occurred
Memory Leaks
Section titled “Memory Leaks”- Always pass
instanceIdwhen subscribing to events - Call unsubscribe functions in
disconnectedCallback - Use browser DevTools to monitor event listener counts
Related Documentation
Section titled “Related Documentation”- Widget System Reference - Complete widget API reference
- Web Components Guide - Building custom widgets
- Widget Context API - Context available to widgets