Appearance
Simulator events console design
Context
The simulator page now covers source data input and runtime controls, but it still lacks visibility into SDK callbacks. Developers can click rooms and tune runtime values, yet they cannot see which public callbacks the SDK actually fires or inspect the payload shape without writing custom code.
This design adds an Events console to the simulator so developers can verify SDK callback behavior from the docs UI.
Goals
- Record only SDK public callbacks that are meaningful to integrators.
- Show callback names exactly as they appear in
MapCallbacks. - Make event payloads easy to scan, expand, and copy.
- Keep the map preview large and preserve the simulator's minimal visual style.
- Introduce a reusable UI primitive layer for popovers, tooltips, and menus without forcing a heavy component framework into the docs site.
Non-goals
- Do not record simulator-internal actions such as runtime patches, auto-render, cache restore, or example reset.
- Do not build a general-purpose logging system for the SDK.
- Do not add toast notifications for every callback.
- Do not replace all existing simulator controls with third-party primitives in this iteration.
Recommended approach
Option 1: toast plus history
Show a transient toast for each callback and also append the event to a history panel.
- Pros: immediate feedback.
- Cons: noisy, distracts from map interaction, and scales poorly during rapid clicks.
Option 2: dedicated events console
Add a fixed Events panel near the map. Each callback appends a structured record with a short summary and expandable JSON payload.
- Pros: developer-friendly, easy to filter, easy to copy, and aligned with how engineers debug SDK integrations.
- Cons: weaker instant feedback than a toast, but still clear enough in a live panel.
Option 3: console plus map overlay
Combine the event console with a temporary overlay that shows the latest event inside the map preview.
- Pros: strongest immediate feedback.
- Cons: more UI complexity and more risk of visual noise.
This design uses option 2.
Page information architecture
The simulator keeps the current two-column layout.
- Left column:
DataRuntimeInspector
- Right column:
- map preview
Events
The Events panel belongs with the map, not with the left control column. Events are a result of interacting with the SDK surface, so the event stream should remain visually close to the preview that triggers it.
Event model
The event console records only SDK callbacks exposed through MapCallbacks.
V1 starts with callbacks that already exist and matter in the current simulator flow:
onClickRoomonClickRoomProperties
Each event record has this shape:
ts
type SimulatorEventRecord = {
id: string
name: keyof MapCallbacks
timestamp: number
timeLabel: string
payload: unknown
summary: string
}Field purpose
id: stable render key.name: the exact callback name shown to developers.timestamp: raw sort and copy value.timeLabel: readable time for the list.payload: full callback payload used for JSON expansion and copy.summary: concise text for the collapsed row.
Event source strategy
The simulator must not infer events from UI state. It should record only what MapApplication actually emits.
Use wrapped SDK callbacks when creating or updating the map instance:
- inject a recorder-backed
eventsobject into the SDK config - let the SDK invoke callbacks normally
- append a record to the event store inside each callback wrapper
This guarantees the console reflects the real public API surface rather than a simulator-specific approximation.
Events panel behavior
The Events panel is a compact developer console.
Toolbar
The header includes:
- callback filter
PauseClearCopy JSON
List rows
Each row shows:
- callback name
- event time
- summary line
- expand or collapse control for payload JSON
Empty state
Show a single neutral message:
No SDK callbacks yet
Capacity
Keep only the most recent 100 records. Drop the oldest record first when the limit is exceeded.
Summary rules
Collapsed rows need short summaries that are useful at a glance.
Examples:
onClickRoom->roomId=8, name=阳台8onClickRoomProperties->roomId=8, property clicked
Summary generation stays in a dedicated helper so more callbacks can be added later without bloating the panel component.
UI primitive strategy
The simulator is starting to depend on recurring interaction patterns:
- tooltip
- popover
- dropdown menu
- collapsible content
- custom select behavior
A full UI framework would add unnecessary visual and structural weight. This iteration introduces reka-ui as a headless primitive layer instead.
Why reka-ui
- It fits Vue 3 well.
- It supplies behavior and accessibility without imposing a visual system.
- It matches the simulator's existing design direction better than a full UI framework.
- It creates a path to standardize future overlays and menus without forcing a full component rewrite now.
V1 usage boundary
Only use reka-ui where it solves an actual problem in this iteration:
- event filter menu or select
- event row collapsible payload
- tooltip or popover where the simulator already needs one
Do not use this iteration to replace every custom simulator control.
Component structure
Recommended additions:
useSimulatorEvents.tseventSummaries.tsSimulatorEventsPanel.vueSimulatorEventItem.vue
Expected integration points:
useMapCanvas.tsorusePlaygroundRender.tsfor callback injectionuseMapPlayground.tsfor page-level state wiringMapPlayground.vuefor layout placement
Data flow
- The simulator creates the map instance with recorder-backed SDK callbacks.
- The SDK fires a public callback.
- The wrapper creates a
SimulatorEventRecord. useSimulatorEvents()appends the record.SimulatorEventsPanel.vuereacts and renders the update.
The source of truth is the event store, not the UI.
Error handling
Event recording should fail soft.
- If summary generation fails, store the event with a fallback summary such as
payload recorded. - If JSON copy fails, show a lightweight UI failure state but keep the list.
- If the event filter or payload viewer fails, do not affect the map or runtime controls.
Verification strategy
- Click a room and confirm
onClickRoomappears with the correct payload. - Click a room property label and confirm
onClickRoomPropertiesappears. - Pause the console and confirm new callbacks stop appending.
- Clear the console and confirm only event state resets.
- Copy the event log and confirm the output is a valid JSON array.
- Confirm the docs build still passes and the map preview remains visually stable.